Skip to content
Open
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/datachainlab/ibc-proxy
go 1.16

replace (
github.com/cosmos/ibc-go => github.com/datachainlab/ibc-go v0.0.0-20210623043207-6582d8c965f8
github.com/cosmos/ibc-go => github.com/datachainlab/ibc-go v0.0.0-20220120054455-a627cf595609
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
github.com/datachainlab/ibc-go v0.0.0-20210623043207-6582d8c965f8 h1:Nx9l9NCCKvCmGDDQslhKHc4hWXINcMKFykMQjrvu5o8=
github.com/datachainlab/ibc-go v0.0.0-20210623043207-6582d8c965f8/go.mod h1:NU4IARjXt3Hj5xcju207SWjDMpqMx3CHUXejGe0EXfY=
github.com/datachainlab/ibc-go v0.0.0-20220120054455-a627cf595609 h1:F/4hdX1IO88bt0Pzvm+ogaq7e6OPA1w+vuwjxA7kT5E=
github.com/datachainlab/ibc-go v0.0.0-20220120054455-a627cf595609/go.mod h1:NU4IARjXt3Hj5xcju207SWjDMpqMx3CHUXejGe0EXfY=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
18 changes: 18 additions & 0 deletions modules/proxy/keeper/commitment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

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

clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types"
connectiontypes "github.com/cosmos/ibc-go/modules/core/03-connection/types"
Expand Down Expand Up @@ -181,3 +182,20 @@ func (k Keeper) SetProxyNextSequenceRecv(
store.Set(host.NextSequenceRecvKey(portID, channelID), bz)
return nil
}

func (k Keeper) GetUpstreamTimestampAtHeight(
ctx sdk.Context,
upstreamClientID string,
height exported.Height,
) (uint64, error) {
consensusState, found := k.clientKeeper.GetClientConsensusState(ctx, upstreamClientID, height)

if !found {
return 0, sdkerrors.Wrapf(
clienttypes.ErrConsensusStateNotFound,
"clientID (%s), height (%s)", upstreamClientID, height,
)
}

return consensusState.GetTimestamp(), nil
}
10 changes: 10 additions & 0 deletions modules/proxy/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,13 @@ func (k *Keeper) ProxyAcknowledgePacket(goCtx context.Context, msg *types.MsgPro
}
return &types.MsgProxyAcknowledgePacketResponse{}, nil
}

// ProxyTimeoutPacket implements types.MsgServer
func (k Keeper) ProxyTimeoutPacket(goCtx context.Context, msg *types.MsgProxyTimeoutPacket) (*types.MsgProxyTimeoutPacketResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
err := k.TimeoutPacket(ctx, msg.UpstreamClientId, msg.UpstreamPrefix, msg.Packet, msg.ProofUnreceived, msg.ProofHeight, msg.NextSequenceRecv)
if err != nil {
return nil, err
}
return &types.MsgProxyTimeoutPacketResponse{}, nil
}
90 changes: 88 additions & 2 deletions modules/proxy/keeper/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/cosmos/ibc-go/modules/core/exported"
)

// upstream: chainA, downstream: chainB
// upstream(dst): chainA, downstream(src): chainB
func (k Keeper) RecvPacket(
ctx sdk.Context,
upstreamClientID string, // the client ID corresponding to light client for chainA on chainB
Expand Down Expand Up @@ -60,7 +60,7 @@ func (k Keeper) RecvPacket(
return nil
}

// upstream: chainA, downstream: chainB
// upstream: chainA(src), downstream: chainB(dst)
func (k Keeper) AcknowledgePacket(
ctx sdk.Context,
upstreamClientID string, // the client ID corresponding to light client for chainA on chainB
Expand Down Expand Up @@ -100,3 +100,89 @@ func (k Keeper) AcknowledgePacket(

return nil
}

// upstream(dst): chainA, downstream(src): chainB
func (k Keeper) TimeoutPacket(
ctx sdk.Context,
upstreamClientID string, // the client ID corresponding to light client for chainA on chainB
upstreamPrefix exported.Prefix, // store prefix on chainA
packet exported.PacketI,
proof []byte,
proofHeight exported.Height,
nextSequenceRecv uint64,
) error {
channel, found := k.GetProxyChannel(ctx, upstreamPrefix, upstreamClientID, packet.GetSourcePort(), packet.GetSourceChannel())
if !found {
return sdkerrors.Wrapf(
channeltypes.ErrChannelNotFound,
"port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel(),
)
}
if channel.State != channeltypes.OPEN {
return sdkerrors.Wrapf(
channeltypes.ErrInvalidChannelState,
"channel state is not OPEN (got %s)", channel.State.String(),
)
}

if packet.GetDestPort() != channel.Counterparty.PortId {
return sdkerrors.Wrapf(
channeltypes.ErrInvalidPacket,
"packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortId,
)
}

if packet.GetDestChannel() != channel.Counterparty.ChannelId {
return sdkerrors.Wrapf(
channeltypes.ErrInvalidPacket,
"packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelId,
)
}

connectionEnd, found := k.GetProxyConnection(ctx, upstreamPrefix, upstreamClientID, channel.ConnectionHops[0])
if !found {
return sdkerrors.Wrap(
connectiontypes.ErrConnectionNotFound,
channel.ConnectionHops[0],
)
}

proofTimestamp, err := k.GetUpstreamTimestampAtHeight(ctx, upstreamClientID, proofHeight)
if err != nil {
return err
}
timeoutHeight := packet.GetTimeoutHeight()
if (timeoutHeight.IsZero() || proofHeight.LT(timeoutHeight)) &&
(packet.GetTimeoutTimestamp() == 0 || proofTimestamp < packet.GetTimeoutTimestamp()) {
return sdkerrors.Wrap(channeltypes.ErrPacketTimeout, "packet timeout has not been reached for height or timestamp")
}

switch channel.Ordering {
case channeltypes.ORDERED:
// check that packet has not been received
if nextSequenceRecv > packet.GetSequence() {
return sdkerrors.Wrapf(
channeltypes.ErrPacketReceived,
"packet already received, next sequence receive > packet sequence (%d > %d)", nextSequenceRecv, packet.GetSequence(),
)
}
// check that the recv sequence is as claimed
err = k.VerifyAndProxyNextSequenceRecv(
ctx, upstreamClientID, upstreamPrefix, connectionEnd, proofHeight, proof,
packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv,
)
case channeltypes.UNORDERED:
err = k.VerifyAndProxyPacketReceiptAbsence(
ctx, upstreamClientID, upstreamPrefix, connectionEnd, proofHeight, proof,
packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(),
)
default:
panic(sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, channel.Ordering.String()))
}

if err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions modules/proxy/keeper/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,5 +418,6 @@ func (k Keeper) VerifyAndProxyNextSequenceRecv(

// getBlockDelay always returns 0
func (k Keeper) getBlockDelay(ctx sdk.Context, connection exported.ConnectionI) uint64 {
// TODO can we use the parameter `KeyMaxExpectedTimePerBlock` of the proxy to calclulate the block delay?
return 0
}
1 change: 1 addition & 0 deletions modules/proxy/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
&MsgProxyChannelOpenFinalize{},
&MsgProxyRecvPacket{},
&MsgProxyAcknowledgePacket{},
&MsgProxyTimeoutPacket{},
)
registry.RegisterImplementations((*exported.ClientState)(nil), &proxytypes.ClientState{})
registry.RegisterImplementations((*exported.ConsensusState)(nil), &proxytypes.ConsensusState{})
Expand Down
1 change: 1 addition & 0 deletions modules/proxy/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
type ClientKeeper interface {
ClientStore(ctx sdk.Context, clientID string) sdk.KVStore
GetClientState(ctx sdk.Context, clientID string) (exported.ClientState, bool)
GetClientConsensusState(ctx sdk.Context, clientID string, height exported.Height) (exported.ConsensusState, bool)
GetSelfConsensusState(ctx sdk.Context, height exported.Height) (exported.ConsensusState, bool)
ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error
}
28 changes: 19 additions & 9 deletions modules/proxy/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
)

var (
_, _, _, _ sdk.Msg = (*MsgProxyClientState)(nil), (*MsgProxyConnectionOpenTry)(nil), (*MsgProxyConnectionOpenAck)(nil), (*MsgProxyConnectionOpenConfirm)(nil)
_, _, _, _ codectypes.UnpackInterfacesMessage = (*MsgProxyClientState)(nil), (*MsgProxyConnectionOpenTry)(nil), (*MsgProxyConnectionOpenAck)(nil), (*MsgProxyConnectionOpenConfirm)(nil)
_, _, _, _, _ sdk.Msg = (*MsgProxyClientState)(nil), (*MsgProxyConnectionOpenTry)(nil), (*MsgProxyConnectionOpenAck)(nil), (*MsgProxyConnectionOpenConfirm)(nil), (*MsgProxyConnectionOpenFinalize)(nil)
_, _, _ codectypes.UnpackInterfacesMessage = (*MsgProxyClientState)(nil), (*MsgProxyConnectionOpenTry)(nil), (*MsgProxyConnectionOpenAck)(nil)

_, _, _ sdk.Msg = (*MsgProxyChannelOpenTry)(nil), (*MsgProxyChannelOpenAck)(nil), (*MsgProxyChannelOpenConfirm)(nil)
_, _ sdk.Msg = (*MsgProxyRecvPacket)(nil), (*MsgProxyAcknowledgePacket)(nil)
_, _, _, _ sdk.Msg = (*MsgProxyChannelOpenTry)(nil), (*MsgProxyChannelOpenAck)(nil), (*MsgProxyChannelOpenConfirm)(nil), (*MsgProxyChannelOpenFinalize)(nil)
_, _, _ sdk.Msg = (*MsgProxyRecvPacket)(nil), (*MsgProxyAcknowledgePacket)(nil), (*MsgProxyTimeoutPacket)(nil)
)

func NewMsgProxyClientState(
Expand Down Expand Up @@ -291,11 +291,6 @@ func (msg MsgProxyConnectionOpenFinalize) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{accAddr}
}

// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (msg MsgProxyConnectionOpenFinalize) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
return nil
}

// ValidateBasic implements sdk.Msg
func (msg MsgProxyChannelOpenTry) ValidateBasic() error {
return nil
Expand Down Expand Up @@ -371,6 +366,7 @@ func (msg MsgProxyAcknowledgePacket) ValidateBasic() error {
return nil
}

// GetSigners implements sdk.Msg
func (msg MsgProxyAcknowledgePacket) GetSigners() []sdk.AccAddress {
accAddr, err := sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
Expand All @@ -379,6 +375,20 @@ func (msg MsgProxyAcknowledgePacket) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{accAddr}
}

// ValidateBasic implements sdk.Msg
func (msg MsgProxyTimeoutPacket) ValidateBasic() error {
return nil
}

// GetSigners implements sdk.Msg
func (msg MsgProxyTimeoutPacket) GetSigners() []sdk.AccAddress {
accAddr, err := sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
panic(err)
}
return []sdk.AccAddress{accAddr}
}

func mustPackClientState(clientState exported.ClientState) *codectypes.Any {
anyClient, err := clienttypes.PackClientState(clientState)
if err != nil {
Expand Down
Loading