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

Commit

Permalink
Merge pull request #89 from strangelove-ventures/steve/abstractions2
Browse files Browse the repository at this point in the history
Add receiver interface for mailbox (CW abstraction)
  • Loading branch information
misko9 authored Dec 13, 2023
2 parents bb23774 + d72572f commit eab7081
Show file tree
Hide file tree
Showing 49 changed files with 1,276 additions and 196 deletions.
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"))
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

0 comments on commit eab7081

Please sign in to comment.