8 "github.com/bytom/vapor/application/mov/common"
9 "github.com/bytom/vapor/application/mov/database"
10 "github.com/bytom/vapor/application/mov/mock"
11 "github.com/bytom/vapor/consensus"
12 dbm "github.com/bytom/vapor/database/leveldb"
13 "github.com/bytom/vapor/protocol/bc"
14 "github.com/bytom/vapor/protocol/bc/types"
15 "github.com/bytom/vapor/protocol/vm"
16 "github.com/bytom/vapor/testutil"
19 var initBlockHeader = &types.BlockHeader{Height: 1, PreviousBlockHash: bc.Hash{}}
21 func TestApplyBlock(t *testing.T) {
26 initOrders []*common.Order
27 wantOrders []*common.Order
28 wantDBState *common.MovDatabaseState
32 desc: "apply block has pending order transaction",
34 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
35 Transactions: []*types.Tx{
36 mock.Btc2EthMakerTxs[0], mock.Eth2BtcMakerTxs[0],
39 blockFunc: applyBlock,
40 wantOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.Btc2EthMakerTxs[0], 0), mock.MustNewOrderFromOutput(mock.Eth2BtcMakerTxs[0], 0)},
41 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
44 desc: "apply block has two different trade pairs & different trade pair won't affect each order",
46 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
47 Transactions: []*types.Tx{
48 mock.Btc2EthMakerTxs[0],
49 mock.Eth2BtcMakerTxs[0],
50 mock.Eos2EtcMakerTxs[0],
51 mock.Eth2EosMakerTxs[0],
54 blockFunc: applyBlock,
55 wantOrders: []*common.Order{
56 mock.MustNewOrderFromOutput(mock.Btc2EthMakerTxs[0], 0),
57 mock.MustNewOrderFromOutput(mock.Eth2BtcMakerTxs[0], 0),
58 mock.MustNewOrderFromOutput(mock.Eos2EtcMakerTxs[0], 0),
59 mock.MustNewOrderFromOutput(mock.Eth2EosMakerTxs[0], 0),
61 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
64 desc: "apply block has full matched transaction",
66 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
67 Transactions: []*types.Tx{
71 blockFunc: applyBlock,
72 initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Btc2EthOrders[1], mock.Eth2BtcOrders[0]},
73 wantOrders: []*common.Order{mock.Btc2EthOrders[1]},
74 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
77 desc: "apply block has partial matched transaction",
79 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
80 Transactions: []*types.Tx{
84 blockFunc: applyBlock,
85 initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[1]},
86 wantOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.MatchedTxs[0], 1)},
87 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
90 desc: "apply block has two partial matched transaction",
92 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
93 Transactions: []*types.Tx{
94 mock.MatchedTxs[2], mock.MatchedTxs[3],
97 blockFunc: applyBlock,
98 initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Btc2EthOrders[1], mock.Eth2BtcOrders[2]},
99 wantOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.MatchedTxs[3], 1)},
100 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
103 desc: "apply block has partial matched transaction by pending orders from tx pool",
105 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
106 Transactions: []*types.Tx{
107 mock.Btc2EthMakerTxs[0],
108 mock.Eth2BtcMakerTxs[1],
112 blockFunc: applyBlock,
113 initOrders: []*common.Order{},
114 wantOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.MatchedTxs[4], 1)},
115 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
118 desc: "apply block which node packed maker tx and match transaction in random orde",
120 BlockHeader: types.BlockHeader{Height: 2, PreviousBlockHash: initBlockHeader.Hash()},
121 Transactions: []*types.Tx{
122 mock.Eos2EtcMakerTxs[0],
123 mock.Btc2EthMakerTxs[0],
125 mock.Eth2EosMakerTxs[0],
126 mock.Eth2BtcMakerTxs[1],
128 mock.Etc2EosMakerTxs[0],
131 blockFunc: applyBlock,
132 initOrders: []*common.Order{},
133 wantOrders: []*common.Order{
134 mock.MustNewOrderFromOutput(mock.MatchedTxs[4], 1),
135 mock.MustNewOrderFromOutput(mock.Eth2EosMakerTxs[0], 0),
137 wantDBState: &common.MovDatabaseState{Height: 2, Hash: hashPtr(testutil.MustDecodeHash("88dbcde57bb2b53b107d7494f20f1f1a892307a019705980c3510890449c0020"))},
140 desc: "detach block has pending order transaction",
142 BlockHeader: *initBlockHeader,
143 Transactions: []*types.Tx{
144 mock.Btc2EthMakerTxs[0], mock.Eth2BtcMakerTxs[1],
147 blockFunc: detachBlock,
148 initOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.Btc2EthMakerTxs[0], 0), mock.MustNewOrderFromOutput(mock.Eth2BtcMakerTxs[1], 0)},
149 wantOrders: []*common.Order{},
150 wantDBState: &common.MovDatabaseState{Height: 0, Hash: &bc.Hash{}},
153 desc: "detach block has two different trade pairs & different trade pair won't affect each order",
155 BlockHeader: *initBlockHeader,
156 Transactions: []*types.Tx{
157 mock.Btc2EthMakerTxs[0],
158 mock.Eth2BtcMakerTxs[0],
159 mock.Eos2EtcMakerTxs[0],
160 mock.Eth2EosMakerTxs[0],
163 blockFunc: detachBlock,
164 initOrders: []*common.Order{
165 mock.MustNewOrderFromOutput(mock.Btc2EthMakerTxs[0], 0),
166 mock.MustNewOrderFromOutput(mock.Eth2BtcMakerTxs[0], 0),
167 mock.MustNewOrderFromOutput(mock.Eos2EtcMakerTxs[0], 0),
168 mock.MustNewOrderFromOutput(mock.Eth2EosMakerTxs[0], 0),
170 wantOrders: []*common.Order{},
171 wantDBState: &common.MovDatabaseState{Height: 0, Hash: &bc.Hash{}},
174 desc: "detach block has full matched transaction",
176 BlockHeader: *initBlockHeader,
177 Transactions: []*types.Tx{
181 blockFunc: detachBlock,
182 initOrders: []*common.Order{mock.Btc2EthOrders[1]},
183 wantOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Btc2EthOrders[1], mock.Eth2BtcOrders[0]},
184 wantDBState: &common.MovDatabaseState{Height: 0, Hash: &bc.Hash{}},
187 desc: "detach block has partial matched transaction",
189 BlockHeader: *initBlockHeader,
190 Transactions: []*types.Tx{
194 blockFunc: detachBlock,
195 initOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.MatchedTxs[0], 1)},
196 wantOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[1]},
197 wantDBState: &common.MovDatabaseState{Height: 0, Hash: &bc.Hash{}},
200 desc: "detach block has two partial matched transaction",
202 BlockHeader: *initBlockHeader,
203 Transactions: []*types.Tx{
204 mock.MatchedTxs[2], mock.MatchedTxs[3],
207 blockFunc: detachBlock,
208 initOrders: []*common.Order{mock.MustNewOrderFromOutput(mock.MatchedTxs[3], 1)},
209 wantOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Btc2EthOrders[1], mock.Eth2BtcOrders[2]},
210 wantDBState: &common.MovDatabaseState{Height: 0, Hash: &bc.Hash{}},
213 desc: "detach block which node packed maker tx and match transaction in random orde",
215 BlockHeader: *initBlockHeader,
216 Transactions: []*types.Tx{
217 mock.Eos2EtcMakerTxs[0],
218 mock.Btc2EthMakerTxs[0],
220 mock.Eth2EosMakerTxs[0],
221 mock.Eth2BtcMakerTxs[1],
223 mock.Etc2EosMakerTxs[0],
226 blockFunc: detachBlock,
227 initOrders: []*common.Order{
228 mock.MustNewOrderFromOutput(mock.MatchedTxs[4], 1),
229 mock.MustNewOrderFromOutput(mock.Eth2EosMakerTxs[0], 0),
231 wantOrders: []*common.Order{},
232 wantDBState: &common.MovDatabaseState{Height: 0, Hash: &bc.Hash{}},
236 defer os.RemoveAll("temp")
237 for i, c := range cases {
238 testDB := dbm.NewDB("testdb", "leveldb", "temp")
239 store := database.NewLevelDBMovStore(testDB)
240 if err := store.InitDBState(0, &bc.Hash{}); err != nil {
244 if err := store.ProcessOrders(c.initOrders, nil, initBlockHeader); err != nil {
248 movCore := &MovCore{movStore: store}
249 if err := c.blockFunc(movCore, c.block); err != c.wantError {
250 t.Errorf("#%d(%s):apply block want error(%v), got error(%v)", i, c.desc, c.wantError, err)
253 gotOrders := queryAllOrders(store)
254 if !ordersEquals(c.wantOrders, gotOrders) {
255 t.Errorf("#%d(%s):apply block want orders(%v), got orders(%v)", i, c.desc, c.wantOrders, gotOrders)
258 dbState, err := store.GetMovDatabaseState()
263 if !testutil.DeepEqual(c.wantDBState, dbState) {
264 t.Errorf("#%d(%s):apply block want db state(%v), got db state(%v)", i, c.desc, c.wantDBState, dbState)
272 func TestValidateBlock(t *testing.T) {
276 verifyResults []*bc.TxVerifyResult
280 desc: "block only has maker tx",
282 Transactions: []*types.Tx{
283 mock.Eth2BtcMakerTxs[0],
284 mock.Btc2EthMakerTxs[0],
287 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}, {StatusFail: false}},
291 desc: "block only has matched tx",
293 Transactions: []*types.Tx{
299 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}, {StatusFail: false}, {StatusFail: false}},
303 desc: "block has maker tx and matched tx",
305 Transactions: []*types.Tx{
306 mock.Eth2BtcMakerTxs[0],
307 mock.Btc2EthMakerTxs[0],
313 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}, {StatusFail: false}, {StatusFail: false}, {StatusFail: false}, {StatusFail: false}},
317 desc: "status fail of maker tx is true",
319 Transactions: []*types.Tx{
320 mock.Eth2BtcMakerTxs[0],
321 mock.Btc2EthMakerTxs[0],
324 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}, {StatusFail: true}},
325 wantError: errStatusFailMustFalse,
328 desc: "status fail of matched tx is true",
330 Transactions: []*types.Tx{
335 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}, {StatusFail: true}},
336 wantError: errStatusFailMustFalse,
339 desc: "asset id in matched tx is not unique",
341 Transactions: []*types.Tx{
342 types.NewTx(types.TxData{
343 Inputs: []*types.TxInput{
344 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, mock.Btc2EthOrders[0].Utxo.ControlProgram),
345 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *mock.Eth2BtcOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Eth2BtcOrders[0].Utxo.Amount, mock.Eth2BtcOrders[0].Utxo.SourcePos, mock.Eth2BtcOrders[0].Utxo.ControlProgram),
347 Outputs: []*types.TxOutput{
348 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
349 types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("53")),
350 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 10, []byte{0x51}),
355 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}, {StatusFail: true}},
356 wantError: errAssetIDMustUniqueInMatchedTx,
359 desc: "common input in the matched tx",
361 Transactions: []*types.Tx{
362 types.NewTx(types.TxData{
363 Inputs: []*types.TxInput{
364 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, mock.Btc2EthOrders[0].Utxo.ControlProgram),
365 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *mock.Eth2BtcOrders[0].Utxo.SourceID, *mock.Eth2BtcOrders[0].FromAssetID, mock.Eth2BtcOrders[0].Utxo.Amount, mock.Eth2BtcOrders[0].Utxo.SourcePos, mock.Eth2BtcOrders[0].Utxo.ControlProgram),
366 types.NewSpendInput(nil, testutil.MustDecodeHash("28b7b53d8dc90006bf97e0a4eaae2a72ec3d869873188698b694beaf20789f21"), *consensus.BTMAssetID, 100, 0, []byte{0x51}),
368 Outputs: []*types.TxOutput{
369 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
370 types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("53")),
371 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 10, []byte{0x51}),
372 types.NewIntraChainOutput(*consensus.BTMAssetID, 100, []byte{0x51}),
377 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
378 wantError: errInputProgramMustP2WMCScript,
381 desc: "cancel order in the matched tx",
383 Transactions: []*types.Tx{
384 types.NewTx(types.TxData{
385 Inputs: []*types.TxInput{
386 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, mock.Btc2EthOrders[0].Utxo.ControlProgram),
387 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *mock.Eth2BtcOrders[0].Utxo.SourceID, *mock.Eth2BtcOrders[0].FromAssetID, mock.Eth2BtcOrders[0].Utxo.Amount, mock.Eth2BtcOrders[0].Utxo.SourcePos, mock.Eth2BtcOrders[0].Utxo.ControlProgram),
388 types.NewSpendInput([][]byte{{}, {}, vm.Int64Bytes(2)}, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, mock.Btc2EthOrders[0].Utxo.ControlProgram),
390 Outputs: []*types.TxOutput{
391 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
392 types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("53")),
393 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 10, []byte{0x51}),
394 types.NewIntraChainOutput(*consensus.BTMAssetID, 100, []byte{0x51}),
399 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
400 wantError: errExistCancelOrderInMatchedTx,
403 desc: "common input in the cancel order tx",
405 Transactions: []*types.Tx{
406 types.NewTx(types.TxData{
407 Inputs: []*types.TxInput{
408 types.NewSpendInput([][]byte{{}, {}, vm.Int64Bytes(2)}, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, mock.Btc2EthOrders[0].Utxo.ControlProgram),
409 types.NewSpendInput(nil, testutil.MustDecodeHash("28b7b53d8dc90006bf97e0a4eaae2a72ec3d869873188698b694beaf20789f21"), *consensus.BTMAssetID, 100, 0, []byte{0x51}),
411 Outputs: []*types.TxOutput{
412 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, 10, testutil.MustDecodeHexString("51")),
413 types.NewIntraChainOutput(*consensus.BTMAssetID, 100, []byte{0x51}),
418 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
419 wantError: errInputProgramMustP2WMCScript,
422 desc: "amount of fee greater than max fee amount",
424 Transactions: []*types.Tx{
425 types.NewTx(types.TxData{
426 Inputs: []*types.TxInput{
427 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, mock.Btc2EthOrders[0].Utxo.ControlProgram),
428 types.NewSpendInput([][]byte{vm.Int64Bytes(10), vm.Int64Bytes(1), vm.Int64Bytes(0)}, *mock.Eth2BtcOrders[2].Utxo.SourceID, *mock.Eth2BtcOrders[2].FromAssetID, mock.Eth2BtcOrders[2].Utxo.Amount, mock.Eth2BtcOrders[2].Utxo.SourcePos, mock.Eth2BtcOrders[2].Utxo.ControlProgram),
430 Outputs: []*types.TxOutput{
431 types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
432 types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].ToAssetID, 10, testutil.MustDecodeHexString("55")),
434 types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].FromAssetID, 270, mock.Eth2BtcOrders[2].Utxo.ControlProgram),
436 types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].FromAssetID, 40, []byte{0x59}),
441 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
442 wantError: errAmountOfFeeGreaterThanMaximum,
445 desc: "ratio numerator is zero",
447 Transactions: []*types.Tx{
448 types.NewTx(types.TxData{
449 Inputs: []*types.TxInput{types.NewSpendInput(nil, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, []byte{0x51})},
450 Outputs: []*types.TxOutput{types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.MustCreateP2WMCProgram(mock.ETH, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251"), 0, 1))},
454 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
455 wantError: errRatioOfTradeLessThanZero,
458 desc: "ratio denominator is zero",
460 Transactions: []*types.Tx{
461 types.NewTx(types.TxData{
462 Inputs: []*types.TxInput{types.NewSpendInput(nil, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, []byte{0x51})},
463 Outputs: []*types.TxOutput{types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.MustCreateP2WMCProgram(mock.ETH, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251"), 1, 0))},
467 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
468 wantError: errRatioOfTradeLessThanZero,
471 desc: "want amount is overflow",
473 Transactions: []*types.Tx{
474 types.NewTx(types.TxData{
475 Inputs: []*types.TxInput{types.NewSpendInput(nil, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, []byte{0x51})},
476 Outputs: []*types.TxOutput{types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.MustCreateP2WMCProgram(mock.ETH, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251"), math.MaxInt64, 1))},
480 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
481 wantError: errRequestAmountMath,
485 for i, c := range cases {
486 movCore := &MovCore{}
487 if err := movCore.ValidateBlock(c.block, c.verifyResults); err != c.wantError {
488 t.Errorf("#%d(%s):validate block want error(%v), got error(%v)", i, c.desc, c.wantError, err)
493 func TestBeforeProposalBlock(t *testing.T) {
496 initOrders []*common.Order
498 wantMatchedTxs []*types.Tx
501 desc: "has matched tx, but gas left is zero",
502 initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0]},
504 wantMatchedTxs: []*types.Tx{},
507 desc: "has one matched tx, and gas is sufficient",
508 initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0]},
510 wantMatchedTxs: []*types.Tx{mock.MatchedTxs[1]},
513 desc: "has two matched tx, but gas is only enough to pack a matched tx",
514 initOrders: []*common.Order{
515 mock.Btc2EthOrders[0],
516 mock.Btc2EthOrders[1],
517 mock.Eth2BtcOrders[2],
520 wantMatchedTxs: []*types.Tx{mock.MatchedTxs[2]},
523 desc: "has two matched tx, and gas left is sufficient",
524 initOrders: []*common.Order{
525 mock.Btc2EthOrders[0],
526 mock.Btc2EthOrders[1],
527 mock.Eth2BtcOrders[2],
530 wantMatchedTxs: []*types.Tx{mock.MatchedTxs[2], mock.MatchedTxs[3]},
533 desc: "has multiple trade pairs, and gas left is sufficient",
534 initOrders: []*common.Order{
535 mock.Btc2EthOrders[0],
536 mock.Btc2EthOrders[1],
537 mock.Eth2BtcOrders[2],
538 mock.Eos2EtcOrders[0],
539 mock.Etc2EosOrders[0],
542 wantMatchedTxs: []*types.Tx{mock.MatchedTxs[2], mock.MatchedTxs[3], mock.MatchedTxs[5]},
546 for i, c := range cases {
547 testDB := dbm.NewDB("testdb", "leveldb", "temp")
548 store := database.NewLevelDBMovStore(testDB)
549 if err := store.InitDBState(0, &bc.Hash{}); err != nil {
553 if err := store.ProcessOrders(c.initOrders, nil, initBlockHeader); err != nil {
557 movCore := &MovCore{movStore: store}
558 gotMatchedTxs, err := movCore.BeforeProposalBlock(nil, []byte{0x51}, 2, c.gasLeft, func() bool { return false })
563 gotMatchedTxMap := make(map[string]interface{})
564 for _, matchedTx := range gotMatchedTxs {
565 gotMatchedTxMap[matchedTx.ID.String()] = nil
568 wantMatchedTxMap := make(map[string]interface{})
569 for _, matchedTx := range c.wantMatchedTxs {
570 wantMatchedTxMap[matchedTx.ID.String()] = nil
573 if !testutil.DeepEqual(gotMatchedTxMap, wantMatchedTxMap) {
574 t.Errorf("#%d(%s):want matched tx(%v) is not equals got matched tx(%v)", i, c.desc, c.wantMatchedTxs, gotMatchedTxs)
582 type testFun func(movCore *MovCore, block *types.Block) error
584 func applyBlock(movCore *MovCore, block *types.Block) error {
585 return movCore.ApplyBlock(block)
588 func detachBlock(movCore *MovCore, block *types.Block) error {
589 return movCore.DetachBlock(block)
592 func queryAllOrders(store *database.LevelDBMovStore) []*common.Order {
593 var orders []*common.Order
594 tradePairIterator := database.NewTradePairIterator(store)
595 for tradePairIterator.HasNext() {
596 orderIterator := database.NewOrderIterator(store, tradePairIterator.Next())
597 for orderIterator.HasNext() {
598 orders = append(orders, orderIterator.NextBatch()...)
604 func ordersEquals(orders1 []*common.Order, orders2 []*common.Order) bool {
605 orderMap1 := make(map[string]*common.Order)
606 for _, order := range orders1 {
607 orderMap1[order.Key()] = order
610 orderMap2 := make(map[string]*common.Order)
611 for _, order := range orders2 {
612 orderMap2[order.Key()] = order
614 return testutil.DeepEqual(orderMap1, orderMap2)
617 func hashPtr(hash bc.Hash) *bc.Hash {