Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Add receiver interface for mailbox (CW abstraction) #89

Merged
merged 5 commits into from
Dec 13, 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
3 changes: 2 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,8 @@ func NewSimApp(
// domain := uint32(12345)
app.IgpKeeper = igpkeeper.NewKeeper(appCodec, keys[igptypes.StoreKey], app.BankKeeper.(bankkeeper.SendKeeper), app.StakingKeeper, "")
app.IsmKeeper = ismkeeper.NewKeeper(appCodec, keys[ismtypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.MailboxKeeper = mailboxkeeper.NewKeeper(appCodec, keys[mailboxtypes.StoreKey], &app.WasmKeeper, &app.IsmKeeper)
app.MailboxKeeper = mailboxkeeper.NewKeeper(appCodec, keys[mailboxtypes.StoreKey], &app.IsmKeeper)
app.MailboxKeeper.AddWasmReceiver(&app.WasmKeeper)
app.AnnounceKeeper = announcekeeper.NewKeeper(appCodec, keys[announcetypes.StoreKey], app.MailboxKeeper)
// app.MailboxKeeper.SetDomain(domain)

Expand Down
9 changes: 8 additions & 1 deletion contracts/interface-test/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{
error::ContractError,
msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg},
state::OWNER,
state::{
OWNER, ISM,
},
execute, queries,
hyperlane_bindings::HyperlaneMsg,
};
Expand All @@ -19,6 +21,7 @@ pub fn instantiate(
_msg: InstantiateMsg,
) -> Result<Response, ContractError> {
OWNER.save(deps.storage, &info.sender)?;
ISM.save(deps.storage, &0)?;

Ok(Response::new()
.add_event(Event::new("hyperlane_init").add_attribute("attr", "value"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: remove attr/value attribute

Expand Down Expand Up @@ -53,6 +56,9 @@ pub fn execute(
ExecuteMsg::ChangeContractOwner { new_owner } => {
execute::change_contract_owner(deps, info, new_owner)
}
ExecuteMsg::SetIsmId { ism_id } => {
execute::set_ism(deps, info, ism_id)
}
}
}

Expand All @@ -61,5 +67,6 @@ pub fn execute(
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::Owner {} => to_binary(&queries::query_owner(deps)?),
QueryMsg::Ism {} => to_binary(&queries::query_ism(deps)?),
}
}
19 changes: 18 additions & 1 deletion contracts/interface-test/src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
error::ContractError,
state::OWNER,
state::{OWNER, ISM},
hyperlane_bindings::HyperlaneMsg,
};
use cosmwasm_std::{Addr, Deps, DepsMut, MessageInfo, Response, CosmosMsg};
Expand Down Expand Up @@ -75,4 +75,21 @@ pub fn check_is_contract_owner(deps: Deps, sender: Addr) -> Result<(), ContractE
} else {
Ok(())
}
}

pub fn set_ism(
deps: DepsMut,
info: MessageInfo,
ism_id: u32,
) -> Result<Response<HyperlaneMsg>, ContractError> {
// Only allow current contract owner to change owner
check_is_contract_owner(deps.as_ref(), info.sender)?;

// update ism id
ISM.save(deps.storage, &ism_id)?;

// return OK
Ok(Response::new()
.add_attribute("action", "set_ism")
.add_attribute("ism_id", ism_id.to_string()))
}
10 changes: 10 additions & 0 deletions contracts/interface-test/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub enum ExecuteMsg {
ChangeContractOwner {
new_owner: String,
},
SetIsmId {
ism_id: u32,
}
}

#[cw_serde]
Expand All @@ -29,9 +32,16 @@ pub enum QueryMsg {
/// Owner returns the owner of the contract. Response: OwnerResponse
#[returns(OwnerResponse)]
Owner {},
#[returns(IsmResponse)]
Ism {},
}

#[cw_serde]
pub struct OwnerResponse {
pub address: String,
}

#[cw_serde]
pub struct IsmResponse {
pub ism_id: u32,
}
9 changes: 7 additions & 2 deletions contracts/interface-test/src/queries.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
msg::OwnerResponse,
state::OWNER,
msg::{IsmResponse, OwnerResponse},
state::{ISM, OWNER},
};
use cosmwasm_std::{Deps, StdResult};

Expand All @@ -9,4 +9,9 @@ pub fn query_owner(deps: Deps) -> StdResult<OwnerResponse> {
Ok(OwnerResponse {
address: owner.to_string(),
})
}

pub fn query_ism(deps: Deps) -> StdResult<IsmResponse> {
let ism = ISM.load(deps.storage)?;
Ok(IsmResponse { ism_id: ism })
}
3 changes: 2 additions & 1 deletion contracts/interface-test/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_std::Addr;
use cw_storage_plus::Item;

pub const OWNER: Item<Addr> = Item::new("owner");
pub const OWNER: Item<Addr> = Item::new("owner");
pub const ISM: Item<u32> = Item::new("ism");
Binary file modified interchaintest/contracts/hyperlane.wasm
Binary file not shown.
50 changes: 47 additions & 3 deletions interchaintest/counterchain/counter_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ import (

"github.com/strangelove-ventures/hyperlane-cosmos/imt"
common "github.com/strangelove-ventures/hyperlane-cosmos/x/common"
ismtypes "github.com/strangelove-ventures/hyperlane-cosmos/x/ism/types"
"github.com/strangelove-ventures/hyperlane-cosmos/x/ism/types/legacy_multisig"
"github.com/strangelove-ventures/hyperlane-cosmos/x/ism/types/merkle_root_multisig"
"github.com/strangelove-ventures/hyperlane-cosmos/x/ism/types/message_id_multisig"
)

const MAX_MESSAGE_BODY_BYTES = 2_000

var (
LEGACY_MULTISIG = "legacy_multisig"
MERKLE_ROOT_MULTISIG = "merkle_root_multisig"
MESSAGE_ID_MULTISIG = "message_id_multisig"
LEGACY_MULTISIG = "LegacyMultiSig"
MERKLE_ROOT_MULTISIG = "MerkleRootMultiSig"
MESSAGE_ID_MULTISIG = "MessageIdMultiSig"
)

type CounterChain struct {
Expand Down Expand Up @@ -113,3 +117,43 @@ func (c *CounterChain) CreateMessage(sender string, originDomain uint32, destDom

return message, proof
}

func (c *CounterChain) VerifyAbstractIsm(ism ismtypes.AbstractIsm) bool {
switch c.IsmType {
case LEGACY_MULTISIG:
lms := ism.(*legacy_multisig.LegacyMultiSig)
if lms.Threshold == uint32(c.ValSet.Threshold) {
for i, val := range c.ValSet.Vals {
if val.Addr != lms.ValidatorPubKeys[i] {
return false
}
}
return true
}

case MESSAGE_ID_MULTISIG:
mims := ism.(*message_id_multisig.MessageIdMultiSig)
if mims.Threshold == uint32(c.ValSet.Threshold) {
for i, val := range c.ValSet.Vals {
if val.Addr != mims.ValidatorPubKeys[i] {
return false
}
}
return true
}

case MERKLE_ROOT_MULTISIG:
mrms := ism.(*merkle_root_multisig.MerkleRootMultiSig)
if mrms.Threshold == uint32(c.ValSet.Threshold) {
for i, val := range c.ValSet.Vals {
if val.Addr != mrms.ValidatorPubKeys[i] {
return false
}
}
return true
}

}

return false
}
14 changes: 14 additions & 0 deletions interchaintest/helpers/cosmwasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package helpers

import (
"context"
"encoding/json"
"testing"

"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
"github.com/stretchr/testify/require"
)

Expand All @@ -17,3 +19,15 @@ func SetupContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain,

return codeId, contractAddr
}

func SetContractsIsm(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, contractAddr string, ismId uint32) {
setIsmMsg := ExecuteMsg{
SetIsmId: &SetIsmId{
IsmId: ismId,
},
}
setIsmMsgBz, err := json.Marshal(setIsmMsg)
require.NoError(t, err)
_, err = chain.ExecuteContract(ctx, user.KeyName(), contractAddr, string(setIsmMsgBz))
require.NoError(t, err)
}
90 changes: 90 additions & 0 deletions interchaintest/helpers/ism.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package helpers
import (
"context"
"fmt"
"strconv"
"testing"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
Expand Down Expand Up @@ -92,6 +94,68 @@ func SetDefaultIsm(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain,
require.NoError(t, err)
}

func CreateCustomIsm(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, keyName string, counterChain *counterchain.CounterChain) uint32 {
var valSet []string
for _, val := range counterChain.ValSet.Vals {
valSet = append(valSet, val.Addr)
}

var ism ismtypes.AbstractIsm
switch counterChain.IsmType {
case counterchain.LEGACY_MULTISIG:
ism = &legacy_multisig.LegacyMultiSig{
Threshold: uint32(counterChain.ValSet.Threshold),
ValidatorPubKeys: valSet,
}
case counterchain.MERKLE_ROOT_MULTISIG:
ism = &merkle_root_multisig.MerkleRootMultiSig{
Threshold: uint32(counterChain.ValSet.Threshold),
ValidatorPubKeys: valSet,
}
case counterchain.MESSAGE_ID_MULTISIG:
ism = &message_id_multisig.MessageIdMultiSig{
Threshold: uint32(counterChain.ValSet.Threshold),
ValidatorPubKeys: valSet,
}
}

msgBz, err := chain.Config().EncodingConfig.Codec.MarshalJSON(ism)
fmt.Println("Msg: ", string(msgBz))
require.NoError(t, err)

cmd := []string{
"simd", "tx", "hyperlane-ism", "create-multisig-ism", counterChain.IsmType,
string(msgBz),
"--node", chain.GetRPCAddress(),
"--home", chain.HomeDir(),
"--chain-id", chain.Config().ChainID,
"--from", keyName,
"--gas", "2500000",
"--gas-adjustment", "2.0",
"--keyring-dir", chain.HomeDir(),
"--keyring-backend", keyring.BackendTest,
"-y",
}
stdout, stderr, err := chain.Exec(ctx, cmd, nil)
require.NoError(t, err)

fmt.Println("CreateCustomIsm stdout: ", string(stdout))
fmt.Println("CreateCustomIsm stderr: ", string(stderr))

err = testutil.WaitForBlocks(ctx, 2, chain)
require.NoError(t, err)

ismTxHash := ParseTxHash(string(stdout))

events, err := GetEvents(chain, ismTxHash)
require.NoError(t, err)
ismId, found := GetEventAttribute(events, ismtypes.EventTypeCreateCustomIsm, ismtypes.AttributeKeyIndex)
require.True(t, found)
ismId32, err := strconv.ParseUint(ismId, 10, 32)
require.NoError(t, err)
return uint32(ismId32)
}

func QueryAllDefaultIsms(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain) *ismtypes.QueryAllDefaultIsmsResponse {
grpcAddress := chain.GetHostGRPCAddress()
conn, err := grpc.Dial(grpcAddress, grpc.WithInsecure())
Expand All @@ -104,3 +168,29 @@ func QueryAllDefaultIsms(t *testing.T, ctx context.Context, chain *cosmos.Cosmos

return res
}

func QueryCustomIsm(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, ismId uint32) *ismtypes.QueryCustomIsmResponse {
grpcAddress := chain.GetHostGRPCAddress()
conn, err := grpc.Dial(grpcAddress, grpc.WithInsecure())
require.NoError(t, err)
defer conn.Close()

queryClient := ismtypes.NewQueryClient(conn)
res, err := queryClient.CustomIsm(ctx, &ismtypes.QueryCustomIsmRequest{IsmId: ismId})
require.NoError(t, err)

return res
}

func QueryAllCustomIsms(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain) *ismtypes.QueryAllCustomIsmsResponse {
grpcAddress := chain.GetHostGRPCAddress()
conn, err := grpc.Dial(grpcAddress, grpc.WithInsecure())
require.NoError(t, err)
defer conn.Close()

queryClient := ismtypes.NewQueryClient(conn)
res, err := queryClient.AllCustomIsms(ctx, &ismtypes.QueryAllCustomIsmsRequest{})
require.NoError(t, err)

return res
}
17 changes: 17 additions & 0 deletions interchaintest/helpers/mailbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
mbtypes "github.com/strangelove-ventures/hyperlane-cosmos/x/mailbox/types"

"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/testutil"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)

// simd tx hyperlane-mailbox process <metadata> <message>
Expand Down Expand Up @@ -246,3 +248,18 @@ func GetMailboxAddress() (string, []byte) {
mailboxAddrBytes, _ := hex.DecodeString(mailboxAddr)
return mailboxAddr, mailboxAddrBytes
}

func QueryRecipientsIsmId(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, recipient string) uint32 {
grpcAddress := chain.GetHostGRPCAddress()
conn, err := grpc.Dial(grpcAddress, grpc.WithInsecure())
require.NoError(t, err)
defer conn.Close()

queryClient := mbtypes.NewQueryClient(conn)
recipientBz, err := sdk.AccAddressFromBech32(recipient)
require.NoError(t, err)
res, err := queryClient.RecipientsIsmId(ctx, &mbtypes.QueryRecipientsIsmIdRequest{Recipient: recipientBz})
require.NoError(t, err)

return res.IsmId
}
5 changes: 5 additions & 0 deletions interchaintest/helpers/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type ExecuteMsg struct {
DispatchMsg *DispatchMsg `json:"dispatch_msg,omitempty"`
ProcessMsg *ProcessMsg `json:"process_msg,omitempty"`
ChangeContractOwner *ChangeContractOwner `json:"change_contract_owner,omitempty"`
SetIsmId *SetIsmId `json:"set_ism_id,omitempty"`
}

type ExecuteRsp struct{}
Expand All @@ -39,3 +40,7 @@ type ProcessMsg struct {
type ChangeContractOwner struct {
NewOwner string `json:"new_owner"`
}

type SetIsmId struct {
IsmId uint32 `json:"ism_id"`
}
Loading
Loading