Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support cross chain for multiple blockchains #242

Merged
merged 4 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions types/cross_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ type CrossChainApplication interface {
}

type CrossChainAppContext struct {
Sequence uint64
Header *PackageHeader
SrcChainId ChainID
Sequence uint64
Header *PackageHeader
}

type ExecuteResult struct {
Expand Down
4 changes: 2 additions & 2 deletions x/crosschain/keeper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import sdk "github.com/cosmos/cosmos-sdk/types"

type crossChainConfig struct {
srcChainID sdk.ChainID
destChainId sdk.ChainID
destBscChainId sdk.ChainID
nameToChannelID map[string]sdk.ChannelID
channelIDToName map[sdk.ChannelID]string
channelIDToApp map[sdk.ChannelID]sdk.CrossChainApplication
Expand All @@ -13,7 +13,7 @@ type crossChainConfig struct {
func newCrossChainCfg() *crossChainConfig {
config := &crossChainConfig{
srcChainID: 0,
destChainId: 0,
destBscChainId: 0,
nameToChannelID: make(map[string]sdk.ChannelID),
channelIDToName: make(map[sdk.ChannelID]string),
channelIDToApp: make(map[sdk.ChannelID]sdk.CrossChainApplication),
Expand Down
6 changes: 3 additions & 3 deletions x/crosschain/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (k Keeper) CrossChainPackage(c context.Context, req *types.QueryCrossChainP
}

ctx := sdk.UnwrapSDKContext(c)
pack, err := k.GetCrossChainPackage(ctx, sdk.ChannelID(req.ChannelId), req.Sequence)
pack, err := k.GetCrossChainPackage(ctx, k.GetDestBscChainID(), sdk.ChannelID(req.ChannelId), req.Sequence)
if err != nil {
return nil, err
}
Expand All @@ -42,7 +42,7 @@ func (k Keeper) SendSequence(c context.Context, req *types.QuerySendSequenceRequ
}

ctx := sdk.UnwrapSDKContext(c)
sequence := k.GetSendSequence(ctx, sdk.ChannelID(req.ChannelId))
sequence := k.GetSendSequence(ctx, k.GetDestBscChainID(), sdk.ChannelID(req.ChannelId))

return &types.QuerySendSequenceResponse{
Sequence: sequence,
Expand All @@ -56,7 +56,7 @@ func (k Keeper) ReceiveSequence(c context.Context, req *types.QueryReceiveSequen
}

ctx := sdk.UnwrapSDKContext(c)
sequence := k.GetReceiveSequence(ctx, sdk.ChannelID(req.ChannelId))
sequence := k.GetReceiveSequence(ctx, k.GetDestBscChainID(), sdk.ChannelID(req.ChannelId))

return &types.QueryReceiveSequenceResponse{
Sequence: sequence,
Expand Down
42 changes: 21 additions & 21 deletions x/crosschain/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error {
}

// CreateRawIBCPackageWithFee creates a cross chain package with given cross chain fee
func (k Keeper) CreateRawIBCPackageWithFee(ctx sdk.Context, channelID sdk.ChannelID,
func (k Keeper) CreateRawIBCPackageWithFee(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID,
packageType sdk.CrossChainPackageType, packageLoad []byte, relayerFee, ackRelayerFee *big.Int,
) (uint64, error) {
if packageType == sdk.SynCrossChainPackageType && k.GetChannelSendPermission(ctx, k.GetDestChainID(), channelID) != sdk.ChannelAllow {
if packageType == sdk.SynCrossChainPackageType && k.GetChannelSendPermission(ctx, destChainId, channelID) != sdk.ChannelAllow {
return 0, fmt.Errorf("channel %d is not allowed to write syn package", channelID)
}

sequence := k.GetSendSequence(ctx, channelID)
key := types.BuildCrossChainPackageKey(k.GetSrcChainID(), k.GetDestChainID(), channelID, sequence)
sequence := k.GetSendSequence(ctx, destChainId, channelID)
key := types.BuildCrossChainPackageKey(k.GetSrcChainID(), destChainId, channelID, sequence)
kvStore := ctx.KVStore(k.storeKey)
if kvStore.Has(key) {
return 0, fmt.Errorf("duplicated sequence")
Expand All @@ -116,11 +116,11 @@ func (k Keeper) CreateRawIBCPackageWithFee(ctx sdk.Context, channelID sdk.Channe

kvStore.Set(key, append(packageHeader, packageLoad...))

k.IncrSendSequence(ctx, channelID)
k.IncrSendSequence(ctx, destChainId, channelID)

err := ctx.EventManager().EmitTypedEvent(&types.EventCrossChain{
SrcChainId: uint32(k.GetSrcChainID()),
DestChainId: uint32(k.GetDestChainID()),
DestChainId: uint32(destChainId),
ChannelId: uint32(channelID),
Sequence: sequence,
PackageType: uint32(packageType),
Expand Down Expand Up @@ -157,7 +157,7 @@ func (k Keeper) RegisterChannel(name string, id sdk.ChannelID, app sdk.CrossChai

// IsDestChainSupported returns the support status of a dest chain
func (k Keeper) IsDestChainSupported(chainID sdk.ChainID) bool {
return chainID == k.cfg.destChainId
return chainID == k.cfg.destBscChainId
}

// SetChannelSendPermission sets the channel send permission
Expand Down Expand Up @@ -188,39 +188,39 @@ func (k Keeper) GetSrcChainID() sdk.ChainID {

// SetDestChainID sets the destination chain id
func (k Keeper) SetDestChainID(destChainId sdk.ChainID) {
k.cfg.destChainId = destChainId
k.cfg.destBscChainId = destChainId
}

// GetDestChainID gets the destination chain id
func (k Keeper) GetDestChainID() sdk.ChainID {
return k.cfg.destChainId
// GetDestBscChainID gets the destination chain id of bsc
func (k Keeper) GetDestBscChainID() sdk.ChainID {
return k.cfg.destBscChainId
}

// GetCrossChainPackage returns the ibc package by sequence
func (k Keeper) GetCrossChainPackage(ctx sdk.Context, channelId sdk.ChannelID, sequence uint64) ([]byte, error) {
func (k Keeper) GetCrossChainPackage(ctx sdk.Context, destChainId sdk.ChainID, channelId sdk.ChannelID, sequence uint64) ([]byte, error) {
kvStore := ctx.KVStore(k.storeKey)
key := types.BuildCrossChainPackageKey(k.GetSrcChainID(), k.GetDestChainID(), channelId, sequence)
key := types.BuildCrossChainPackageKey(k.GetSrcChainID(), destChainId, channelId, sequence)
return kvStore.Get(key), nil
}

// GetSendSequence returns the sending sequence of the channel
func (k Keeper) GetSendSequence(ctx sdk.Context, channelID sdk.ChannelID) uint64 {
return k.getSequence(ctx, k.GetDestChainID(), channelID, types.PrefixForSendSequenceKey)
func (k Keeper) GetSendSequence(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID) uint64 {
return k.getSequence(ctx, destChainId, channelID, types.PrefixForSendSequenceKey)
}

// IncrSendSequence increases the sending sequence of the channel
func (k Keeper) IncrSendSequence(ctx sdk.Context, channelID sdk.ChannelID) {
k.incrSequence(ctx, k.GetDestChainID(), channelID, types.PrefixForSendSequenceKey)
func (k Keeper) IncrSendSequence(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID) {
k.incrSequence(ctx, destChainId, channelID, types.PrefixForSendSequenceKey)
}

// GetReceiveSequence returns the receiving sequence of the channel
func (k Keeper) GetReceiveSequence(ctx sdk.Context, channelID sdk.ChannelID) uint64 {
return k.getSequence(ctx, k.GetDestChainID(), channelID, types.PrefixForReceiveSequenceKey)
func (k Keeper) GetReceiveSequence(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID) uint64 {
return k.getSequence(ctx, destChainId, channelID, types.PrefixForReceiveSequenceKey)
}

// IncrReceiveSequence increases the receiving sequence of the channel
func (k Keeper) IncrReceiveSequence(ctx sdk.Context, channelID sdk.ChannelID) {
k.incrSequence(ctx, k.GetDestChainID(), channelID, types.PrefixForReceiveSequenceKey)
func (k Keeper) IncrReceiveSequence(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID) {
k.incrSequence(ctx, destChainId, channelID, types.PrefixForReceiveSequenceKey)
}

// getSequence returns the sequence with a prefix
Expand Down
12 changes: 6 additions & 6 deletions x/crosschain/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,21 @@ func TestTestSuite(t *testing.T) {
}

func (s *TestSuite) TestIncrSendSequence() {
beforeSequence := s.crossChainKeeper.GetSendSequence(s.ctx, sdk.ChannelID(1))
beforeSequence := s.crossChainKeeper.GetSendSequence(s.ctx, sdk.ChainID(1), sdk.ChannelID(1))

s.crossChainKeeper.IncrSendSequence(s.ctx, sdk.ChannelID(1))
s.crossChainKeeper.IncrSendSequence(s.ctx, sdk.ChainID(1), sdk.ChannelID(1))

afterSequence := s.crossChainKeeper.GetSendSequence(s.ctx, sdk.ChannelID(1))
afterSequence := s.crossChainKeeper.GetSendSequence(s.ctx, sdk.ChainID(1), sdk.ChannelID(1))

s.Require().EqualValues(afterSequence, beforeSequence+1)
}

func (s *TestSuite) TestIncrReceiveSequence() {
beforeSequence := s.crossChainKeeper.GetReceiveSequence(s.ctx, sdk.ChannelID(1))
beforeSequence := s.crossChainKeeper.GetReceiveSequence(s.ctx, sdk.ChainID(1), sdk.ChannelID(1))

s.crossChainKeeper.IncrReceiveSequence(s.ctx, sdk.ChannelID(1))
s.crossChainKeeper.IncrReceiveSequence(s.ctx, sdk.ChainID(1), sdk.ChannelID(1))

afterSequence := s.crossChainKeeper.GetReceiveSequence(s.ctx, sdk.ChannelID(1))
afterSequence := s.crossChainKeeper.GetReceiveSequence(s.ctx, sdk.ChainID(1), sdk.ChannelID(1))

s.Require().EqualValues(afterSequence, beforeSequence+1)
}
Expand Down
5 changes: 0 additions & 5 deletions x/crosschain/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ const (

MaxSideChainIdLength = 20
SequenceLength = 8

GovChannelId = sdk.ChannelID(9)
)

var (
Expand Down Expand Up @@ -58,9 +56,6 @@ func (c *ChannelPermissionSetting) Check() error {
if len(c.DestChainId) == 0 || len(c.DestChainId) > MaxSideChainIdLength {
return fmt.Errorf("invalid dest chain id")
}
if c.ChannelId == GovChannelId {
return fmt.Errorf("gov channel id is forbidden to set")
}
if c.Permission != sdk.ChannelAllow && c.Permission != sdk.ChannelForbidden {
return fmt.Errorf("permission %d is invalid", c.Permission)
}
Expand Down
3 changes: 2 additions & 1 deletion x/gov/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ func setupGovKeeper(t *testing.T) (
govKeeper.SetLegacyRouter(govRouter)
govKeeper.SetParams(ctx, v1.DefaultParams())

crossChainKeeper.EXPECT().CreateRawIBCPackageWithFee(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(uint64(0), nil).AnyTimes()
crossChainKeeper.EXPECT().GetDestBscChainID().Return(sdk.ChainID(714)).AnyTimes()
crossChainKeeper.EXPECT().CreateRawIBCPackageWithFee(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(uint64(0), nil).AnyTimes()

// Register all handlers for the MegServiceRouter.
msr.SetInterfaceRegistry(encCfg.InterfaceRegistry)
Expand Down
1 change: 1 addition & 0 deletions x/gov/keeper/crosschain.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (k Keeper) SyncParams(ctx sdk.Context, cpc govv1.CrossChainParamsChange) er

_, err := k.crossChainKeeper.CreateRawIBCPackageWithFee(
ctx,
k.crossChainKeeper.GetDestBscChainID(),
types.SyncParamsChannelID,
sdk.SynCrossChainPackageType,
encodedPackage,
Expand Down
7 changes: 4 additions & 3 deletions x/gov/testutil/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ type StakingKeeper interface {

// CrossChainKeeper defines the expected crossChain keeper
type CrossChainKeeper interface {
RegisterChannel(name string, id sdk.ChannelID, app sdk.CrossChainApplication) error

CreateRawIBCPackageWithFee(ctx sdk.Context, channelID sdk.ChannelID, packageType sdk.CrossChainPackageType,
GetDestBscChainID() sdk.ChainID
CreateRawIBCPackageWithFee(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID, packageType sdk.CrossChainPackageType,
packageLoad []byte, relayerFee, ackRelayerFee *big.Int,
) (uint64, error)

RegisterChannel(name string, id sdk.ChannelID, app sdk.CrossChainApplication) error
}
23 changes: 18 additions & 5 deletions x/gov/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion x/gov/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ type BankKeeper interface {
}

type CrossChainKeeper interface {
CreateRawIBCPackageWithFee(ctx sdk.Context, channelID sdk.ChannelID, packageType sdk.CrossChainPackageType,
GetDestBscChainID() sdk.ChainID
CreateRawIBCPackageWithFee(ctx sdk.Context, destChainId sdk.ChainID, channelID sdk.ChannelID, packageType sdk.CrossChainPackageType,
packageLoad []byte, relayerFee, ackRelayerFee *big.Int,
) (uint64, error)

Expand Down
30 changes: 17 additions & 13 deletions x/oracle/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (k msgServer) Claim(goCtx context.Context, req *types.MsgClaim) (*types.Msg
return nil, sdkerrors.Wrapf(types.ErrInvalidSrcChainId, "src chain id(%d) is not supported", req.SrcChainId)
}

sequence := k.CrossChainKeeper.GetReceiveSequence(ctx, types.RelayPackagesChannelId)
sequence := k.CrossChainKeeper.GetReceiveSequence(ctx, sdk.ChainID(req.SrcChainId), types.RelayPackagesChannelId)
if sequence != req.Sequence {
return nil, sdkerrors.Wrapf(types.ErrInvalidReceiveSequence, "current sequence of channel %d is %d", types.RelayPackagesChannelId, sequence)
}
Expand Down Expand Up @@ -92,15 +92,15 @@ func (k msgServer) Claim(goCtx context.Context, req *types.MsgClaim) (*types.Msg
totalRelayerFee = totalRelayerFee.Add(relayerFee)

// increase channel sequence
k.CrossChainKeeper.IncrReceiveSequence(ctx, pack.ChannelId)
k.CrossChainKeeper.IncrReceiveSequence(ctx, sdk.ChainID(req.SrcChainId), pack.ChannelId)
}

err = k.distributeReward(ctx, relayer, signedRelayers, totalRelayerFee)
if err != nil {
return nil, err
}

k.CrossChainKeeper.IncrReceiveSequence(ctx, types.RelayPackagesChannelId)
k.CrossChainKeeper.IncrReceiveSequence(ctx, sdk.ChainID(req.SrcChainId), types.RelayPackagesChannelId)

err = ctx.EventManager().EmitTypedEvents(events...)
if err != nil {
Expand Down Expand Up @@ -179,7 +179,7 @@ func (k Keeper) handlePackage(
return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrChannelNotRegistered, "channel %d not registered", pack.ChannelId)
}

sequence := k.CrossChainKeeper.GetReceiveSequence(ctx, pack.ChannelId)
sequence := k.CrossChainKeeper.GetReceiveSequence(ctx, sdk.ChainID(srcChainId), pack.ChannelId)
if sequence != pack.Sequence {
return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidReceiveSequence,
"current sequence of channel %d is %d", pack.ChannelId, sequence)
Expand All @@ -201,7 +201,7 @@ func (k Keeper) handlePackage(
}

cacheCtx, write := ctx.CacheContext()
crash, result := executeClaim(cacheCtx, crossChainApp, sequence, pack.Payload, &packageHeader)
crash, result := executeClaim(cacheCtx, crossChainApp, srcChainId, sequence, pack.Payload, &packageHeader)
if result.IsOk() {
write()
}
Expand All @@ -216,15 +216,15 @@ func (k Keeper) handlePackage(
return sdkmath.ZeroInt(), nil, sdkerrors.Wrapf(types.ErrInvalidPackage, "payload without header")
}

sendSeq, ibcErr := k.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, pack.ChannelId,
sendSeq, ibcErr := k.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, sdk.ChainID(srcChainId), pack.ChannelId,
sdk.FailAckCrossChainPackageType, pack.Payload[sdk.SynPackageHeaderLength:], packageHeader.AckRelayerFee, sdk.NilAckRelayerFee)
if ibcErr != nil {
logger.Error("failed to write FailAckCrossChainPackage", "err", err)
return sdkmath.ZeroInt(), nil, ibcErr
}
sendSequence = int64(sendSeq)
} else if len(result.Payload) != 0 {
sendSeq, err := k.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, pack.ChannelId,
sendSeq, err := k.CrossChainKeeper.CreateRawIBCPackageWithFee(ctx, sdk.ChainID(srcChainId), pack.ChannelId,
sdk.AckCrossChainPackageType, result.Payload, packageHeader.AckRelayerFee, sdk.NilAckRelayerFee)
if err != nil {
logger.Error("failed to write AckCrossChainPackage", "err", err)
Expand Down Expand Up @@ -253,6 +253,7 @@ func (k Keeper) handlePackage(
func executeClaim(
ctx sdk.Context,
app sdk.CrossChainApplication,
srcChainId uint32,
sequence uint64,
payload []byte,
header *sdk.PackageHeader,
Expand All @@ -272,18 +273,21 @@ func executeClaim(
switch header.PackageType {
case sdk.SynCrossChainPackageType:
result = app.ExecuteSynPackage(ctx, &sdk.CrossChainAppContext{
Sequence: sequence,
Header: header,
SrcChainId: sdk.ChainID(srcChainId),
Sequence: sequence,
Header: header,
}, payload[sdk.SynPackageHeaderLength:])
case sdk.AckCrossChainPackageType:
result = app.ExecuteAckPackage(ctx, &sdk.CrossChainAppContext{
Sequence: sequence,
Header: header,
SrcChainId: sdk.ChainID(srcChainId),
Sequence: sequence,
Header: header,
}, payload[sdk.AckPackageHeaderLength:])
case sdk.FailAckCrossChainPackageType:
result = app.ExecuteFailAckPackage(ctx, &sdk.CrossChainAppContext{
Sequence: sequence,
Header: header,
SrcChainId: sdk.ChainID(srcChainId),
Sequence: sequence,
Header: header,
}, payload[sdk.AckPackageHeaderLength:])
default:
panic(fmt.Sprintf("receive unexpected package type %d", header.PackageType))
Expand Down
Loading
Loading