OSDN Git Service

init delete the pow related (#55)
[bytom/vapor.git] / test / protocol_test.go
1 // +build functional
2
3 package test
4
5 import (
6         "os"
7         "testing"
8
9         "github.com/vapor/consensus"
10         dbm "github.com/vapor/database/leveldb"
11         "github.com/vapor/protocol/bc/types"
12         "github.com/vapor/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, consensus.CoinbasePendingBlockNumber+1); 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 = chain.ProcessBlock(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         if isOrphan, err := chain.ValidateTx(tx); isOrphan == false && err == nil {
137                 t.Fatal("validate double spent tx success")
138         }
139         if txPool.HaveTransaction(&tx.ID) {
140                 t.Fatalf("tx pool have double spent tx")
141         }
142 }
143
144 func TestDoubleSpentInSameBlock(t *testing.T) {
145         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
146         defer os.RemoveAll("tx_pool_test")
147         chain, _, txPool, err := MockChain(chainDB)
148         if err != nil {
149                 t.Fatal(err)
150         }
151         if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
152                 t.Fatal(err)
153         }
154
155         // create tx spend the coinbase output in block 1
156         block, err := chain.GetBlockByHeight(1)
157         if err != nil {
158                 t.Fatal(err)
159         }
160         tx1, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
161         if err != nil {
162                 t.Fatal(err)
163         }
164
165         // create tx spend the coinbase output in block 1
166         tx2, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
167         if err != nil {
168                 t.Fatal(err)
169         }
170
171         _, err = chain.ValidateTx(tx1)
172         if err != nil {
173                 t.Fatal(err)
174         }
175         _, err = chain.ValidateTx(tx2)
176         if err != nil {
177                 t.Fatal(err)
178         }
179
180         if !txPool.HaveTransaction(&tx1.ID) {
181                 t.Fatalf("can't find tx in tx pool")
182         }
183         if !txPool.HaveTransaction(&tx2.ID) {
184                 t.Fatalf("can't find tx in tx pool")
185         }
186
187         block, err = NewBlock(chain, []*types.Tx{tx1, tx2}, []byte{byte(vm.OP_TRUE)})
188         if err != nil {
189                 t.Fatal(err)
190         }
191
192         if _, err := chain.ProcessBlock(block); err == nil {
193                 t.Fatalf("process double spent tx success")
194         }
195 }
196
197 func TestTxPoolDependencyTx(t *testing.T) {
198         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
199         defer os.RemoveAll("tx_pool_test")
200         chain, _, txPool, err := MockChain(chainDB)
201         if err != nil {
202                 t.Fatal(err)
203         }
204         if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
205                 t.Fatal(err)
206         }
207
208         block, err := chain.GetBlockByHeight(1)
209         if err != nil {
210                 t.Fatal(err)
211         }
212
213         tx, err := CreateTxFromTx(block.Transactions[0], 0, 5000000000, []byte{byte(vm.OP_TRUE)})
214         if err != nil {
215                 t.Fatal(err)
216         }
217
218         outputAmount := uint64(5000000000)
219         txs := []*types.Tx{nil}
220         txs[0] = tx
221         for i := 1; i < 10; i++ {
222                 outputAmount -= 50000000
223                 tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)})
224                 if err != nil {
225                         t.Fatal(err)
226                 }
227                 txs = append(txs, tx)
228         }
229
230         // validate tx and put it into tx pool
231         for _, tx := range txs {
232                 if _, err := chain.ValidateTx(tx); err != nil {
233                         t.Fatal(err)
234                 }
235                 if !txPool.HaveTransaction(&tx.ID) {
236                         t.Fatal("can't find tx in txpool")
237                 }
238         }
239
240         block, err = NewBlock(chain, txs, []byte{byte(vm.OP_TRUE)})
241         if err != nil {
242                 t.Fatal(err)
243         }
244
245         if _, err := chain.ProcessBlock(block); err != nil {
246                 t.Fatal("process dependency tx failed")
247         }
248 }
249
250 func TestAddInvalidTxToTxPool(t *testing.T) {
251         chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
252         defer os.RemoveAll("tx_pool_test")
253
254         chain, _, txPool, err := MockChain(chainDB)
255         if err != nil {
256                 t.Fatal(err)
257         }
258
259         if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
260                 t.Fatal(err)
261         }
262
263         block, err := chain.GetBlockByHeight(1)
264         if err != nil {
265                 t.Fatal(err)
266         }
267
268         //invalid tx, output amount greater than input
269         tx, err := CreateTxFromTx(block.Transactions[0], 0, 60000000000, []byte{byte(vm.OP_TRUE)})
270         if err != nil {
271                 t.Fatal(err)
272         }
273
274         if _, err := chain.ValidateTx(tx); err == nil {
275                 t.Fatalf("add invalid tx to txpool success")
276         }
277
278         if txPool.IsTransactionInPool(&tx.ID) {
279                 t.Fatalf("add invalid tx to txpool success")
280         }
281
282         if !txPool.IsTransactionInErrCache(&tx.ID) {
283                 t.Fatalf("can't find invalid tx in txpool err cache")
284         }
285 }