OSDN Git Service

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