From 9f3042be407cf307fbf6c3318f02f94ae27e6292 Mon Sep 17 00:00:00 2001 From: Poseidon Date: Wed, 22 Jan 2020 15:05:54 +0800 Subject: [PATCH] fix decimal (#479) * fix decimal * fix decimal * bug fix * fix decimal --- application/mov/match/match.go | 15 +--- application/mov/match/match_test.go | 160 ++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 11 deletions(-) diff --git a/application/mov/match/match.go b/application/mov/match/match.go index 4c0234f9..845c2283 100644 --- a/application/mov/match/match.go +++ b/application/mov/match/match.go @@ -240,20 +240,13 @@ func IsMatched(orders []*common.Order) bool { return false } - rate := orderRatio(sortedOrders[0]) - oppositeRate := big.NewFloat(0).SetInt64(1) + rate := big.NewRat(sortedOrders[0].RatioDenominator, sortedOrders[0].RatioNumerator) + oppositeRate := big.NewRat(1, 1) for i := 1; i < len(sortedOrders); i++ { - oppositeRate.Mul(oppositeRate, orderRatio(sortedOrders[i])) + oppositeRate.Mul(oppositeRate, big.NewRat(sortedOrders[i].RatioNumerator, sortedOrders[i].RatioDenominator)) } - one := big.NewFloat(0).SetInt64(1) - return one.Quo(one, rate).Cmp(oppositeRate) >= 0 -} - -func orderRatio(order *common.Order) *big.Float { - ratio := big.NewFloat(0).SetInt64(order.RatioNumerator) - ratio.Quo(ratio, big.NewFloat(0).SetInt64(order.RatioDenominator)) - return ratio + return rate.Cmp(oppositeRate) >= 0 } func setMatchTxArguments(txInput *types.TxInput, isPartialTrade bool, position int, receiveAmounts uint64) { diff --git a/application/mov/match/match_test.go b/application/mov/match/match_test.go index 640f4cfb..7d013ec8 100644 --- a/application/mov/match/match_test.go +++ b/application/mov/match/match_test.go @@ -256,3 +256,163 @@ func TestValidateTradePairs(t *testing.T) { } } } + +func TestIsMatched(t *testing.T) { + cases := []struct { + desc string + orders []*common.Order + wantMatched bool + }{ + { + desc: "ratio is equals", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 6250, + RatioDenominator: 3, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.BTC, + RatioNumerator: 3, + RatioDenominator: 6250, + }, + }, + wantMatched: true, + }, + { + desc: "ratio is equals, and numerator and denominator are multiples of the opposite", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 6250, + RatioDenominator: 3, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.BTC, + RatioNumerator: 9, + RatioDenominator: 18750, + }, + }, + wantMatched: true, + }, + { + desc: "matched with a slight diff", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 62500000000000000, + RatioDenominator: 30000000000001, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.BTC, + RatioNumerator: 3, + RatioDenominator: 6250, + }, + }, + wantMatched: true, + }, + { + desc: "not matched with a slight diff", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 62500000000000001, + RatioDenominator: 30000000000000, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.BTC, + RatioNumerator: 3, + RatioDenominator: 6250, + }, + }, + wantMatched: false, + }, + { + desc: "ring matched", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 2000000003, + RatioDenominator: 100000001, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.EOS, + RatioNumerator: 400000000001, + RatioDenominator: 2000000003, + }, + { + FromAssetID: &mock.EOS, + ToAssetID: &mock.BTC, + RatioNumerator: 100000001, + RatioDenominator: 400000000001, + }, + }, + wantMatched: true, + }, + { + desc: "ring matched with a slight diff", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 2000000003, + RatioDenominator: 100000001, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.EOS, + RatioNumerator: 400000000001, + RatioDenominator: 2000000003, + }, + { + FromAssetID: &mock.EOS, + ToAssetID: &mock.BTC, + RatioNumerator: 100000000, + RatioDenominator: 400000000001, + }, + }, + wantMatched: true, + }, + { + desc: "ring fail matched with a slight diff", + orders: []*common.Order{ + { + FromAssetID: &mock.BTC, + ToAssetID: &mock.ETH, + RatioNumerator: 2000000003, + RatioDenominator: 100000001, + }, + { + FromAssetID: &mock.ETH, + ToAssetID: &mock.EOS, + RatioNumerator: 400000000001, + RatioDenominator: 2000000003, + }, + { + FromAssetID: &mock.EOS, + ToAssetID: &mock.BTC, + RatioNumerator: 100000002, + RatioDenominator: 400000000001, + }, + }, + wantMatched: false, + }, + } + + for i, c := range cases { + gotMatched := IsMatched(c.orders) + if gotMatched != c.wantMatched { + t.Errorf("#%d(%s) got matched:%v, want matched:%v", i, c.desc, gotMatched, c.wantMatched) + } + } +} -- 2.11.0