Skip to content

Commit

Permalink
finalize the antehandler design
Browse files Browse the repository at this point in the history
  • Loading branch information
cgorenflo committed Nov 30, 2023
1 parent b6c05ef commit 97b4516
Show file tree
Hide file tree
Showing 14 changed files with 328 additions and 161 deletions.
35 changes: 4 additions & 31 deletions app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package app

import (
"fmt"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/axelarnetwork/axelar-core/x/ante"
"reflect"
"strings"

Expand Down Expand Up @@ -168,8 +166,10 @@ func initWasmKeeper(encodingConfig axelarParams.EncodingConfig, keys map[string]
// if we want to allow any custom callbacks
wasmOpts = append(wasmOpts, wasmkeeper.WithMessageHandlerDecorator(
func(old wasmkeeper.Messenger) wasmkeeper.Messenger {
return withAnteChecks(
wasm.DefaultEncoders(), // todo add custom encoder
encoders := wasm.DefaultEncoders(encodingConfig.Codec, getKeeper[ibctransferkeeper.Keeper](keepers))
encoders.Custom = nexusKeeper.EncodeRoutingMessage
return withAnteHandlers(
encoders,
initMessageAnteDecorators(encodingConfig, keepers),
wasmkeeper.NewMessageHandlerChain(old, nexusKeeper.NewMessenger(getKeeper[nexusKeeper.Keeper](keepers))))
}))
Expand Down Expand Up @@ -200,33 +200,6 @@ func initWasmKeeper(encodingConfig axelarParams.EncodingConfig, keys map[string]
return &wasmK
}

type Messenger struct {
anteHandle ante.MessageAnteHandler
encoders wasm.MessageEncoders
messenger wasmkeeper.Messenger
}

func (m Messenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
sdkMsgs, err := m.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg)
if err != nil {
return nil, nil, err
}
ctx, err = m.anteHandle(ctx, sdkMsgs, false) //todo: how do I get the simulate boolean?
if err != nil {
return nil, nil, err
}

return m.messenger.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
}

func withAnteChecks(encoders wasmkeeper.MessageEncoders, anteHandler ante.MessageAnteHandler, messenger wasmkeeper.Messenger) wasmkeeper.Messenger {
return Messenger{
encoders: encoders,
anteHandle: anteHandler,
messenger: messenger,
}
}

func initGovernanceKeeper(appCodec codec.Codec, keys map[string]*sdk.KVStoreKey, keepers *keeperCache) *govkeeper.Keeper {
// Add governance proposal hooks
govRouter := govtypes.NewRouter()
Expand Down
38 changes: 38 additions & 0 deletions app/wasm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package app

import (
"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/axelarnetwork/axelar-core/x/ante"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type AnteHandlerMessenger struct {
anteHandle ante.MessageAnteHandler
encoders wasm.MessageEncoders
messenger wasmkeeper.Messenger
}

func (m AnteHandlerMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
sdkMsgs, err := m.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg)
if err != nil {
return nil, nil, err
}

// we can't know if this is a simulation or not at this stage, so we treat it as a regular execution
ctx, err = m.anteHandle(ctx, sdkMsgs, false)
if err != nil {
return nil, nil, err
}

return m.messenger.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
}

func withAnteHandlers(encoders wasmkeeper.MessageEncoders, anteHandler ante.MessageAnteHandler, messenger wasmkeeper.Messenger) wasmkeeper.Messenger {
return AnteHandlerMessenger{
encoders: encoders,
anteHandle: anteHandler,
messenger: messenger,
}
}
1 change: 1 addition & 0 deletions docs/proto/proto-docs.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions proto/axelar/nexus/exported/v1beta1/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@ message WasmMessage {
bytes payload_hash = 5;
bytes source_tx_id = 6 [ (gogoproto.customname) = "SourceTxID" ];
uint64 source_tx_index = 7;
bytes sender = 8 [ (gogoproto.casttype) =
"github.com/cosmos/cosmos-sdk/types.AccAddress" ];
}
31 changes: 20 additions & 11 deletions third_party/proto/cosmwasm/wasm/v1/authz.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ option (gogoproto.goproto_getters_all) = false;
// ContractExecutionAuthorization defines authorization for wasm execute.
// Since: wasmd 0.30
message ContractExecutionAuthorization {
option (cosmos_proto.implements_interface) = "Authorization";
option (cosmos_proto.implements_interface) =
"cosmos.authz.v1beta1.Authorization";

// Grants for contract executions
repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ];
Expand All @@ -21,7 +22,8 @@ message ContractExecutionAuthorization {
// ContractMigrationAuthorization defines authorization for wasm contract
// migration. Since: wasmd 0.30
message ContractMigrationAuthorization {
option (cosmos_proto.implements_interface) = "Authorization";
option (cosmos_proto.implements_interface) =
"cosmos.authz.v1beta1.Authorization";

// Grants for contract migrations
repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ];
Expand All @@ -35,20 +37,22 @@ message ContractGrant {

// Limit defines execution limits that are enforced and updated when the grant
// is applied. When the limit lapsed the grant is removed.
google.protobuf.Any limit = 2
[ (cosmos_proto.accepts_interface) = "ContractAuthzLimitX" ];
google.protobuf.Any limit = 2 [ (cosmos_proto.accepts_interface) =
"cosmwasm.wasm.v1.ContractAuthzLimitX" ];

// Filter define more fine-grained control on the message payload passed
// to the contract in the operation. When no filter applies on execution, the
// operation is prohibited.
google.protobuf.Any filter = 3
[ (cosmos_proto.accepts_interface) = "ContractAuthzFilterX" ];
[ (cosmos_proto.accepts_interface) =
"cosmwasm.wasm.v1.ContractAuthzFilterX" ];
}

// MaxCallsLimit limited number of calls to the contract. No funds transferable.
// Since: wasmd 0.30
message MaxCallsLimit {
option (cosmos_proto.implements_interface) = "ContractAuthzLimitX";
option (cosmos_proto.implements_interface) =
"cosmwasm.wasm.v1.ContractAuthzLimitX";

// Remaining number that is decremented on each execution
uint64 remaining = 1;
Expand All @@ -57,7 +61,8 @@ message MaxCallsLimit {
// MaxFundsLimit defines the maximal amounts that can be sent to the contract.
// Since: wasmd 0.30
message MaxFundsLimit {
option (cosmos_proto.implements_interface) = "ContractAuthzLimitX";
option (cosmos_proto.implements_interface) =
"cosmwasm.wasm.v1.ContractAuthzLimitX";

// Amounts is the maximal amount of tokens transferable to the contract.
repeated cosmos.base.v1beta1.Coin amounts = 1 [
Expand All @@ -70,7 +75,8 @@ message MaxFundsLimit {
// the maximal number of calls executable. Both need to remain >0 to be valid.
// Since: wasmd 0.30
message CombinedLimit {
option (cosmos_proto.implements_interface) = "ContractAuthzLimitX";
option (cosmos_proto.implements_interface) =
"cosmwasm.wasm.v1.ContractAuthzLimitX";

// Remaining number that is decremented on each execution
uint64 calls_remaining = 1;
Expand All @@ -85,14 +91,16 @@ message CombinedLimit {
// message.
// Since: wasmd 0.30
message AllowAllMessagesFilter {
option (cosmos_proto.implements_interface) = "ContractAuthzFilterX";
option (cosmos_proto.implements_interface) =
"cosmwasm.wasm.v1.ContractAuthzFilterX";
}

// AcceptedMessageKeysFilter accept only the specific contract message keys in
// the json object to be executed.
// Since: wasmd 0.30
message AcceptedMessageKeysFilter {
option (cosmos_proto.implements_interface) = "ContractAuthzFilterX";
option (cosmos_proto.implements_interface) =
"cosmwasm.wasm.v1.ContractAuthzFilterX";

// Messages is the list of unique keys
repeated string keys = 1;
Expand All @@ -102,7 +110,8 @@ message AcceptedMessageKeysFilter {
// executed.
// Since: wasmd 0.30
message AcceptedMessagesFilter {
option (cosmos_proto.implements_interface) = "ContractAuthzFilterX";
option (cosmos_proto.implements_interface) =
"cosmwasm.wasm.v1.ContractAuthzFilterX";

// Messages is the list of raw contract messages
repeated bytes messages = 1 [ (gogoproto.casttype) = "RawContractMessage" ];
Expand Down
18 changes: 0 additions & 18 deletions third_party/proto/cosmwasm/wasm/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cosmwasm.wasm.v1;

import "gogoproto/gogo.proto";
import "cosmwasm/wasm/v1/types.proto";
import "cosmwasm/wasm/v1/tx.proto";

option go_package = "github.com/CosmWasm/wasmd/x/wasm/types";

Expand All @@ -20,23 +19,6 @@ message GenesisState {
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "sequences,omitempty"
];
repeated GenMsgs gen_msgs = 5 [
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "gen_msgs,omitempty"
];

// GenMsgs define the messages that can be executed during genesis phase in
// order. The intention is to have more human readable data that is auditable.
message GenMsgs {
// sum is a single message
oneof sum {
MsgStoreCode store_code = 1;
MsgInstantiateContract instantiate_contract = 2;
MsgExecuteContract execute_contract = 3;
// MsgInstantiateContract2 intentionally not supported
// see https://github.com/CosmWasm/wasmd/issues/987
}
}
}

// Code struct encompasses CodeInfo and CodeBytes
Expand Down
6 changes: 6 additions & 0 deletions third_party/proto/cosmwasm/wasm/v1/ibc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ message MsgIBCSend {
bytes data = 6;
}

// MsgIBCSendResponse
message MsgIBCSendResponse {
// Sequence number of the IBC packet sent
uint64 sequence = 1;
}

// MsgIBCCloseChannel port and channel need to be owned by the contract
message MsgIBCCloseChannel {
string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ];
Expand Down
54 changes: 54 additions & 0 deletions third_party/proto/cosmwasm/wasm/v1/proposal.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";
package cosmwasm.wasm.v1;

import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmwasm/wasm/v1/types.proto";

Expand All @@ -12,6 +13,8 @@ option (gogoproto.equal_all) = true;

// StoreCodeProposal gov proposal content type to submit WASM code to the system
message StoreCodeProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand Down Expand Up @@ -39,6 +42,8 @@ message StoreCodeProposal {
// InstantiateContractProposal gov proposal content type to instantiate a
// contract.
message InstantiateContractProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand All @@ -60,8 +65,41 @@ message InstantiateContractProposal {
];
}

// InstantiateContract2Proposal gov proposal content type to instantiate
// contract 2
message InstantiateContract2Proposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
string description = 2;
// RunAs is the address that is passed to the contract's enviroment as sender
string run_as = 3;
// Admin is an optional address that can execute migrations
string admin = 4;
// CodeID is the reference to the stored WASM code
uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ];
// Label is optional metadata to be stored with a constract instance.
string label = 6;
// Msg json encode message to be passed to the contract on instantiation
bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ];
// Funds coins that are transferred to the contract on instantiation
repeated cosmos.base.v1beta1.Coin funds = 8 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
// Salt is an arbitrary value provided by the sender. Size can be 1 to 64.
bytes salt = 9;
// FixMsg include the msg value into the hash for the predictable address.
// Default is false
bool fix_msg = 10;
}

// MigrateContractProposal gov proposal content type to migrate a contract.
message MigrateContractProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand All @@ -78,6 +116,8 @@ message MigrateContractProposal {

// SudoContractProposal gov proposal content type to call sudo on a contract.
message SudoContractProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand All @@ -91,6 +131,8 @@ message SudoContractProposal {
// ExecuteContractProposal gov proposal content type to call execute on a
// contract.
message ExecuteContractProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand All @@ -110,6 +152,8 @@ message ExecuteContractProposal {

// UpdateAdminProposal gov proposal content type to set an admin for a contract.
message UpdateAdminProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand All @@ -123,6 +167,8 @@ message UpdateAdminProposal {
// ClearAdminProposal gov proposal content type to clear the admin of a
// contract.
message ClearAdminProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand All @@ -134,6 +180,8 @@ message ClearAdminProposal {
// PinCodesProposal gov proposal content type to pin a set of code ids in the
// wasmvm cache.
message PinCodesProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ];
// Description is a human readable text
Expand All @@ -148,6 +196,8 @@ message PinCodesProposal {
// UnpinCodesProposal gov proposal content type to unpin a set of code ids in
// the wasmvm cache.
message UnpinCodesProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ];
// Description is a human readable text
Expand All @@ -171,6 +221,8 @@ message AccessConfigUpdate {
// UpdateInstantiateConfigProposal gov proposal content type to update
// instantiate config to a set of code ids.
message UpdateInstantiateConfigProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ];
// Description is a human readable text
Expand All @@ -184,6 +236,8 @@ message UpdateInstantiateConfigProposal {
// StoreAndInstantiateContractProposal gov proposal content type to store
// and instantiate the contract.
message StoreAndInstantiateContractProposal {
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

// Title is a short summary
string title = 1;
// Description is a human readable text
Expand Down
Loading

0 comments on commit 97b4516

Please sign in to comment.