• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: 提交

Golang implemented sidechain for Bytom


Commit MetaInfo

修订版38de5720d9b9302a7bbafe9015f45517cdf02b27 (tree)
时间2020-03-25 22:28:22
作者paladz <453256728@qq.c...>
Commiterpaladz

Log Message

fix fee

更改概述

差异

--- a/application/mov/match/engine.go
+++ b/application/mov/match/engine.go
@@ -62,20 +62,42 @@ 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, orders []*common.Order, 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+ refoundAddress := [][]byte{}
72+ for _, input := range txData.Inputs {
73+ refoundAmount[input.AssetID()] += input.Amount()
74+ contractArgs, err := segwit.DecodeP2WMCProgram(input.ControlProgram())
75+ if err != nil {
76+ return err
77+ }
78+
79+ refoundAddress = append(refoundAddress, contractArgs.SellerProgram)
80+ }
81+
82+ for _, output := range txData.Outputs {
83+ assetAmount := output.AssetAmount()
84+ refoundAmount[*assetAmount.AssetId] -= assetAmount.Amount
85+ if refoundAmount[*assetAmount.AssetId] == 0 {
86+ delete(refoundAmount, *assetAmount.AssetId)
87+ }
88+ }
89+
90+ refoundCount := len(refoundAddress)
91+ for asset, amount := range refoundAmount {
92+ averageAmount := amount / uint64(refoundCount)
93+ if averageAmount == 0 {
94+ averageAmount = 1
95+ }
7796
78- txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*assetAmount.AssetId, assetAmount.Amount, contractArgs.SellerProgram))
97+ for i := 0; i < refoundCount && amount > 0; i++ {
98+ txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(asset,
99+ averageAmount, refoundAddress[i]))
100+ amount -= averageAmount
79101 }
80102 }
81103 return nil
@@ -104,13 +126,13 @@ func (e *Engine) buildMatchTx(orders []*common.Order) (*types.Tx, error) {
104126 txData.Inputs = append(txData.Inputs, input)
105127 }
106128
107- receivedAmounts, priceDiffs := CalcReceivedAmount(orders)
108- allocatedAssets := e.feeStrategy.Allocate(receivedAmounts, priceDiffs)
129+ receivedAmounts := CalcReceivedAmount(orders)
130+ allocatedAssets := e.feeStrategy.Allocate(receivedAmounts)
109131 if err := addMatchTxOutput(txData, orders, receivedAmounts, allocatedAssets); err != nil {
110132 return nil, err
111133 }
112134
113- if err := e.addMatchTxFeeOutput(txData, allocatedAssets.Refunds, allocatedAssets.Fees); err != nil {
135+ if err := e.addMatchTxFeeOutput(txData, orders, allocatedAssets.Fees); err != nil {
114136 return nil, err
115137 }
116138
@@ -140,8 +162,6 @@ func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmou
140162 txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.ToAssetID, allocatedAssets.Receives[i].Amount, contractArgs.SellerProgram))
141163 if isPartialTrade {
142164 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)
145165 }
146166 }
147167 return nil
@@ -171,26 +191,16 @@ func calcShouldPayAmount(receiveAmount uint64, ratioNumerator, ratioDenominator
171191 }
172192
173193 // CalcReceivedAmount return amount of assets received by each participant in the matching transaction and the price difference
174-func CalcReceivedAmount(orders []*common.Order) ([]*bc.AssetAmount, []*bc.AssetAmount) {
175- var receivedAmounts, priceDiffs, shouldPayAmounts []*bc.AssetAmount
194+func CalcReceivedAmount(orders []*common.Order) []*bc.AssetAmount {
195+ var receivedAmounts []*bc.AssetAmount
176196 for i, order := range orders {
177197 requestAmount := CalcRequestAmount(order.Utxo.Amount, order.RatioNumerator, order.RatioDenominator)
178198 oppositeOrder := orders[calcOppositeIndex(len(orders), i)]
179199 receiveAmount := vprMath.MinUint64(oppositeOrder.Utxo.Amount, requestAmount)
180- shouldPayAmount := calcShouldPayAmount(receiveAmount, order.RatioNumerator, order.RatioDenominator)
181200 receivedAmounts = append(receivedAmounts, &bc.AssetAmount{AssetId: order.ToAssetID, Amount: receiveAmount})
182- shouldPayAmounts = append(shouldPayAmounts, &bc.AssetAmount{AssetId: order.FromAssetID, Amount: shouldPayAmount})
183201 }
184202
185- for i, receivedAmount := range receivedAmounts {
186- oppositeShouldPayAmount := shouldPayAmounts[calcOppositeIndex(len(orders), i)]
187- 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})
191- }
192- }
193- return receivedAmounts, priceDiffs
203+ return receivedAmounts
194204 }
195205
196206 // IsMatched check does the orders can be exchange
--- a/application/mov/match/fee_strategy.go
+++ b/application/mov/match/fee_strategy.go
@@ -15,7 +15,6 @@ 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
@@ -43,14 +42,14 @@ type FeeStrategy interface {
4342 // @param receiveAmounts the amount of assets that the participants in the matching transaction can received when no fee is considered
4443 // @param priceDiffs price differential of matching transaction
4544 // @return reallocated assets after calculating fees
46- Allocate(receiveAmounts, priceDiffs []*bc.AssetAmount) *AllocatedAssets
45+ Allocate(receiveAmounts []*bc.AssetAmount) *AllocatedAssets
4746
4847 // Validate verify that the fee charged for a matching transaction is correct
4948 Validate(receiveAmounts []*bc.AssetAmount, feeAmounts map[bc.AssetID]uint64) error
5049 }
5150
5251 // DefaultFeeStrategy represent the default fee charge strategy
53-type DefaultFeeStrategy struct {}
52+type DefaultFeeStrategy struct{}
5453
5554 // NewDefaultFeeStrategy return a new instance of DefaultFeeStrategy
5655 func NewDefaultFeeStrategy() *DefaultFeeStrategy {
@@ -58,47 +57,17 @@ func NewDefaultFeeStrategy() *DefaultFeeStrategy {
5857 }
5958
6059 // Allocate will allocate the price differential in matching transaction to the participants and the fee
61-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))
60+func (d *DefaultFeeStrategy) Allocate(receiveAmounts []*bc.AssetAmount) *AllocatedAssets {
6961 receives := make([]*bc.AssetAmount, len(receiveAmounts))
62+ fees := make([]*bc.AssetAmount, len(receiveAmounts))
7063
7164 for i, receiveAmount := range receiveAmounts {
7265 amount := receiveAmount.Amount
7366 minFeeAmount := d.calcMinFeeAmount(amount)
7467 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
82- }
83-
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- }
68+ fees[i] = &bc.AssetAmount{AssetId: receiveAmount.AssetId, Amount: minFeeAmount}
10069 }
101- return &AllocatedAssets{Receives: receives, Refunds: refunds, Fees: fees}
70+ return &AllocatedAssets{Receives: receives, Fees: fees}
10271 }
10372
10473 // Validate verify that the fee charged for a matching transaction is correct
--- a/application/mov/mov_core.go
+++ b/application/mov/mov_core.go
@@ -298,7 +298,7 @@ func validateMatchedTxFee(tx *types.Tx, blockHeight uint64) error {
298298 return err
299299 }
300300
301- receivedAmount, _ := match.CalcReceivedAmount(orders)
301+ receivedAmount := match.CalcReceivedAmount(orders)
302302 feeAmounts := make(map[bc.AssetID]uint64)
303303 for assetID, fee := range matchedTxFees {
304304 feeAmounts[assetID] = fee.amount
Show on old repository browser