From a548019459ac42abc18a8588225209411f1c28c0 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 17 Jan 2024 09:22:28 +0900 Subject: [PATCH] add `ProveHostConsensusState` to StateProver interface Signed-off-by: Jun Kimura --- chains/tendermint/prover.go | 6 ++++++ core/connection.go | 28 ++++++++++++++++++++++------ core/pathEnd.go | 2 ++ core/provers.go | 5 +++++ provers/mock/prover.go | 5 +++++ 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/chains/tendermint/prover.go b/chains/tendermint/prover.go index 30904770..a289d6d7 100644 --- a/chains/tendermint/prover.go +++ b/chains/tendermint/prover.go @@ -54,6 +54,12 @@ func (pr *Prover) ProveState(ctx core.QueryContext, path string, value []byte) ( } } +// ProveHostConsensusState returns the existence proof of the consensus state at `height` +// ibc-go doesn't use this proof, so it returns nil +func (pr *Prover) ProveHostConsensusState(ctx core.QueryContext, height ibcexported.Height, consensusState ibcexported.ConsensusState) ([]byte, error) { + return nil, nil +} + /* LightClient implementation */ // CreateInitialLightClientState creates a pair of ClientState and ConsensusState submitted to the counterparty chain as MsgCreateClient diff --git a/core/connection.go b/core/connection.go index e2732435..ab4c0878 100644 --- a/core/connection.go +++ b/core/connection.go @@ -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) @@ -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 { @@ -160,7 +176,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().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) @@ -168,7 +184,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().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: @@ -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: @@ -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: diff --git a/core/pathEnd.go b/core/pathEnd.go index c8e9033d..f786bea2 100644 --- a/core/pathEnd.go +++ b/core/pathEnd.go @@ -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) @@ -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) } diff --git a/core/provers.go b/core/provers.go index 7f584883..f4e0bf8b 100644 --- a/core/provers.go +++ b/core/provers.go @@ -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 diff --git a/provers/mock/prover.go b/provers/mock/prover.go index ee53bf95..6ce35b7f 100644 --- a/provers/mock/prover.go +++ b/provers/mock/prover.go @@ -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[:]