9 dbm "github.com/tendermint/tmlibs/db"
11 "github.com/vapor/consensus"
12 "github.com/vapor/protocol/bc/types"
13 "github.com/vapor/protocol/vm"
16 // case1: |------c1(height=7)
18 // |------------c2(height=9)
19 func TestForkCase1(t *testing.T) {
20 c1, err := declChain("chain1", nil, 0, 7)
21 defer os.RemoveAll("chain1")
26 c2, err := declChain("chain2", c1, 5, 9)
27 defer os.RemoveAll("chain2")
32 bestBlockHash := c2.BestBlockHash()
33 if err := merge(c1, c2); err != nil {
37 if *c1.BestBlockHash() != *bestBlockHash || *c2.BestBlockHash() != *bestBlockHash {
38 t.Fatalf("test fork case1 failed")
41 if !c1.InMainChain(*bestBlockHash) || !c2.InMainChain(*bestBlockHash) {
42 t.Fatalf("best block is not in main chain")
46 // case2: |----c1(height=6)
47 // ---------(height 5)
49 func TestForkCase2(t *testing.T) {
50 c1, err := declChain("chain1", nil, 0, 6)
51 defer os.RemoveAll("chain1")
56 c2, err := declChain("chain2", c1, 5, 6)
57 defer os.RemoveAll("chain2")
62 c1BestBlockHash := c1.BestBlockHash()
63 c2BestBlockHash := c2.BestBlockHash()
64 if err := merge(c1, c2); err != nil {
68 if *c1.BestBlockHash() != *c1BestBlockHash || *c2.BestBlockHash() != *c2BestBlockHash {
69 t.Fatalf("test fork case2 failed")
72 if !c1.InMainChain(*c1BestBlockHash) || !c2.InMainChain(*c2BestBlockHash) {
73 t.Fatalf("best block is not in main chain")
77 func TestBlockSync(t *testing.T) {
78 c1, err := declChain("chain1", nil, 0, 5)
79 defer os.RemoveAll("chain1")
84 c2, err := declChain("chain2", c1, 5, 8)
85 defer os.RemoveAll("chain2")
90 bestBlockHash := c2.BestBlockHash()
91 if err := merge(c1, c2); err != nil {
95 if *c1.BestBlockHash() != *bestBlockHash || *c2.BestBlockHash() != *bestBlockHash {
96 t.Fatalf("test block sync failed")
99 if !c1.InMainChain(*bestBlockHash) || !c2.InMainChain(*bestBlockHash) {
100 t.Fatalf("test block sync failed, best block is not in main chain")
104 func TestDoubleSpentInDiffBlock(t *testing.T) {
105 chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
106 defer os.RemoveAll("tx_pool_test")
107 chain, _, txPool, err := MockChain(chainDB)
111 if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
115 // create tx spend the coinbase output in block 1
116 block, err := chain.GetBlockByHeight(1)
120 tx, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
125 newBlock, err := NewBlock(chain, []*types.Tx{tx}, []byte{byte(vm.OP_TRUE)})
126 err = SolveAndUpdate(chain, newBlock)
131 // create a double spent tx in another block
132 tx, err = CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
137 if isOrphan, err := chain.ValidateTx(tx); isOrphan == false && err == nil {
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, consensus.CoinbasePendingBlockNumber+1); 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, consensus.CoinbasePendingBlockNumber+1); 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, consensus.CoinbasePendingBlockNumber+1); 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")