9 dbm "github.com/tendermint/tmlibs/db"
11 "github.com/bytom/protocol/bc/types"
12 "github.com/bytom/protocol/vm"
15 // case1: |------c1(height=7)
17 // |------------c2(height=9)
18 func TestForkCase1(t *testing.T) {
19 c1, err := declChain("chain1", nil, 0, 7)
20 defer os.RemoveAll("chain1")
25 c2, err := declChain("chain2", c1, 5, 9)
26 defer os.RemoveAll("chain2")
31 bestBlockHash := c2.BestBlockHash()
32 if err := merge(c1, c2); err != nil {
36 if *c1.BestBlockHash() != *bestBlockHash || *c2.BestBlockHash() != *bestBlockHash {
37 t.Fatalf("test fork case1 failed")
40 if !c1.InMainChain(*bestBlockHash) || !c2.InMainChain(*bestBlockHash) {
41 t.Fatalf("best block is not in main chain")
45 // case2: |----c1(height=6)
46 // ---------(height 5)
48 func TestForkCase2(t *testing.T) {
49 c1, err := declChain("chain1", nil, 0, 6)
50 defer os.RemoveAll("chain1")
55 c2, err := declChain("chain2", c1, 5, 6)
56 defer os.RemoveAll("chain2")
61 c1BestBlockHash := c1.BestBlockHash()
62 c2BestBlockHash := c2.BestBlockHash()
63 if err := merge(c1, c2); err != nil {
67 if *c1.BestBlockHash() != *c1BestBlockHash || *c2.BestBlockHash() != *c2BestBlockHash {
68 t.Fatalf("test fork case2 failed")
71 if !c1.InMainChain(*c1BestBlockHash) || !c2.InMainChain(*c2BestBlockHash) {
72 t.Fatalf("best block is not in main chain")
76 func TestBlockSync(t *testing.T) {
77 c1, err := declChain("chain1", nil, 0, 5)
78 defer os.RemoveAll("chain1")
83 c2, err := declChain("chain2", c1, 5, 8)
84 defer os.RemoveAll("chain2")
89 bestBlockHash := c2.BestBlockHash()
90 if err := merge(c1, c2); err != nil {
94 if *c1.BestBlockHash() != *bestBlockHash || *c2.BestBlockHash() != *bestBlockHash {
95 t.Fatalf("test block sync failed")
98 if !c1.InMainChain(*bestBlockHash) || !c2.InMainChain(*bestBlockHash) {
99 t.Fatalf("test block sync failed, best block is not in main chain")
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)
110 if err := AppendBlocks(chain, 6); err != nil {
114 // create tx spend the coinbase output in block 1
115 block, err := chain.GetBlockByHeight(1)
119 tx, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
124 newBlock, err := NewBlock(chain, []*types.Tx{tx}, []byte{byte(vm.OP_TRUE)})
125 err = SolveAndUpdate(chain, newBlock)
130 // create a double spent tx in another block
131 tx, err = CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
136 _, err = chain.ValidateTx(tx)
138 t.Fatal("validate double spent tx success")
140 if txPool.HaveTransaction(&tx.ID) {
141 t.Fatalf("tx pool have double spent tx")
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)
152 if err := AppendBlocks(chain, 7); err != nil {
156 // create tx spend the coinbase output in block 1
157 block, err := chain.GetBlockByHeight(1)
161 tx1, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
166 // create tx spend the coinbase output in block 1
167 tx2, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
172 _, err = chain.ValidateTx(tx1)
176 _, err = chain.ValidateTx(tx2)
181 if !txPool.HaveTransaction(&tx1.ID) {
182 t.Fatalf("can't find tx in tx pool")
184 if !txPool.HaveTransaction(&tx2.ID) {
185 t.Fatalf("can't find tx in tx pool")
188 block, err = NewBlock(chain, []*types.Tx{tx1, tx2}, []byte{byte(vm.OP_TRUE)})
193 if err := SolveAndUpdate(chain, block); err == nil {
194 t.Fatalf("process double spent tx success")
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)
205 if err := AppendBlocks(chain, 7); err != nil {
209 block, err := chain.GetBlockByHeight(1)
214 tx, err := CreateTxFromTx(block.Transactions[0], 0, 5000000000, []byte{byte(vm.OP_TRUE)})
219 outputAmount := uint64(5000000000)
220 txs := []*types.Tx{nil}
222 for i := 1; i < 10; i++ {
223 outputAmount -= 50000000
224 tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)})
228 txs = append(txs, tx)
231 // validate tx and put it into tx pool
232 for _, tx := range txs {
233 if _, err := chain.ValidateTx(tx); err != nil {
236 if !txPool.HaveTransaction(&tx.ID) {
237 t.Fatal("can't find tx in txpool")
241 block, err = NewBlock(chain, txs, []byte{byte(vm.OP_TRUE)})
246 if err := SolveAndUpdate(chain, block); err != nil {
247 t.Fatal("process dependency tx failed")
251 func TestAddInvalidTxToTxPool(t *testing.T) {
252 chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
253 defer os.RemoveAll("tx_pool_test")
255 chain, _, txPool, err := MockChain(chainDB)
260 if err := AppendBlocks(chain, 7); err != nil {
264 block, err := chain.GetBlockByHeight(1)
269 //invalid tx, output amount greater than input
270 tx, err := CreateTxFromTx(block.Transactions[0], 0, 60000000000, []byte{byte(vm.OP_TRUE)})
275 if _, err := chain.ValidateTx(tx); err == nil {
276 t.Fatalf("add invalid tx to txpool success")
279 if txPool.IsTransactionInPool(&tx.ID) {
280 t.Fatalf("add invalid tx to txpool success")
283 if !txPool.IsTransactionInErrCache(&tx.ID) {
284 t.Fatalf("can't find invalid tx in txpool err cache")