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 dc54ff2
Show file tree
Hide file tree
Showing 23 changed files with 430 additions and 213 deletions.
4 changes: 2 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,15 +391,15 @@ func NewTerraApp(
wasmtypes.WasmMsgParserRouteStaking: stakingwasm.NewWasmMsgParser(),
wasmtypes.WasmMsgParserRouteMarket: marketwasm.NewWasmMsgParser(),
wasmtypes.WasmMsgParserRouteWasm: wasmkeeper.NewWasmMsgParser(),
})
}, wasmkeeper.NewStargateWasmMsgParser(appCodec))
app.WasmKeeper.RegisterQueriers(map[string]wasmtypes.WasmQuerierInterface{
wasmtypes.WasmQueryRouteBank: bankwasm.NewWasmQuerier(app.BankKeeper),
wasmtypes.WasmQueryRouteStaking: stakingwasm.NewWasmQuerier(app.StakingKeeper, app.DistrKeeper),
wasmtypes.WasmQueryRouteMarket: marketwasm.NewWasmQuerier(app.MarketKeeper),
wasmtypes.WasmQueryRouteOracle: oraclewasm.NewWasmQuerier(app.OracleKeeper),
wasmtypes.WasmQueryRouteTreasury: treasurywasm.NewWasmQuerier(app.TreasuryKeeper),
wasmtypes.WasmQueryRouteWasm: wasmkeeper.NewWasmQuerier(app.WasmKeeper),
})
}, wasmkeeper.NewStargateWasmQuerier(app.WasmKeeper))

// register the proposal types
govRouter := govtypes.NewRouter()
Expand Down
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
28 changes: 21 additions & 7 deletions x/wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type Keeper struct {
router sdk.Router
queryRouter types.GRPCQueryRouter

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

Expand All @@ -56,7 +56,7 @@ func NewKeeper(
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 @@ -76,7 +76,7 @@ func NewKeeper(
storeKey: storeKey,
cdc: cdc,
paramSpace: paramspace,
wasmer: wasmer,
wasmVM: wasmVM,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
treasuryKeeper: treasuryKeeper,
Expand Down Expand Up @@ -210,7 +210,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 +219,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
}
}
6 changes: 3 additions & 3 deletions x/wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestCodeInfo(t *testing.T) {
ctx, keeper := input.Ctx, input.WasmKeeper

codeID := uint64(1)
creatorAddr := addrFromUint64(codeID)
_, _, creatorAddr := keyPubAddr()
expected := types.NewCodeInfo(codeID, []byte{1, 2, 3}, creatorAddr)
keeper.SetCodeInfo(ctx, 1, expected)

Expand All @@ -37,8 +37,8 @@ func TestContractInfo(t *testing.T) {

codeID := uint64(1)
instanceID := uint64(1)
creatorAddr := addrFromUint64(codeID)
contractAddr := keeper.generateContractAddress(ctx, codeID, instanceID)
_, _, creatorAddr := keyPubAddr()
contractAddr := types.GenerateContractAddress(codeID, instanceID)

initMsg := HackatomExampleInitMsg{
Verifier: alice,
Expand Down
Loading

0 comments on commit dc54ff2

Please sign in to comment.