github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/test/block_test.go (about)

     1  // +build functional
     2  
     3  package test
     4  
     5  import (
     6  	"os"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/bytom/bytom/consensus"
    11  	"github.com/bytom/bytom/protocol/bc"
    12  	"github.com/bytom/bytom/protocol/bc/types"
    13  	"github.com/bytom/bytom/protocol/vm"
    14  	dbm "github.com/bytom/bytom/database/leveldb"
    15  )
    16  
    17  func TestBlockHeader(t *testing.T) {
    18  	db := dbm.NewDB("block_test_db", "leveldb", "block_test_db")
    19  	defer os.RemoveAll("block_test_db")
    20  	chain, _, _, _ := MockChain(db)
    21  	genesisHeader := chain.BestBlockHeader()
    22  	if err := AppendBlocks(chain, 1); err != nil {
    23  		t.Fatal(err)
    24  	}
    25  
    26  	cases := []struct {
    27  		desc       string
    28  		version    func() uint64
    29  		prevHeight func() uint64
    30  		timestamp  func() uint64
    31  		prevHash   func() *bc.Hash
    32  		bits       func() uint64
    33  		solve      bool
    34  		valid      bool
    35  	}{
    36  		{
    37  			desc:       "block version is 1",
    38  			version:    func() uint64 { return 1 },
    39  			prevHeight: chain.BestBlockHeight,
    40  			timestamp:  func() uint64 { return chain.BestBlockHeader().Timestamp + 1 },
    41  			prevHash:   chain.BestBlockHash,
    42  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
    43  			solve:      true,
    44  			valid:      true,
    45  		},
    46  		{
    47  			desc:       "invalid block, misorder block height",
    48  			version:    func() uint64 { return chain.BestBlockHeader().Version },
    49  			prevHeight: func() uint64 { return chain.BestBlockHeight() + 1 },
    50  			timestamp:  func() uint64 { return chain.BestBlockHeader().Timestamp + 1 },
    51  			prevHash:   chain.BestBlockHash,
    52  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
    53  			solve:      true,
    54  			valid:      false,
    55  		},
    56  		{
    57  			desc:       "invalid prev hash, prev hash dismatch",
    58  			version:    func() uint64 { return chain.BestBlockHeader().Version },
    59  			prevHeight: chain.BestBlockHeight,
    60  			timestamp:  func() uint64 { return chain.BestBlockHeader().Timestamp + 1 },
    61  			prevHash:   func() *bc.Hash { hash := genesisHeader.Hash(); return &hash },
    62  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
    63  			solve:      true,
    64  			valid:      false,
    65  		},
    66  		{
    67  			desc:       "invalid bits",
    68  			version:    func() uint64 { return chain.BestBlockHeader().Version },
    69  			prevHeight: chain.BestBlockHeight,
    70  			timestamp:  func() uint64 { return chain.BestBlockHeader().Timestamp + 1 },
    71  			prevHash:   chain.BestBlockHash,
    72  			bits:       func() uint64 { return chain.BestBlockHeader().Bits + 100 },
    73  			solve:      true,
    74  			valid:      false,
    75  		},
    76  		{
    77  			desc:       "invalid timestamp, greater than MaxTimeOffsetSeconds from system time",
    78  			version:    func() uint64 { return chain.BestBlockHeader().Version },
    79  			prevHeight: chain.BestBlockHeight,
    80  			timestamp:  func() uint64 { return uint64(time.Now().Unix()) + consensus.MaxTimeOffsetSeconds + 60 },
    81  			prevHash:   chain.BestBlockHash,
    82  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
    83  			solve:      true,
    84  			valid:      false,
    85  		},
    86  		{
    87  			desc:       "valid timestamp, greater than last block",
    88  			version:    func() uint64 { return chain.BestBlockHeader().Version },
    89  			prevHeight: chain.BestBlockHeight,
    90  			timestamp:  func() uint64 { return chain.BestBlockHeader().Timestamp + 3 },
    91  			prevHash:   chain.BestBlockHash,
    92  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
    93  			solve:      true,
    94  			valid:      true,
    95  		},
    96  		{
    97  			desc:       "valid timestamp, less than last block, but greater than median",
    98  			version:    func() uint64 { return chain.BestBlockHeader().Version },
    99  			prevHeight: chain.BestBlockHeight,
   100  			timestamp:  func() uint64 { return chain.BestBlockHeader().Timestamp - 1 },
   101  			prevHash:   chain.BestBlockHash,
   102  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
   103  			solve:      true,
   104  			valid:      true,
   105  		},
   106  		{
   107  			desc:       "invalid timestamp, less than median",
   108  			version:    func() uint64 { return chain.BestBlockHeader().Version },
   109  			prevHeight: chain.BestBlockHeight,
   110  			timestamp:  func() uint64 { return genesisHeader.Timestamp },
   111  			prevHash:   chain.BestBlockHash,
   112  			bits:       func() uint64 { return chain.BestBlockHeader().Bits },
   113  			solve:      true,
   114  			valid:      false,
   115  		},
   116  	}
   117  
   118  	for _, c := range cases {
   119  		block, err := NewBlock(chain, nil, []byte{byte(vm.OP_TRUE)})
   120  		if err != nil {
   121  			t.Fatal(err)
   122  		}
   123  
   124  		block.Version = c.version()
   125  		block.Height = c.prevHeight() + 1
   126  		block.Timestamp = c.timestamp()
   127  		block.PreviousBlockHash = *c.prevHash()
   128  		block.Bits = c.bits()
   129  		seed, err := chain.CalcNextSeed(&block.PreviousBlockHash)
   130  		if err != nil && c.valid {
   131  			t.Fatal(err)
   132  		}
   133  
   134  		if c.solve {
   135  			Solve(seed, block)
   136  		}
   137  		_, err = chain.ProcessBlock(block)
   138  		result := err == nil
   139  		if result != c.valid {
   140  			t.Fatalf("%s test failed, expected: %t, have: %t, err: %s", c.desc, c.valid, result, err)
   141  		}
   142  	}
   143  }
   144  
   145  func TestMaxBlockGas(t *testing.T) {
   146  	chainDB := dbm.NewDB("test_block_db", "leveldb", "test_block_db")
   147  	defer os.RemoveAll("test_block_db")
   148  	chain, _, _, err := MockChain(chainDB)
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  
   153  	if err := AppendBlocks(chain, 7); err != nil {
   154  		t.Fatal(err)
   155  	}
   156  
   157  	block, err := chain.GetBlockByHeight(1)
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  
   162  	tx, err := CreateTxFromTx(block.Transactions[0], 0, 600000000000, []byte{byte(vm.OP_TRUE)})
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	outputAmount := uint64(600000000000)
   168  	txs := []*types.Tx{tx}
   169  	for i := 1; i < 50000; i++ {
   170  		outputAmount -= 10000000
   171  		tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)})
   172  		if err != nil {
   173  			t.Fatal(err)
   174  		}
   175  		txs = append(txs, tx)
   176  	}
   177  
   178  	block, err = NewBlock(chain, txs, []byte{byte(vm.OP_TRUE)})
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  
   183  	if err := SolveAndUpdate(chain, block); err == nil {
   184  		t.Fatalf("test max block gas failed")
   185  	}
   186  }