diff --git a/app/app.go b/app/app.go index 7670c42c8..e05039ac4 100644 --- a/app/app.go +++ b/app/app.go @@ -55,6 +55,7 @@ import ( "github.com/bnb-chain/node/plugins/dex/list" "github.com/bnb-chain/node/plugins/dex/order" dextypes "github.com/bnb-chain/node/plugins/dex/types" + tokenRecover "github.com/bnb-chain/node/plugins/recover" "github.com/bnb-chain/node/plugins/tokens" "github.com/bnb-chain/node/plugins/tokens/issue" "github.com/bnb-chain/node/plugins/tokens/ownership" @@ -918,6 +919,7 @@ func (app *BNBBeaconChain) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) tokens.EndBreatheBlock(ctx, app.swapKeeper) } else { app.Logger.Debug("normal block", "height", height) + tokens.EndBlocker(ctx, app.timeLockKeeper, app.swapKeeper) } app.DexKeeper.StoreTradePrices(ctx) @@ -1156,6 +1158,7 @@ func MakeCodec() *wire.Codec { bridge.RegisterWire(cdc) oracle.RegisterWire(cdc) ibc.RegisterWire(cdc) + tokenRecover.RegisterWire(cdc) return cdc } diff --git a/cmd/bnbcli/main.go b/cmd/bnbcli/main.go index f53d16aa1..7a5c95e33 100644 --- a/cmd/bnbcli/main.go +++ b/cmd/bnbcli/main.go @@ -13,6 +13,7 @@ import ( sidecmd "github.com/cosmos/cosmos-sdk/x/sidechain/client/cli" slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" + "github.com/spf13/cobra" "github.com/tendermint/tendermint/libs/cli" @@ -25,6 +26,7 @@ import ( apiserv "github.com/bnb-chain/node/plugins/api" bridgecmd "github.com/bnb-chain/node/plugins/bridge/client/cli" dexcmd "github.com/bnb-chain/node/plugins/dex/client/cli" + recovercmd "github.com/bnb-chain/node/plugins/recover/client/cli" tokencmd "github.com/bnb-chain/node/plugins/tokens/client/cli" "github.com/bnb-chain/node/version" ) @@ -98,6 +100,7 @@ func main() { admin.AddCommands(rootCmd, cdc) bridgecmd.AddCommands(rootCmd, cdc) sidecmd.AddCommands(rootCmd, cdc) + recovercmd.AddCommands(rootCmd, cdc) // prepare and add flags executor := cli.PrepareMainCmd(rootCmd, "BC", app.DefaultCLIHome) diff --git a/go.mod b/go.mod index ebf902b3f..780457fa9 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/cosmos/cosmos-sdk v0.25.0 github.com/deathowl/go-metrics-prometheus v0.0.0-20200518174047-74482eab5bfb github.com/eapache/go-resiliency v1.1.0 + github.com/ethereum/go-ethereum v1.11.3 github.com/go-kit/kit v0.10.0 github.com/google/btree v1.0.0 github.com/gorilla/mux v1.8.0 @@ -48,7 +49,6 @@ require ( github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/etcd-io/bbolt v1.3.3 // indirect - github.com/ethereum/go-ethereum v1.11.3 // indirect github.com/ferranbt/fastssz v0.0.0-20210526181520-7df50c8568f8 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -165,7 +165,8 @@ require ( replace ( github.com/Shopify/sarama v1.26.1 => github.com/Shopify/sarama v1.21.0 - github.com/cosmos/cosmos-sdk => github.com/bnb-chain/bnc-cosmos-sdk v0.26.6 + // TODO: bump to official release + github.com/cosmos/cosmos-sdk => github.com/j75689/bnc-cosmos-sdk v0.0.0-20231129030639-0bac8422dcb4 github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/go-amino => github.com/bnb-chain/bnc-go-amino v0.14.1-binance.2 diff --git a/go.sum b/go.sum index df36bf095..c76c3abd1 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,6 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/bnb-chain/bnc-cosmos-sdk v0.26.6 h1:5NrdUXplI2cqWZlLOovSqm+xO5ja03ZPCPT4bQqCD1Y= -github.com/bnb-chain/bnc-cosmos-sdk v0.26.6/go.mod h1:OjdXpDHofs6gcPLM9oGD+mm8DPc6Lsevz0Kia53zt3Q= github.com/bnb-chain/bnc-go-amino v0.14.1-binance.2 h1:iAlp9gqG0f2LGAauf3ZiijWlT6NI+W2r9y70HH9LI3k= github.com/bnb-chain/bnc-go-amino v0.14.1-binance.2/go.mod h1:LiCO7jev+3HwLGAiN9gpD0z+jTz95RqgSavbse55XOY= github.com/bnb-chain/bnc-tendermint v0.32.3-bc.10 h1:E4iSwEbJCLYchHiHE1gnOM3jjmJXLBxARhy/RCl8CpI= @@ -789,6 +787,8 @@ github.com/iris-contrib/jade v1.1.4/go.mod h1:EDqR+ur9piDl6DUgs6qRrlfzmlx/D5Uybo github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= +github.com/j75689/bnc-cosmos-sdk v0.0.0-20231129030639-0bac8422dcb4 h1:uGe9w4AzTkpmuTORXrKf35I0zpn2OfFByvxb5uOq1jk= +github.com/j75689/bnc-cosmos-sdk v0.0.0-20231129030639-0bac8422dcb4/go.mod h1:OjdXpDHofs6gcPLM9oGD+mm8DPc6Lsevz0Kia53zt3Q= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= diff --git a/plugins/dex/order/handler.go b/plugins/dex/order/handler.go index ac3ea9e22..a0d198696 100644 --- a/plugins/dex/order/handler.go +++ b/plugins/dex/order/handler.go @@ -104,6 +104,7 @@ func validateQtyAndLockBalance(ctx sdk.Context, keeper *DexKeeper, acc common.Na func handleNewOrder( ctx sdk.Context, dexKeeper *DexKeeper, msg NewOrderMsg, ) sdk.Result { + if _, ok := dexKeeper.OrderExists(msg.Symbol, msg.Id); ok { errString := fmt.Sprintf("Duplicated order [%v] on symbol [%v]", msg.Id, msg.Symbol) return sdk.NewError(types.DefaultCodespace, types.CodeDuplicatedOrder, errString).Result() diff --git a/plugins/recover/client/cli/commands.go b/plugins/recover/client/cli/commands.go new file mode 100644 index 000000000..73be057dd --- /dev/null +++ b/plugins/recover/client/cli/commands.go @@ -0,0 +1,22 @@ +package cli + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/spf13/cobra" +) + +func AddCommands(cmd *cobra.Command, cdc *codec.Codec) { + airdropCmd := &cobra.Command{ + Use: "recover", + Short: "recover commands", + } + + airdropCmd.AddCommand( + client.PostCommands( + SignTokenRecoverRequestCmd(cdc), + )..., + ) + + cmd.AddCommand(airdropCmd) +} diff --git a/plugins/recover/client/cli/tx.go b/plugins/recover/client/cli/tx.go new file mode 100644 index 000000000..36576781f --- /dev/null +++ b/plugins/recover/client/cli/tx.go @@ -0,0 +1,105 @@ +package cli + +import ( + "encoding/hex" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/secp256k1" + + airdrop "github.com/bnb-chain/node/plugins/recover" +) + +const ( + flagAmount = "amount" + flagTokenSymbol = "token-symbol" + flagRecipient = "recipient" +) + +func SignTokenRecoverRequestCmd(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "sign-token-recover-request", + Short: "get token recover request sign data", + RunE: func(cmd *cobra.Command, args []string) error { + txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc) + cliCtx := context.NewCLIContext(). + WithCodec(cdc). + WithAccountDecoder(authcmd.GetAccountDecoder(cdc)) + + amount := viper.GetInt64(flagAmount) + tokenSymbol := viper.GetString(flagTokenSymbol) + recipient := viper.GetString(flagRecipient) + msg := airdrop.NewTokenRecoverRequestMsg(tokenSymbol, uint64(amount), strings.ToLower(common.HexToAddress(recipient).Hex())) + + sdkErr := msg.ValidateBasic() + if sdkErr != nil { + return fmt.Errorf("%v", sdkErr.Data()) + } + return SignAndPrint(cliCtx, txBldr, msg) + }, + } + + cmd.Flags().String(flagTokenSymbol, "", "owner token symbol") + cmd.Flags().Int64(flagAmount, 0, "amount of token") + cmd.Flags().String(flagRecipient, "", "bsc recipient address") + + return cmd +} + +func SignAndPrint(ctx context.CLIContext, builder authtxb.TxBuilder, msg sdk.Msg) error { + name, err := ctx.GetFromName() + if err != nil { + return err + } + + passphrase, err := keys.GetPassphrase(name) + if err != nil { + return err + } + + // build and sign the transaction + stdMsg, err := builder.Build([]sdk.Msg{msg}) + if err != nil { + return err + } + txBytes, err := builder.Sign(name, passphrase, stdMsg) + if err != nil { + return err + } + + var tx auth.StdTx + err = builder.Codec.UnmarshalBinaryLengthPrefixed(txBytes, &tx) + if err != nil { + return err + } + json, err := builder.Codec.MarshalJSON(tx) + if err != nil { + return err + } + + fmt.Printf("TX JSON: %s\n", json) + fmt.Println("Sign Message: ", string(stdMsg.Bytes())) + fmt.Println("Sign Message Hash: ", hex.EncodeToString(crypto.Sha256(stdMsg.Bytes()))) + sig := tx.GetSignatures()[0] + fmt.Printf("Signature: %s\n", hex.EncodeToString(sig.Signature)) + var originPubKey secp256k1.PubKeySecp256k1 + err = builder.Codec.UnmarshalBinaryBare(sig.PubKey.Bytes(), &originPubKey) + if err != nil { + return err + } + fmt.Printf("PubKey: %s\n", hex.EncodeToString(originPubKey)) + return nil +} diff --git a/plugins/recover/msg.go b/plugins/recover/msg.go new file mode 100644 index 000000000..7c87b3b2f --- /dev/null +++ b/plugins/recover/msg.go @@ -0,0 +1,96 @@ +package recover + +import ( + "encoding/hex" + "encoding/json" + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" +) + +const ( + Route = "recover" + MsgType = "request_token" +) + +var _ sdk.Msg = TokenRecoverRequest{} + +func NewTokenRecoverRequestMsg(tokenSymbol string, amount uint64, recipient string) TokenRecoverRequest { + return TokenRecoverRequest{ + TokenSymbol: tokenSymbol, + Amount: amount, + Recipient: recipient, + } +} + +func newTokenRecoverRequestSignData(tokenSymbol string, amount uint64, recipient string) tokenRecoverRequestSignData { + var tokenSymbolBytes [32]byte + copy(tokenSymbolBytes[:], []byte(tokenSymbol)) + + return tokenRecoverRequestSignData{ + TokenSymbol: hex.EncodeToString(tokenSymbolBytes[:]), + Amount: hex.EncodeToString(big.NewInt(int64(amount)).FillBytes(make([]byte, 32))), + Recipient: recipient, + } +} + +type tokenRecoverRequestSignData struct { + TokenSymbol string `json:"token_symbol"` // hex string(32 bytes) + Amount string `json:"amount"` // hex string(32 bytes) + Recipient string `json:"recipient"` // eth address(20 bytes) +} + +type TokenRecoverRequest struct { + TokenSymbol string `json:"token_symbol"` + Amount uint64 `json:"amount"` + Recipient string `json:"recipient"` // eth address +} + +// GetInvolvedAddresses implements types.Msg. +func (msg TokenRecoverRequest) GetInvolvedAddresses() []sdk.AccAddress { + return msg.GetSigners() +} + +// GetSignBytes implements types.Msg. +func (msg TokenRecoverRequest) GetSignBytes() []byte { + b, err := json.Marshal(newTokenRecoverRequestSignData(msg.TokenSymbol, msg.Amount, msg.Recipient)) + if err != nil { + panic(err) + } + return b +} + +// GetSigners implements types.Msg. +func (m TokenRecoverRequest) GetSigners() []sdk.AccAddress { + // This is not a real on-chain transaction + // We can get signer from the public key. + return []sdk.AccAddress{} +} + +// Route implements types.Msg. +func (TokenRecoverRequest) Route() string { + return Route +} + +// Type implements types.Msg. +func (TokenRecoverRequest) Type() string { + return MsgType +} + +// ValidateBasic implements types.Msg. +func (msg TokenRecoverRequest) ValidateBasic() sdk.Error { + if msg.TokenSymbol == "" { + return sdk.ErrUnknownRequest("Invalid token symbol") + } + + if msg.Amount == 0 { + return sdk.ErrUnknownRequest("Invalid amount, should be greater than 0") + } + + if !common.IsHexAddress(msg.Recipient) { + return sdk.ErrInvalidAddress("Invalid recipient address") + } + + return nil +} diff --git a/plugins/recover/wire.go b/plugins/recover/wire.go new file mode 100644 index 000000000..0624360a5 --- /dev/null +++ b/plugins/recover/wire.go @@ -0,0 +1,10 @@ +package recover + +import ( + "github.com/bnb-chain/node/wire" +) + +// Register concrete types on wire codec +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterConcrete(TokenRecoverRequest{}, "recover/TokenRecoverRequest", nil) +} diff --git a/plugins/tokens/freeze/handler.go b/plugins/tokens/freeze/handler.go index 70a3fb952..b6cabb117 100644 --- a/plugins/tokens/freeze/handler.go +++ b/plugins/tokens/freeze/handler.go @@ -19,6 +19,9 @@ func NewHandler(tokenMapper store.Mapper, accKeeper auth.AccountKeeper, keeper b return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case FreezeMsg: + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + return sdk.ErrMsgNotSupported("").Result() + } return handleFreezeToken(ctx, tokenMapper, accKeeper, keeper, msg) case UnfreezeMsg: return handleUnfreezeToken(ctx, tokenMapper, accKeeper, keeper, msg) diff --git a/plugins/tokens/issue/handler.go b/plugins/tokens/issue/handler.go index db8fa3d04..82ef70444 100644 --- a/plugins/tokens/issue/handler.go +++ b/plugins/tokens/issue/handler.go @@ -21,6 +21,9 @@ import ( // NewHandler creates a new token issue message handler func NewHandler(tokenMapper store.Mapper, keeper bank.Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + return sdk.ErrMsgNotSupported("").Result() + } switch msg := msg.(type) { case IssueMsg: return handleIssueToken(ctx, tokenMapper, keeper, msg) @@ -62,7 +65,7 @@ func handleIssueToken(ctx sdk.Context, tokenMapper store.Mapper, bankKeeper bank return issue(ctx, logger, tokenMapper, bankKeeper, token) } -//Mint MiniToken is also handled by this function +// Mint MiniToken is also handled by this function func handleMintToken(ctx sdk.Context, tokenMapper store.Mapper, bankKeeper bank.Keeper, msg MintMsg) sdk.Result { symbol := strings.ToUpper(msg.Symbol) logger := log.With("module", "token", "symbol", symbol, "amount", msg.Amount, "minter", msg.From) diff --git a/plugins/tokens/plugin.go b/plugins/tokens/plugin.go index a19acd0aa..d22bc4d1c 100644 --- a/plugins/tokens/plugin.go +++ b/plugins/tokens/plugin.go @@ -51,6 +51,59 @@ func createQueryHandler(mapper Mapper, queryPrefix string) app.AbciQueryHandler return createAbciQueryHandler(mapper, queryPrefix) } +const ( + MaxUnlockItems = 10 +) + +func EndBlocker(ctx sdk.Context, timelockKeeper timelock.Keeper, swapKeeper swap.Keeper) { + if !sdk.IsUpgrade(sdk.SecondSunsetFork) { + return + } + logger := bnclog.With("module", "tokens") + logger.Info("unlock the time locks", "blockHeight", ctx.BlockHeight()) + + iterator := timelockKeeper.GetTimeLockRecordIterator(ctx) + defer iterator.Close() + i := 0 + for ; iterator.Valid(); iterator.Next() { + if i >= MaxUnlockItems { + break + } + addr, id, err := timelock.ParseKeyRecord(iterator.Key()) + if err != nil { + logger.Error("ParseKeyRecord error", "error", err) + continue + } + err = timelockKeeper.TimeUnlock(ctx, addr, id) + if err != nil { + logger.Error("TimeUnlock error", "error", err) + continue + } + i++ + } + + swapIterator := swapKeeper.GetSwapIterator(ctx) + defer swapIterator.Close() + i = 0 + for ; swapIterator.Valid(); swapIterator.Next() { + if i >= MaxUnlockItems { + break + } + var automaticSwap swap.AtomicSwap + swapKeeper.CDC().MustUnmarshalBinaryBare(swapIterator.Value(), &automaticSwap) + swapID := swapIterator.Key()[len(swap.HashKey):] + result := swap.HandleRefundHashTimerLockedTransferAfterBCFusion(ctx, swapKeeper, swap.RefundHTLTMsg{ + From: automaticSwap.From, + SwapID: swapID, + }) + if !result.IsOK() { + logger.Error("Refund error", "swapId", swapID) + continue + } + i++ + } +} + // EndBreatheBlock processes the breathe block lifecycle event. func EndBreatheBlock(ctx sdk.Context, swapKeeper swap.Keeper) { logger := bnclog.With("module", "tokens") diff --git a/plugins/tokens/swap/handler.go b/plugins/tokens/swap/handler.go index 4c740500f..4ac933448 100644 --- a/plugins/tokens/swap/handler.go +++ b/plugins/tokens/swap/handler.go @@ -12,13 +12,19 @@ func NewHandler(kp Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case HTLTMsg: + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + return sdk.ErrMsgNotSupported("").Result() + } return handleHashTimerLockedTransfer(ctx, kp, msg) case DepositHTLTMsg: + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + return sdk.ErrMsgNotSupported("").Result() + } return handleDepositHashTimerLockedTransfer(ctx, kp, msg) case ClaimHTLTMsg: return handleClaimHashTimerLockedTransfer(ctx, kp, msg) case RefundHTLTMsg: - return handleRefundHashTimerLockedTransfer(ctx, kp, msg) + return handleRefundHashTimerLockedTransfer(ctx, kp, msg, false) default: errMsg := fmt.Sprintf("unrecognized message type: %T", msg) return sdk.ErrUnknownRequest(errMsg).Result() @@ -158,7 +164,11 @@ func handleClaimHashTimerLockedTransfer(ctx sdk.Context, kp Keeper, msg ClaimHTL return sdk.Result{Tags: tags} } -func handleRefundHashTimerLockedTransfer(ctx sdk.Context, kp Keeper, msg RefundHTLTMsg) sdk.Result { +func HandleRefundHashTimerLockedTransferAfterBCFusion(ctx sdk.Context, kp Keeper, msg RefundHTLTMsg) sdk.Result { + return handleRefundHashTimerLockedTransfer(ctx, kp, msg, true) +} + +func handleRefundHashTimerLockedTransfer(ctx sdk.Context, kp Keeper, msg RefundHTLTMsg, isBCFusionRefund bool) sdk.Result { swap := kp.GetSwap(ctx, msg.SwapID) if swap == nil { return ErrNonExistSwapID(fmt.Sprintf("No matched swap with swapID %v", msg.SwapID)).Result() @@ -166,8 +176,10 @@ func handleRefundHashTimerLockedTransfer(ctx sdk.Context, kp Keeper, msg RefundH if swap.Status != Open { return ErrUnexpectedSwapStatus(fmt.Sprintf("Expected swap status is Open, actually it is %s", swap.Status.String())).Result() } - if ctx.BlockHeight() < swap.ExpireHeight { - return ErrRefundUnexpiredSwap(fmt.Sprintf("Current block height is %d, the expire height (%d) is still not reached", ctx.BlockHeight(), swap.ExpireHeight)).Result() + if !isBCFusionRefund { + if ctx.BlockHeight() < swap.ExpireHeight { + return ErrRefundUnexpiredSwap(fmt.Sprintf("Current block height is %d, the expire height (%d) is still not reached", ctx.BlockHeight(), swap.ExpireHeight)).Result() + } } tags := sdk.EmptyTags() diff --git a/plugins/tokens/swap/keeper.go b/plugins/tokens/swap/keeper.go index e781af106..060f77473 100644 --- a/plugins/tokens/swap/keeper.go +++ b/plugins/tokens/swap/keeper.go @@ -41,6 +41,10 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ck bank.Keeper, addrPool *sdk } } +func (keeper Keeper) CDC() *codec.Codec { + return keeper.cdc +} + func (kp *Keeper) CreateSwap(ctx sdk.Context, swapID SwapBytes, swap *AtomicSwap) sdk.Error { if swap == nil { return sdk.ErrInternal("empty atomic swap pointer") @@ -137,6 +141,11 @@ func (kp *Keeper) GetSwap(ctx sdk.Context, swapID SwapBytes) *AtomicSwap { return &swap } +func (kp *Keeper) GetSwapIterator(ctx sdk.Context) (iterator store.Iterator) { + kvStore := ctx.KVStore(kp.storeKey) + return sdk.KVStorePrefixIterator(kvStore, HashKey) +} + func (kp *Keeper) GetSwapCreatorIterator(ctx sdk.Context, addr sdk.AccAddress) (iterator store.Iterator) { kvStore := ctx.KVStore(kp.storeKey) return sdk.KVStorePrefixIterator(kvStore, BuildSwapCreatorQueueKey(addr)) diff --git a/plugins/tokens/timelock/handler.go b/plugins/tokens/timelock/handler.go index 5be0fca45..f69741954 100644 --- a/plugins/tokens/timelock/handler.go +++ b/plugins/tokens/timelock/handler.go @@ -11,10 +11,16 @@ func NewHandler(keeper Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case TimeLockMsg: + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + return sdk.ErrMsgNotSupported("").Result() + } return handleTimeLock(ctx, keeper, msg) case TimeUnlockMsg: return handleTimeUnlock(ctx, keeper, msg) case TimeRelockMsg: + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + return sdk.ErrMsgNotSupported("").Result() + } return handleTimeRelock(ctx, keeper, msg) default: errMsg := fmt.Sprintf("unrecognized time lock message type: %T", msg) diff --git a/plugins/tokens/timelock/keeper.go b/plugins/tokens/timelock/keeper.go index 17b33b2e3..686f2025e 100644 --- a/plugins/tokens/timelock/keeper.go +++ b/plugins/tokens/timelock/keeper.go @@ -6,6 +6,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -88,6 +89,11 @@ func (keeper Keeper) GetTimeLockRecords(ctx sdk.Context, addr sdk.AccAddress) [] return records } +func (kp *Keeper) GetTimeLockRecordIterator(ctx sdk.Context) (iterator store.Iterator) { + kvStore := ctx.KVStore(kp.storeKey) + return sdk.KVStorePrefixIterator(kvStore, []byte{}) +} + func (keeper Keeper) getTimeLockId(ctx sdk.Context, from sdk.AccAddress) int64 { acc := keeper.ak.GetAccount(ctx, from) return acc.GetSequence() diff --git a/plugins/tokens/timelock/keys.go b/plugins/tokens/timelock/keys.go index 0b55b4968..dd306a60b 100644 --- a/plugins/tokens/timelock/keys.go +++ b/plugins/tokens/timelock/keys.go @@ -1,7 +1,10 @@ package timelock import ( + "bytes" + "encoding/hex" "fmt" + "strconv" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -13,3 +16,19 @@ func KeyRecord(addr sdk.AccAddress, id int64) []byte { func KeyRecordSubSpace(addr sdk.AccAddress) []byte { return []byte(fmt.Sprintf("record:%d", addr)) } + +func ParseKeyRecord(key []byte) (sdk.AccAddress, int64, error) { + key = bytes.TrimPrefix(key, []byte("record:")) + accKeyStr := key[:sdk.AddrLen*2] + accKeyBytes, err := hex.DecodeString(string(accKeyStr)) + if err != nil { + return []byte{}, 0, err + } + addr := sdk.AccAddress(accKeyBytes) + + id, err := strconv.ParseInt(string(key[sdk.AddrLen*2+1:]), 10, 64) + if err != nil { + return []byte{}, 0, err + } + return addr, id, nil +} diff --git a/plugins/tokens/timelock/keys_test.go b/plugins/tokens/timelock/keys_test.go new file mode 100644 index 000000000..146ac5bf3 --- /dev/null +++ b/plugins/tokens/timelock/keys_test.go @@ -0,0 +1,32 @@ +package timelock + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestParseKeyRecord(t *testing.T) { + account, err := sdk.AccAddressFromHex("5B38Da6a701c568545dCfcB03FcB875f56beddC4") + if err != nil { + t.Fatal(err) + return + } + accId := int64(1513) + key := KeyRecord(account, accId) + + acc, id, err := ParseKeyRecord([]byte(key)) + if err != nil { + t.Fatal(err) + return + } + + if !acc.Equals(account) { + t.Fatal("parse account error") + return + } + if id != accId { + t.Fatal("parse id error") + return + } +}