diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b102629d..dcd0aaefa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.7.2 +BUG FIXES +* [\#753](https://github.com/binance-chain/node/pull/753) [\#760](https://github.com/binance-chain/node/pull/760) [Dex] Delete recent price from db when delisting +* [\#758](https://github.com/binance-chain/node/pull/758) [Dex] Force match all BEP2 symbols on BEP8 upgrade height to update last match height +* [\#762](https://github.com/binance-chain/node/pull/762) [Dex] Fix mini msg ## 0.7.0 FEATURES * [\#725](https://github.com/binance-chain/node/pull/725) [Token] [Dex] BEP8 - Mini-BEP2 token features diff --git a/app/app.go b/app/app.go index e33086009..076859ba2 100644 --- a/app/app.go +++ b/app/app.go @@ -38,6 +38,7 @@ import ( "github.com/binance-chain/node/plugins/dex" "github.com/binance-chain/node/plugins/dex/list" "github.com/binance-chain/node/plugins/dex/order" + dextypes "github.com/binance-chain/node/plugins/dex/types" "github.com/binance-chain/node/plugins/ico" "github.com/binance-chain/node/plugins/param" "github.com/binance-chain/node/plugins/param/paramhub" @@ -295,7 +296,7 @@ func SetUpgradeConfig(upgradeConfig *config.UpgradeConfig) { issue.IssueMiniMsg{}.Type(), issue.IssueTinyMsg{}.Type(), seturi.SetURIMsg{}.Type(), - list.ListMiniMsg{}.Type(), + dextypes.ListMiniMsg{}.Type(), ) } diff --git a/common/types/mini_token.go b/common/types/mini_token.go index 0ffba0569..fd3c1850a 100644 --- a/common/types/mini_token.go +++ b/common/types/mini_token.go @@ -21,7 +21,7 @@ const ( MiniTokenMinExecutionAmount int64 = 1e8 // 1 with 8 decimal digits MiniTokenSupplyUpperBound int64 = 1000000e8 // 1m with 8 decimal digits - TinyTokenSupplyUpperBound int64 = 10000e8 // 10k with 8 decimal digits + TinyTokenSupplyUpperBound int64 = 10000e8 // 10k with 8 decimal digits MaxTokenURILength = 2048 TinyRangeType SupplyRangeType = 1 diff --git a/integration_test.sh b/integration_test.sh index 84d49dc0b..74f55cffc 100755 --- a/integration_test.sh +++ b/integration_test.sh @@ -34,6 +34,10 @@ function prepare_node() { #$(cd "./${home}/config" && sed -i -e "s/db_backend = \"goleveldb\"/db_backend = \"boltdb\"/g" config.toml) $(cd "./${home}/config" && sed -i -e "s/log_level = \"main\:info,state\:info,\*\:error\"/log_level = \"*\:debug\"/g" config.toml) $(cd "./${home}/config" && sed -i -e 's/"voting_period": "1209600000000000"/"voting_period": "5000000000"/g' genesis.json) + $(cd "./${home}/config" && sed -i -e "s/BEP3Height = 9223372036854775807/BEP3Height = 1/g" app.toml) + $(cd "./${home}/config" && sed -i -e "s/BEP8Height = 9223372036854775807/BEP8Height = 1/g" app.toml) + $(cd "./${home}/config" && sed -i -e "s/BEP67Height = 9223372036854775807/BEP67Height = 1/g" app.toml) + $(cd "./${home}/config" && sed -i -e "s/BEP70Height = 9223372036854775807/BEP70Height = 1/g" app.toml) # stop and start node ps -ef | grep bnbchaind | grep testnoded | awk '{print $2}' | xargs kill -9 @@ -328,6 +332,10 @@ result=$(expect ./issue_mini.exp MBC MiniBitcoin 900000000000 true alice ${chain mbc_symbol=$(echo "${result}" | tail -n 1 | grep -o "MBC-[0-9A-Z]*M") check_operation "Issue Mini Token" "${result}" "${chain_operation_words}" +sleep 1s +# mint token +result=$(expect ./seturi.exp ${mbc_symbol} 10000000000 alice ${chain_id} ${cli_home}) +check_operation "Mint Token" "${result}" "${chain_operation_words}" sleep 1s # send diff --git a/networks/demo/seturi.exp b/networks/demo/seturi.exp new file mode 100644 index 000000000..c1528d9a5 --- /dev/null +++ b/networks/demo/seturi.exp @@ -0,0 +1,17 @@ +#!/usr/bin/expect + +set symbol [lindex $argv 0] +set amount [lindex $argv 1] +set from [lindex $argv 2] +set chain_id [lindex $argv 3] +set home [lindex $argv 4] + +set timeout 30 + if {"${home}" == ""} { + spawn ./bnbcli token mint -s $symbol -n $amount --from $from --chain-id $chain_id + } else { + spawn ./bnbcli token mint --home $home -s $symbol -n $amount --from $from --chain-id $chain_id + } + expect "Password*" + send "12345678\r" +interact diff --git a/plugins/dex/abci.go b/plugins/dex/abci.go index cabd4082b..e257c3cf0 100644 --- a/plugins/dex/abci.go +++ b/plugins/dex/abci.go @@ -204,4 +204,4 @@ func listPairs(keeper *DexKeeper, ctx sdk.Context, abciPrefix string) []types.Tr } } return rs -} \ No newline at end of file +} diff --git a/plugins/dex/client/cli/list.go b/plugins/dex/client/cli/list.go index 9c515a8cd..dccac14dc 100644 --- a/plugins/dex/client/cli/list.go +++ b/plugins/dex/client/cli/list.go @@ -2,6 +2,7 @@ package commands import ( "errors" + "strings" "github.com/spf13/cobra" @@ -10,7 +11,7 @@ import ( "github.com/binance-chain/node/common/client" "github.com/binance-chain/node/common/types" "github.com/binance-chain/node/common/utils" - "github.com/binance-chain/node/plugins/dex/list" + dextypes "github.com/binance-chain/node/plugins/dex/types" "github.com/binance-chain/node/wire" ) @@ -57,7 +58,7 @@ func listTradingPairCmd(cdc *wire.Codec) *cobra.Command { return errors.New("proposal id should larger than zero") } - msg := list.NewMsg(from, proposalId, baseAsset, quoteAsset, initPrice) + msg := dextypes.NewListMsg(from, proposalId, baseAsset, quoteAsset, initPrice) err = client.SendOrPrintTx(cliCtx, txbldr, msg) if err != nil { return err @@ -107,7 +108,7 @@ func listMiniTradingPairCmd(cdc *wire.Codec) *cobra.Command { return err } - msg := list.NewListMiniMsg(from, baseAsset, quoteAsset, initPrice) + msg := dextypes.NewListMiniMsg(from, baseAsset, quoteAsset, initPrice) err = client.SendOrPrintTx(cliCtx, txbldr, msg) if err != nil { return err diff --git a/plugins/dex/list/handler.go b/plugins/dex/list/handler.go index 7aced6b44..0e691057f 100644 --- a/plugins/dex/list/handler.go +++ b/plugins/dex/list/handler.go @@ -21,9 +21,9 @@ import ( func NewHandler(keeper *order.DexKeeper, tokenMapper tokens.Mapper, govKeeper gov.Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { - case ListMsg: + case types.ListMsg: return handleList(ctx, keeper, tokenMapper, govKeeper, msg) - case ListMiniMsg: + case types.ListMiniMsg: return handleListMini(ctx, keeper, tokenMapper, msg) default: errMsg := fmt.Sprintf("Unrecognized dex msg type: %v", reflect.TypeOf(msg).Name()) @@ -32,7 +32,7 @@ func NewHandler(keeper *order.DexKeeper, tokenMapper tokens.Mapper, govKeeper go } } -func checkListProposal(ctx sdk.Context, govKeeper gov.Keeper, msg ListMsg) error { +func checkListProposal(ctx sdk.Context, govKeeper gov.Keeper, msg types.ListMsg) error { proposal := govKeeper.GetProposal(ctx, msg.ProposalId) if proposal == nil { return fmt.Errorf("proposal %d does not exist", msg.ProposalId) @@ -77,7 +77,7 @@ func checkListProposal(ctx sdk.Context, govKeeper gov.Keeper, msg ListMsg) error } func handleList(ctx sdk.Context, keeper *order.DexKeeper, tokenMapper tokens.Mapper, govKeeper gov.Keeper, - msg ListMsg) sdk.Result { + msg types.ListMsg) sdk.Result { if err := checkListProposal(ctx, govKeeper, msg); err != nil { return types.ErrInvalidProposal(err.Error()).Result() } diff --git a/plugins/dex/list/handler_mini.go b/plugins/dex/list/handler_mini.go index 317cf6063..21775fa52 100644 --- a/plugins/dex/list/handler_mini.go +++ b/plugins/dex/list/handler_mini.go @@ -2,6 +2,8 @@ package list import ( "github.com/binance-chain/node/common/log" + ctypes "github.com/binance-chain/node/common/types" + "github.com/binance-chain/node/common/upgrade" "github.com/binance-chain/node/plugins/dex/order" "github.com/binance-chain/node/plugins/dex/types" "github.com/binance-chain/node/plugins/tokens" @@ -9,7 +11,18 @@ import ( ) func handleListMini(ctx sdk.Context, dexKeeper *order.DexKeeper, tokenMapper tokens.Mapper, - msg ListMiniMsg) sdk.Result { + msg types.ListMiniMsg) sdk.Result { + + // before BEP70 upgraded, we only support listing mini token against NativeToken + if sdk.IsUpgrade(upgrade.BEP70) { + if ctypes.NativeTokenSymbol != msg.QuoteAssetSymbol && order.BUSDSymbol != msg.QuoteAssetSymbol { + return sdk.ErrInvalidCoins("quote token is not valid ").Result() + } + } else { + if ctypes.NativeTokenSymbol != msg.QuoteAssetSymbol { + return sdk.ErrInvalidCoins("quote token is not valid ").Result() + } + } if err := dexKeeper.CanListTradingPair(ctx, msg.BaseAssetSymbol, msg.QuoteAssetSymbol); err != nil { return sdk.ErrInvalidCoins(err.Error()).Result() diff --git a/plugins/dex/list/handler_mini_test.go b/plugins/dex/list/handler_mini_test.go index 99b83d253..f7aff4dca 100644 --- a/plugins/dex/list/handler_mini_test.go +++ b/plugins/dex/list/handler_mini_test.go @@ -11,7 +11,10 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/binance-chain/node/common/types" + common "github.com/binance-chain/node/common/types" "github.com/binance-chain/node/common/upgrade" + "github.com/binance-chain/node/plugins/dex/order" + dextypes "github.com/binance-chain/node/plugins/dex/types" "github.com/binance-chain/node/plugins/tokens" ) @@ -59,13 +62,58 @@ func TestHandleListMiniIdenticalSymbols(t *testing.T) { ms, orderKeeper, tokenMapper, _ := MakeKeepers(cdc) ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) setupForMini(ctx, tokenMapper, t) - result := handleListMini(ctx, orderKeeper, tokenMapper, ListMiniMsg{ + result := handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ From: sdk.AccAddress("testacc"), BaseAssetSymbol: "BTC-000M", QuoteAssetSymbol: "BTC-000M", InitPrice: 1000, }) - require.Contains(t, result.Log, "base asset symbol should not be identical to quote asset symbol") + require.Contains(t, result.Log, "quote token is not valid") +} + +func TestMiniWrongQuoteAssetSymbol(t *testing.T) { + setChainVersion() + defer resetChainVersion() + cdc := MakeCodec() + ms, orderKeeper, tokenMapper, _ := MakeKeepers(cdc) + ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) + setupForMini(ctx, tokenMapper, t) + result := handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ + From: sdk.AccAddress("testacc"), + BaseAssetSymbol: "BTC-000M", + QuoteAssetSymbol: "ETH-000M", + InitPrice: 1000, + }) + require.Contains(t, result.Log, "quote token is not valid") +} + +func TestMiniBUSDQuote(t *testing.T) { + setChainVersion() + defer resetChainVersion() + cdc := MakeCodec() + ms, orderKeeper, tokenMapper, _ := MakeKeepers(cdc) + ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) + setupForMini(ctx, tokenMapper, t) + result := handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ + From: sdk.AccAddress("testacc"), + BaseAssetSymbol: "BTC-000M", + QuoteAssetSymbol: "BUSD-000", + InitPrice: 1000, + }) + require.Contains(t, result.Log, "quote token is not valid") + + order.BUSDSymbol = "BUSD-000" + busd, _ := common.NewToken("BUSD", "BUSD-000", 10000000000, nil, false) + tokenMapper.NewToken(ctx, busd) + pair := dextypes.NewTradingPair(types.NativeTokenSymbol, "BUSD-000", 1000) + orderKeeper.PairMapper.AddTradingPair(ctx, pair) + result = handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ + From: sdk.AccAddress("testacc"), + BaseAssetSymbol: "BTC-000M", + QuoteAssetSymbol: "BUSD-000", + InitPrice: 1000, + }) + require.Equal(t, true, result.IsOK()) } func TestHandleListMiniWrongBaseSymbol(t *testing.T) { @@ -75,7 +123,7 @@ func TestHandleListMiniWrongBaseSymbol(t *testing.T) { ms, orderKeeper, tokenMapper, _ := MakeKeepers(cdc) ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) setupForMini(ctx, tokenMapper, t) - result := handleListMini(ctx, orderKeeper, tokenMapper, ListMiniMsg{ + result := handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ From: sdk.AccAddress("testacc"), BaseAssetSymbol: "BTC", QuoteAssetSymbol: "BNB", @@ -92,7 +140,7 @@ func TestHandleListMiniRight(t *testing.T) { ms, orderKeeper, tokenMapper, _ := MakeKeepers(cdc) ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) setupForMini(ctx, tokenMapper, t) - result := handleListMini(ctx, orderKeeper, tokenMapper, ListMiniMsg{ + result := handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ From: sdk.AccAddress("testacc"), BaseAssetSymbol: "BTC-000M", QuoteAssetSymbol: "BNB", @@ -108,7 +156,7 @@ func TestHandleListTinyRight(t *testing.T) { ms, orderKeeper, tokenMapper, _ := MakeKeepers(cdc) ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) setupForMini(ctx, tokenMapper, t) - result := handleListMini(ctx, orderKeeper, tokenMapper, ListMiniMsg{ + result := handleListMini(ctx, orderKeeper, tokenMapper, dextypes.ListMiniMsg{ From: sdk.AccAddress("testacc"), BaseAssetSymbol: "ETH-000M", QuoteAssetSymbol: "BNB", diff --git a/plugins/dex/list/handler_test.go b/plugins/dex/list/handler_test.go index aec312a94..4f998aa63 100644 --- a/plugins/dex/list/handler_test.go +++ b/plugins/dex/list/handler_test.go @@ -120,7 +120,7 @@ func TestListHandler(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) // proposal does not exist - result := handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result := handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, }) require.Contains(t, result.Log, "proposal 1 does not exist") @@ -129,7 +129,7 @@ func TestListHandler(t *testing.T) { // wrong status govKeeper.SetProposal(ctx, proposal) - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, }) require.Contains(t, result.Log, "proposal status(DepositPeriod) should be Passed before you can list your token") @@ -139,7 +139,7 @@ func TestListHandler(t *testing.T) { proposal.SetProposalType(gov.ProposalTypeParameterChange) proposal.SetStatus(gov.StatusPassed) govKeeper.SetProposal(ctx, proposal) - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, }) require.Contains(t, result.Log, "proposal type(ParameterChange) should be ListTradingPair") @@ -149,7 +149,7 @@ func TestListHandler(t *testing.T) { proposal.SetStatus(gov.StatusPassed) proposal.SetDescription("wrong params") govKeeper.SetProposal(ctx, proposal) - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, }) require.Contains(t, result.Log, "illegal list params in proposal") @@ -158,20 +158,20 @@ func TestListHandler(t *testing.T) { proposal = getProposal(false, "BTC-000", "BNB") proposal.SetStatus(gov.StatusPassed) govKeeper.SetProposal(ctx, proposal) - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ BaseAssetSymbol: "BTC-001", ProposalId: 1, }) require.Contains(t, result.Log, "base asset symbol(BTC-001) is not identical to symbol in proposal(BTC-000)") - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: "BNC", ProposalId: 1, }) require.Contains(t, result.Log, "quote asset symbol(BNC) is not identical to symbol in proposal(BNB)") - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: "BNB", InitPrice: 100, @@ -187,7 +187,7 @@ func TestListHandler(t *testing.T) { ctx = ctx.WithBlockHeader(abci.Header{ Time: expiredTime, }) - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -197,7 +197,7 @@ func TestListHandler(t *testing.T) { // token not found ctx = sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -215,7 +215,7 @@ func TestListHandler(t *testing.T) { require.Nil(t, err, "new token error") // no quote asset - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -223,7 +223,7 @@ func TestListHandler(t *testing.T) { }) require.Contains(t, result.Log, "only the owner of the token can list the token") - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -242,7 +242,7 @@ func TestListHandler(t *testing.T) { require.Nil(t, err, "new token error") // right case - result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, ListMsg{ + result = handleList(ctx, orderKeeper, tokenMapper, govKeeper, dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -278,7 +278,7 @@ func TestListHandler_LowerCase(t *testing.T) { proposal.SetStatus(gov.StatusPassed) govKeeper.SetProposal(ctx, proposal) //ctx = sdk.NewContext(ms, abci.Header{}, sdk.RunTxModeDeliver, log.NewNopLogger()) - listMsg := ListMsg{ + listMsg := dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -300,7 +300,7 @@ func TestListHandler_WrongTradingPair(t *testing.T) { proposal := getProposal(true, baseAsset, quoteAsset) proposal.SetStatus(gov.StatusPassed) govKeeper.SetProposal(ctx, proposal) - listMsg := ListMsg{ + listMsg := dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: baseAsset, QuoteAssetSymbol: quoteAsset, @@ -349,7 +349,7 @@ func TestListHandler_AfterUpgrade(t *testing.T) { sdk.UpgradeMgr.SetHeight(upgradeHeight + 1) // wrong owner - listMsg := ListMsg{ + listMsg := dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, @@ -360,7 +360,7 @@ func TestListHandler_AfterUpgrade(t *testing.T) { require.Contains(t, result.Log, "only the owner of the base asset or quote asset can list the trading pair") // right owner - listMsg = ListMsg{ + listMsg = dexTypes.ListMsg{ ProposalId: 1, BaseAssetSymbol: "BTC-000", QuoteAssetSymbol: types.NativeTokenSymbol, diff --git a/plugins/dex/order/keeper.go b/plugins/dex/order/keeper.go index b16a828d2..799da84f6 100644 --- a/plugins/dex/order/keeper.go +++ b/plugins/dex/order/keeper.go @@ -986,7 +986,7 @@ func (kp *DexKeeper) DelistTradingPair(ctx sdk.Context, symbol string, postAlloc } delete(kp.engines, symbol) - delete(kp.recentPrices, symbol) + kp.deleteRecentPrices(ctx, symbol) kp.mustGetOrderKeeper(symbol).deleteOrdersForPair(symbol) baseAsset, quoteAsset := dexUtils.TradingPair2AssetsSafe(symbol) @@ -996,6 +996,11 @@ func (kp *DexKeeper) DelistTradingPair(ctx sdk.Context, symbol string, postAlloc } } +func (kp *DexKeeper) deleteRecentPrices(ctx sdk.Context, symbol string) { + delete(kp.recentPrices, symbol) + kp.PairMapper.DeleteRecentPrices(ctx, symbol) +} + func (kp *DexKeeper) expireAllOrders(ctx sdk.Context, symbol string) []chan Transfer { ordersOfSymbol := make(map[string]*OrderInfo) if dexOrderKeeper, err := kp.getOrderKeeper(symbol); err == nil { diff --git a/plugins/dex/order/keeper_match.go b/plugins/dex/order/keeper_match.go index 0b439e664..fbe530df8 100644 --- a/plugins/dex/order/keeper_match.go +++ b/plugins/dex/order/keeper_match.go @@ -4,14 +4,23 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/binance-chain/node/common/fees" + "github.com/binance-chain/node/common/upgrade" "github.com/binance-chain/node/common/utils" ) func (kp *DexKeeper) SelectSymbolsToMatch(height int64, matchAllSymbols bool) []string { - symbolsToMatch := make([]string, 0, 256) - for _, orderKeeper := range kp.OrderKeepers { - if orderKeeper.supportUpgradeVersion() { - symbolsToMatch = append(symbolsToMatch, orderKeeper.selectSymbolsToMatch(height, matchAllSymbols)...) + var symbolsToMatch []string + if sdk.IsUpgradeHeight(upgrade.BEP8) { + symbolsToMatch = make([]string, 0, len(kp.engines)) + for symbol := range kp.engines { + symbolsToMatch = append(symbolsToMatch, symbol) + } + } else { + symbolsToMatch = make([]string, 0, 256) + for _, orderKeeper := range kp.OrderKeepers { + if orderKeeper.supportUpgradeVersion() { + symbolsToMatch = append(symbolsToMatch, orderKeeper.selectSymbolsToMatch(height, matchAllSymbols)...) + } } } return symbolsToMatch @@ -23,12 +32,13 @@ func (kp *DexKeeper) MatchAndAllocateSymbols(ctx sdk.Context, postAlloTransHandl timestamp := blockHeader.Time.UnixNano() symbolsToMatch := kp.SelectSymbolsToMatch(blockHeader.Height, matchAllSymbols) + kp.logger.Info("symbols to match", "symbols", symbolsToMatch) var tradeOuts []chan Transfer if len(symbolsToMatch) == 0 { kp.logger.Info("No order comes in for the block") } else { - tradeOuts = kp.matchAndDistributeTrades(true, blockHeader.Height, timestamp) + tradeOuts = kp.matchAndDistributeTrades(true, blockHeader.Height, timestamp, symbolsToMatch) } totalFee := kp.allocateAndCalcFee(ctx, tradeOuts, postAlloTransHandler) @@ -38,7 +48,7 @@ func (kp *DexKeeper) MatchAndAllocateSymbols(ctx sdk.Context, postAlloTransHandl // please note if distributeTrade this method will work in async mode, otherwise in sync mode. // Always run kp.SelectSymbolsToMatch(ctx.BlockHeader().Height, matchAllSymbols) before matchAndDistributeTrades -func (kp *DexKeeper) matchAndDistributeTrades(distributeTrade bool, height, timestamp int64) []chan Transfer { +func (kp *DexKeeper) matchAndDistributeTrades(distributeTrade bool, height, timestamp int64, symbolsToMatch []string) []chan Transfer { concurrency := 1 << kp.poolSize tradeOuts := make([]chan Transfer, concurrency) @@ -56,10 +66,8 @@ func (kp *DexKeeper) matchAndDistributeTrades(distributeTrade bool, height, time symbolCh := make(chan string, concurrency) producer := func() { - for i := range kp.OrderKeepers { - kp.OrderKeepers[i].iterateRoundSelectedPairs(func(symbol string) { - symbolCh <- symbol - }) + for _, symbol := range symbolsToMatch { + symbolCh <- symbol } close(symbolCh) } @@ -89,7 +97,7 @@ func (kp *DexKeeper) MatchSymbols(height, timestamp int64, matchAllSymbols bool) if len(symbolsToMatch) == 0 { kp.logger.Info("No order comes in for the block") } else { - kp.matchAndDistributeTrades(false, height, timestamp) + kp.matchAndDistributeTrades(false, height, timestamp, symbolsToMatch) } kp.ClearAfterMatch() diff --git a/plugins/dex/order/keeper_recovery.go b/plugins/dex/order/keeper_recovery.go index e43687192..18ac2606e 100644 --- a/plugins/dex/order/keeper_recovery.go +++ b/plugins/dex/order/keeper_recovery.go @@ -24,6 +24,8 @@ import ( "github.com/binance-chain/node/common/upgrade" "github.com/binance-chain/node/common/utils" me "github.com/binance-chain/node/plugins/dex/matcheng" + dextypes "github.com/binance-chain/node/plugins/dex/types" + dexutils "github.com/binance-chain/node/plugins/dex/utils" "github.com/binance-chain/node/wire" ) @@ -253,6 +255,10 @@ func (kp *DexKeeper) replayOneBlocks(logger log.Logger, block *tmtypes.Block, st logger.Error("Failed to replay cancel msg", "err", err) } logger.Info("Canceled Order", "order", msg) + case dextypes.ListMiniMsg: + kp.engines[dexutils.Assets2TradingPair(msg.BaseAssetSymbol, msg.QuoteAssetSymbol)].LastMatchHeight = 0 + case dextypes.ListMsg: + kp.engines[dexutils.Assets2TradingPair(msg.BaseAssetSymbol, msg.QuoteAssetSymbol)].LastMatchHeight = 0 } } } diff --git a/plugins/dex/order/keeper_test.go b/plugins/dex/order/keeper_test.go index 7dbeb4b02..946f4d385 100644 --- a/plugins/dex/order/keeper_test.go +++ b/plugins/dex/order/keeper_test.go @@ -48,6 +48,7 @@ func MakeCodec() *wire.Codec { cdc.RegisterConcrete(OrderBookSnapshot{}, "dex/OrderBookSnapshot", nil) cdc.RegisterConcrete(ActiveOrders{}, "dex/ActiveOrders", nil) + cdc.RegisterConcrete(store.RecentPrice{}, "dex/RecentPrice", nil) return cdc } @@ -109,7 +110,7 @@ func TestKeeper_MatchFailure(t *testing.T) { keeper.AddOrder(ord, false) symbolsToMatch := keeper.SelectSymbolsToMatch(ctx.BlockHeader().Height, false) logger.Info("symbols to match", "symbols", symbolsToMatch) - tradeOuts := keeper.matchAndDistributeTrades(true, 42, 0) + tradeOuts := keeper.matchAndDistributeTrades(true, 42, 0, symbolsToMatch) c := channelHash(accAdd, 4) i := 0 for tr := range tradeOuts[c] { @@ -545,6 +546,8 @@ func setup() (ctx sdk.Context, mapper auth.AccountKeeper, keeper *DexKeeper) { cdc := wire.NewCodec() types.RegisterWire(cdc) wire.RegisterCrypto(cdc) + cdc.RegisterConcrete(dextypes.TradingPair{}, "dex/TradingPair", nil) + cdc.RegisterConcrete(store.RecentPrice{}, "dex/RecentPrice", nil) mapper = auth.NewAccountKeeper(cdc, capKey, types.ProtoAppAccount) accountCache := getAccountCache(cdc, ms, capKey) pairMapper := store.NewTradingPairMapper(cdc, common.PairStoreKey) @@ -607,27 +610,29 @@ func TestKeeper_ExpireOrders(t *testing.T) { } func TestKeeper_ExpireOrdersBasedOnPrice(t *testing.T) { + setChainVersion() + defer resetChainVersion() ctx, am, keeper := setup() upgrade.Mgr.AddUpgradeHeight(upgrade.BEP67, -1) keeper.FeeManager.UpdateConfig(NewTestFeeConfig()) _, acc := testutils.NewAccount(ctx, am, 0) addr := acc.GetAddress() keeper.AddEngine(dextypes.NewTradingPair("ABC-000", "BNB", 1e6)) - keeper.AddEngine(dextypes.NewTradingPair("XYZ-000", "BNB", 1e6)) + keeper.AddEngine(dextypes.NewTradingPair("XYZ-000M", "BNB", 1e6)) keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "1", Side.BUY, "ABC-000_BNB", 3e6, 3e6), 4999, 0, 5001, 0, 0, "", 0}, false) keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "2", Side.BUY, "ABC-000_BNB", 1e6, 1e6), 10000, 0, 10000, 0, 0, "", 0}, false) keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "3", Side.BUY, "ABC-000_BNB", 2e6, 2e6), 10000, 0, 10000, 0, 0, "", 0}, false) - keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "4", Side.BUY, "XYZ-000_BNB", 1e6, 2e6), 10000, 0, 10000, 0, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "4", Side.BUY, "XYZ-000M_BNB", 1e6, 2e6), 10000, 0, 10000, 0, 0, "", 0}, false) keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "5", Side.SELL, "ABC-000_BNB", 1e6, 1e8), 10000, 0, 10000, 0, 0, "", 0}, false) keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "6", Side.SELL, "ABC-000_BNB", 2e6, 2e8), 15000, 0, 15000, 0, 0, "", 0}, false) - keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "7", Side.BUY, "XYZ-000_BNB", 2e6, 2e6), 20000, 0, 20000, 0, 0, "", 0}, false) - keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "8", Side.SELL, "XYZ-000_BNB", 2e6, 2e6), 3000, 0, 3000, 0, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "7", Side.BUY, "XYZ-000M_BNB", 2e6, 2e6), 20000, 0, 20000, 0, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{NewNewOrderMsg(addr, "8", Side.SELL, "XYZ-000M_BNB", 2e6, 2e6), 3000, 0, 3000, 0, 0, "", 0}, false) acc.(types.NamedAccount).SetLockedCoins(sdk.Coins{ sdk.NewCoin("ABC-000", 3e8), sdk.NewCoin("BNB", 11e4), - sdk.NewCoin("XYZ-000", 2e6), + sdk.NewCoin("XYZ-000M", 2e6), }.Sort()) am.SetAccount(ctx, acc) @@ -642,12 +647,12 @@ func TestKeeper_ExpireOrdersBasedOnPrice(t *testing.T) { require.Len(t, sells[0].Orders, 1) require.Equal(t, int64(1e8), sells[0].TotalLeavesQty()) require.Len(t, keeper.GetAllOrdersForPair("ABC-000_BNB"), 4) - buys, sells = keeper.engines["XYZ-000_BNB"].Book.GetAllLevels() + buys, sells = keeper.engines["XYZ-000M_BNB"].Book.GetAllLevels() require.Len(t, buys, 2) require.Len(t, sells, 0) require.Len(t, buys[0].Orders, 1) require.Equal(t, int64(2e6), buys[0].TotalLeavesQty()) - require.Len(t, keeper.GetAllOrdersForPair("XYZ-000_BNB"), 2) + require.Len(t, keeper.GetAllOrdersForPair("XYZ-000M_BNB"), 2) fees.Pool.Clear() upgrade.Mgr.AddUpgradeHeight(upgrade.BEP67, 0) } @@ -757,33 +762,53 @@ func TestKeeper_UpdateTickSizeAndLotSize(t *testing.T) { } func TestKeeper_UpdateLotSize(t *testing.T) { + symbol := "XYZ-000" + updateLotSize(t, symbol) +} + +func TestKeeper_UpdateLotSize_Mini(t *testing.T) { + setChainVersion() + defer resetChainVersion() + symbol := "XYZ-000M" + updateLotSize(t, symbol) +} + +func updateLotSize(t *testing.T, symbol string) { assert := assert.New(t) cdc := MakeCodec() keeper := MakeKeeper(cdc) logger := log.NewTMLogger(os.Stdout) cms := MakeCMS(nil) ctx := sdk.NewContext(cms, abci.Header{}, sdk.RunTxModeCheck, logger) - tradingPair := dextypes.NewTradingPair("XYZ-000", "BNB", 1e8) + tradingPair := dextypes.NewTradingPair(symbol, "BNB", 1e8) keeper.PairMapper.AddTradingPair(ctx, tradingPair) keeper.AddEngine(tradingPair) - keeper.UpdateLotSize(tradingPair.GetSymbol(), 1e3) - assert.Equal(int64(1e3), keeper.engines[tradingPair.GetSymbol()].LotSize) } func TestOpenOrders_AfterMatch(t *testing.T) { + addOrderAfterMatch(t, "NNB-123") +} + +func TestOpenOrders_AfterMatch_Mini(t *testing.T) { + setChainVersion() + defer resetChainVersion() + addOrderAfterMatch(t, "NNB-123M") +} + +func addOrderAfterMatch(t *testing.T, symbol string) { assert := assert.New(t) keeper := initKeeper() - keeper.AddEngine(dextypes.NewTradingPair("NNB", "BNB", 100000000)) - + keeper.AddEngine(dextypes.NewTradingPair(symbol, "BNB", 100000000)) // add an original buy order, waiting to be filled - msg := NewNewOrderMsg(zc, ZcAddr+"-0", Side.BUY, "NNB_BNB", 1000000000, 1000000000) + pair := symbol + "_BNB" + msg := NewNewOrderMsg(zc, ZcAddr+"-0", Side.BUY, pair, 1000000000, 1000000000) orderInfo := OrderInfo{msg, 42, 84, 42, 84, 0, "", 0} keeper.AddOrder(orderInfo, false) - res := keeper.GetOpenOrders("NNB_BNB", zc) + res := keeper.GetOpenOrders(pair, zc) assert.Equal(1, len(res)) - assert.Equal("NNB_BNB", res[0].Symbol) + assert.Equal(pair, res[0].Symbol) assert.Equal(ZcAddr+"-0", res[0].Id) assert.Equal(utils.Fixed8(0), res[0].CumQty) assert.Equal(utils.Fixed8(1000000000), res[0].Price) @@ -792,39 +817,36 @@ func TestOpenOrders_AfterMatch(t *testing.T) { assert.Equal(int64(84), res[0].CreatedTimestamp) assert.Equal(int64(42), res[0].LastUpdatedHeight) assert.Equal(int64(84), res[0].LastUpdatedTimestamp) - // add a sell order, partialled fill the buy order - msg = NewNewOrderMsg(zz, ZzAddr+"-0", Side.SELL, "NNB_BNB", 900000000, 300000000) + msg = NewNewOrderMsg(zz, ZzAddr+"-0", Side.SELL, pair, 900000000, 300000000) orderInfo = OrderInfo{msg, 43, 86, 43, 86, 0, "", 0} keeper.AddOrder(orderInfo, false) - res = keeper.GetOpenOrders("NNB_BNB", zz) + res = keeper.GetOpenOrders(pair, zz) assert.Equal(1, len(res)) - // match existing two orders keeper.MatchSymbols(43, 86, false) - // after match, the original buy order's cumQty and latest updated fields should be updated - res = keeper.GetOpenOrders("NNB_BNB", zc) + res = keeper.GetOpenOrders(pair, zc) assert.Equal(1, len(res)) assert.Equal(utils.Fixed8(300000000), res[0].CumQty) - assert.Equal(utils.Fixed8(1000000000), res[0].Price) // price shouldn't change - assert.Equal(utils.Fixed8(1000000000), res[0].Quantity) // quantity shouldn't change + assert.Equal(utils.Fixed8(1000000000), res[0].Price) + // price shouldn't change + assert.Equal(utils.Fixed8(1000000000), res[0].Quantity) + // quantity shouldn't change assert.Equal(int64(42), res[0].CreatedHeight) assert.Equal(int64(84), res[0].CreatedTimestamp) assert.Equal(int64(43), res[0].LastUpdatedHeight) assert.Equal(int64(86), res[0].LastUpdatedTimestamp) - // after match, the sell order should be closed - res = keeper.GetOpenOrders("NNB_BNB", zz) + res = keeper.GetOpenOrders(pair, zz) assert.Equal(0, len(res)) - // add another sell order to fully fill original buy order - msg = NewNewOrderMsg(zz, ZzAddr+"-1", Side.SELL, "NNB_BNB", 1000000000, 700000000) + msg = NewNewOrderMsg(zz, ZzAddr+"-1", Side.SELL, pair, 1000000000, 700000000) orderInfo = OrderInfo{msg, 44, 88, 44, 88, 0, "", 0} keeper.AddOrder(orderInfo, false) - res = keeper.GetOpenOrders("NNB_BNB", zz) + res = keeper.GetOpenOrders(pair, zz) assert.Equal(1, len(res)) - assert.Equal("NNB_BNB", res[0].Symbol) + assert.Equal(pair, res[0].Symbol) assert.Equal(ZzAddr+"-1", res[0].Id) assert.Equal(utils.Fixed8(0), res[0].CumQty) assert.Equal(utils.Fixed8(1000000000), res[0].Price) @@ -833,14 +855,12 @@ func TestOpenOrders_AfterMatch(t *testing.T) { assert.Equal(int64(88), res[0].CreatedTimestamp) assert.Equal(int64(44), res[0].LastUpdatedHeight) assert.Equal(int64(88), res[0].LastUpdatedTimestamp) - // match existing two orders keeper.MatchSymbols(44, 88, false) - // after match, all orders should be closed - res = keeper.GetOpenOrders("NNB_BNB", zc) + res = keeper.GetOpenOrders(pair, zc) assert.Equal(0, len(res)) - res = keeper.GetOpenOrders("NNB_BNB", zz) + res = keeper.GetOpenOrders(pair, zz) assert.Equal(0, len(res)) } @@ -851,6 +871,7 @@ func TestKeeper_DelistTradingPair(t *testing.T) { keeper.FeeManager.UpdateConfig(NewTestFeeConfig()) _, acc := testutils.NewAccount(ctx, am, 0) addr := acc.GetAddress() + ctx = ctx.WithBlockHeight(2000) tradingPair := dextypes.NewTradingPair("XYZ-000", "BNB", 1e8) keeper.PairMapper.AddTradingPair(ctx, tradingPair) @@ -868,30 +889,36 @@ func TestKeeper_DelistTradingPair(t *testing.T) { am.SetAccount(ctx, acc) msg := NewNewOrderMsg(addr, "123456", Side.BUY, "XYZ-000_BNB", 1e6, 1e6) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "1234562", Side.BUY, "XYZ-000_BNB", 1e6, 1e6) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "123457", Side.BUY, "XYZ-000_BNB", 2e6, 1e6) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "123458", Side.BUY, "XYZ-000_BNB", 3e6, 1e6) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "123459", Side.SELL, "XYZ-000_BNB", 5e6, 1e4) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "123460", Side.SELL, "XYZ-000_BNB", 6e6, 1e4) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "1234602", Side.SELL, "XYZ-000_BNB", 6e6, 1e4) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "123461", Side.SELL, "XYZ-000_BNB", 7e6, 1e4) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) msg = NewNewOrderMsg(addr, "123462", Side.BUY, "XYZ-000_BNB", 4e6, 1e6) - keeper.AddOrder(OrderInfo{msg, 42, 84, 42, 84, 0, "", 0}, false) + keeper.AddOrder(OrderInfo{msg, 2000, 84, 42, 84, 0, "", 0}, false) + + lastTradePrices := make(map[string]int64, 1) + lastTradePrices["XYZ-000_BNB"] = 3e6 + keeper.PairMapper.UpdateRecentPrices(ctx, pricesStoreEvery, numPricesStored, lastTradePrices) assert.Equal(1, len(keeper.GetAllOrders())) assert.Equal(9, len(keeper.GetAllOrdersForPair("XYZ-000_BNB"))) assert.Equal(1, len(keeper.engines)) + assert.Equal(1, len(keeper.PairMapper.GetRecentPrices(ctx, pricesStoreEvery, numPricesStored))) keeper.DelistTradingPair(ctx, "XYZ-000_BNB", nil) assert.Equal(0, len(keeper.GetAllOrders())) assert.Equal(0, len(keeper.engines)) + assert.Equal(0, len(keeper.PairMapper.GetRecentPrices(ctx, pricesStoreEvery, numPricesStored))) expectFees := types.NewFee(sdk.Coins{ sdk.NewCoin("BNB", 10e4), diff --git a/plugins/dex/order/symbol_selector.go b/plugins/dex/order/symbol_selector.go index 91ae115de..f400611f1 100644 --- a/plugins/dex/order/symbol_selector.go +++ b/plugins/dex/order/symbol_selector.go @@ -63,7 +63,7 @@ func (mss *MiniSymbolSelector) SelectSymbolsToMatch(roundOrders map[string][]str func (mss *MiniSymbolSelector) selectMiniSymbolsToMatch(roundOrders map[string][]string, height int64, postSelect func(map[string]struct{})) { symbolsToMatch := make(map[string]struct{}, 256) mss.selectActiveMiniSymbols(symbolsToMatch, roundOrders, defaultActiveMiniSymbolCount) - mss.selectMiniSymbolsRoundRobin(symbolsToMatch, height, defaultMiniBlockMatchInterval) + mss.selectMiniSymbolsRoundRobin(symbolsToMatch, roundOrders, height, defaultMiniBlockMatchInterval) postSelect(symbolsToMatch) } @@ -80,9 +80,10 @@ func (mss *MiniSymbolSelector) selectActiveMiniSymbols(symbolsToMatch map[string } } -func (mss *MiniSymbolSelector) selectMiniSymbolsRoundRobin(symbolsToMatch map[string]struct{}, height int64, matchInterval int) { +func (mss *MiniSymbolSelector) selectMiniSymbolsRoundRobin(symbolsToMatch map[string]struct{}, roundOrdersMini map[string][]string, height int64, matchInterval int) { m := height % int64(matchInterval) - for symbol, symbolHash := range mss.symbolsHash { + for symbol := range roundOrdersMini { + symbolHash := mss.symbolsHash[symbol] if int64(symbolHash%uint32(matchInterval)) == m { symbolsToMatch[symbol] = struct{}{} } diff --git a/plugins/dex/route.go b/plugins/dex/route.go index 2b9eeb9df..2ffab5932 100644 --- a/plugins/dex/route.go +++ b/plugins/dex/route.go @@ -1,6 +1,7 @@ package dex import ( + "github.com/binance-chain/node/plugins/dex/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov" @@ -15,6 +16,6 @@ func Routes(dexKeeper *DexKeeper, tokenMapper tokens.Mapper, govKeeper gov.Keepe orderHandler := order.NewHandler(dexKeeper) routes[order.RouteNewOrder] = orderHandler routes[order.RouteCancelOrder] = orderHandler - routes[list.Route] = list.NewHandler(dexKeeper, tokenMapper, govKeeper) + routes[types.ListRoute] = list.NewHandler(dexKeeper, tokenMapper, govKeeper) return routes } diff --git a/plugins/dex/store/mapper.go b/plugins/dex/store/mapper.go index 5919f0a4a..b3933de5a 100644 --- a/plugins/dex/store/mapper.go +++ b/plugins/dex/store/mapper.go @@ -26,6 +26,7 @@ type TradingPairMapper interface { ListAllTradingPairs(ctx sdk.Context) []types.TradingPair UpdateRecentPrices(ctx sdk.Context, pricesStoreEvery, numPricesStored int64, lastTradePrices map[string]int64) GetRecentPrices(ctx sdk.Context, pricesStoreEvery, numPricesStored int64) map[string]*utils.FixedSizeRing + DeleteRecentPrices(ctx sdk.Context, symbol string) } var _ TradingPairMapper = mapper{} @@ -157,7 +158,7 @@ func (m mapper) GetRecentPrices(ctx sdk.Context, pricesStoreEvery, numPricesStor } else { recordStarted = true } - prices := m.decodeRecentPrices(bz, numPricesStored) + prices := m.decodeRecentPrices(bz) numSymbol := len(prices.Pair) for i := 0; i < numSymbol; i++ { symbol := prices.Pair[i] @@ -172,6 +173,24 @@ func (m mapper) GetRecentPrices(ctx sdk.Context, pricesStoreEvery, numPricesStor return recentPrices } +func (m mapper) DeleteRecentPrices(ctx sdk.Context, symbol string) { + store := ctx.KVStore(m.key) + iter := sdk.KVStorePrefixIterator(store, []byte(recentPricesKeyPrefix)) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + bz := iter.Value() + prices := m.decodeRecentPrices(bz) + prices.removePair(symbol) + if len(prices.Pair) == 0 { + store.Delete(iter.Key()) + } else { + bz = m.cdc.MustMarshalBinaryBare(prices) + store.Set(iter.Key(), bz) + } + } +} + func (m mapper) encodeRecentPrices(recentPrices map[string]int64) []byte { value := RecentPrice{} numSymbol := len(recentPrices) @@ -195,7 +214,7 @@ func (m mapper) encodeRecentPrices(recentPrices map[string]int64) []byte { return bz } -func (m mapper) decodeRecentPrices(bz []byte, numPricesStored int64) *RecentPrice { +func (m mapper) decodeRecentPrices(bz []byte) *RecentPrice { value := RecentPrice{} m.cdc.MustUnmarshalBinaryBare(bz, &value) return &value diff --git a/plugins/dex/store/mapper_test.go b/plugins/dex/store/mapper_test.go index 3bef25063..a991d3fc3 100644 --- a/plugins/dex/store/mapper_test.go +++ b/plugins/dex/store/mapper_test.go @@ -1,11 +1,15 @@ package store import ( + "path" + "path/filepath" + "runtime" "testing" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" @@ -123,3 +127,113 @@ func TestMapper_UpdateRecentPrices(t *testing.T) { require.Equal(t, int64(5), allRecentPrices["ABC"].Count()) require.Equal(t, []interface{}{int64(10), int64(10), int64(10), int64(10), int64(10)}, allRecentPrices["ABC"].Elements()) } + +func TestMapper_DeleteRecentPrices(t *testing.T) { + const numPricesStored = 5 + const pairNum = 3 + const priceStoreEvery = 2 + pairMapper, ctx := setup() + for i := 0; i < 30; i++ { + lastPrices := make(map[string]int64, pairNum) + lastPrices["ABC_BNB"] = 10 + lastPrices["ABC_EFG"] = 3 + lastPrices["EFG_BNB"] = 3 + ctx = ctx.WithBlockHeight(int64(priceStoreEvery * (i + 1))) + pairMapper.UpdateRecentPrices(ctx, priceStoreEvery, numPricesStored, lastPrices) + } + + allRecentPrices := pairMapper.GetRecentPrices(ctx, priceStoreEvery, numPricesStored) + require.Equal(t, 3, len(allRecentPrices)) + require.Equal(t, int64(5), allRecentPrices["ABC_BNB"].Count()) + require.Equal(t, []interface{}{int64(10), int64(10), int64(10), int64(10), int64(10)}, allRecentPrices["ABC_BNB"].Elements()) + require.Equal(t, int64(5), allRecentPrices["ABC_EFG"].Count()) + require.Equal(t, []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3)}, allRecentPrices["ABC_EFG"].Elements()) + require.Equal(t, int64(5), allRecentPrices["ABC_EFG"].Count()) + require.Equal(t, []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3)}, allRecentPrices["EFG_BNB"].Elements()) + + pairMapper.DeleteRecentPrices(ctx, "ABC_EFG") + allRecentPrices = pairMapper.GetRecentPrices(ctx, priceStoreEvery, numPricesStored) + require.Equal(t, 2, len(allRecentPrices)) + require.Equal(t, int64(5), allRecentPrices["ABC_BNB"].Count()) + require.Equal(t, []interface{}{int64(10), int64(10), int64(10), int64(10), int64(10)}, allRecentPrices["ABC_BNB"].Elements()) + require.Equal(t, int64(5), allRecentPrices["EFG_BNB"].Count()) + require.Equal(t, []interface{}{int64(3), int64(3), int64(3), int64(3), int64(3)}, allRecentPrices["EFG_BNB"].Elements()) +} + +func TestMapper_DeleteOneRecentPrices(t *testing.T) { + const numPricesStored = 10 + const pairNum = 1 + const priceStoreEvery = 2 + pairMapper, ctx := setup() + for i := 0; i < numPricesStored; i++ { + lastPrices := make(map[string]int64, pairNum) + if i < 5 { + lastPrices["ABC_BNB"] = 10 + } + ctx = ctx.WithBlockHeight(int64(2 * (i + 1))) + pairMapper.UpdateRecentPrices(ctx, priceStoreEvery, numPricesStored, lastPrices) + } + allRecentPrices := pairMapper.GetRecentPrices(ctx, priceStoreEvery, numPricesStored) + require.Equal(t, 1, len(allRecentPrices)) + require.Equal(t, int64(5), allRecentPrices["ABC_BNB"].Count()) + require.Equal(t, []interface{}{int64(10), int64(10), int64(10), int64(10), int64(10)}, allRecentPrices["ABC_BNB"].Elements()) + + pairMapper.DeleteRecentPrices(ctx, "ABC_BNB") + allRecentPrices = pairMapper.GetRecentPrices(ctx, priceStoreEvery, numPricesStored) + require.Equal(t, 0, len(allRecentPrices)) + + //allowed to delete again + pairMapper.DeleteRecentPrices(ctx, "ABC_BNB") + allRecentPrices = pairMapper.GetRecentPrices(ctx, priceStoreEvery, numPricesStored) + require.Equal(t, 0, len(allRecentPrices)) +} + +func BenchmarkMapper_DeleteRecentPrices(b *testing.B) { + db, pairMapper, ctx := setupForBenchTest() + defer db.Close() + b.ResetTimer() + for i := 0; i < b.N; i++ { + pairMapper.DeleteRecentPrices(ctx, string(i)+"_"+string(i)) + } +} + +func setupForBenchTest() (dbm.DB, TradingPairMapper, sdk.Context) { + const numPricesStored = 2000 + const pairNum = 500 + const priceStoreEvery = 1000 + db, ms, key := setupLevelDbMultiStore() + ctx := sdk.NewContext(ms, abci.Header{Height: 1}, sdk.RunTxModeDeliver, log.NewNopLogger()) + var cdc = wire.NewCodec() + cdc.RegisterConcrete(dextypes.TradingPair{}, "dex/TradingPair", nil) + cdc.RegisterConcrete(RecentPrice{}, "dex/RecentPrice", nil) + pairMapper := NewTradingPairMapper(cdc, key) + for i := 0; i < pairNum; i++ { + tradingPair := dextypes.NewTradingPair(string(i), string(i), 102000) + pairMapper.AddTradingPair(ctx, tradingPair) + } + + for i := 0; i < numPricesStored; i++ { + lastPrices := make(map[string]int64, pairNum) + for j := 0; j < pairNum; j++ { + lastPrices[string(j)+"_"+string(j)] = 8 + } + ctx = ctx.WithBlockHeight(int64(priceStoreEvery * (i + 1))) + pairMapper.UpdateRecentPrices(ctx, priceStoreEvery, numPricesStored, lastPrices) + } + + return db, pairMapper, ctx +} + +func setupLevelDbMultiStore() (dbm.DB, sdk.MultiStore, *sdk.KVStoreKey) { + _, b, _, _ := runtime.Caller(0) + basePath := filepath.Dir(b) + db, err := db.NewGoLevelDB("test", path.Join(basePath, "data")) + if err != nil { + panic(err) + } + key := sdk.NewKVStoreKey("pair") + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) + ms.LoadLatestVersion() + return db, ms, key +} diff --git a/plugins/dex/store/types.go b/plugins/dex/store/types.go index 2824b90a9..91b0b7fe7 100644 --- a/plugins/dex/store/types.go +++ b/plugins/dex/store/types.go @@ -35,3 +35,15 @@ type RecentPrice struct { Pair []string Price []int64 } + +func (prices *RecentPrice) removePair(symbolToDelete string) { + numSymbol := len(prices.Pair) + for i := 0; i < numSymbol; i++ { + symbol := prices.Pair[i] + if symbol == symbolToDelete { + prices.Pair = append(prices.Pair[:i], prices.Pair[i+1:]...) + prices.Price = append(prices.Price[:i], prices.Price[i+1:]...) + break + } + } +} diff --git a/plugins/dex/list/msg.go b/plugins/dex/types/msg.go similarity index 84% rename from plugins/dex/list/msg.go rename to plugins/dex/types/msg.go index 9845366c7..dc18020b4 100644 --- a/plugins/dex/list/msg.go +++ b/plugins/dex/types/msg.go @@ -1,4 +1,4 @@ -package list +package types import ( "encoding/json" @@ -9,7 +9,7 @@ import ( "github.com/binance-chain/node/common/types" ) -const Route = "dexList" +const ListRoute = "dexList" var _ sdk.Msg = ListMsg{} @@ -21,7 +21,7 @@ type ListMsg struct { InitPrice int64 `json:"init_price"` } -func NewMsg(from sdk.AccAddress, proposalId int64, baseAssetSymbol string, quoteAssetSymbol string, initPrice int64) ListMsg { +func NewListMsg(from sdk.AccAddress, proposalId int64, baseAssetSymbol string, quoteAssetSymbol string, initPrice int64) ListMsg { return ListMsg{ From: from, ProposalId: proposalId, @@ -31,8 +31,8 @@ func NewMsg(from sdk.AccAddress, proposalId int64, baseAssetSymbol string, quote } } -func (msg ListMsg) Route() string { return Route } -func (msg ListMsg) Type() string { return Route } +func (msg ListMsg) Route() string { return ListRoute } +func (msg ListMsg) Type() string { return ListRoute } func (msg ListMsg) String() string { return fmt.Sprintf("MsgList{%#v}", msg) } func (msg ListMsg) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.From} } diff --git a/plugins/dex/list/msg_mini.go b/plugins/dex/types/msg_mini.go similarity index 72% rename from plugins/dex/list/msg_mini.go rename to plugins/dex/types/msg_mini.go index 09c0111ba..4a41ae49d 100644 --- a/plugins/dex/list/msg_mini.go +++ b/plugins/dex/types/msg_mini.go @@ -1,4 +1,4 @@ -package list +package types import ( "encoding/json" @@ -7,8 +7,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/binance-chain/node/common/types" - "github.com/binance-chain/node/common/upgrade" - "github.com/binance-chain/node/plugins/dex/order" ) const MiniMsg = "dexListMini" @@ -31,7 +29,7 @@ func NewListMiniMsg(from sdk.AccAddress, baseAssetSymbol string, quoteAssetSymbo } } -func (msg ListMiniMsg) Route() string { return Route } +func (msg ListMiniMsg) Route() string { return ListRoute } func (msg ListMiniMsg) Type() string { return MiniMsg } func (msg ListMiniMsg) String() string { return fmt.Sprintf("MsgListMini{%#v}", msg) } func (msg ListMiniMsg) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.From} } @@ -45,17 +43,6 @@ func (msg ListMiniMsg) ValidateBasic() sdk.Error { return sdk.ErrInvalidCoins("quote token is empty ") } - // before BEP70 upgraded, we only support listing mini token against NativeToken - if sdk.IsUpgrade(upgrade.BEP70) { - if types.NativeTokenSymbol != msg.QuoteAssetSymbol && order.BUSDSymbol != msg.QuoteAssetSymbol { - return sdk.ErrInvalidCoins("quote token is not valid ") - } - } else { - if types.NativeTokenSymbol != msg.QuoteAssetSymbol { - return sdk.ErrInvalidCoins("quote token is not valid ") - } - } - if msg.InitPrice <= 0 { return sdk.ErrInvalidCoins("price should be positive") } diff --git a/plugins/dex/list/msg_mini_test.go b/plugins/dex/types/msg_mini_test.go similarity index 51% rename from plugins/dex/list/msg_mini_test.go rename to plugins/dex/types/msg_mini_test.go index b399247c3..86f1d4a19 100644 --- a/plugins/dex/list/msg_mini_test.go +++ b/plugins/dex/types/msg_mini_test.go @@ -1,4 +1,4 @@ -package list +package types import ( "testing" @@ -6,17 +6,8 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/binance-chain/node/plugins/dex/order" ) -func TestMiniIdenticalBaseAssetAndQuoteAsset(t *testing.T) { - msg := NewListMiniMsg(sdk.AccAddress{}, "BTC-000M", "BTC-000M", 1000) - err := msg.ValidateBasic() - require.NotNil(t, err, "msg should be error") - require.Contains(t, err.Error(), "quote token is not valid") -} - func TestMiniWrongBaseAssetSymbol(t *testing.T) { msg := NewListMiniMsg(sdk.AccAddress{}, "BTC", "BTC-000", 1000) err := msg.ValidateBasic() @@ -31,13 +22,6 @@ func TestMiniWrongBaseAssetSymbolNotMiniToken(t *testing.T) { require.Contains(t, err.Error(), "base token: mini-token symbol suffix must be 4 chars in length, got 3") } -func TestMiniWrongQuoteAssetSymbol(t *testing.T) { - msg := NewListMiniMsg(sdk.AccAddress{}, "BTC-000M", "ETH-123", 1000) - err := msg.ValidateBasic() - require.NotNil(t, err, "msg should be error") - require.Contains(t, err.Error(), "quote token is not valid") -} - func TestMiniWrongInitPrice(t *testing.T) { msg := NewListMiniMsg(sdk.AccAddress{}, "BTC-000M", "BNB", -1000) err := msg.ValidateBasic() @@ -50,18 +34,3 @@ func TestMiniRightMsg(t *testing.T) { err := msg.ValidateBasic() require.Nil(t, err, "msg should not be error") } - -func TestMiniBUSDQuote(t *testing.T) { - msg := NewListMiniMsg(sdk.AccAddress{}, "BTC-000M", "BUSD-000", 1000) - err := msg.ValidateBasic() - require.NotNil(t, err, "msg should be error") - require.Contains(t, err.Error(), "quote token is not valid") - - setChainVersion() - defer resetChainVersion() - order.BUSDSymbol = "BUSD-000" - msg = NewListMiniMsg(sdk.AccAddress{}, "BTC-000M", "BUSD-000", 1000) - err = msg.ValidateBasic() - require.Nil(t, err, "msg should not be error") - -} diff --git a/plugins/dex/list/msg_test.go b/plugins/dex/types/msg_test.go similarity index 74% rename from plugins/dex/list/msg_test.go rename to plugins/dex/types/msg_test.go index f591f52a2..82bf74e60 100644 --- a/plugins/dex/list/msg_test.go +++ b/plugins/dex/types/msg_test.go @@ -1,49 +1,50 @@ -package list +package types import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestIdenticalBaseAssetAndQuoteAsset(t *testing.T) { - msg := NewMsg(sdk.AccAddress{}, 1, "BTC-000", "BTC-000", 1000) + msg := NewListMsg(sdk.AccAddress{}, 1, "BTC-000", "BTC-000", 1000) err := msg.ValidateBasic() require.NotNil(t, err, "msg should be error") require.Contains(t, err.Error(), "base token and quote token should not be the same") } func TestWrongProposalId(t *testing.T) { - msg := NewMsg(sdk.AccAddress{}, -1, "BTC-000", "BTC-000", 1000) + msg := NewListMsg(sdk.AccAddress{}, -1, "BTC-000", "BTC-000", 1000) err := msg.ValidateBasic() require.NotNil(t, err, "msg should be error") require.Contains(t, err.Error(), "proposal id should be positive") } func TestWrongBaseAssetSymbol(t *testing.T) { - msg := NewMsg(sdk.AccAddress{}, 1, "BTC", "BTC-000", 1000) + msg := NewListMsg(sdk.AccAddress{}, 1, "BTC", "BTC-000", 1000) err := msg.ValidateBasic() require.NotNil(t, err, "msg should be error") require.Contains(t, err.Error(), "base token: suffixed token symbol") } func TestWrongQuoteAssetSymbol(t *testing.T) { - msg := NewMsg(sdk.AccAddress{}, 1, "BTC-000", "ETH", 1000) + msg := NewListMsg(sdk.AccAddress{}, 1, "BTC-000", "ETH", 1000) err := msg.ValidateBasic() require.NotNil(t, err, "msg should be error") require.Contains(t, err.Error(), "quote token: suffixed token symbol") } func TestWrongInitPrice(t *testing.T) { - msg := NewMsg(sdk.AccAddress{}, 1, "BTC-000", "BNB", -1000) + msg := NewListMsg(sdk.AccAddress{}, 1, "BTC-000", "BNB", -1000) err := msg.ValidateBasic() require.NotNil(t, err, "msg should be error") require.Contains(t, err.Error(), "price should be positive") } func TestRightMsg(t *testing.T) { - msg := NewMsg(sdk.AccAddress{}, 1, "BTC-000", "BNB", 1000) + msg := NewListMsg(sdk.AccAddress{}, 1, "BTC-000", "BNB", 1000) err := msg.ValidateBasic() require.Nil(t, err, "msg should not be error") } diff --git a/plugins/dex/wire.go b/plugins/dex/wire.go index e0900b5e0..f91a001b1 100644 --- a/plugins/dex/wire.go +++ b/plugins/dex/wire.go @@ -1,7 +1,6 @@ package dex import ( - "github.com/binance-chain/node/plugins/dex/list" "github.com/binance-chain/node/plugins/dex/order" "github.com/binance-chain/node/plugins/dex/store" "github.com/binance-chain/node/plugins/dex/types" @@ -15,10 +14,10 @@ func RegisterWire(cdc *wire.Codec) { cdc.RegisterConcrete(order.NewOrderMsg{}, "dex/NewOrder", nil) cdc.RegisterConcrete(order.CancelOrderMsg{}, "dex/CancelOrder", nil) - cdc.RegisterConcrete(list.ListMsg{}, "dex/ListMsg", nil) + cdc.RegisterConcrete(types.ListMsg{}, "dex/ListMsg", nil) cdc.RegisterConcrete(types.TradingPair{}, "dex/TradingPair", nil) - cdc.RegisterConcrete(list.ListMiniMsg{}, "dex/ListMiniMsg", nil) + cdc.RegisterConcrete(types.ListMiniMsg{}, "dex/ListMiniMsg", nil) cdc.RegisterConcrete(order.FeeConfig{}, "dex/FeeConfig", nil) cdc.RegisterConcrete(order.OrderBookSnapshot{}, "dex/OrderBookSnapshot", nil) diff --git a/plugins/param/genesis.go b/plugins/param/genesis.go index 27f10ce16..c2867de91 100644 --- a/plugins/param/genesis.go +++ b/plugins/param/genesis.go @@ -6,8 +6,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" sdk "github.com/binance-chain/node/common/types" - "github.com/binance-chain/node/plugins/dex/list" "github.com/binance-chain/node/plugins/dex/order" + "github.com/binance-chain/node/plugins/dex/types" param "github.com/binance-chain/node/plugins/param/types" "github.com/binance-chain/node/plugins/tokens/burn" "github.com/binance-chain/node/plugins/tokens/freeze" @@ -55,9 +55,9 @@ const ( //MiniToken fee TinyIssueFee = 2e8 - MiniIssueFee = 4e8 + MiniIssueFee = 3e8 MiniSetUriFee = 37500 - MiniListingFee = 10e8 + MiniListingFee = 8e8 ) var DefaultGenesisState = param.GenesisState{ @@ -74,7 +74,7 @@ var FeeGenesisState = []param.FeeParam{ ¶m.FixedFeeParams{gov.MsgVote{}.Type(), sdk.ZeroFee, sdk.FeeFree}, ¶m.FixedFeeParams{stake.MsgCreateValidator{}.Type(), CreateValidatorFee, sdk.FeeForProposer}, ¶m.FixedFeeParams{stake.MsgRemoveValidator{}.Type(), RemoveValidatorFee, sdk.FeeForProposer}, - ¶m.FixedFeeParams{list.Route, ListingFee, sdk.FeeForAll}, + ¶m.FixedFeeParams{types.ListRoute, ListingFee, sdk.FeeForAll}, ¶m.FixedFeeParams{order.RouteNewOrder, sdk.ZeroFee, sdk.FeeFree}, ¶m.FixedFeeParams{order.RouteCancelOrder, sdk.ZeroFee, sdk.FeeFree}, ¶m.FixedFeeParams{issue.IssueMsgType, IssueFee, sdk.FeeForAll}, diff --git a/plugins/param/plugin.go b/plugins/param/plugin.go index 101973ed3..e3b4dc060 100644 --- a/plugins/param/plugin.go +++ b/plugins/param/plugin.go @@ -11,8 +11,8 @@ import ( app "github.com/binance-chain/node/common/types" "github.com/binance-chain/node/common/upgrade" "github.com/binance-chain/node/plugins/account" - "github.com/binance-chain/node/plugins/dex/list" "github.com/binance-chain/node/plugins/dex/order" + dextypes "github.com/binance-chain/node/plugins/dex/types" "github.com/binance-chain/node/plugins/param/paramhub" param "github.com/binance-chain/node/plugins/param/types" "github.com/binance-chain/node/plugins/tokens" @@ -66,7 +66,7 @@ func RegisterUpgradeBeginBlocker(paramHub *ParamHub) { ¶m.FixedFeeParams{MsgType: issue.IssueTinyMsgType, Fee: TinyIssueFee, FeeFor: types.FeeForAll}, ¶m.FixedFeeParams{MsgType: issue.IssueMiniMsgType, Fee: MiniIssueFee, FeeFor: types.FeeForAll}, ¶m.FixedFeeParams{MsgType: miniURI.SetURIMsg{}.Type(), Fee: MiniSetUriFee, FeeFor: types.FeeForProposer}, - ¶m.FixedFeeParams{MsgType: list.ListMiniMsg{}.Type(), Fee: MiniListingFee, FeeFor: types.FeeForAll}, + ¶m.FixedFeeParams{MsgType: dextypes.ListMiniMsg{}.Type(), Fee: MiniListingFee, FeeFor: types.FeeForAll}, } paramHub.UpdateFeeParams(ctx, miniTokenFeeParams) }) @@ -86,7 +86,7 @@ func init() { gov.MsgVote{}.Type(): fees.FixedFeeCalculatorGen, stake.MsgCreateValidator{}.Type(): fees.FixedFeeCalculatorGen, stake.MsgRemoveValidator{}.Type(): fees.FixedFeeCalculatorGen, - list.Route: fees.FixedFeeCalculatorGen, + dextypes.ListMsg{}.Type(): fees.FixedFeeCalculatorGen, order.RouteNewOrder: fees.FixedFeeCalculatorGen, order.RouteCancelOrder: fees.FixedFeeCalculatorGen, issue.IssueMsgType: fees.FixedFeeCalculatorGen, @@ -105,6 +105,6 @@ func init() { issue.IssueTinyMsgType: fees.FixedFeeCalculatorGen, issue.IssueMiniMsgType: fees.FixedFeeCalculatorGen, miniURI.SetURIRoute: fees.FixedFeeCalculatorGen, - list.ListMiniMsg{}.Type(): fees.FixedFeeCalculatorGen, + dextypes.ListMiniMsg{}.Type(): fees.FixedFeeCalculatorGen, } } diff --git a/plugins/tokens/freeze/handler.go b/plugins/tokens/freeze/handler.go index 89bb0be0b..bf2acb029 100644 --- a/plugins/tokens/freeze/handler.go +++ b/plugins/tokens/freeze/handler.go @@ -73,7 +73,7 @@ func handleUnfreezeToken(ctx sdk.Context, tokenMapper store.Mapper, accKeeper au if common.IsMiniTokenSymbol(symbol) { if unfreezeAmount < common.MiniTokenMinExecutionAmount && frozenAmount != unfreezeAmount { logger.Info("unfreeze token failed", "reason", "unfreeze amount doesn't reach the min amount") - return sdk.ErrInvalidCoins(fmt.Sprintf("freeze amount is too small, the min amount is %d or total frozen balance", + return sdk.ErrInvalidCoins(fmt.Sprintf("unfreeze amount is too small, the min amount is %d or total frozen balance", common.MiniTokenMinExecutionAmount)).Result() } } diff --git a/plugins/tokens/tokens.go b/plugins/tokens/tokens.go index 7a9547342..7fe4d341f 100644 --- a/plugins/tokens/tokens.go +++ b/plugins/tokens/tokens.go @@ -3,4 +3,5 @@ package tokens import "github.com/binance-chain/node/plugins/tokens/store" type Mapper = store.Mapper + var NewMapper = store.NewMapper diff --git a/version/version.go b/version/version.go index 41fed57aa..2ef5e4e5b 100644 --- a/version/version.go +++ b/version/version.go @@ -12,7 +12,7 @@ var ( Version string ) -const NodeVersion = "0.7.0" +const NodeVersion = "0.7.2" func init() { Version = fmt.Sprintf("Binance Chain Release: %s;", NodeVersion)