Skip to content

Commit

Permalink
Merge pull request #103 from bianjieai/impl-mt-transfer
Browse files Browse the repository at this point in the history
Implement mt transfer
  • Loading branch information
zhangyelong authored Mar 8, 2022
2 parents 4a7b468 + 464450a commit dee181f
Show file tree
Hide file tree
Showing 35 changed files with 5,455 additions and 5 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/irisnet/irismod v1.5.2-alpha1
github.com/irisnet/irismod v1.5.2-alpha1.0.20220307063410-7b1dd26ad4d6
github.com/pkg/errors v0.9.1
github.com/rakyll/statik v0.1.7
github.com/spf13/cast v1.4.0
Expand All @@ -27,6 +27,7 @@ require (
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67
google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.27.1
)

replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/irisnet/irismod v1.5.2-alpha1 h1:Xv3cU8Yj+B4nhbGKwIykVGCFM6S4vOPAlvxES/lCtd0=
github.com/irisnet/irismod v1.5.2-alpha1/go.mod h1:IrhKhC64ZkZ8gGkXS1+XXnZNLQWGocZv9W/gGmynEFA=
github.com/irisnet/irismod v1.5.2-alpha1.0.20220307063410-7b1dd26ad4d6 h1:6NcnSNo0TbEiPFGDEv4dIeQ8nqulUYeFBBGNL5qWZl8=
github.com/irisnet/irismod v1.5.2-alpha1.0.20220307063410-7b1dd26ad4d6/go.mod h1:IrhKhC64ZkZ8gGkXS1+XXnZNLQWGocZv9W/gGmynEFA=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
Expand Down
41 changes: 41 additions & 0 deletions modules/tibc/apps/mt_transfer/client/cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cli

import (
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
)

// NewTxCmd returns the transaction commands for TIBC multi token transfer
func NewTxCmd() *cobra.Command {
txCmd := &cobra.Command{
Use: "tibc-mt-transfer",
Short: "TIBC multi token transfer transaction subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

txCmd.AddCommand(
NewTransferTxCmd(),
)

return txCmd
}

// GetQueryCmd returns the query commands for TIBC multi token transfer
func GetQueryCmd() *cobra.Command {
queryCmd := &cobra.Command{
Use: "tibc-mt-transfer",
Short: "TIBC multi token transfer query subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
}

queryCmd.AddCommand(
GetCmdQueryClassTrace(),
GetCmdQueryClassTraces(),
)

return queryCmd
}
19 changes: 19 additions & 0 deletions modules/tibc/apps/mt_transfer/client/cli/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cli

import (
flag "github.com/spf13/pflag"
)

const (
FlagRelayChain = "relay-chain"
FlagDestContract = "dest-contract"
)

var (
FsMtTransfer = flag.NewFlagSet("", flag.ContinueOnError)
)

func init() {
FsMtTransfer.String(FlagRelayChain, "", "relay chain used by cross-chain mt")
FsMtTransfer.String(FlagDestContract, "", "the destination contract address to receive the mt")
}
83 changes: 83 additions & 0 deletions modules/tibc/apps/mt_transfer/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package cli

import (
"fmt"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/version"
"github.com/spf13/cobra"

"github.com/bianjieai/tibc-go/modules/tibc/apps/nft_transfer/types"
)

// GetCmdQueryClassTrace defines the command to query a class trace from a given hash.
func GetCmdQueryClassTrace() *cobra.Command {
cmd := &cobra.Command{
Use: "class-trace [hash]",
Short: "Query the class trace info from a given trace hash",
Long: "Query the class trace info from a given trace hash",
Example: fmt.Sprintf("%s query tibc-mt-transfer class-trace [hash]", version.AppName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

req := &types.QueryClassTraceRequest{
Hash: args[0],
}

res, err := queryClient.ClassTrace(cmd.Context(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)
return cmd
}

// GetCmdQueryClassTraces defines the command to query all the class trace infos
// that this chain mantains.
func GetCmdQueryClassTraces() *cobra.Command {
cmd := &cobra.Command{
Use: "class-traces",
Short: "Query the trace info for all mt classes",
Long: "Query the trace info for all mt classes",
Example: fmt.Sprintf("%s query tibc-mt-transfer class-traces", version.AppName),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

pageReq, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}

req := &types.QueryClassTracesRequest{
Pagination: pageReq,
}

res, err := queryClient.ClassTraces(cmd.Context(), req)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}
flags.AddQueryFlagsToCmd(cmd)
flags.AddPaginationFlagsToCmd(cmd, "class trace")

return cmd
}
71 changes: 71 additions & 0 deletions modules/tibc/apps/mt_transfer/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cli

import (
"fmt"
"strconv"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/version"

"github.com/bianjieai/tibc-go/modules/tibc/apps/mt_transfer/types"
)

// NewTransferTxCmd returns the command to create a NewMsgTransfer transaction
func NewTransferTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer [dest-chain] [receiver] [class] [id] [amount]",
Short: "Transfer a mt through TIBC",
Example: fmt.Sprintf(
"%s tx tibc-mt-transfer transfer <dest-chain-name> <receiver> <denom-id> <mt-id> <amount>"+
"--relay-chain=<relay-chain-name> "+
"--dest-contract=<receive-the-contract-address-of-nft>",
version.AppName,
),
Args: cobra.ExactArgs(5),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
sender := clientCtx.GetFromAddress().String()
destChain := args[0]
receiver := args[1]
class := args[2]
id := args[3]
amount := args[4]

relayChain, err := cmd.Flags().GetString(FlagRelayChain)
if err != nil {
return err
}

destContract, err := cmd.Flags().GetString(FlagDestContract)
if err != nil {
return err
}

amt, err := strconv.ParseUint(amount, 10, 64)
if err != nil {
return err
}

msg := types.NewMsgMtTransfer(
class, id, sender, receiver,
destChain, relayChain, destContract, amt,
)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().AddFlagSet(FsMtTransfer)
flags.AddTxFlagsToCmd(cmd)

return cmd
}
25 changes: 25 additions & 0 deletions modules/tibc/apps/mt_transfer/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package mt_transfer

import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"github.com/bianjieai/tibc-go/modules/tibc/apps/mt_transfer/keeper"
mttransfertypes "github.com/bianjieai/tibc-go/modules/tibc/apps/mt_transfer/types"
)

// NewHandler defines the TIBC mt transfer handler
func NewHandler(k keeper.Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())

switch msg := msg.(type) {
case *mttransfertypes.MsgMtTransfer:
res, err := k.MtTransfer(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)

default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized TIBC message type: %T", msg)
}
}
}
22 changes: 22 additions & 0 deletions modules/tibc/apps/mt_transfer/keeper/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package keeper

import (
"github.com/bianjieai/tibc-go/modules/tibc/apps/mt_transfer/types"
)

// MustMarshalClassTrace attempts to encode an ClassTrace object and returns the
// raw encoded bytes. It panics on error.
func (k Keeper) MustMarshalClassTrace(classTrace types.ClassTrace) []byte {
return k.cdc.MustMarshal(&classTrace)
}

// UnmarshalClassTrace attempts to decode and return an ClassTrace object from
// raw encoded bytes.
func (k Keeper) UnmarshalClassTrace(bz []byte) (types.ClassTrace, error) {
var classTrace types.ClassTrace
if err := k.cdc.Unmarshal(bz, &classTrace); err != nil {
return types.ClassTrace{}, err
}

return classTrace, nil
}
73 changes: 73 additions & 0 deletions modules/tibc/apps/mt_transfer/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package keeper

import (
"context"
"fmt"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/query"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/bianjieai/tibc-go/modules/tibc/apps/mt_transfer/types"
)

var _ types.QueryServer = Keeper{}

// ClassTrace implements the Query/ClassTrace gRPC method
func (q Keeper) ClassTrace(c context.Context, req *types.QueryClassTraceRequest) (*types.QueryClassTraceResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

hash, err := types.ParseHexHash(req.Hash)
if err != nil {
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid class trace hash %s, %s", req.Hash, err))
}

ctx := sdk.UnwrapSDKContext(c)
classTrace, found := q.GetClassTrace(ctx, hash)
if !found {
return nil, status.Error(
codes.NotFound,
sdkerrors.Wrap(types.ErrTraceNotFound, req.Hash).Error(),
)
}

return &types.QueryClassTraceResponse{
ClassTrace: &classTrace,
}, nil
}

// ClassTraces implements the Query/ClassTraces gRPC method
func (q Keeper) ClassTraces(c context.Context, req *types.QueryClassTracesRequest) (*types.QueryClassTracesResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(c)

traces := types.Traces{}
store := prefix.NewStore(ctx.KVStore(q.storeKey), types.ClassTraceKey)

pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error {
result, err := q.UnmarshalClassTrace(value)
if err != nil {
return err
}

traces = append(traces, result)
return nil
})

if err != nil {
return nil, err
}

return &types.QueryClassTracesResponse{
ClassTraces: traces.Sort(),
Pagination: pageRes,
}, nil
}
Loading

0 comments on commit dee181f

Please sign in to comment.