* fix match engine
* opt code
* opt code for add refund
-func (e *Engine) addMatchTxFeeOutput(txData *types.TxData, refunds []RefundAssets, fees []*bc.AssetAmount) error {
+func (e *Engine) addMatchTxFeeOutput(txData *types.TxData, refunds RefundAssets, fees []*bc.AssetAmount) error {
for _, feeAmount := range fees {
txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*feeAmount.AssetId, feeAmount.Amount, e.rewardProgram))
}
for _, feeAmount := range fees {
txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*feeAmount.AssetId, feeAmount.Amount, e.rewardProgram))
}
receivedAmounts, priceDiffs := CalcReceivedAmount(orders)
allocatedAssets := e.feeStrategy.Allocate(receivedAmounts, priceDiffs)
receivedAmounts, priceDiffs := CalcReceivedAmount(orders)
allocatedAssets := e.feeStrategy.Allocate(receivedAmounts, priceDiffs)
- if err := addMatchTxOutput(txData, orders, receivedAmounts, allocatedAssets.Receives); err != nil {
+ if err := addMatchTxOutput(txData, orders, receivedAmounts, allocatedAssets); err != nil {
return types.NewTx(*txData), nil
}
return types.NewTx(*txData), nil
}
-func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmounts, deductFeeReceives []*bc.AssetAmount) error {
+func addMatchTxOutput(txData *types.TxData, orders []*common.Order, receivedAmounts []*bc.AssetAmount, allocatedAssets *AllocatedAssets) error {
for i, order := range orders {
contractArgs, err := segwit.DecodeP2WMCProgram(order.Utxo.ControlProgram)
if err != nil {
return err
}
for i, order := range orders {
contractArgs, err := segwit.DecodeP2WMCProgram(order.Utxo.ControlProgram)
if err != nil {
return err
}
- requestAmount := CalcRequestAmount(order.Utxo.Amount, contractArgs.RatioNumerator, contractArgs.RatioDenominator)
receivedAmount := receivedAmounts[i].Amount
shouldPayAmount := calcShouldPayAmount(receivedAmount, contractArgs.RatioNumerator, contractArgs.RatioDenominator)
receivedAmount := receivedAmounts[i].Amount
shouldPayAmount := calcShouldPayAmount(receivedAmount, contractArgs.RatioNumerator, contractArgs.RatioDenominator)
- isPartialTrade := requestAmount > receivedAmount
- setMatchTxArguments(txData.Inputs[i], isPartialTrade, len(txData.Outputs), receivedAmounts[i].Amount)
- txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.ToAssetID, deductFeeReceives[i].Amount, contractArgs.SellerProgram))
+ exchangeAmount := order.Utxo.Amount - shouldPayAmount
+ isPartialTrade := CalcRequestAmount(exchangeAmount, contractArgs.RatioNumerator, contractArgs.RatioDenominator) >= 1
+
+ setMatchTxArguments(txData.Inputs[i], isPartialTrade, len(txData.Outputs), receivedAmount)
+ txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.ToAssetID, allocatedAssets.Receives[i].Amount, contractArgs.SellerProgram))
- txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.FromAssetID, order.Utxo.Amount-shouldPayAmount, order.Utxo.ControlProgram))
+ txData.Outputs = append(txData.Outputs, types.NewIntraChainOutput(*order.FromAssetID, exchangeAmount, order.Utxo.ControlProgram))
+ } else if exchangeAmount > 0 {
+ allocatedAssets.Refunds.Add(i, *order.FromAssetID, exchangeAmount)
// AllocatedAssets represent reallocated assets after calculating fees
type AllocatedAssets struct {
Receives []*bc.AssetAmount
// AllocatedAssets represent reallocated assets after calculating fees
type AllocatedAssets struct {
Receives []*bc.AssetAmount
Fees []*bc.AssetAmount
}
// RefundAssets represent alias for assetAmount array, because each transaction participant can be refunded multiple assets
Fees []*bc.AssetAmount
}
// RefundAssets represent alias for assetAmount array, because each transaction participant can be refunded multiple assets
-type RefundAssets []*bc.AssetAmount
+type RefundAssets [][]*bc.AssetAmount
+
+// Add used to add a refund to specify order
+func (r RefundAssets) Add(index int, asset bc.AssetID, amount uint64) {
+ if index >= len(r) {
+ index = 0
+ }
+
+ for _, assetAmount := range r[index] {
+ if *assetAmount.AssetId == asset {
+ assetAmount.Amount += amount
+ return
+ }
+ }
+ r[index] = append(r[index], &bc.AssetAmount{AssetId: &asset, Amount: amount})
+}
// FeeStrategy used to indicate how to charge a matching fee
type FeeStrategy interface {
// FeeStrategy used to indicate how to charge a matching fee
type FeeStrategy interface {
}
var fees []*bc.AssetAmount
}
var fees []*bc.AssetAmount
- refunds := make([]RefundAssets, len(receiveAmounts))
+ refunds := make([][]*bc.AssetAmount, len(receiveAmounts))
receives := make([]*bc.AssetAmount, len(receiveAmounts))
for i, receiveAmount := range receiveAmounts {
receives := make([]*bc.AssetAmount, len(receiveAmounts))
for i, receiveAmount := range receiveAmounts {
}
if common.IsMatchedTx(tx) {
}
if common.IsMatchedTx(tx) {
- if err := validateMatchedTx(tx, verifyResult, blockHeight); err != nil {
+ if err := validateMatchedTx(tx, blockHeight); err != nil {
return err
}
} else if common.IsCancelOrderTx(tx) {
return err
}
} else if common.IsCancelOrderTx(tx) {
- if err := validateCancelOrderTx(tx, verifyResult); err != nil {
+ if err := validateCancelOrderTx(tx); err != nil {
return assetFeeMap, nil
}
return assetFeeMap, nil
}
-func validateCancelOrderTx(tx *types.Tx, verifyResult *bc.TxVerifyResult) error {
+func validateCancelOrderTx(tx *types.Tx) error {
for _, input := range tx.Inputs {
if !segwit.IsP2WMCScript(input.ControlProgram()) {
return errInputProgramMustP2WMCScript
for _, input := range tx.Inputs {
if !segwit.IsP2WMCScript(input.ControlProgram()) {
return errInputProgramMustP2WMCScript
-func validateMatchedTx(tx *types.Tx, verifyResult *bc.TxVerifyResult, blockHeight uint64) error {
+func validateMatchedTx(tx *types.Tx, blockHeight uint64) error {
fromAssetIDMap := make(map[string]bool)
toAssetIDMap := make(map[string]bool)
for i, input := range tx.Inputs {
fromAssetIDMap := make(map[string]bool)
toAssetIDMap := make(map[string]bool)
for i, input := range tx.Inputs {