OSDN Git Service

return asset definition when get balances
[bytom/bytom.git] / test / protocol_test.go
1 // +build functional
2
3 package test
4
5 import (
6         "os"
7         "testing"
8
9         dbm "github.com/tendermint/tmlibs/db"
10
11         "github.com/bytom/protocol/bc/types"
12         "github.com/bytom/protocol/vm"
13 )
14
15 // case1:           |------c1(height=7)
16 // --------(height=5)
17 //                  |------------c2(height=9)
18 func TestForkCase1(t *testing.T) {
19         c1, err := declChain("chain1", nil, 0, 7)
20         defer os.RemoveAll("chain1")
21         if err != nil {
22                 t.Fatal(err)
23         }
24
25         c2, err := declChain("chain2", c1, 5, 9)
26         defer os.RemoveAll("chain2")
27         if err != nil {
28                 t.Fatal(err)
29         }
30
31         bestBlockHash := c2.BestBlockHash()
32         if err := merge(c1, c2); err != nil {
33                 t.Fatal(err)
34         }
35
36         if *c1.BestBlockHash() != *bestBlockHash || *c2.BestBlockHash() != *bestBlockHash {
37                 t.Fatalf("test fork case1 failed")
38         }
39
40         if !c1.InMainChain(*bestBlockHash) || !c2.InMainChain(*bestBlockHash) {
41                 t.Fatalf("best block is not in main chain")
42         }
43 }
44
45 // case2:            |----c1(height=6)
46 // ---------(height 5)
47 //                   |----c2(height=6)
48 func TestForkCase2(t *testing.T) {
49         c1, err := declChain("chain1", nil, 0, 6)
50         defer os.RemoveAll("chain1")
51         if err != nil {
52                 t.Fatal(err)
53         }
54
55         c2, err := declChain("chain2", c1, 5, 6)
56         defer os.RemoveAll("chain2")
57         if err != nil {
58                 t.Fatal(err)
59         }
60
61         c1BestBlockHash := c1.BestBlockHash()
62         c2BestBlockHash := c2.BestBlockHash()
63         if err := merge(c1, c2); err != nil {
64                 t.Fatal(err)
65         }
66
67         if *c1.BestBlockHash() != *c1BestBlockHash || *c2.BestBlockHash() != *c2BestBlockHash {
68                 t.Fatalf("test fork case2 failed")
69         }
70
71         if !c1.InMainChain(*c1BestBlockHash) || !c2.InMainChain(*c2BestBlockHash) {
72                 t.Fatalf("best block is not in main chain")
73         }
74 }
75
76 func TestBlockSync(t *testing.T) {
77         c1, err := declChain("chain1", nil, 0, 5)
78         defer os.RemoveAll("chain1")
79         if err != nil {
80                 t.Fatal(err)
81         }
82
83         c2, err := declChain("chain2", c1, 5, 8)
84         defer os.RemoveAll("chain2")
85         if err != nil {
86                 t.Fatal(err)
87         }
88
89         bestBlockHash := c2.BestBlockHash()
90         if err := merge(c1, c2); err != nil {
91                 t.Fatal(err)
92         }
93
94         if *c1.BestBlockHash() != *bestBlockHash || *c2.BestBlockHash() != *bestBlockHash {
95                 t.Fatalf("test block sync failed")
96         }
97
98         if !c1.InMainChain(*bestBlockHash) || !c2.InMainChain(*bestBlockHash) {
99                 t.Fatalf("test block sync failed, best block is not in main chain")
100         }
101 }
102
103 func TestDoubleSpentInDiffBlock(t *testing.T) {
104         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
105         defer os.RemoveAll("tx_pool_test")
106         chain, _, txPool, err := MockChain(chainDB)
107         if err != nil {
108                 t.Fatal(err)
109         }
110         if err := AppendBlocks(chain, 6); err != nil {
111                 t.Fatal(err)
112         }
113
114         // create tx spend the coinbase output in block 1
115         block, err := chain.GetBlockByHeight(1)
116         if err != nil {
117                 t.Fatal(err)
118         }
119         tx, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
120         if err != nil {
121                 t.Fatal(err)
122         }
123
124         newBlock, err := NewBlock(chain, []*types.Tx{tx}, []byte{byte(vm.OP_TRUE)})
125         err = SolveAndUpdate(chain, newBlock)
126         if err != nil {
127                 t.Fatal(err)
128         }
129
130         // create a double spent tx in another block
131         tx, err = CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
132         if err != nil {
133                 t.Fatal(err)
134         }
135
136         _, err = chain.ValidateTx(tx)
137         if err == nil {
138                 t.Fatal("validate double spent tx success")
139         }
140         if txPool.HaveTransaction(&tx.ID) {
141                 t.Fatalf("tx pool have double spent tx")
142         }
143 }
144
145 func TestDoubleSpentInSameBlock(t *testing.T) {
146         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
147         defer os.RemoveAll("tx_pool_test")
148         chain, _, txPool, err := MockChain(chainDB)
149         if err != nil {
150                 t.Fatal(err)
151         }
152         if err := AppendBlocks(chain, 7); err != nil {
153                 t.Fatal(err)
154         }
155
156         // create tx spend the coinbase output in block 1
157         block, err := chain.GetBlockByHeight(1)
158         if err != nil {
159                 t.Fatal(err)
160         }
161         tx1, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
162         if err != nil {
163                 t.Fatal(err)
164         }
165
166         // create tx spend the coinbase output in block 1
167         tx2, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
168         if err != nil {
169                 t.Fatal(err)
170         }
171
172         _, err = chain.ValidateTx(tx1)
173         if err != nil {
174                 t.Fatal(err)
175         }
176         _, err = chain.ValidateTx(tx2)
177         if err != nil {
178                 t.Fatal(err)
179         }
180
181         if !txPool.HaveTransaction(&tx1.ID) {
182                 t.Fatalf("can't find tx in tx pool")
183         }
184         if !txPool.HaveTransaction(&tx2.ID) {
185                 t.Fatalf("can't find tx in tx pool")
186         }
187
188         block, err = NewBlock(chain, []*types.Tx{tx1, tx2}, []byte{byte(vm.OP_TRUE)})
189         if err != nil {
190                 t.Fatal(err)
191         }
192
193         if err := SolveAndUpdate(chain, block); err == nil {
194                 t.Fatalf("process double spent tx success")
195         }
196 }
197
198 func TestTxPoolDependencyTx(t *testing.T) {
199         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
200         defer os.RemoveAll("tx_pool_test")
201         chain, _, txPool, err := MockChain(chainDB)
202         if err != nil {
203                 t.Fatal(err)
204         }
205         if err := AppendBlocks(chain, 7); err != nil {
206                 t.Fatal(err)
207         }
208
209         block, err := chain.GetBlockByHeight(1)
210         if err != nil {
211                 t.Fatal(err)
212         }
213
214         tx, err := CreateTxFromTx(block.Transactions[0], 0, 5000000000, []byte{byte(vm.OP_TRUE)})
215         if err != nil {
216                 t.Fatal(err)
217         }
218
219         outputAmount := uint64(5000000000)
220         txs := []*types.Tx{nil}
221         txs[0] = tx
222         for i := 1; i < 10; i++ {
223                 outputAmount -= 50000000
224                 tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)})
225                 if err != nil {
226                         t.Fatal(err)
227                 }
228                 txs = append(txs, tx)
229         }
230
231         // validate tx and put it into tx pool
232         for _, tx := range txs {
233                 if _, err := chain.ValidateTx(tx); err != nil {
234                         t.Fatal(err)
235                 }
236                 if !txPool.HaveTransaction(&tx.ID) {
237                         t.Fatal("can't find tx in txpool")
238                 }
239         }
240
241         block, err = NewBlock(chain, txs, []byte{byte(vm.OP_TRUE)})
242         if err != nil {
243                 t.Fatal(err)
244         }
245
246         if err := SolveAndUpdate(chain, block); err != nil {
247                 t.Fatal("process dependency tx failed")
248         }
249 }
250
251 func TestAddInvalidTxToTxPool(t *testing.T) {
252         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
253         defer os.RemoveAll("tx_pool_test")
254
255         chain, _, txPool, err := MockChain(chainDB)
256         if err != nil {
257                 t.Fatal(err)
258         }
259
260         if err := AppendBlocks(chain, 7); err != nil {
261                 t.Fatal(err)
262         }
263
264         block, err := chain.GetBlockByHeight(1)
265         if err != nil {
266                 t.Fatal(err)
267         }
268
269         //invalid tx, output amount greater than input
270         tx, err := CreateTxFromTx(block.Transactions[0], 0, 60000000000, []byte{byte(vm.OP_TRUE)})
271         if err != nil {
272                 t.Fatal(err)
273         }
274
275         if _, err := chain.ValidateTx(tx); err == nil {
276                 t.Fatalf("add invalid tx to txpool success")
277         }
278
279         if txPool.IsTransactionInPool(&tx.ID) {
280                 t.Fatalf("add invalid tx to txpool success")
281         }
282
283         if !txPool.IsTransactionInErrCache(&tx.ID) {
284                 t.Fatalf("can't find invalid tx in txpool err cache")
285         }
286 }