OSDN Git Service

Validate matched tx sequence test (#486)
authorPoseidon <shenao.78@163.com>
Wed, 12 Feb 2020 10:20:05 +0000 (18:20 +0800)
committerGitHub <noreply@github.com>
Wed, 12 Feb 2020 10:20:05 +0000 (18:20 +0800)
* validate_matched_tx_sequence_test

* validate_matched_tx_sequence_test

application/mov/mock/mock.go
application/mov/mov_core_test.go

index 835a7c9..6bd6e0d 100644 (file)
@@ -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")),
+                       },
+               }),
        }
 )
 
index 9c0b354..f084d34 100644 (file)
@@ -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 {