Skip to content

Commit

Permalink
Update binding interface to reject IBC and Burn message
Browse files Browse the repository at this point in the history
  • Loading branch information
yun-yeo committed Apr 22, 2021
1 parent 323aa49 commit 2bf62e6
Show file tree
Hide file tree
Showing 24 changed files with 644 additions and 225 deletions.
1 change: 1 addition & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2197,6 +2197,7 @@ ContractInfo stores a WASM contract instance
| `code_id` | [uint64](#uint64) | | CodeID is the reference to the stored Wasm code |
| `init_msg` | [bytes](#bytes) | | InitMsg is the raw message used when instantiating a contract |
| `migratable` | [bool](#bool) | | Migratable is the flag to specify the contract migratability |
| `ibc_port_id` | [string](#string) | | IBCPortID is the ID used in ibc communication |



Expand Down
2 changes: 2 additions & 0 deletions proto/terra/wasm/v1beta1/wasm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@ message ContractInfo {
bytes init_msg = 4 [(gogoproto.moretags) = "yaml:\"init_msg\"", (gogoproto.casttype) = "encoding/json.RawMessage"];
// Migratable is the flag to specify the contract migratability
bool migratable = 5 [(gogoproto.moretags) = "yaml:\"migratable\""];
// IBCPortID is the ID used in ibc communication
string ibc_port_id = 6 [(gogoproto.moretags) = "yaml:\"ibc_port_id\"", (gogoproto.customname) = "IBCPortID"];
}
84 changes: 27 additions & 57 deletions x/wasm/keeper/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,62 +103,11 @@ func (k Keeper) dispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, m
return nil
}

// dispatchMessage does not emit events to prevent duplicate emission
func (k Keeper) dispatchMessage(ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data []byte, err error) {
sdkMsg, err := k.msgParser.Parse(contractAddr, msg)
if err != nil {
return nil, nil, err
}

// Charge tax on result msg
taxes := ante.FilterMsgAndComputeTax(ctx, k.treasuryKeeper, sdkMsg)
if !taxes.IsZero() {
contractAcc := k.accountKeeper.GetAccount(ctx, contractAddr)
if err := cosmosante.DeductFees(k.bankKeeper, ctx, contractAcc, taxes); err != nil {
return nil, nil, err
}
}

res, err := k.handleSdkMessage(ctx, contractAddr, sdkMsg)
if err != nil {
return nil, nil, err
}

// set data
data = make([]byte, len(res.Data))
copy(data, res.Data)

// convert Tendermint.Events to sdk.Event
sdkEvents := make([]sdk.Event, len(res.Events))
for i := range res.Events {
sdkEvents[i] = sdk.Event(res.Events[i])
}

// append events
events = append(events, sdkEvents...)

return
}

// dispatchMessageWithGasLimit does not emit events to prevent duplicate emission
func (k Keeper) dispatchMessageWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.CosmosMsg, gasLimit uint64) (events []sdk.Event, data []byte, err error) {
limitedMeter := sdk.NewGasMeter(gasLimit)
subCtx := ctx.WithGasMeter(limitedMeter)

sdkMsg, err := k.msgParser.Parse(contractAddr, msg)
if err != nil {
return nil, nil, err
}

// Charge tax on result msg
taxes := ante.FilterMsgAndComputeTax(subCtx, k.treasuryKeeper, sdkMsg)
if !taxes.IsZero() {
contractAcc := k.accountKeeper.GetAccount(subCtx, contractAddr)
if err := cosmosante.DeductFees(k.bankKeeper, subCtx, contractAcc, taxes); err != nil {
return nil, nil, err
}
}

// catch out of gas panic and just charge the entire gas limit
defer func() {
if r := recover(); r != nil {
Expand All @@ -174,7 +123,32 @@ func (k Keeper) dispatchMessageWithGasLimit(ctx sdk.Context, contractAddr sdk.Ac
}
}()

res, err := k.handleSdkMessage(subCtx, contractAddr, sdkMsg)
events, data, err = k.dispatchMessage(subCtx, contractAddr, msg)

// make sure we charge the parent what was spent
spent := subCtx.GasMeter().GasConsumed()
ctx.GasMeter().ConsumeGas(spent, "From limited Sub-Message")

return events, data, err
}

// dispatchMessage does not emit events to prevent duplicate emission
func (k Keeper) dispatchMessage(ctx sdk.Context, contractAddr sdk.AccAddress, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data []byte, err error) {
sdkMsg, err := k.msgParser.Parse(ctx, contractAddr, msg)
if err != nil {
return nil, nil, err
}

// Charge tax on result msg
taxes := ante.FilterMsgAndComputeTax(ctx, k.treasuryKeeper, sdkMsg)
if !taxes.IsZero() {
contractAcc := k.accountKeeper.GetAccount(ctx, contractAddr)
if err := cosmosante.DeductFees(k.bankKeeper, ctx, contractAcc, taxes); err != nil {
return nil, nil, err
}
}

res, err := k.handleSdkMessage(ctx, contractAddr, sdkMsg)
if err != nil {
return nil, nil, err
}
Expand All @@ -192,11 +166,7 @@ func (k Keeper) dispatchMessageWithGasLimit(ctx sdk.Context, contractAddr sdk.Ac
// append events
events = append(events, sdkEvents...)

// make sure we charge the parent what was spent
spent := subCtx.GasMeter().GasConsumed()
ctx.GasMeter().ConsumeGas(spent, "From limited Sub-Message")

return events, data, err
return
}

func (k Keeper) handleSdkMessage(ctx sdk.Context, contractAddr sdk.AccAddress, msg sdk.Msg) (*sdk.Result, error) {
Expand Down
43 changes: 12 additions & 31 deletions x/wasm/keeper/contract.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package keeper

import (
"encoding/binary"
"time"

"github.com/tendermint/tendermint/crypto"

wasmvmtypes "github.com/CosmWasm/wasmvm/types"

"github.com/terra-project/core/x/wasm/types"
Expand All @@ -32,7 +29,7 @@ func (k Keeper) CompileCode(ctx sdk.Context, wasmCode []byte) (codeHash []byte,
// consume gas for compile cost
ctx.GasMeter().ConsumeGas(types.CompileCostPerByte*uint64(len(wasmCode)), "Compiling WASM Bytes Cost")

codeHash, err = k.wasmer.Create(wasmCode)
codeHash, err = k.wasmVM.Create(wasmCode)
if err != nil {
return nil, sdkerrors.Wrap(types.ErrStoreCodeFailed, err.Error())
}
Expand Down Expand Up @@ -84,7 +81,7 @@ func (k Keeper) InstantiateContract(
instanceID++

// create contract address
contractAddress := k.generateContractAddress(ctx, codeID, instanceID)
contractAddress := types.GenerateContractAddress(codeID, instanceID)
existingAcct := k.accountKeeper.GetAccount(ctx, contractAddress)
if existingAcct != nil {
return nil, nil, sdkerrors.Wrap(types.ErrAccountExists, existingAcct.GetAddress().String())
Expand Down Expand Up @@ -120,14 +117,14 @@ func (k Keeper) InstantiateContract(
contractStore := prefix.NewStore(ctx.KVStore(k.storeKey), contractStoreKey)

// instantiate wasm contract
res, gasUsed, err := k.wasmer.Instantiate(
res, gasUsed, err := k.wasmVM.Instantiate(
codeInfo.CodeHash,
env,
info,
initMsg,
contractStore,
k.getCosmWasmAPI(ctx),
k.querier.WithCtx(ctx),
k.querier.WithCtx(ctx).WithContractAddr(contractAddress),
k.getGasMeter(ctx),
k.getGasRemaining(ctx),
)
Expand Down Expand Up @@ -195,14 +192,14 @@ func (k Keeper) ExecuteContract(

env := types.NewEnv(ctx, contractAddress)
info := types.NewInfo(caller, coins)
res, gasUsed, err := k.wasmer.Execute(
res, gasUsed, err := k.wasmVM.Execute(
codeInfo.CodeHash,
env,
info,
exeMsg,
storePrefix,
k.getCosmWasmAPI(ctx),
k.querier.WithCtx(ctx),
k.querier.WithCtx(ctx).WithContractAddr(contractAddress),
k.getGasMeter(ctx),
k.getGasRemaining(ctx),
)
Expand Down Expand Up @@ -272,13 +269,13 @@ func (k Keeper) MigrateContract(
prefixStoreKey := types.GetContractStoreKey(contractAddress)
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), prefixStoreKey)

res, gasUsed, err := k.wasmer.Migrate(
res, gasUsed, err := k.wasmVM.Migrate(
newCodeInfo.CodeHash,
env,
migrateMsg,
prefixStore,
k.getCosmWasmAPI(ctx),
k.querier.WithCtx(ctx),
k.querier.WithCtx(ctx).WithContractAddr(contractAddress),
k.getGasMeter(ctx),
k.getGasRemaining(ctx),
)
Expand Down Expand Up @@ -333,13 +330,13 @@ func (k Keeper) reply(
reply.Result.Ok.Events = reply.Result.Ok.Events[:eventParams.MaxAttributeNum]
}

res, gasUsed, err := k.wasmer.Reply(
res, gasUsed, err := k.wasmVM.Reply(
codeInfo.CodeHash,
env,
reply,
storePrefix,
k.getCosmWasmAPI(ctx),
k.querier.WithCtx(ctx),
k.querier.WithCtx(ctx).WithContractAddr(contractAddress),
k.getGasMeter(ctx),
k.getGasRemaining(ctx),
)
Expand Down Expand Up @@ -371,22 +368,6 @@ func (k Keeper) reply(
return nil
}

// generates a contract address from codeID + instanceID
// and increases last instanceID
func (k Keeper) generateContractAddress(ctx sdk.Context, codeID uint64, instanceID uint64) sdk.AccAddress {
// NOTE: It is possible to get a duplicate address if either codeID or instanceID
// overflow 32 bits. This is highly improbable, but something that could be refactored.
contractID := codeID<<32 + instanceID
return addrFromUint64(contractID)
}

func addrFromUint64(id uint64) sdk.AccAddress {
addr := make([]byte, 20)
addr[0] = 'C'
binary.PutUvarint(addr[1:], id)
return sdk.AccAddress(crypto.AddressHash(addr))
}

func (k Keeper) queryToStore(ctx sdk.Context, contractAddress sdk.AccAddress, key []byte) []byte {
defer telemetry.MeasureSince(time.Now(), "wasm", "contract", "query-raw")
if key == nil {
Expand All @@ -409,13 +390,13 @@ func (k Keeper) queryToContract(ctx sdk.Context, contractAddress sdk.AccAddress,
}

env := types.NewEnv(ctx, contractAddress)
queryResult, gasUsed, err := k.wasmer.Query(
queryResult, gasUsed, err := k.wasmVM.Query(
codeInfo.CodeHash,
env,
queryMsg,
contractStorePrefix,
k.getCosmWasmAPI(ctx),
k.querier.WithCtx(ctx),
k.querier.WithCtx(ctx).WithContractAddr(contractAddress),
k.getGasMeter(ctx),
k.getGasRemaining(ctx),
)
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/keeper/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func TestExecuteWithNonExistingContractAddress(t *testing.T) {
creator := createFakeFundedAccount(ctx, accKeeper, bankKeeper, deposit.Add(deposit...))

// unauthorized - trialCtx so we don't change state
nonExistingContractAddress := addrFromUint64(9999)
nonExistingContractAddress := types.GenerateContractAddress(9999, 9999)
_, err := keeper.ExecuteContract(ctx, nonExistingContractAddress, creator, []byte(`{}`), nil)
require.Error(t, err, sdkerrors.Wrapf(types.ErrNotFound, "contract %s", nonExistingContractAddress))
}
Expand Down
65 changes: 44 additions & 21 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ type Keeper struct {
cdc codec.BinaryMarshaler
paramSpace paramstypes.Subspace

accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
treasuryKeeper types.TreasuryKeeper
accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
treasuryKeeper types.TreasuryKeeper
portKeeper types.PortKeeper
capabilityKeeper types.CapabilityKeeper
channelKeeper types.ChannelKeeper

router sdk.Router
queryRouter types.GRPCQueryRouter

wasmer types.WasmerEngine
wasmVM types.WasmerEngine
querier types.Querier
msgParser types.MsgParser

Expand All @@ -51,12 +54,15 @@ func NewKeeper(
accountKeeper types.AccountKeeper,
bankKeeper types.BankKeeper,
treasuryKeeper types.TreasuryKeeper,
channelKeeper types.ChannelKeeper,
portKeeper types.PortKeeper,
capabilityKeeper types.CapabilityKeeper,
router sdk.Router,
queryRouter types.GRPCQueryRouter,
supportedFeatures string,
homePath string,
wasmConfig *config.Config) Keeper {
wasmer, err := wasmvm.NewVM(
wasmVM, err := wasmvm.NewVM(
filepath.Join(homePath, config.DBDir),
supportedFeatures,
types.ContractMemoryLimit,
Expand All @@ -73,18 +79,21 @@ func NewKeeper(
}

return Keeper{
storeKey: storeKey,
cdc: cdc,
paramSpace: paramspace,
wasmer: wasmer,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
treasuryKeeper: treasuryKeeper,
router: router,
queryRouter: queryRouter,
wasmConfig: wasmConfig,
msgParser: types.NewModuleMsgParser(),
querier: types.NewModuleQuerier(),
storeKey: storeKey,
cdc: cdc,
paramSpace: paramspace,
wasmVM: wasmVM,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
treasuryKeeper: treasuryKeeper,
portKeeper: portKeeper,
capabilityKeeper: capabilityKeeper,
channelKeeper: channelKeeper,
router: router,
queryRouter: queryRouter,
wasmConfig: wasmConfig,
msgParser: types.NewModuleMsgParser(),
querier: types.NewModuleQuerier(),
}
}

Expand Down Expand Up @@ -210,7 +219,7 @@ func (k Keeper) GetByteCode(ctx sdk.Context, codeID uint64) ([]byte, error) {
return nil, sdkErr
}

byteCode, err := k.wasmer.GetCode(codeInfo.CodeHash)
byteCode, err := k.wasmVM.GetCode(codeInfo.CodeHash)
if err != nil {
return nil, err
}
Expand All @@ -219,15 +228,29 @@ func (k Keeper) GetByteCode(ctx sdk.Context, codeID uint64) ([]byte, error) {
}

// RegisterMsgParsers register module msg parsers
func (k *Keeper) RegisterMsgParsers(parsers map[string]types.WasmMsgParserInterface) {
func (k *Keeper) RegisterMsgParsers(
parsers map[string]types.WasmMsgParserInterface,
stargateWasmMsgParser types.StargateWasmMsgParserInterface,
) {
for route, parser := range parsers {
k.msgParser[route] = parser
k.msgParser.Parsers[route] = parser
}

if stargateWasmMsgParser != nil {
k.msgParser.StargateParser = stargateWasmMsgParser
}
}

// RegisterQueriers register module queriers
func (k *Keeper) RegisterQueriers(queriers map[string]types.WasmQuerierInterface) {
func (k *Keeper) RegisterQueriers(
queriers map[string]types.WasmQuerierInterface,
stargateWasmQuerier types.StargateWasmQuerierInterface,
) {
for route, querier := range queriers {
k.querier.Queriers[route] = querier
}

if stargateWasmQuerier != nil {
k.querier.StargateQuerier = stargateWasmQuerier
}
}
Loading

0 comments on commit 2bf62e6

Please sign in to comment.