• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: 提交

Golang implemented sidechain for Bytom


Commit MetaInfo

修訂bb191b49f352204f457585d4b6f219826b894452 (tree)
時間2020-03-26 10:51:54
作者shenao78 <shenao.78@163....>
Commitershenao78

Log Message

Merge branch 'fix_fee' into mov_fast_sync

Change Summary

差異

--- a/application/mov/match/engine.go
+++ b/application/mov/match/engine.go
@@ -62,20 +62,44 @@ func (e *Engine) NextMatchedTx(tradePairs ...*common.TradePair) (*types.Tx, erro
6262 return tx, nil
6363 }
6464
65-func (e *Engine) addMatchTxFeeOutput(txData *types.TxData, refunds RefundAssets, fees []*bc.AssetAmount) error {
65+func (e *Engine) addMatchTxFeeOutput(txData *types.TxData, fees []*bc.AssetAmount) error {
6666 for _, feeAmount := range fees {
6767 txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*feeAmount.AssetId, feeAmount.Amount, e.rewardProgram))
6868 }
6969
70- for i, refund := range refunds {
71- // each trading participant may be refunded multiple assets
72- for _, assetAmount := range refund {
73- contractArgs, err := segwit.DecodeP2WMCProgram(txData.Inputs[i].ControlProgram())
74- if err != nil {
75- return err
76- }
70+ refoundAmount := map[bc.AssetID]uint64{}
71+ assetIDs := []bc.AssetID{}
72+ refoundScript := [][]byte{}
73+ for _, input := range txData.Inputs {
74+ refoundAmount[input.AssetID()] += input.Amount()
75+ contractArgs, err := segwit.DecodeP2WMCProgram(input.ControlProgram())
76+ if err != nil {
77+ return err
78+ }
79+
80+ assetIDs = append(assetIDs, input.AssetID())
81+ refoundScript = append(refoundScript, contractArgs.SellerProgram)
82+ }
7783
78- txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*assetAmount.AssetId, assetAmount.Amount, contractArgs.SellerProgram))
84+ for _, output := range txData.Outputs {
85+ assetAmount := output.AssetAmount()
86+ refoundAmount[*assetAmount.AssetId] -= assetAmount.Amount
87+ }
88+
89+ refoundCount := len(refoundScript)
90+ for _, assetID := range assetIDs {
91+ amount := refoundAmount[assetID]
92+ averageAmount := amount / uint64(refoundCount)
93+ if averageAmount == 0 {
94+ averageAmount = 1
95+ }
96+
97+ for i := 0; i < refoundCount && amount > 0; i++ {
98+ if i == refoundCount-1 {
99+ averageAmount = amount
100+ }
101+ txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(assetID, averageAmount, refoundScript[i]))
102+ amount -= averageAmount
79103 }
80104 }
81105 return nil
@@ -110,7 +134,7 @@ func (e *Engine) buildMatchTx(orders []*common.Order) (*types.Tx, error) {
110134 return nil, err
111135 }
112136
113- if err := e.addMatchTxFeeOutput(txData, allocatedAssets.Refunds, allocatedAssets.Fees); err != nil {
137+ if err := e.addMatchTxFeeOutput(txData, allocatedAssets.Fees); err != nil {
114138 return nil, err
115139 }
116140
@@ -140,8 +164,6 @@ func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmou
140164 txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.ToAssetID, allocatedAssets.Receives[i].Amount, contractArgs.SellerProgram))
141165 if isPartialTrade {
142166 txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.FromAssetID, exchangeAmount, order.Utxo.ControlProgram))
143- } else if exchangeAmount > 0 {
144- allocatedAssets.Refunds.Add(i, *order.FromAssetID, exchangeAmount)
145167 }
146168 }
147169 return nil
@@ -184,10 +206,9 @@ func CalcReceivedAmount(orders []*common.Order) ([]*bc.AssetAmount, []*bc.AssetA
184206
185207 for i, receivedAmount := range receivedAmounts {
186208 oppositeShouldPayAmount := shouldPayAmounts[calcOppositeIndex(len(orders), i)]
209+ priceDiffs = append(priceDiffs, &bc.AssetAmount{AssetId: oppositeShouldPayAmount.AssetId, Amount: 0})
187210 if oppositeShouldPayAmount.Amount > receivedAmount.Amount {
188- assetID := oppositeShouldPayAmount.AssetId
189- amount := oppositeShouldPayAmount.Amount - receivedAmount.Amount
190- priceDiffs = append(priceDiffs, &bc.AssetAmount{AssetId: assetID, Amount: amount})
211+ priceDiffs[i].Amount = oppositeShouldPayAmount.Amount - receivedAmount.Amount
191212 }
192213 }
193214 return receivedAmounts, priceDiffs
--- a/application/mov/match/fee_strategy.go
+++ b/application/mov/match/fee_strategy.go
@@ -15,28 +15,9 @@ var (
1515 // AllocatedAssets represent reallocated assets after calculating fees
1616 type AllocatedAssets struct {
1717 Receives []*bc.AssetAmount
18- Refunds RefundAssets
1918 Fees []*bc.AssetAmount
2019 }
2120
22-// RefundAssets represent alias for assetAmount array, because each transaction participant can be refunded multiple assets
23-type RefundAssets [][]*bc.AssetAmount
24-
25-// Add used to add a refund to specify order
26-func (r RefundAssets) Add(index int, asset bc.AssetID, amount uint64) {
27- if index >= len(r) {
28- index = 0
29- }
30-
31- for _, assetAmount := range r[index] {
32- if *assetAmount.AssetId == asset {
33- assetAmount.Amount += amount
34- return
35- }
36- }
37- r[index] = append(r[index], &bc.AssetAmount{AssetId: &asset, Amount: amount})
38-}
39-
4021 // FeeStrategy used to indicate how to charge a matching fee
4122 type FeeStrategy interface {
4223 // Allocate will allocate the price differential in matching transaction to the participants and the fee
@@ -50,7 +31,7 @@ type FeeStrategy interface {
5031 }
5132
5233 // DefaultFeeStrategy represent the default fee charge strategy
53-type DefaultFeeStrategy struct {}
34+type DefaultFeeStrategy struct{}
5435
5536 // NewDefaultFeeStrategy return a new instance of DefaultFeeStrategy
5637 func NewDefaultFeeStrategy() *DefaultFeeStrategy {
@@ -59,46 +40,20 @@ func NewDefaultFeeStrategy() *DefaultFeeStrategy {
5940
6041 // Allocate will allocate the price differential in matching transaction to the participants and the fee
6142 func (d *DefaultFeeStrategy) Allocate(receiveAmounts, priceDiffs []*bc.AssetAmount) *AllocatedAssets {
62- feeMap := make(map[bc.AssetID]uint64)
63- for _, priceDiff := range priceDiffs {
64- feeMap[*priceDiff.AssetId] = priceDiff.Amount
65- }
66-
67- var fees []*bc.AssetAmount
68- refunds := make([][]*bc.AssetAmount, len(receiveAmounts))
6943 receives := make([]*bc.AssetAmount, len(receiveAmounts))
44+ fees := make([]*bc.AssetAmount, len(receiveAmounts))
7045
7146 for i, receiveAmount := range receiveAmounts {
72- amount := receiveAmount.Amount
73- minFeeAmount := d.calcMinFeeAmount(amount)
74- receives[i] = &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: amount - minFeeAmount}
75- feeMap[*receiveAmount.AssetId] += minFeeAmount
76-
77- maxFeeAmount := d.calcMaxFeeAmount(amount)
78- feeAmount, reminder := feeMap[*receiveAmount.AssetId], uint64(0)
79- if feeAmount > maxFeeAmount {
80- reminder = feeAmount - maxFeeAmount
81- feeAmount = maxFeeAmount
47+ standFee := d.calcMinFeeAmount(receiveAmount.Amount)
48+ fee := standFee + priceDiffs[i].Amount
49+ if maxFeeAmount := d.calcMaxFeeAmount(receiveAmount.Amount); fee > maxFeeAmount {
50+ fee = maxFeeAmount
8251 }
8352
84- fees = append(fees, &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: feeAmount})
85-
86- // There is the remaining amount after paying the handling fee, assign it evenly to participants in the transaction
87- averageAmount := reminder / uint64(len(receiveAmounts))
88- if averageAmount == 0 {
89- averageAmount = 1
90- }
91-
92- for j := 0; j < len(receiveAmounts) && reminder > 0; j++ {
93- refundAmount := averageAmount
94- if j == len(receiveAmounts)-1 {
95- refundAmount = reminder
96- }
97- refunds[j] = append(refunds[j], &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: refundAmount})
98- reminder -= averageAmount
99- }
53+ receives[i] = &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: receiveAmount.Amount - standFee}
54+ fees[i] = &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: fee}
10055 }
101- return &AllocatedAssets{Receives: receives, Refunds: refunds, Fees: fees}
56+ return &AllocatedAssets{Receives: receives, Fees: fees}
10257 }
10358
10459 // Validate verify that the fee charged for a matching transaction is correct
--- a/application/mov/mock/mock.go
+++ b/application/mov/mock/mock.go
@@ -453,10 +453,10 @@ var (
453453 types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 25, RewardProgram),
454454 types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 1, RewardProgram),
455455 // refund
456- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 38, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
457456 types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 3, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
458- types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 38, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
459457 types.NewIntraChainOutput(*Eth2BtcOrders[3].ToAssetID, 3, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
458+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 38, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19251")),
459+ types.NewIntraChainOutput(*Btc2EthOrders[0].ToAssetID, 38, testutil.MustDecodeHexString("0014f928b723999312df4ed51cb275a2644336c19256")),
460460 },
461461 }),
462462 }
Show on old repository browser