Skip to content

Commit

Permalink
feat(e2e): verify membership test passing
Browse files Browse the repository at this point in the history
  • Loading branch information
srdtrk committed Jun 10, 2024
1 parent 22eae6e commit e0f1db2
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 45 deletions.
1 change: 1 addition & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
# List your tests here
- TestWithICS07TendermintTestSuite/TestInstantiate
- TestWithICS07TendermintTestSuite/TestUpdateClient
- TestWithICS07TendermintTestSuite/TestVerifyMembership
name: ${{ matrix.test }}
runs-on: ubuntu-latest
steps:
Expand Down
21 changes: 10 additions & 11 deletions e2e/interchaintestv8/chainconfig/chain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ var DefaultChainSpecs = []*interchaintest.ChainSpec{
ChainID: "wasmd-1",
Images: []ibc.DockerImage{
{
Repository: "cosmwasm/wasmd", // FOR LOCAL IMAGE USE: Docker Image Name
Version: "v0.51.0", // FOR LOCAL IMAGE USE: Docker Image Tag
Repository: "srdtrk/wasmd", // FOR LOCAL IMAGE USE: Docker Image Name
Version: "v0.51-ibc-go-v8.3", // FOR LOCAL IMAGE USE: Docker Image Tag
UidGid: "1025:1025",
},
},
Expand All @@ -30,26 +30,25 @@ var DefaultChainSpecs = []*interchaintest.ChainSpec{
NoHostMount: false,
},
},
// -- WASMD --
// -- IBC-Go --
{
ChainConfig: ibc.ChainConfig{
Type: "cosmos",
Name: "wasmd-2",
ChainID: "wasmd-2",
Name: "ibc-go-simd",
ChainID: "simd-1",
Images: []ibc.DockerImage{
{
Repository: "cosmwasm/wasmd", // FOR LOCAL IMAGE USE: Docker Image Name
Version: "v0.51.0", // FOR LOCAL IMAGE USE: Docker Image Tag
Repository: "ghcr.io/cosmos/ibc-go-simd", // FOR LOCAL IMAGE USE: Docker Image Name
Version: "v8.3.0", // FOR LOCAL IMAGE USE: Docker Image Tag
UidGid: "1025:1025",
},
},
Bin: "wasmd",
Bech32Prefix: "wasm",
Bin: "simd",
Bech32Prefix: "cosmos",
Denom: "stake",
GasPrices: "0.00stake",
GasAdjustment: 1.3,
EncodingConfig: WasmEncodingConfig(),
ModifyGenesis: defaultModifyGenesis(),
EncodingConfig: CosmosEncodingConfig(),
TrustingPeriod: "508h",
NoHostMount: false,
},
Expand Down
5 changes: 5 additions & 0 deletions e2e/interchaintestv8/chainconfig/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ func WasmEncodingConfig() *sdktestutil.TestEncodingConfig {
return encodingConfig("wasm")
}

// CosmosEncodingConfig returns the global E2E encoding config for simd.
func CosmosEncodingConfig() *sdktestutil.TestEncodingConfig {
return encodingConfig("cosmos")
}

// EncodingConfig returns the global E2E encoding config.
// It includes CosmosSDK, IBC, and Wasm messages
func encodingConfig(bech32Prefix string) *sdktestutil.TestEncodingConfig {
Expand Down
12 changes: 6 additions & 6 deletions e2e/interchaintestv8/e2esuite/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,34 +125,34 @@ func (s *TestSuite) QuerySignedHeader(
}

// QueryProofs queries the proofs from the chain for the given key
func (s *TestSuite) QueryProofs(
func (*TestSuite) QueryProofs(
ctx context.Context, chain *cosmos.CosmosChain,
storeKey string, key []byte, height int64,
) ([]byte, int64, error) {
) ([]byte, []byte, int64, error) {
resp, err := GRPCQuery[cmtservice.ABCIQueryResponse](ctx, chain, &cmtservice.ABCIQueryRequest{
Path: fmt.Sprintf("store/%s/key", storeKey),
Height: height - 1, // Copied from ibc-go test
Data: key,
Prove: true,
})
if err != nil {
return nil, 0, err
return nil, nil, 0, err
}

merkleProof, err := types.ConvertProofs(resp.ProofOps)
if err != nil {
return nil, 0, err
return nil, nil, 0, err
}

proof, err := chain.Config().EncodingConfig.Codec.Marshal(&merkleProof)
if err != nil {
return nil, 0, err
return nil, nil, 0, err
}

// proof height + 1 is returned as the proof created corresponds to the height the proof
// was created in the IAVL tree. Tendermint and subsequently the clients that rely on it
// have heights 1 above the IAVL tree. Thus we return proof height + 1
return proof, resp.Height + 1, nil
return resp.Value, proof, resp.Height + 1, nil
}

func (s *TestSuite) FetchHeader(ctx context.Context, chain *cosmos.CosmosChain) (*cmtservice.Header, error) {
Expand Down
106 changes: 78 additions & 28 deletions e2e/interchaintestv8/ics07tendermint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,24 @@ import (
"fmt"
"testing"

"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/suite"

sdkmath "cosmossdk.io/math"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types"
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint"
ibctesting "github.com/cosmos/ibc-go/v8/testing"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"

"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/testutil"

"github.com/srdtrk/cw-ibc-lite/e2esuite/v8/e2esuite"
"github.com/srdtrk/cw-ibc-lite/e2esuite/v8/testvalues"
"github.com/srdtrk/cw-ibc-lite/e2esuite/v8/types"
"github.com/srdtrk/cw-ibc-lite/e2esuite/v8/types/ics07tendermint"
)
Expand All @@ -44,25 +43,25 @@ type ICS07TendermintTestSuite struct {
func (s *ICS07TendermintTestSuite) SetupSuite(ctx context.Context) {
s.TestSuite.SetupSuite(ctx)

wasmd1, wasmd2 := s.ChainA, s.ChainB
wasmd, simd := s.ChainA, s.ChainB

var codeID string
s.Require().True(s.Run("StoreCode", func() {
// Upload the contract to the chain
proposal, err := types.NewCompressedStoreCodeMsg(ctx, wasmd1, s.UserA, "../../artifacts/cw_ibc_lite_ics07_tendermint.wasm")
proposal, err := types.NewCompressedStoreCodeMsg(ctx, wasmd, s.UserA, "../../artifacts/cw_ibc_lite_ics07_tendermint.wasm")
s.Require().NoError(err)
_, err = s.BroadcastMessages(ctx, wasmd1, s.UserA, 6_000_000, proposal)
_, err = s.BroadcastMessages(ctx, wasmd, s.UserA, 6_000_000, proposal)
s.Require().NoError(err)

codeResp, err := e2esuite.GRPCQuery[wasmtypes.QueryCodesResponse](ctx, wasmd1, &wasmtypes.QueryCodesRequest{})
codeResp, err := e2esuite.GRPCQuery[wasmtypes.QueryCodesResponse](ctx, wasmd, &wasmtypes.QueryCodesRequest{})
s.Require().NoError(err)
s.Require().Len(codeResp.CodeInfos, 1)

codeID = fmt.Sprintf("%d", codeResp.CodeInfos[0].CodeID)
}))

s.Require().True(s.Run("InstantiateContract", func() {
header, err := s.FetchHeader(ctx, wasmd2)
header, err := s.FetchHeader(ctx, simd)
s.Require().NoError(err)

var (
Expand All @@ -80,15 +79,15 @@ func (s *ICS07TendermintTestSuite) SetupSuite(ctx context.Context) {
tmConfig.TrustLevel, tmConfig.TrustingPeriod, tmConfig.UnbondingPeriod, tmConfig.MaxClockDrift,
height, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath,
)
clientStateBz = clienttypes.MustMarshalClientState(wasmd2.Config().EncodingConfig.Codec, clientState)
clientStateBz = clienttypes.MustMarshalClientState(simd.Config().EncodingConfig.Codec, clientState)

consensusState := ibctm.NewConsensusState(header.Time, commitmenttypes.NewMerkleRoot([]byte(ibctm.SentinelRoot)), header.ValidatorsHash)
consensusStateBz = clienttypes.MustMarshalConsensusState(wasmd2.Config().EncodingConfig.Codec, consensusState)
consensusStateBz = clienttypes.MustMarshalConsensusState(simd.Config().EncodingConfig.Codec, consensusState)
}))

// Instantiate the contract using contract helpers.
// This will an error if the instantiate message is invalid.
s.tendermintContract, err = ics07tendermint.Instantiate(ctx, s.UserA.KeyName(), codeID, "", wasmd1, ics07tendermint.InstantiateMsg{
s.tendermintContract, err = ics07tendermint.Instantiate(ctx, s.UserA.KeyName(), codeID, "", wasmd, ics07tendermint.InstantiateMsg{
ClientState: ics07tendermint.ToBinary(clientStateBz),
ConsensusState: ics07tendermint.ToBinary(consensusStateBz),
})
Expand Down Expand Up @@ -133,11 +132,19 @@ func (s *ICS07TendermintTestSuite) TestUpdateClient() {

s.SetupSuite(ctx)

_, wasmd2 := s.ChainA, s.ChainB
_, simd := s.ChainA, s.ChainB

initialHeight := s.trustedHeight

s.Require().NoError(testutil.WaitForBlocks(ctx, 2, simd))

s.UpdateClientContract(ctx, s.tendermintContract, wasmd2)
s.UpdateClientContract(ctx, s.tendermintContract, simd, s.trustedHeight.RevisionHeight+2)

s.Require().True(s.Run("VerifyClientStatus", func() {
// The client should be at a higher height
s.Require().Greater(s.trustedHeight.RevisionHeight, initialHeight.RevisionHeight)
s.Require().Equal(s.trustedHeight.RevisionNumber, initialHeight.RevisionNumber)

statusResp, err := s.tendermintContract.QueryClient().Status(ctx, &ics07tendermint.QueryMsg_Status{})
s.Require().NoError(err)
s.Require().Equal(ibcexported.Active.String(), statusResp.Status)
Expand All @@ -159,32 +166,74 @@ func (s *ICS07TendermintTestSuite) TestVerifyMembership() {

s.SetupSuite(ctx)

_, wasmd2 := s.ChainA, s.ChainB
wasmd, simd := s.ChainA, s.ChainB

// We will verify the balance of s.UserB on wasmd2
// Since we will be testing the same ideas on both the cosmwasm tendermint client and the go client,
// we will first update the go client and then retrieve its height
var (
proofHeight int64
proof []byte
value []byte
merklePath *commitmenttypes.MerklePath
height clienttypes.Height
)
s.Require().True(s.Run("CreateBankProof", func() {
key, err := types.GetBankBalanceKey(s.UserB.Address(), wasmd2.Config().Denom)
s.Require().True(s.Run("UpdateGoAndContractClient", func() {
s.Require().NoError(s.Relayer.StopRelayer(ctx, s.ExecRep))
s.Require().NoError(s.Relayer.UpdateClients(ctx, s.ExecRep, s.PathName))

stateResp, err := e2esuite.GRPCQuery[clienttypes.QueryClientStateResponse](ctx, wasmd, &clienttypes.QueryClientStateRequest{
ClientId: ibctesting.FirstClientID,
})
s.Require().NoError(err)
value, err = banktypes.BalanceValueCodec.Encode(sdkmath.NewInt(testvalues.StartingTokenAmount))

state := &ibctm.ClientState{}
err = proto.Unmarshal(stateResp.ClientState.Value, state)
s.Require().NoError(err)

merklePath, err = types.ConvertToMerklePath([]byte(banktypes.StoreKey), key)
height = state.LatestHeight

s.UpdateClientContract(ctx, s.tendermintContract, simd, height.RevisionHeight)
}))

// We will verify the client state of s.UserB on simd
var (
proofHeight int64
proof []byte
value []byte
merklePath commitmenttypes.MerklePath
)
s.Require().True(s.Run("CreateClientStateProof", func() {
var err error
key := host.FullClientStateKey(ibctesting.FirstClientID)
merklePath = commitmenttypes.NewMerklePath(string(key))
merklePath, err = commitmenttypes.ApplyPrefix(commitmenttypes.NewMerklePrefix([]byte(ibcexported.StoreKey)), merklePath)
s.Require().NoError(err)

// Create a proof for the balance of s.UserB on wasmd2
proof, proofHeight, err = s.QueryProofs(ctx, wasmd2, banktypes.StoreKey, key, int64(s.trustedHeight.RevisionHeight))
// Create a proof for the client state
value, proof, proofHeight, err = s.QueryProofs(ctx, simd, ibcexported.StoreKey, key, int64(s.trustedHeight.RevisionHeight))
s.Require().NoError(err)
s.Require().NotEmpty(proof)
s.Require().NotEmpty(value)
// s.Require().Equal(expValue, value)
s.Require().Equal(int64(s.trustedHeight.RevisionHeight), proofHeight)
}))

s.Require().True(s.Run("VerifyMembership", func() {
// TODO: investigate why the go client is not accepting the proof but the contract is accepting it...

// we first query the go client to verify the membership
// This way, we know that the query parameters are correct
// clientResp, err := e2esuite.GRPCQuery[clienttypes.QueryVerifyMembershipResponse](ctx, wasmd, &clienttypes.QueryVerifyMembershipRequest{
// ClientId: ibctesting.FirstClientID,
// Proof: proof,
// ProofHeight: clienttypes.Height{
// RevisionNumber: s.trustedHeight.RevisionNumber,
// RevisionHeight: uint64(proofHeight),
// },
// MerklePath: merklePath,
// Value: value,
// TimeDelay: 0,
// BlockDelay: 0,
// })
// s.Require().NoError(err)
// s.Require().True(clientResp.Success)

_, err := s.tendermintContract.QueryClient().VerifyMembership(ctx, &ics07tendermint.QueryMsg_VerifyMembership{
DelayBlockPeriod: 0,
DelayTimePeriod: 0,
Expand All @@ -204,8 +253,9 @@ func (s *ICS07TendermintTestSuite) TestVerifyMembership() {
}))
}

func (s *ICS07TendermintTestSuite) UpdateClientContract(ctx context.Context, tmContract *ics07tendermint.Contract, counterpartyChain *cosmos.CosmosChain) {
signedHeader, err := s.QuerySignedHeader(ctx, counterpartyChain, s.trustedHeight)
func (s *ICS07TendermintTestSuite) UpdateClientContract(ctx context.Context, tmContract *ics07tendermint.Contract, counterpartyChain *cosmos.CosmosChain, height uint64) {
newHeight := clienttypes.NewHeight(s.trustedHeight.RevisionNumber, height)
signedHeader, err := s.QuerySignedHeader(ctx, counterpartyChain, newHeight)
s.Require().NoError(err)

anyHeader, err := codectypes.NewAnyWithValue(signedHeader)
Expand Down

0 comments on commit e0f1db2

Please sign in to comment.