// +build functional package test import ( "os" "testing" "time" "github.com/vapor/consensus" dbm "github.com/vapor/database/leveldb" "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" "github.com/vapor/protocol/vm" ) func TestBlockHeader(t *testing.T) { db := dbm.NewDB("block_test_db", "leveldb", "block_test_db") defer os.RemoveAll("block_test_db") chain, _, _, err := MockChain(db) if err != nil { t.Fatal(err) } genesisHeader := chain.BestBlockHeader() if err := AppendBlocks(chain, 1); err != nil { t.Fatal(err) } cases := []struct { desc string version func() uint64 prevHeight func() uint64 timestamp func() uint64 prevHash func() *bc.Hash valid bool }{ { desc: "block version is 1", version: func() uint64 { return 1 }, prevHeight: chain.BestBlockHeight, timestamp: func() uint64 { return chain.BestBlockHeader().Timestamp + 1 }, prevHash: chain.BestBlockHash, valid: true, }, { desc: "invalid block, misorder block height", version: func() uint64 { return chain.BestBlockHeader().Version }, prevHeight: func() uint64 { return chain.BestBlockHeight() + 1 }, timestamp: func() uint64 { return chain.BestBlockHeader().Timestamp + 1 }, prevHash: chain.BestBlockHash, valid: false, }, { desc: "invalid prev hash, prev hash dismatch", version: func() uint64 { return chain.BestBlockHeader().Version }, prevHeight: chain.BestBlockHeight, timestamp: func() uint64 { return chain.BestBlockHeader().Timestamp + 1 }, prevHash: func() *bc.Hash { hash := genesisHeader.Hash(); return &hash }, valid: false, }, { desc: "invalid timestamp, greater than MaxTimeOffsetMs from system time", version: func() uint64 { return chain.BestBlockHeader().Version }, prevHeight: chain.BestBlockHeight, timestamp: func() uint64 { return uint64(time.Now().Unix()) + consensus.ActiveNetParams.MaxTimeOffsetMs + 60 }, prevHash: chain.BestBlockHash, valid: false, }, { desc: "valid timestamp, greater than last block", version: func() uint64 { return chain.BestBlockHeader().Version }, prevHeight: chain.BestBlockHeight, timestamp: func() uint64 { return chain.BestBlockHeader().Timestamp + 3 }, prevHash: chain.BestBlockHash, valid: true, }, { desc: "valid timestamp, less than last block, but greater than median", version: func() uint64 { return chain.BestBlockHeader().Version }, prevHeight: chain.BestBlockHeight, timestamp: func() uint64 { return chain.BestBlockHeader().Timestamp - 1 }, prevHash: chain.BestBlockHash, valid: true, }, { desc: "invalid timestamp, less than median", version: func() uint64 { return chain.BestBlockHeader().Version }, prevHeight: chain.BestBlockHeight, timestamp: func() uint64 { return genesisHeader.Timestamp }, prevHash: chain.BestBlockHash, valid: false, }, } for _, c := range cases { block, err := NewBlock(chain, nil, []byte{byte(vm.OP_TRUE)}) if err != nil { t.Fatal(err) } block.Version = c.version() block.Height = c.prevHeight() + 1 block.Timestamp = c.timestamp() block.PreviousBlockHash = *c.prevHash() _, err = chain.ProcessBlock(block) result := err == nil if result != c.valid { t.Fatalf("%s test failed, expected: %t, have: %t, err: %s", c.desc, c.valid, result, err) } } } func TestMaxBlockGas(t *testing.T) { chainDB := dbm.NewDB("test_block_db", "leveldb", "test_block_db") defer os.RemoveAll("test_block_db") chain, _, _, err := MockChain(chainDB) if err != nil { t.Fatal(err) } if err := AppendBlocks(chain, 7); err != nil { t.Fatal(err) } block, err := chain.GetBlockByHeight(1) if err != nil { t.Fatal(err) } tx, err := CreateTxFromTx(block.Transactions[0], 0, 600000000000, []byte{byte(vm.OP_TRUE)}) if err != nil { t.Fatal(err) } outputAmount := uint64(600000000000) txs := []*types.Tx{tx} for i := 1; i < 50000; i++ { outputAmount -= 10000000 tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)}) if err != nil { t.Fatal(err) } txs = append(txs, tx) } block, err = NewBlock(chain, txs, []byte{byte(vm.OP_TRUE)}) if err != nil { t.Fatal(err) } if _, err := chain.ProcessBlock(block); err == nil { t.Fatalf("test max block gas failed") } }