6 "github.com/vapor/protocol/vm"
7 "github.com/vapor/testutil"
9 "github.com/vapor/application/mov/common"
10 "github.com/vapor/application/mov/database"
11 "github.com/vapor/protocol/bc"
12 "github.com/vapor/protocol/bc/types"
13 "github.com/vapor/protocol/vm/vmutil"
17 btc = bc.NewAssetID([32]byte{1})
18 eth = bc.NewAssetID([32]byte{2})
20 orders = []*common.Order{
26 Utxo: &common.MovUtxo{
27 SourceID: hashPtr(testutil.MustDecodeHash("37b8edf656e45a7addf47f5626e114a8c394d918a36f61b5a2905675a09b40ae")),
30 ControlProgram: mustCreateP2WMCProgram(eth, testutil.MustDecodeHexString("51"), 50, 1),
37 Utxo: &common.MovUtxo{
38 SourceID: hashPtr(testutil.MustDecodeHash("3ec2bbfb499a8736d377b547eee5392bcddf7ec2b287e9ed20b5938c3d84e7cd")),
41 ControlProgram: mustCreateP2WMCProgram(eth, testutil.MustDecodeHexString("52"), 53, 1),
50 Utxo: &common.MovUtxo{
51 SourceID: hashPtr(testutil.MustDecodeHash("fba43ff5155209cb1769e2ec0e1d4a33accf899c740865edfc6d1de39b873b29")),
54 ControlProgram: mustCreateP2WMCProgram(btc, testutil.MustDecodeHexString("53"), 1, 51.0),
61 Utxo: &common.MovUtxo{
62 SourceID: hashPtr(testutil.MustDecodeHash("05f24bb847db823075d81786aa270748e02602199cd009c0284f928503846a5a")),
65 ControlProgram: mustCreateP2WMCProgram(btc, testutil.MustDecodeHexString("54"), 1, 52.0),
72 Utxo: &common.MovUtxo{
73 SourceID: hashPtr(testutil.MustDecodeHash("119a02980796dc352cf6475457463aef5666f66622088de3551fa73a65f0d201")),
76 ControlProgram: mustCreateP2WMCProgram(btc, testutil.MustDecodeHexString("55"), 1, 54.0),
82 func TestGenerateMatchedTxs(t *testing.T) {
83 btc2eth := &common.TradePair{FromAssetID: &btc, ToAssetID: ð}
84 eth2btc := &common.TradePair{FromAssetID: ð, ToAssetID: &btc}
88 tradePair *common.TradePair
89 storeOrderMap map[string][]*common.Order
90 wantMatchedTxs []*types.TxData
94 tradePair: &common.TradePair{FromAssetID: &btc, ToAssetID: ð},
95 storeOrderMap: map[string][]*common.Order{
96 btc2eth.Key(): {orders[0], orders[1]},
97 eth2btc.Key(): {orders[2], orders[3]},
99 wantMatchedTxs: []*types.TxData{
101 Inputs: []*types.TxInput{
102 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *orders[0].Utxo.SourceID, *orders[0].FromAssetID, orders[0].Utxo.Amount, orders[0].Utxo.SourcePos, orders[0].Utxo.ControlProgram),
103 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *orders[2].Utxo.SourceID, *orders[2].FromAssetID, orders[2].Utxo.Amount, orders[2].Utxo.SourcePos, orders[2].Utxo.ControlProgram),
105 Outputs: []*types.TxOutput{
106 types.NewIntraChainOutput(*orders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
107 types.NewIntraChainOutput(*orders[2].ToAssetID, 10, testutil.MustDecodeHexString("53")),
108 types.NewIntraChainOutput(*orders[0].ToAssetID, 10, []byte{0x51}),
114 desc: "partial matched",
115 tradePair: &common.TradePair{FromAssetID: &btc, ToAssetID: ð},
116 storeOrderMap: map[string][]*common.Order{
117 btc2eth.Key(): {orders[0], orders[1]},
118 eth2btc.Key(): {orders[3]},
120 wantMatchedTxs: []*types.TxData{
122 Inputs: []*types.TxInput{
123 types.NewSpendInput([][]byte{vm.Int64Bytes(416), vm.Int64Bytes(0), vm.Int64Bytes(0)}, *orders[0].Utxo.SourceID, *orders[0].FromAssetID, orders[0].Utxo.Amount, orders[0].Utxo.SourcePos, orders[0].Utxo.ControlProgram),
124 types.NewSpendInput([][]byte{vm.Int64Bytes(2), vm.Int64Bytes(1)}, *orders[3].Utxo.SourceID, *orders[3].FromAssetID, orders[3].Utxo.Amount, orders[3].Utxo.SourcePos, orders[3].Utxo.ControlProgram),
126 Outputs: []*types.TxOutput{
127 types.NewIntraChainOutput(*orders[0].ToAssetID, 416, testutil.MustDecodeHexString("51")),
129 types.NewIntraChainOutput(*orders[0].FromAssetID, 1, orders[0].Utxo.ControlProgram),
130 types.NewIntraChainOutput(*orders[3].ToAssetID, 8, testutil.MustDecodeHexString("54")),
132 types.NewIntraChainOutput(*orders[3].ToAssetID, 1, []byte{0x51}),
138 desc: "partial matched and continue to match",
139 tradePair: &common.TradePair{FromAssetID: &btc, ToAssetID: ð},
140 storeOrderMap: map[string][]*common.Order{
141 btc2eth.Key(): {orders[0], orders[1]},
142 eth2btc.Key(): {orders[4]},
144 wantMatchedTxs: []*types.TxData{
146 Inputs: []*types.TxInput{
147 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(1)}, *orders[0].Utxo.SourceID, *orders[0].FromAssetID, orders[0].Utxo.Amount, orders[0].Utxo.SourcePos, orders[0].Utxo.ControlProgram),
148 types.NewSpendInput([][]byte{vm.Int64Bytes(10), vm.Int64Bytes(1), vm.Int64Bytes(0)}, *orders[4].Utxo.SourceID, *orders[4].FromAssetID, orders[4].Utxo.Amount, orders[4].Utxo.SourcePos, orders[4].Utxo.ControlProgram),
150 Outputs: []*types.TxOutput{
151 types.NewIntraChainOutput(*orders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
152 types.NewIntraChainOutput(*orders[4].ToAssetID, 10, testutil.MustDecodeHexString("55")),
154 types.NewIntraChainOutput(*orders[4].FromAssetID, 270, orders[4].Utxo.ControlProgram),
156 types.NewIntraChainOutput(*orders[4].FromAssetID, 27, []byte{0x51}),
158 types.NewIntraChainOutput(*orders[4].FromAssetID, 6, testutil.MustDecodeHexString("51")),
159 types.NewIntraChainOutput(*orders[4].FromAssetID, 7, testutil.MustDecodeHexString("55")),
163 Inputs: []*types.TxInput{
164 types.NewSpendInput([][]byte{vm.Int64Bytes(0), vm.Int64Bytes(0)}, *orders[1].Utxo.SourceID, *orders[1].FromAssetID, orders[1].Utxo.Amount, orders[1].Utxo.SourcePos, orders[1].Utxo.ControlProgram),
165 types.NewSpendInput([][]byte{vm.Int64Bytes(2), vm.Int64Bytes(1)}, testutil.MustDecodeHash("f47177c12d25f5316eb377ea006e77bf07e4f9646860e4641e313e004f9aa989"), *orders[4].FromAssetID, 270, 2, orders[4].Utxo.ControlProgram),
167 Outputs: []*types.TxOutput{
168 types.NewIntraChainOutput(*orders[1].ToAssetID, 270, testutil.MustDecodeHexString("52")),
170 types.NewIntraChainOutput(*orders[1].FromAssetID, 14, orders[1].Utxo.ControlProgram),
171 types.NewIntraChainOutput(*orders[4].ToAssetID, 5, testutil.MustDecodeHexString("55")),
172 types.NewIntraChainOutput(*orders[1].FromAssetID, 1, []byte{0x51}),
179 for i, c := range cases {
180 movStore := &database.MockMovStore{OrderMap: c.storeOrderMap}
181 matchEngine := NewEngine(movStore, []byte{0x51})
182 var gotMatchedTxs []*types.Tx
183 for matchEngine.HasMatchedTx(c.tradePair, c.tradePair.Reverse()) {
184 matchedTx, err := matchEngine.NextMatchedTx(c.tradePair, c.tradePair.Reverse())
189 gotMatchedTxs = append(gotMatchedTxs, matchedTx)
192 if len(c.wantMatchedTxs) != len(gotMatchedTxs) {
193 t.Errorf("#%d(%s) the length of got matched tx is not equals want matched tx", i, c.desc)
197 for i, gotMatchedTx := range gotMatchedTxs {
198 c.wantMatchedTxs[i].Version = 1
199 byteData, err := c.wantMatchedTxs[i].MarshalText()
204 c.wantMatchedTxs[i].SerializedSize = uint64(len(byteData))
205 wantMatchedTx := types.NewTx(*c.wantMatchedTxs[i])
206 if gotMatchedTx.ID != wantMatchedTx.ID {
207 t.Errorf("#%d(%s) the tx hash of got matched tx: %s is not equals want matched tx: %s", i, c.desc, gotMatchedTx.ID.String(), wantMatchedTx.ID.String())
213 func mustCreateP2WMCProgram(requestAsset bc.AssetID, sellerProgram []byte, ratioMolecule, ratioDenominator int64) []byte {
214 contractArgs := vmutil.MagneticContractArgs{
215 RequestedAsset: requestAsset,
216 RatioNumerator: ratioMolecule,
217 RatioDenominator: ratioDenominator,
218 SellerProgram: sellerProgram,
219 SellerKey: testutil.MustDecodeHexString("ad79ec6bd3a6d6dbe4d0ee902afc99a12b9702fb63edce5f651db3081d868b75"),
221 program, err := vmutil.P2WMCProgram(contractArgs)
228 func hashPtr(hash bc.Hash) *bc.Hash {