From dcbfa4fac72388cd7d7be7968921a12750093382 Mon Sep 17 00:00:00 2001 From: Poseidon Date: Wed, 12 Feb 2020 18:20:05 +0800 Subject: [PATCH] Validate matched tx sequence test (#486) * validate_matched_tx_sequence_test * validate_matched_tx_sequence_test --- application/mov/mock/mock.go | 38 ++++++++++++- application/mov/mov_core_test.go | 120 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) diff --git a/application/mov/mock/mock.go b/application/mov/mock/mock.go index 835a7c9e..6bd6e0d4 100644 --- a/application/mov/mock/mock.go +++ b/application/mov/mock/mock.go @@ -166,6 +166,14 @@ var ( }, } + Btc2EthCancelTxs = []*types.Tx{ + // Btc2EthOrders[0] + types.NewTx(types.TxData{ + Inputs: []*types.TxInput{types.NewSpendInput([][]byte{{}, {}, vm.Int64Bytes(2)}, *Btc2EthOrders[0].Utxo.SourceID, *Btc2EthOrders[0].FromAssetID, Btc2EthOrders[0].Utxo.Amount, Btc2EthOrders[0].Utxo.SourcePos, Btc2EthOrders[0].Utxo.ControlProgram)}, + Outputs: []*types.TxOutput{types.NewIntraChainOutput(*Btc2EthOrders[0].FromAssetID, Btc2EthOrders[0].Utxo.Amount, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251"))}, + }), + } + Btc2EthMakerTxs = []*types.Tx{ // Btc2EthOrders[0] types.NewTx(types.TxData{ @@ -304,7 +312,7 @@ var ( }, }), - // full matched transaction from Eos2Etc[0] Etc2Eos[0] + // full matched transaction from Eos2EtcMakerTxs[0] Etc2EosMakerTxs[0] types.NewTx(types.TxData{ Inputs: []*types.TxInput{ types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *MustNewOrderFromOutput(Eos2EtcMakerTxs[0], 0).Utxo.SourceID, *Eos2EtcOrders[0].FromAssetID, Eos2EtcOrders[0].Utxo.Amount, Eos2EtcOrders[0].Utxo.SourcePos, Eos2EtcOrders[0].Utxo.ControlProgram), @@ -343,6 +351,34 @@ var ( types.NewIntraChainOutput(*Eth2BtcOrders[0].FromAssetID, 404, Eth2BtcOrders[0].Utxo.ControlProgram), }, }), + + // partial matched transaction from Btc2EthOrders[3], Eth2BtcOrders[2] + types.NewTx(types.TxData{ + Inputs: []*types.TxInput{ + types.NewSpendInput([][]byte{vm.Int64Bytes(810), vm.Int64Bytes(0), vm.Int64Bytes(0)}, *Btc2EthOrders[3].Utxo.SourceID, *Btc2EthOrders[3].FromAssetID, Btc2EthOrders[3].Utxo.Amount, Btc2EthOrders[3].Utxo.SourcePos, Btc2EthOrders[3].Utxo.ControlProgram), + types.NewSpendInput([][]byte{vm.Int64Bytes(2), vm.Int64Bytes(1)}, *Eth2BtcOrders[2].Utxo.SourceID, *Eth2BtcOrders[2].FromAssetID, Eth2BtcOrders[2].Utxo.Amount, Eth2BtcOrders[2].Utxo.SourcePos, Eth2BtcOrders[2].Utxo.ControlProgram), + }, + Outputs: []*types.TxOutput{ + types.NewIntraChainOutput(*Btc2EthOrders[3].ToAssetID, 810, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19252")), + // re-order + types.NewIntraChainOutput(*Btc2EthOrders[3].FromAssetID, 1, Btc2EthOrders[3].Utxo.ControlProgram), + types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 15, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")), + // fee + types.NewIntraChainOutput(*Btc2EthOrders[3].FromAssetID, 1, NodeProgram), + }, + }), + + // full matched transaction from Eos2EtcOrders[0] Etc2EosOrders[0] + types.NewTx(types.TxData{ + Inputs: []*types.TxInput{ + types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *Eos2EtcOrders[0].Utxo.SourceID, *Eos2EtcOrders[0].FromAssetID, Eos2EtcOrders[0].Utxo.Amount, Eos2EtcOrders[0].Utxo.SourcePos, Eos2EtcOrders[0].Utxo.ControlProgram), + types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *Etc2EosOrders[0].Utxo.SourceID, *Etc2EosOrders[0].FromAssetID, Etc2EosOrders[0].Utxo.Amount, Etc2EosOrders[0].Utxo.SourcePos, Etc2EosOrders[0].Utxo.ControlProgram), + }, + Outputs: []*types.TxOutput{ + types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 50, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")), + types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 100, testutil.MustDecodeHexString("0014df7a97e53bbe278e4e44810b0a760fb472daa9a3")), + }, + }), } ) diff --git a/application/mov/mov_core_test.go b/application/mov/mov_core_test.go index 9c0b3549..f084d346 100644 --- a/application/mov/mov_core_test.go +++ b/application/mov/mov_core_test.go @@ -596,6 +596,126 @@ func TestBeforeProposalBlock(t *testing.T) { } } +func TestValidateMatchedTxSequence(t *testing.T) { + cases := []struct { + desc string + initOrders []*common.Order + transactions []*types.Tx + wantError error + }{ + { + desc: "both db orders and transactions is empty", + initOrders: []*common.Order{}, + transactions: []*types.Tx{}, + wantError: nil, + }, + { + desc: "existing matched orders in db, and transactions is empty", + initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0]}, + transactions: []*types.Tx{}, + wantError: nil, + }, + { + desc: "db orders is empty, but transactions has matched tx", + initOrders: []*common.Order{}, + transactions: []*types.Tx{mock.MatchedTxs[1]}, + wantError: errNotMatchedOrder, + }, + { + desc: "existing matched orders in db, and corresponding matched tx in transactions", + initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0]}, + transactions: []*types.Tx{mock.MatchedTxs[1]}, + wantError: nil, + }, + { + desc: "existing two matched orders in db, and only one corresponding matched tx in transactions", + initOrders: []*common.Order{ + mock.Btc2EthOrders[3], mock.Eth2BtcOrders[2], + mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0], + }, + transactions: []*types.Tx{mock.MatchedTxs[8]}, + wantError: nil, + }, + { + desc: "existing two matched orders in db, and the sequence of match txs in incorrect", + initOrders: []*common.Order{ + mock.Btc2EthOrders[3], mock.Eth2BtcOrders[2], + mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0], + }, + transactions: []*types.Tx{mock.MatchedTxs[1], mock.MatchedTxs[8]}, + wantError: errSpendOutputIDIsIncorrect, + }, + { + desc: "package full matched tx from maker tx", + initOrders: []*common.Order{}, + transactions: []*types.Tx{mock.Btc2EthMakerTxs[0], mock.Eth2BtcMakerTxs[1], mock.MatchedTxs[4]}, + wantError: nil, + }, + { + desc: "package the matched tx first, then package match orders", + initOrders: []*common.Order{}, + transactions: []*types.Tx{mock.MatchedTxs[4], mock.Btc2EthMakerTxs[0], mock.Eth2BtcMakerTxs[1]}, + wantError: errNotMatchedOrder, + }, + { + desc: "cancel order in transactions", + initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0]}, + transactions: []*types.Tx{mock.Btc2EthCancelTxs[0], mock.MatchedTxs[1]}, + wantError: errNotMatchedOrder, + }, + { + desc: "package cancel order after match tx", + initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0]}, + transactions: []*types.Tx{mock.MatchedTxs[1], mock.Btc2EthCancelTxs[0]}, + wantError: nil, + }, + { + desc: "package matched txs of different trade pairs", + initOrders: []*common.Order{ + mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0], + mock.Eos2EtcOrders[0], mock.Etc2EosOrders[0], + }, + transactions: []*types.Tx{mock.MatchedTxs[1], mock.MatchedTxs[9]}, + wantError: nil, + }, + { + desc: "package matched txs of different trade pairs in different sequence", + initOrders: []*common.Order{ + mock.Btc2EthOrders[0], mock.Eth2BtcOrders[0], + mock.Eos2EtcOrders[0], mock.Etc2EosOrders[0], + }, + transactions: []*types.Tx{mock.MatchedTxs[9], mock.MatchedTxs[1]}, + wantError: nil, + }, + { + desc: "package partial matched tx from db orders", + initOrders: []*common.Order{mock.Btc2EthOrders[0], mock.Btc2EthOrders[1], mock.Eth2BtcOrders[2]}, + transactions: []*types.Tx{mock.MatchedTxs[2], mock.MatchedTxs[3]}, + wantError: nil, + }, + } + + for i, c := range cases { + testDB := dbm.NewDB("testdb", "leveldb", "temp") + store := database.NewLevelDBMovStore(testDB) + if err := store.InitDBState(0, &bc.Hash{}); err != nil { + t.Fatal(err) + } + + if err := store.ProcessOrders(c.initOrders, nil, initBlockHeader); err != nil { + t.Fatal(err) + } + + movCore := &MovCore{movStore: store} + if err := movCore.validateMatchedTxSequence(c.transactions); err != c.wantError { + t.Errorf("#%d(%s):wanet error(%v), got error(%v)", i, c.desc, c.wantError, err) + } + + testDB.Close() + os.RemoveAll("temp") + } +} + type testFun func(movCore *MovCore, block *types.Block) error func applyBlock(movCore *MovCore, block *types.Block) error { -- 2.11.0