Skip to content

Commit

Permalink
add ProveHostConsensusState to StateProver interface
Browse files Browse the repository at this point in the history
Signed-off-by: Jun Kimura <[email protected]>
  • Loading branch information
bluele committed Jan 17, 2024
1 parent c226f1b commit 5a9539b
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
5 changes: 5 additions & 0 deletions chains/tendermint/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func (pr *Prover) ProveState(ctx core.QueryContext, path string, value []byte) (
}
}

// ProveHostConsensusState returns the existen proof of the consensus state at `height`
func (pr *Prover) ProveHostConsensusState(ctx core.QueryContext, height ibcexported.Height, consensusState ibcexported.ConsensusState) ([]byte, error) {
return clienttypes.MarshalConsensusState(pr.chain.Codec(), consensusState)
}

/* LightClient implementation */

// CreateInitialLightClientState creates a pair of ClientState and ConsensusState submitted to the counterparty chain as MsgCreateClient
Expand Down
28 changes: 22 additions & 6 deletions core/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,10 @@ func createConnectionStep(src, dst *ProvableChain) (*RelayMsgs, error) {
srcUpdateHeaders, dstUpdateHeaders []Header
srcCsRes, dstCsRes *clienttypes.QueryClientStateResponse
srcCS, dstCS ibcexported.ClientState
srcCons, dstCons *clienttypes.QueryConsensusStateResponse
srcConsRes, dstConsRes *clienttypes.QueryConsensusStateResponse
srcCons, dstCons ibcexported.ConsensusState
srcConsH, dstConsH ibcexported.Height
srcHostConsProof, dstHostConsProof []byte
)
err = retry.Do(func() error {
srcUpdateHeaders, dstUpdateHeaders, err = sh.SetupBothHeadersForUpdate(src, dst)
Expand Down Expand Up @@ -136,12 +138,26 @@ func createConnectionStep(src, dst *ProvableChain) (*RelayMsgs, error) {

// Store the heights
srcConsH, dstConsH = srcCS.GetLatestHeight(), dstCS.GetLatestHeight()
srcCons, dstCons, err = QueryClientConsensusStatePair(
srcConsRes, dstConsRes, err = QueryClientConsensusStatePair(
sh.GetQueryContext(src.ChainID()), sh.GetQueryContext(dst.ChainID()),
src, dst, srcConsH, dstConsH, true)
if err != nil {
return nil, err
}
if err := src.Codec().UnpackAny(srcConsRes.ConsensusState, &srcCons); err != nil {
return nil, err
}
if err := dst.Codec().UnpackAny(dstConsRes.ConsensusState, &dstCons); err != nil {
return nil, err
}
srcHostConsProof, err = src.ProveHostConsensusState(sh.GetQueryContext(src.ChainID()), dstCS.GetLatestHeight(), dstCons)
if err != nil {
return nil, err
}
dstHostConsProof, err = dst.ProveHostConsensusState(sh.GetQueryContext(dst.ChainID()), srcCS.GetLatestHeight(), srcCons)
if err != nil {
return nil, err
}
}

switch {
Expand All @@ -160,15 +176,15 @@ func createConnectionStep(src, dst *ProvableChain) (*RelayMsgs, error) {
if len(dstUpdateHeaders) > 0 {
out.Src = append(out.Src, src.Path().UpdateClients(dstUpdateHeaders, addr)...)
}
out.Src = append(out.Src, src.Path().ConnTry(dst.Path(), dstCsRes, dstConn, dstCons, addr))
out.Src = append(out.Src, src.Path().ConnTry(dst.Path(), dstCsRes, dstConn, dstConsRes, srcHostConsProof, addr))
// Handshake has started on src (1 step done), relay `connOpenTry` and `updateClient` on dst
case srcConn.Connection.State == conntypes.INIT && dstConn.Connection.State == conntypes.UNINITIALIZED:
logConnectionStates(dst, src, dstConn, srcConn)
addr := mustGetAddress(dst)
if len(srcUpdateHeaders) > 0 {
out.Dst = append(out.Dst, dst.Path().UpdateClients(srcUpdateHeaders, addr)...)
}
out.Dst = append(out.Dst, dst.Path().ConnTry(src.Path(), srcCsRes, srcConn, srcCons, addr))
out.Dst = append(out.Dst, dst.Path().ConnTry(src.Path(), srcCsRes, srcConn, srcConsRes, dstHostConsProof, addr))

// Handshake has started on src end (2 steps done), relay `connOpenAck` and `updateClient` to dst end
case srcConn.Connection.State == conntypes.TRYOPEN && dstConn.Connection.State == conntypes.INIT:
Expand All @@ -177,7 +193,7 @@ func createConnectionStep(src, dst *ProvableChain) (*RelayMsgs, error) {
if len(srcUpdateHeaders) > 0 {
out.Dst = append(out.Dst, dst.Path().UpdateClients(srcUpdateHeaders, addr)...)
}
out.Dst = append(out.Dst, dst.Path().ConnAck(src.Path(), srcCsRes, srcConn, srcCons, addr))
out.Dst = append(out.Dst, dst.Path().ConnAck(src.Path(), srcCsRes, srcConn, srcConsRes, addr))

// Handshake has started on dst end (2 steps done), relay `connOpenAck` and `updateClient` to src end
case srcConn.Connection.State == conntypes.INIT && dstConn.Connection.State == conntypes.TRYOPEN:
Expand All @@ -186,7 +202,7 @@ func createConnectionStep(src, dst *ProvableChain) (*RelayMsgs, error) {
if len(dstUpdateHeaders) > 0 {
out.Src = append(out.Src, src.Path().UpdateClients(dstUpdateHeaders, addr)...)
}
out.Src = append(out.Src, src.Path().ConnAck(dst.Path(), dstCsRes, dstConn, dstCons, addr))
out.Src = append(out.Src, src.Path().ConnAck(dst.Path(), dstCsRes, dstConn, dstConsRes, addr))

// Handshake has confirmed on dst (3 steps done), relay `connOpenConfirm` and `updateClient` to src end
case srcConn.Connection.State == conntypes.TRYOPEN && dstConn.Connection.State == conntypes.OPEN:
Expand Down
2 changes: 2 additions & 0 deletions core/pathEnd.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (pe *PathEnd) ConnTry(
dstClientState *clienttypes.QueryClientStateResponse,
dstConnState *conntypes.QueryConnectionResponse,
dstConsState *clienttypes.QueryConsensusStateResponse,
hostConsensusStateProof []byte,
signer sdk.AccAddress,
) sdk.Msg {
cs, err := clienttypes.UnpackClientState(dstClientState.ClientState)
Expand All @@ -113,6 +114,7 @@ func (pe *PathEnd) ConnTry(
cs.GetLatestHeight().(clienttypes.Height),
signer.String(),
)
msg.HostConsensusStateProof = hostConsensusStateProof
if err = msg.ValidateBasic(); err != nil {
panic(err)
}
Expand Down
5 changes: 5 additions & 0 deletions core/provers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ type Prover interface {

// StateProver provides a generic way to generate existence proof of IBC states (e.g. ClientState, Connection, PacketCommitment, etc.)
type StateProver interface {
// ProveState returns a proof of an IBC state specified by `path` and `value`
ProveState(ctx QueryContext, path string, value []byte) (proof []byte, proofHeight clienttypes.Height, err error)

// ProveHostConsensusState returns an existence proof of the consensus state at `height`
// This proof would be ignored in ibc-go, but it is required to `getSelfConsensusState` of ibc-solidity.
ProveHostConsensusState(ctx QueryContext, height exported.Height, consensusState exported.ConsensusState) (proof []byte, err error)
}

// LightClient provides functions for creating and updating on-chain light clients on the counterparty chain
Expand Down
5 changes: 5 additions & 0 deletions provers/mock/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ func (pr *Prover) ProveState(ctx core.QueryContext, path string, value []byte) (
return makeProof(value), ctx.Height().(clienttypes.Height), nil
}

// ProveHostConsensusState returns the proof of the consensus state at `height`
func (pr *Prover) ProveHostConsensusState(ctx core.QueryContext, height exported.Height, consensusState exported.ConsensusState) ([]byte, error) {
return clienttypes.MarshalConsensusState(pr.chain.Codec(), consensusState)
}

func makeProof(bz []byte) []byte {
h := sha256.Sum256(bz)
return h[:]
Expand Down

0 comments on commit 5a9539b

Please sign in to comment.