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"
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, consensus.CoinbasePendingBlockNumber+1); 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 = chain.ProcessBlock(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 if isOrphan, err := chain.ValidateTx(tx); isOrphan == false && err == nil {
137 t.Fatal("validate double spent tx success")
139 if txPool.HaveTransaction(&tx.ID) {
140 t.Fatalf("tx pool have double spent tx")
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)
151 if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
155 // create tx spend the coinbase output in block 1
156 block, err := chain.GetBlockByHeight(1)
160 tx1, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
165 // create tx spend the coinbase output in block 1
166 tx2, err := CreateTxFromTx(block.Transactions[0], 0, 10000, []byte{byte(vm.OP_TRUE)})
171 _, err = chain.ValidateTx(tx1)
175 _, err = chain.ValidateTx(tx2)
180 if !txPool.HaveTransaction(&tx1.ID) {
181 t.Fatalf("can't find tx in tx pool")
183 if !txPool.HaveTransaction(&tx2.ID) {
184 t.Fatalf("can't find tx in tx pool")
187 block, err = NewBlock(chain, []*types.Tx{tx1, tx2}, []byte{byte(vm.OP_TRUE)})
192 if _, err := chain.ProcessBlock(block); err == nil {
193 t.Fatalf("process double spent tx success")
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)
204 if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
208 block, err := chain.GetBlockByHeight(1)
213 tx, err := CreateTxFromTx(block.Transactions[0], 0, 5000000000, []byte{byte(vm.OP_TRUE)})
218 outputAmount := uint64(5000000000)
219 txs := []*types.Tx{nil}
221 for i := 1; i < 10; i++ {
222 outputAmount -= 50000000
223 tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)})
227 txs = append(txs, tx)
230 // validate tx and put it into tx pool
231 for _, tx := range txs {
232 if _, err := chain.ValidateTx(tx); err != nil {
235 if !txPool.HaveTransaction(&tx.ID) {
236 t.Fatal("can't find tx in txpool")
240 block, err = NewBlock(chain, txs, []byte{byte(vm.OP_TRUE)})
245 if _, err := chain.ProcessBlock(block); err != nil {
246 t.Fatal("process dependency tx failed")
250 func TestAddInvalidTxToTxPool(t *testing.T) {
251 chainDB := dbm.NewDB("tx_pool_test", "leveldb", "tx_pool_test")
252 defer os.RemoveAll("tx_pool_test")
254 chain, _, txPool, err := MockChain(chainDB)
259 if err := AppendBlocks(chain, consensus.CoinbasePendingBlockNumber+1); err != nil {
263 block, err := chain.GetBlockByHeight(1)
268 //invalid tx, output amount greater than input
269 tx, err := CreateTxFromTx(block.Transactions[0], 0, 60000000000, []byte{byte(vm.OP_TRUE)})
274 if _, err := chain.ValidateTx(tx); err == nil {
275 t.Fatalf("add invalid tx to txpool success")
278 if txPool.IsTransactionInPool(&tx.ID) {
279 t.Fatalf("add invalid tx to txpool success")
282 if !txPool.IsTransactionInErrCache(&tx.ID) {
283 t.Fatalf("can't find invalid tx in txpool err cache")