• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: 提交

Golang implemented sidechain for Bytom


Commit MetaInfo

修订版a1d6cf12d000c83ba1ad83ce94e3ee1460789bad (tree)
时间2020-03-10 20:23:41
作者Poseidon <shenao.78@163....>
CommiterGitHub

Log Message

one_thousandth_fee (#508)

* one_thousandth_fee

* opt code

* update fee

* bug fix

* fix all testcase

更改概述

差异

--- a/application/mov/match/match.go
+++ b/application/mov/match/match.go
@@ -106,7 +106,7 @@ func (e *Engine) buildMatchTx(orders []*common.Order) (*types.Tx, error) {
106106
107107 receivedAmounts, priceDiffs := CalcReceivedAmount(orders)
108108 allocatedAssets := e.feeStrategy.Allocate(receivedAmounts, priceDiffs)
109- if err := addMatchTxOutput(txData, orders, receivedAmounts, allocatedAssets.Received); err != nil {
109+ if err := addMatchTxOutput(txData, orders, receivedAmounts, allocatedAssets.Receives); err != nil {
110110 return nil, err
111111 }
112112
@@ -123,7 +123,7 @@ func (e *Engine) buildMatchTx(orders []*common.Order) (*types.Tx, error) {
123123 return types.NewTx(*txData), nil
124124 }
125125
126-func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmounts, receivedAfterDeductFee []*bc.AssetAmount) error {
126+func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmounts, deductFeeReceives []*bc.AssetAmount) error {
127127 for i, order := range orders {
128128 contractArgs, err := segwit.DecodeP2WMCProgram(order.Utxo.ControlProgram)
129129 if err != nil {
@@ -135,8 +135,8 @@ func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmou
135135 shouldPayAmount := calcShouldPayAmount(receivedAmount, contractArgs.RatioNumerator, contractArgs.RatioDenominator)
136136 isPartialTrade := requestAmount > receivedAmount
137137
138- setMatchTxArguments(txData.Inputs[i], isPartialTrade, len(txData.Outputs), receivedAfterDeductFee[i].Amount)
139- txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.ToAssetID, receivedAfterDeductFee[i].Amount, contractArgs.SellerProgram))
138+ setMatchTxArguments(txData.Inputs[i], isPartialTrade, len(txData.Outputs), receivedAmounts[i].Amount)
139+ txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.ToAssetID, deductFeeReceives[i].Amount, contractArgs.SellerProgram))
140140 if isPartialTrade {
141141 txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.FromAssetID, order.Utxo.Amount-shouldPayAmount, order.Utxo.ControlProgram))
142142 }
@@ -168,9 +168,8 @@ func calcShouldPayAmount(receiveAmount uint64, ratioNumerator, ratioDenominator
168168 }
169169
170170 // CalcReceivedAmount return amount of assets received by each participant in the matching transaction and the price difference
171-func CalcReceivedAmount(orders []*common.Order) ([]*bc.AssetAmount, map[bc.AssetID]int64) {
172- priceDiffs := make(map[bc.AssetID]int64)
173- var receivedAmounts, shouldPayAmounts []*bc.AssetAmount
171+func CalcReceivedAmount(orders []*common.Order) ([]*bc.AssetAmount, []*bc.AssetAmount) {
172+ var receivedAmounts, priceDiffs, shouldPayAmounts []*bc.AssetAmount
174173 for i, order := range orders {
175174 requestAmount := CalcRequestAmount(order.Utxo.Amount, order.RatioNumerator, order.RatioDenominator)
176175 oppositeOrder := orders[calcOppositeIndex(len(orders), i)]
@@ -185,7 +184,7 @@ func CalcReceivedAmount(orders []*common.Order) ([]*bc.AssetAmount, map[bc.Asset
185184 if oppositeShouldPayAmount.Amount > receivedAmount.Amount {
186185 assetId := oppositeShouldPayAmount.AssetId
187186 amount := oppositeShouldPayAmount.Amount - receivedAmount.Amount
188- priceDiffs[*assetId] = int64(amount)
187+ priceDiffs = append(priceDiffs, &bc.AssetAmount{AssetId: assetId, Amount: amount})
189188 }
190189 }
191190 return receivedAmounts, priceDiffs
--- a/application/mov/match/match_fee.go
+++ b/application/mov/match/match_fee.go
@@ -8,13 +8,13 @@ import (
88 )
99
1010 var (
11- // ErrAmountOfFeeExceedMaximum represent The fee charged is exceeded the maximum
12- ErrAmountOfFeeExceedMaximum = errors.New("amount of fee greater than max fee amount")
11+ // ErrAmountOfFeeOutOfRange represent The fee charged is out of range
12+ ErrAmountOfFeeOutOfRange = errors.New("amount of fee is out of range")
1313 )
1414
1515 // AllocatedAssets represent reallocated assets after calculating fees
1616 type AllocatedAssets struct {
17- Received []*bc.AssetAmount
17+ Receives []*bc.AssetAmount
1818 Refunds []RefundAssets
1919 Fees []*bc.AssetAmount
2020 }
@@ -28,10 +28,10 @@ type FeeStrategy interface {
2828 // @param receiveAmounts the amount of assets that the participants in the matching transaction can received when no fee is considered
2929 // @param priceDiffs price differential of matching transaction
3030 // @return reallocated assets after calculating fees
31- Allocate(receiveAmounts []*bc.AssetAmount, priceDiffs map[bc.AssetID]int64) *AllocatedAssets
31+ Allocate(receiveAmounts, priceDiffs []*bc.AssetAmount) *AllocatedAssets
3232
3333 // Validate verify that the fee charged for a matching transaction is correct
34- Validate(receiveAmounts []*bc.AssetAmount, priceDiffs, feeAmounts map[bc.AssetID]int64) error
34+ Validate(receiveAmounts []*bc.AssetAmount, feeAmounts map[bc.AssetID]uint64) error
3535 }
3636
3737 // DefaultFeeStrategy represent the default fee charge strategy
@@ -45,59 +45,68 @@ func NewDefaultFeeStrategy(maxFeeRate float64) *DefaultFeeStrategy {
4545 }
4646
4747 // Allocate will allocate the price differential in matching transaction to the participants and the fee
48-func (d *DefaultFeeStrategy) Allocate(receiveAmounts []*bc.AssetAmount, priceDiffs map[bc.AssetID]int64) *AllocatedAssets {
49- var feeAmounts []*bc.AssetAmount
50- refundAmounts := make([]RefundAssets, len(receiveAmounts))
48+func (d *DefaultFeeStrategy) Allocate(receiveAmounts, priceDiffs []*bc.AssetAmount) *AllocatedAssets {
49+ feeMap := make(map[bc.AssetID]uint64)
50+ for _, priceDiff := range priceDiffs {
51+ feeMap[*priceDiff.AssetId] = priceDiff.Amount
52+ }
5153
52- for _, receiveAmount := range receiveAmounts {
53- if _, ok := priceDiffs[*receiveAmount.AssetId]; !ok {
54- continue
55- }
54+ var fees []*bc.AssetAmount
55+ refunds := make([]RefundAssets, len(receiveAmounts))
56+ receives := make([]*bc.AssetAmount, len(receiveAmounts))
5657
57- priceDiff := priceDiffs[*receiveAmount.AssetId]
58- maxFeeAmount := calcMaxFeeAmount(receiveAmount.Amount, d.maxFeeRate)
58+ for i, receiveAmount := range receiveAmounts {
59+ amount := receiveAmount.Amount
60+ minFeeAmount := calcMinFeeAmount(amount)
61+ receives[i] = &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: amount - minFeeAmount}
62+ feeMap[*receiveAmount.AssetId] += minFeeAmount
5963
60- feeAmount, reminder := priceDiff, int64(0)
61- if priceDiff > maxFeeAmount {
64+ maxFeeAmount := calcMaxFeeAmount(amount, d.maxFeeRate)
65+ feeAmount, reminder := feeMap[*receiveAmount.AssetId], uint64(0)
66+ if feeAmount > maxFeeAmount {
67+ reminder = feeAmount - maxFeeAmount
6268 feeAmount = maxFeeAmount
63- reminder = priceDiff - maxFeeAmount
6469 }
6570
66- feeAmounts = append(feeAmounts, &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: uint64(feeAmount)})
71+ if feeAmount > 0 {
72+ fees = append(fees, &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: feeAmount})
73+ }
6774
6875 // There is the remaining amount after paying the handling fee, assign it evenly to participants in the transaction
69- averageAmount := reminder / int64(len(receiveAmounts))
76+ averageAmount := reminder / uint64(len(receiveAmounts))
7077 if averageAmount == 0 {
7178 averageAmount = 1
7279 }
7380
74- for i := 0; i < len(receiveAmounts) && reminder > 0; i++ {
75- amount := averageAmount
76- if i == len(receiveAmounts)-1 {
77- amount = reminder
81+ for j := 0; j < len(receiveAmounts) && reminder > 0; j++ {
82+ refundAmount := averageAmount
83+ if j == len(receiveAmounts)-1 {
84+ refundAmount = reminder
7885 }
79- refundAmounts[i] = append(refundAmounts[i], &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: uint64(amount)})
86+ refunds[j] = append(refunds[j], &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: refundAmount})
8087 reminder -= averageAmount
8188 }
8289 }
83-
84- receivedAfterDeductFee := make([]*bc.AssetAmount, len(receiveAmounts))
85- copy(receivedAfterDeductFee, receiveAmounts)
86- return &AllocatedAssets{Received: receivedAfterDeductFee, Refunds: refundAmounts, Fees: feeAmounts}
90+ return &AllocatedAssets{Receives: receives, Refunds: refunds, Fees: fees}
8791 }
8892
8993 // Validate verify that the fee charged for a matching transaction is correct
90-func (d *DefaultFeeStrategy) Validate(receiveAmounts []*bc.AssetAmount, feeAmounts, priceDiffs map[bc.AssetID]int64) error {
94+func (d *DefaultFeeStrategy) Validate(receiveAmounts []*bc.AssetAmount, feeAmounts map[bc.AssetID]uint64) error {
9195 for _, receiveAmount := range receiveAmounts {
92- if feeAmount, ok := feeAmounts[*receiveAmount.AssetId]; ok {
93- if feeAmount > calcMaxFeeAmount(receiveAmount.Amount+uint64(priceDiffs[*receiveAmount.AssetId]), d.maxFeeRate) {
94- return ErrAmountOfFeeExceedMaximum
95- }
96+ feeAmount := feeAmounts[*receiveAmount.AssetId]
97+ maxFeeAmount := calcMaxFeeAmount(receiveAmount.Amount, d.maxFeeRate)
98+ minFeeAmount := calcMinFeeAmount(receiveAmount.Amount)
99+ if feeAmount < minFeeAmount || feeAmount > maxFeeAmount {
100+ return ErrAmountOfFeeOutOfRange
96101 }
97102 }
98103 return nil
99104 }
100105
101-func calcMaxFeeAmount(amount uint64, maxFeeRate float64) int64 {
102- return int64(math.Ceil(float64(amount) * maxFeeRate))
106+func calcMinFeeAmount(amount uint64) uint64 {
107+ return uint64(math.Ceil(float64(amount) / 1000))
108+}
109+
110+func calcMaxFeeAmount(amount uint64, maxFeeRate float64) uint64 {
111+ return uint64(math.Ceil(float64(amount) * maxFeeRate))
103112 }
--- a/application/mov/mock/mock.go
+++ b/application/mov/mock/mock.go
@@ -265,10 +265,13 @@ var (
265265 types.NewSpendInput([][]byte{vm.Int64Bytes(2), vm.Int64Bytes(1)}, *Eth2BtcOrders[1].Utxo.SourceID, *Eth2BtcOrders[1].FromAssetID, Eth2BtcOrders[1].Utxo.Amount, Eth2BtcOrders[1].Utxo.SourcePos, Eth2BtcOrders[1].Utxo.ControlProgram),
266266 },
267267 Outputs: []*types.TxOutput{
268- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 416, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
268+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 415, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
269269 // re-order
270270 types.NewIntraChainOutput(*Btc2EthOrders[0].FromAssetID, 2, Btc2EthOrders[0].Utxo.ControlProgram),
271- types.NewIntraChainOutput(*Eth2BtcOrders[1].ToAssetID, 8, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19254")),
271+ types.NewIntraChainOutput(*Eth2BtcOrders[1].ToAssetID, 7, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19254")),
272+ // fee
273+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 1, RewardProgram),
274+ types.NewIntraChainOutput(*Eth2BtcOrders[1].ToAssetID, 1, RewardProgram),
272275 },
273276 }),
274277
@@ -279,9 +282,11 @@ var (
279282 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *Eth2BtcOrders[0].Utxo.SourceID, *Eth2BtcOrders[0].FromAssetID, Eth2BtcOrders[0].Utxo.Amount, Eth2BtcOrders[0].Utxo.SourcePos, Eth2BtcOrders[0].Utxo.ControlProgram),
280283 },
281284 Outputs: []*types.TxOutput{
282- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
283- types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19253")),
284- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 10, RewardProgram),
285+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
286+ types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 9, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19253")),
287+ // fee
288+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 11, RewardProgram),
289+ types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 1, RewardProgram),
285290 },
286291 }),
287292
@@ -292,14 +297,15 @@ var (
292297 types.NewSpendInput([][]byte{vm.Int64Bytes(10), vm.Int64Bytes(1), vm.Int64Bytes(0)}, *Eth2BtcOrders[2].Utxo.SourceID, *Eth2BtcOrders[2].FromAssetID, Eth2BtcOrders[2].Utxo.Amount, Eth2BtcOrders[2].Utxo.SourcePos, Eth2BtcOrders[2].Utxo.ControlProgram),
293298 },
294299 Outputs: []*types.TxOutput{
295- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
296- types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 10, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
300+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
301+ types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 9, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
297302 // re-order
298303 types.NewIntraChainOutput(*Eth2BtcOrders[2].FromAssetID, 270, Eth2BtcOrders[2].Utxo.ControlProgram),
299304 // fee
300305 types.NewIntraChainOutput(*Eth2BtcOrders[2].FromAssetID, 25, RewardProgram),
306+ types.NewIntraChainOutput(*Btc2EthOrders[0].FromAssetID, 1, RewardProgram),
301307 // refund
302- types.NewIntraChainOutput(*Eth2BtcOrders[2].FromAssetID, 7, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
308+ types.NewIntraChainOutput(*Eth2BtcOrders[2].FromAssetID, 8, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
303309 types.NewIntraChainOutput(*Eth2BtcOrders[2].FromAssetID, 8, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
304310 },
305311 }),
@@ -309,10 +315,13 @@ var (
309315 types.NewSpendInput([][]byte{vm.Int64Bytes(2), vm.Int64Bytes(1)}, testutil.MustDecodeHash("39bdb7058a0c31fb740af8e3c382bf608efff1b041cd4dd461332722ad24552a"), *Eth2BtcOrders[2].FromAssetID, 270, 2, Eth2BtcOrders[2].Utxo.ControlProgram),
310316 },
311317 Outputs: []*types.TxOutput{
312- types.NewIntraChainOutput(*Btc2EthOrders[1].ToAssetID, 270, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19252")),
318+ types.NewIntraChainOutput(*Btc2EthOrders[1].ToAssetID, 269, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19252")),
313319 // re-order
314320 types.NewIntraChainOutput(*Btc2EthOrders[1].FromAssetID, 15, Btc2EthOrders[1].Utxo.ControlProgram),
315- types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 5, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
321+ types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 4, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
322+ // fee
323+ types.NewIntraChainOutput(*Btc2EthOrders[1].ToAssetID, 1, RewardProgram),
324+ types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 1, RewardProgram),
316325 },
317326 }),
318327
@@ -323,10 +332,13 @@ var (
323332 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *MustNewOrderFromOutput(Eth2BtcMakerTxs[1], 0).Utxo.SourceID, *Eth2BtcOrders[1].FromAssetID, Eth2BtcOrders[1].Utxo.Amount, 0, Eth2BtcOrders[1].Utxo.ControlProgram),
324333 },
325334 Outputs: []*types.TxOutput{
326- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 416, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
335+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 415, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
327336 // re-order
328337 types.NewIntraChainOutput(*Btc2EthOrders[0].FromAssetID, 2, Btc2EthOrders[0].Utxo.ControlProgram),
329- types.NewIntraChainOutput(*Eth2BtcOrders[1].ToAssetID, 8, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19254")),
338+ types.NewIntraChainOutput(*Eth2BtcOrders[1].ToAssetID, 7, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19254")),
339+ // fee
340+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 1, RewardProgram),
341+ types.NewIntraChainOutput(*Eth2BtcOrders[1].ToAssetID, 1, RewardProgram),
330342 },
331343 }),
332344
@@ -337,8 +349,11 @@ var (
337349 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *MustNewOrderFromOutput(Etc2EosMakerTxs[0], 0).Utxo.SourceID, *Etc2EosOrders[0].FromAssetID, Etc2EosOrders[0].Utxo.Amount, Etc2EosOrders[0].Utxo.SourcePos, Etc2EosOrders[0].Utxo.ControlProgram),
338350 },
339351 Outputs: []*types.TxOutput{
340- types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 50, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
341- types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 100, testutil.MustDecodeHexString("0014df7a97e53bbe278e4e44810b0a760fb472daa9a3")),
352+ types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 49, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
353+ types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 99, testutil.MustDecodeHexString("0014df7a97e53bbe278e4e44810b0a760fb472daa9a3")),
354+ // fee
355+ types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 1, RewardProgram),
356+ types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 1, RewardProgram),
342357 },
343358 }),
344359
@@ -350,9 +365,13 @@ var (
350365 types.NewSpendInput([][]byte{vm.Int64Bytes(2), vm.Int64Bytes(1)}, *Eos2BtcOrders[0].Utxo.SourceID, *Eos2BtcOrders[0].FromAssetID, Eos2BtcOrders[0].Utxo.Amount, Eos2BtcOrders[0].Utxo.SourcePos, Eos2BtcOrders[0].Utxo.ControlProgram),
351366 },
352367 Outputs: []*types.TxOutput{
353- types.NewIntraChainOutput(ETH, 500, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
354- types.NewIntraChainOutput(EOS, 1000, testutil.MustDecodeHexString("0014e3178c0f294a9a8f4b304236406507913091df86")),
355- types.NewIntraChainOutput(BTC, 10, testutil.MustDecodeHexString("00144d0dfc8a0c5ce41d31d4f61d99aff70588bff8bc")),
368+ types.NewIntraChainOutput(ETH, 499, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
369+ types.NewIntraChainOutput(EOS, 999, testutil.MustDecodeHexString("0014e3178c0f294a9a8f4b304236406507913091df86")),
370+ types.NewIntraChainOutput(BTC, 9, testutil.MustDecodeHexString("00144d0dfc8a0c5ce41d31d4f61d99aff70588bff8bc")),
371+ // fee
372+ types.NewIntraChainOutput(ETH, 1, RewardProgram),
373+ types.NewIntraChainOutput(EOS, 1, RewardProgram),
374+ types.NewIntraChainOutput(BTC, 1, RewardProgram),
356375 },
357376 }),
358377
@@ -363,10 +382,13 @@ var (
363382 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *MustNewOrderFromOutput(Eth2BtcMakerTxs[0], 0).Utxo.SourceID, *Eth2BtcOrders[0].FromAssetID, Eth2BtcOrders[0].Utxo.Amount, 0, Eth2BtcOrders[0].Utxo.ControlProgram),
364383 },
365384 Outputs: []*types.TxOutput{
366- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 100, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
367- types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 2, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19253")),
385+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 99, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
386+ types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 1, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19253")),
368387 // re-order
369388 types.NewIntraChainOutput(*Eth2BtcOrders[0].FromAssetID, 404, Eth2BtcOrders[0].Utxo.ControlProgram),
389+ // fee
390+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 1, RewardProgram),
391+ types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 1, RewardProgram),
370392 },
371393 }),
372394
@@ -377,12 +399,13 @@ var (
377399 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),
378400 },
379401 Outputs: []*types.TxOutput{
380- types.NewIntraChainOutput(*Btc2EthOrders[3].ToAssetID, 810, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19252")),
402+ types.NewIntraChainOutput(*Btc2EthOrders[3].ToAssetID, 809, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19252")),
381403 // re-order
382404 types.NewIntraChainOutput(*Btc2EthOrders[3].FromAssetID, 1, Btc2EthOrders[3].Utxo.ControlProgram),
383- types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 15, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
405+ types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 14, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
384406 // fee
385- types.NewIntraChainOutput(*Btc2EthOrders[3].FromAssetID, 1, RewardProgram),
407+ types.NewIntraChainOutput(*Btc2EthOrders[3].FromAssetID, 2, RewardProgram),
408+ types.NewIntraChainOutput(*Eth2BtcOrders[2].ToAssetID, 1, RewardProgram),
386409 },
387410 }),
388411
@@ -393,8 +416,11 @@ var (
393416 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),
394417 },
395418 Outputs: []*types.TxOutput{
396- types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 50, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
397- types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 100, testutil.MustDecodeHexString("0014df7a97e53bbe278e4e44810b0a760fb472daa9a3")),
419+ types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 49, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
420+ types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 99, testutil.MustDecodeHexString("0014df7a97e53bbe278e4e44810b0a760fb472daa9a3")),
421+ // fee
422+ types.NewIntraChainOutput(*Eos2EtcOrders[0].ToAssetID, 1, RewardProgram),
423+ types.NewIntraChainOutput(*Etc2EosOrders[0].ToAssetID, 1, RewardProgram),
398424 },
399425 }),
400426
@@ -405,9 +431,12 @@ var (
405431 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *MustNewOrderFromOutput(Eth2BtcMakerTxs[0], 0).Utxo.SourceID, *Eth2BtcOrders[0].FromAssetID, Eth2BtcOrders[0].Utxo.Amount, 0, Eth2BtcOrders[0].Utxo.ControlProgram),
406432 },
407433 Outputs: []*types.TxOutput{
408- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
409- types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19253")),
434+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
435+ types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 9, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19253")),
410436 types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 10, RewardProgram),
437+ // fee
438+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 1, RewardProgram),
439+ types.NewIntraChainOutput(*Eth2BtcOrders[0].ToAssetID, 1, RewardProgram),
411440 },
412441 }),
413442
@@ -418,14 +447,14 @@ var (
418447 types.NewSpendInput([][]byte{vm.Int64Bytes(1), vm.Int64Bytes(1)}, *Eth2BtcOrders[3].Utxo.SourceID, *Eth2BtcOrders[3].FromAssetID, Eth2BtcOrders[3].Utxo.Amount, Eth2BtcOrders[3].Utxo.SourcePos, Eth2BtcOrders[3].Utxo.ControlProgram),
419448 },
420449 Outputs: []*types.TxOutput{
421- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
422- types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 4, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
450+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
451+ types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 3, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
423452 // fee
424453 types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 25, RewardProgram),
425454 types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 1, RewardProgram),
426455 // refund
427- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 37, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
428- types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 2, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
456+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 38, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
457+ types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 3, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
429458 types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 38, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
430459 types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 3, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
431460 },
--- a/application/mov/mov_core.go
+++ b/application/mov/mov_core.go
@@ -183,7 +183,7 @@ func (m *MovCore) ValidateTx(tx *types.Tx, verifyResult *bc.TxVerifyResult, bloc
183183 // matchedTxFee is object to record the mov tx's fee information
184184 type matchedTxFee struct {
185185 rewardProgram []byte
186- amount int64
186+ amount uint64
187187 }
188188
189189 // calcFeeAmount return the amount of fee in the matching transaction
@@ -192,7 +192,7 @@ func calcFeeAmount(matchedTx *types.Tx) (map[bc.AssetID]*matchedTxFee, error) {
192192 dealProgMaps := make(map[string]bool)
193193
194194 for _, input := range matchedTx.Inputs {
195- assetFeeMap[input.AssetID()] = &matchedTxFee{amount: int64(input.AssetAmount().Amount)}
195+ assetFeeMap[input.AssetID()] = &matchedTxFee{amount: input.AssetAmount().Amount}
196196 contractArgs, err := segwit.DecodeP2WMCProgram(input.ControlProgram())
197197 if err != nil {
198198 return nil, err
@@ -204,7 +204,7 @@ func calcFeeAmount(matchedTx *types.Tx) (map[bc.AssetID]*matchedTxFee, error) {
204204 for _, output := range matchedTx.Outputs {
205205 assetAmount := output.AssetAmount()
206206 if _, ok := dealProgMaps[hex.EncodeToString(output.ControlProgram())]; ok || segwit.IsP2WMCScript(output.ControlProgram()) {
207- assetFeeMap[*assetAmount.AssetId].amount -= int64(assetAmount.Amount)
207+ assetFeeMap[*assetAmount.AssetId].amount -= assetAmount.Amount
208208 if assetFeeMap[*assetAmount.AssetId].amount <= 0 {
209209 delete(assetFeeMap, *assetAmount.AssetId)
210210 }
@@ -301,14 +301,14 @@ func validateMatchedTxFee(tx *types.Tx, blockHeight uint64) error {
301301 return err
302302 }
303303
304- feeAmounts := make(map[bc.AssetID]int64)
304+ feeAmounts := make(map[bc.AssetID]uint64)
305305 for assetID, fee := range matchedTxFees {
306306 feeAmounts[assetID] = fee.amount
307307 }
308308
309- receivedAmount, priceDiffs := match.CalcReceivedAmount(orders)
309+ receivedAmount, _ := match.CalcReceivedAmount(orders)
310310 feeStrategy := match.NewDefaultFeeStrategy(maxFeeRate)
311- return feeStrategy.Validate(receivedAmount, feeAmounts, priceDiffs)
311+ return feeStrategy.Validate(receivedAmount, feeAmounts)
312312 }
313313
314314 func (m *MovCore) validateMatchedTxSequence(txs []*types.Tx) error {
--- a/application/mov/mov_core_test.go
+++ b/application/mov/mov_core_test.go
@@ -372,9 +372,11 @@ func TestValidateBlock(t *testing.T) {
372372 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),
373373 },
374374 Outputs: []*types.TxOutput{
375- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
376- types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("53")),
377- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 10, []byte{0x51}),
375+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("51")),
376+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 9, testutil.MustDecodeHexString("53")),
377+ // fee
378+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 11, mock.RewardProgram),
379+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 1, mock.RewardProgram),
378380 },
379381 }),
380382 },
@@ -393,9 +395,10 @@ func TestValidateBlock(t *testing.T) {
393395 types.NewSpendInput(nil, testutil.MustDecodeHash("28b7b53d8dc90006bf97e0a4eaae2a72ec3d869873188698b694beaf20789f21"), *consensus.BTMAssetID, 100, 0, []byte{0x51}),
394396 },
395397 Outputs: []*types.TxOutput{
396- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
397- types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("53")),
398- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 10, []byte{0x51}),
398+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("51")),
399+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 9, testutil.MustDecodeHexString("53")),
400+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 11, mock.RewardProgram),
401+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 1, mock.RewardProgram),
399402 types.NewIntraChainOutput(*consensus.BTMAssetID, 100, []byte{0x51}),
400403 },
401404 }),
@@ -415,10 +418,11 @@ func TestValidateBlock(t *testing.T) {
415418 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),
416419 },
417420 Outputs: []*types.TxOutput{
418- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("51")),
419- types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 10, testutil.MustDecodeHexString("53")),
420- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 10, []byte{0x51}),
421- types.NewIntraChainOutput(*consensus.BTMAssetID, 100, mock.RewardProgram),
421+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("51")),
422+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 9, testutil.MustDecodeHexString("53")),
423+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 11, mock.RewardProgram),
424+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[0].ToAssetID, 1, mock.RewardProgram),
425+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, 10, testutil.MustDecodeHexString("51")),
422426 },
423427 }),
424428 },
@@ -455,18 +459,19 @@ func TestValidateBlock(t *testing.T) {
455459 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),
456460 },
457461 Outputs: []*types.TxOutput{
458- types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 500, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
459- types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].ToAssetID, 10, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
462+ types.NewIntraChainOutput(*mock.Btc2EthOrders[0].ToAssetID, 499, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
463+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].ToAssetID, 9, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19255")),
460464 // re-order
461465 types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].FromAssetID, 270, mock.Eth2BtcOrders[2].Utxo.ControlProgram),
462466 // fee
463- types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].FromAssetID, 40, mock.RewardProgram),
467+ types.NewIntraChainOutput(*mock.Btc2EthOrders[2].ToAssetID, 41, mock.RewardProgram),
468+ types.NewIntraChainOutput(*mock.Eth2BtcOrders[2].ToAssetID, 1, mock.RewardProgram),
464469 },
465470 }),
466471 },
467472 },
468473 verifyResults: []*bc.TxVerifyResult{{StatusFail: false}},
469- wantError: match.ErrAmountOfFeeExceedMaximum,
474+ wantError: match.ErrAmountOfFeeOutOfRange,
470475 },
471476 {
472477 desc: "ratio numerator is zero",
@@ -525,21 +530,30 @@ func TestCalcMatchedTxFee(t *testing.T) {
525530 wantMatchedTxFee map[bc.AssetID]*matchedTxFee
526531 }{
527532 {
528- desc: "fee less than max fee",
529- maxFeeRate: 0.05,
530- wantMatchedTxFee: map[bc.AssetID]*matchedTxFee{mock.ETH: {amount: 10, rewardProgram: mock.RewardProgram}},
531- tx: mock.MatchedTxs[1].TxData,
533+ desc: "fee less than max fee",
534+ maxFeeRate: 0.05,
535+ wantMatchedTxFee: map[bc.AssetID]*matchedTxFee{
536+ mock.ETH: {amount: 11, rewardProgram: mock.RewardProgram},
537+ mock.BTC: {amount: 1, rewardProgram: mock.RewardProgram},
538+ },
539+ tx: mock.MatchedTxs[1].TxData,
532540 },
533541 {
534542 desc: "fee refund in tx",
535543 maxFeeRate: 0.05,
536- wantMatchedTxFee: map[bc.AssetID]*matchedTxFee{mock.ETH: {amount: 25, rewardProgram: mock.RewardProgram}},
544+ wantMatchedTxFee: map[bc.AssetID]*matchedTxFee{
545+ mock.ETH: {amount: 25, rewardProgram: mock.RewardProgram},
546+ mock.BTC: {amount: 1, rewardProgram: mock.RewardProgram},
547+ },
537548 tx: mock.MatchedTxs[2].TxData,
538549 },
539550 {
540- desc: "fee is zero",
551+ desc: "no price diff",
541552 maxFeeRate: 0.05,
542- wantMatchedTxFee: map[bc.AssetID]*matchedTxFee{},
553+ wantMatchedTxFee: map[bc.AssetID]*matchedTxFee{
554+ mock.ETH: {amount: 1, rewardProgram: mock.RewardProgram},
555+ mock.BTC: {amount: 1, rewardProgram: mock.RewardProgram},
556+ },
543557 tx: mock.MatchedTxs[0].TxData,
544558 },
545559 }
Show on old repository browser