Skip to content

Commit

Permalink
feat: CosmWasm 1.0.0-beta implementation (#720)
Browse files Browse the repository at this point in the history
## Description

Closes: #115. 

This PR integrate the CosmWasm module into Desmos.
At the current stage, no rules are applied to the smart contracts store/instantiate flow and any kind of contract can
be deployed on the network if we will update the testnet as it is.
I think that for testing purposes this is the best choice, however, I will work on an ADR for permissioned contracts and contracts limitations soon. Since Desmos is a social network related project, contracts deployment should be limited to contracts that are social-related.

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting))
- [x] provided a link to the relevant issue or specification
- [x] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [ ] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing)
- [x] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
leobragaz committed Jan 18, 2022
1 parent 23cb923 commit 76c0eaf
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: feat
module: none
pull_request: 720
description: Added CosmWasm module
backward_compatible: true
date: 2022-01-11T13:51:01.548936Z
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-arch: [ "amd64", "arm", "arm64" ]
go-arch: [ "amd64" ]
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
Expand Down
13 changes: 8 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,24 @@
#
# To exit the bash, just execute
# > exit
FROM golang:1.15-alpine AS build-env
FROM golang:1.17.3-alpine AS build-env

# Set up dependencies
ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3
RUN apk add --no-cache $PACKAGES
ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 ca-certificates build-base
RUN set -eux; apk add --no-cache $PACKAGES;

# Set working directory for the build
WORKDIR /go/src/github.com/desmos-labs/desmos

# Add source files
COPY . .

# Install Desmos, remove packages
RUN make build-linux
# See https://github.com/CosmWasm/wasmvm/releases
ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0-beta5/libwasmvm_muslc.a /lib/libwasmvm_muslc.a
RUN sha256sum /lib/libwasmvm_muslc.a | grep d16a2cab22c75dbe8af32265b9346c6266070bdcf9ed5aa9b7b39a7e32e25fe0

# force it to use static lib (from above) not standard libgo_cosmwasm.so file
RUN LEDGER_ENABLED=false BUILD_TAGS=muslc make build-linux

# Final image
FROM alpine:edge
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ ifeq ($(LEDGER_ENABLED),true)
endif
endif

# These lines here are essential to include the muslc library for static linking of libraries
# (which is needed for the wasmvm one) available during the build. Without them, the build will fail.
build_tags += $(BUILD_TAGS)
build_tags := $(strip $(build_tags))

whitespace :=
whitespace += $(whitespace)
comma := ,
Expand Down
9 changes: 8 additions & 1 deletion app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/ante"
channelkeeper "github.com/cosmos/ibc-go/v2/modules/core/04-channel/keeper"
ibcante "github.com/cosmos/ibc-go/v2/modules/core/ante"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
)

// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions

IBCChannelkeeper channelkeeper.Keeper
IBCChannelkeeper channelkeeper.Keeper
TxCounterStoreKey sdk.StoreKey
WasmConfig wasmTypes.WasmConfig
}

func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
Expand All @@ -34,6 +39,8 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {

anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(),
wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit),
wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey),
ante.NewRejectExtensionOptionsDecorator(),
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
Expand Down
138 changes: 123 additions & 15 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"os"
"path/filepath"
"strings"

"github.com/cosmos/cosmos-sdk/version"

Expand All @@ -16,6 +17,7 @@ import (
ibcclient "github.com/cosmos/ibc-go/v2/modules/core/02-client"

"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
"github.com/prometheus/client_golang/prometheus"

servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/spf13/cast"
Expand Down Expand Up @@ -111,6 +113,10 @@ import (

authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"

"github.com/CosmWasm/wasmd/x/wasm"
wasmclient "github.com/CosmWasm/wasmd/x/wasm/client"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
)

const (
Expand All @@ -121,6 +127,50 @@ const (
FullFundraiserPath = "44'/852'/0'/0/0"
)

var (
// If EnabledSpecificProposals is "", and this is "true", then enable all x/wasm proposals.
// If EnabledSpecificProposals is "", and this is not "true", then disable all x/wasm proposals.

ProposalsEnabled = "false"

// If set to non-empty string it must be comma-separated list of values that are all a subset
// of "EnableAllProposals" (takes precedence over ProposalsEnabled)
// https://github.com/CosmWasm/wasmd/blob/02a54d33ff2c064f3539ae12d75d027d9c665f05/x/wasm/internal/types/proposal.go#L28-L34

EnableSpecificProposals = ""
)

// GetEnabledProposals parses the ProposalsEnabled / EnableSpecificProposals values to
// produce a list of enabled proposals to pass into desmos app.
func GetEnabledProposals() []wasm.ProposalType {
if EnableSpecificProposals == "" {
if ProposalsEnabled == "true" {
return wasm.EnableAllProposals
}
return wasm.DisableAllProposals
}
chunks := strings.Split(EnableSpecificProposals, ",")
proposals, err := wasm.ConvertToProposals(chunks)
if err != nil {
panic(err)
}
return proposals
}

// GetWasmOpts parses appOpts and add wasm opt to the given options array.
// if telemetry is enabled, the wasmVM cache metrics are activated.
func GetWasmOpts(appOpts servertypes.AppOptions) []wasm.Option {
var wasmOpts []wasm.Option
if cast.ToBool(appOpts.Get("telemetry.enabled")) {
wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer))
}

// add any custom opts under here
// wasmOpts = append(wasmOpts, wasmkeeper.With...)

return wasmOpts
}

var (
// DefaultNodeHome sets the folder where the application data and configuration will be stored
DefaultNodeHome string
Expand All @@ -135,12 +185,15 @@ var (
mint.AppModuleBasic{},
distr.AppModuleBasic{},
gov.NewAppModuleBasic(
paramsclient.ProposalHandler,
distrclient.ProposalHandler,
upgradeclient.ProposalHandler,
upgradeclient.CancelProposalHandler,
ibcclientclient.UpdateClientProposalHandler,
ibcclientclient.UpgradeProposalHandler,
append(
wasmclient.ProposalHandlers,
paramsclient.ProposalHandler,
distrclient.ProposalHandler,
upgradeclient.ProposalHandler,
upgradeclient.CancelProposalHandler,
ibcclientclient.UpdateClientProposalHandler,
ibcclientclient.UpgradeProposalHandler,
)...,
),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
Expand All @@ -152,6 +205,7 @@ var (
ibctransfer.AppModuleBasic{},
authzmodule.AppModuleBasic{},
vesting.AppModuleBasic{},
wasm.AppModuleBasic{},

// Custom modules
profiles.AppModuleBasic{},
Expand All @@ -166,6 +220,7 @@ var (
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
govtypes.ModuleName: {authtypes.Burner},
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
wasm.ModuleName: {authtypes.Burner},
}
)

Expand Down Expand Up @@ -204,11 +259,13 @@ type DesmosApp struct {
EvidenceKeeper evidencekeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
WasmKeeper wasm.Keeper

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedIBCTransferKeeper capabilitykeeper.ScopedKeeper
ScopedProfilesKeeper capabilitykeeper.ScopedKeeper
ScopedWasmKeeper capabilitykeeper.ScopedKeeper

// Custom modules
ProfileKeeper profileskeeper.Keeper
Expand Down Expand Up @@ -255,7 +312,7 @@ func NewDesmosApp(
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
authzkeeper.StoreKey,
authzkeeper.StoreKey, wasm.StoreKey,

// Custom modules
profilestypes.StoreKey,
Expand Down Expand Up @@ -285,6 +342,7 @@ func NewDesmosApp(
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
scopedIBCTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
scopedProfilesKeeper := app.CapabilityKeeper.ScopeToModule(profilestypes.ModuleName)
scopedWasmKeeper := app.CapabilityKeeper.ScopeToModule(wasm.ModuleName)

// seal capability keeper after scoping modules
app.CapabilityKeeper.Seal()
Expand Down Expand Up @@ -339,11 +397,6 @@ func NewDesmosApp(
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))

app.GovKeeper = govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter,
)

// Create Transfer Keepers
app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
Expand All @@ -368,7 +421,6 @@ func NewDesmosApp(
ibcRouter := porttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule)
ibcRouter.AddRoute(profilestypes.ModuleName, profilesModule)
app.IBCKeeper.SetRouter(ibcRouter)

// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
Expand All @@ -377,6 +429,56 @@ func NewDesmosApp(
// If evidence needs to be handled for the app, set routes in router here and seal
app.EvidenceKeeper = *evidenceKeeper

// ------ CosmWasm setup ------

// var wasmRouter = bApp.Router()
wasmDir := filepath.Join(homePath, "wasm")

wasmConfig, err := wasm.ReadWasmConfig(appOpts)
if err != nil {
panic("error while reading wasm config: " + err.Error())
}

supportedFeatures := "iterator,staking,stargate"
wasmOpts := GetWasmOpts(appOpts)

// The last arguments can contain custom message handlers, and custom query handlers,
// if we want to allow any custom callbacks
app.WasmKeeper = wasmkeeper.NewKeeper(
appCodec,
keys[wasm.StoreKey],
app.GetSubspace(wasm.ModuleName),
app.AccountKeeper,
app.BankKeeper,
app.StakingKeeper,
app.DistrKeeper,
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
scopedWasmKeeper,
app.TransferKeeper,
app.MsgServiceRouter(),
app.GRPCQueryRouter(),
wasmDir,
wasmConfig,
supportedFeatures,
wasmOpts...,
)

// The gov proposal types can be individually enabled
enabledWasmProposals := GetEnabledProposals()
if len(enabledWasmProposals) != 0 {
govRouter.AddRoute(wasm.RouterKey, wasm.NewWasmProposalHandler(app.WasmKeeper, enabledWasmProposals))
}

app.GovKeeper = govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter,
)

// Add wasm module route to the ibc router, then set and seal it
ibcRouter.AddRoute(wasm.ModuleName, wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper))
app.IBCKeeper.SetRouter(ibcRouter)

/**** Module Options ****/

// NOTE: we may consider parsing `appOpts` inside module constructors. For the moment
Expand Down Expand Up @@ -408,6 +510,7 @@ func NewDesmosApp(
params.NewAppModule(app.ParamsKeeper),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
transferModule,
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper),

// Custom modules
profilesModule,
Expand All @@ -434,7 +537,7 @@ func NewDesmosApp(
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName,
ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName,
feegrant.ModuleName,
feegrant.ModuleName, wasm.ModuleName,

// Custom modules
profilestypes.ModuleName,
Expand Down Expand Up @@ -469,6 +572,7 @@ func NewDesmosApp(
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
ibc.NewAppModule(app.IBCKeeper),
transferModule,
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper),

// Custom modules
profiles.NewAppModule(app.appCodec, legacyAmino, app.ProfileKeeper, app.AccountKeeper, app.BankKeeper),
Expand All @@ -493,7 +597,9 @@ func NewDesmosApp(
FeegrantKeeper: app.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
IBCChannelkeeper: app.IBCKeeper.ChannelKeeper,
IBCChannelkeeper: app.IBCKeeper.ChannelKeeper,
TxCounterStoreKey: keys[wasm.StoreKey],
WasmConfig: wasmConfig,
},
)
if err != nil {
Expand All @@ -512,6 +618,7 @@ func NewDesmosApp(
app.ScopedIBCKeeper = scopedIBCKeeper
app.ScopedIBCTransferKeeper = scopedIBCTransferKeeper
app.ScopedProfilesKeeper = scopedProfilesKeeper
app.ScopedWasmKeeper = scopedWasmKeeper

return app
}
Expand Down Expand Up @@ -711,6 +818,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibchost.ModuleName)
paramsKeeper.Subspace(wasm.ModuleName)

paramsKeeper.Subspace(profilestypes.ModuleName)

Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module github.com/desmos-labs/desmos/v2
go 1.15

require (
github.com/CosmWasm/wasmd v0.21.1-0.20220105132732-3d2affb31f82
github.com/CosmWasm/wasmvm v1.0.0-beta5
github.com/armon/go-metrics v0.3.10
github.com/btcsuite/btcd v0.22.0-beta
github.com/cosmos/cosmos-sdk v0.44.5
Expand All @@ -16,6 +18,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/manifoldco/promptui v0.9.0
github.com/mr-tron/base58 v1.2.0
github.com/prometheus/client_golang v1.11.0
github.com/rakyll/statik v0.1.7
github.com/regen-network/cosmos-proto v0.3.1
github.com/spf13/cast v1.4.1
Expand All @@ -24,7 +27,7 @@ require (
github.com/tendermint/tendermint v0.34.15
github.com/tendermint/tm-db v0.6.6
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
google.golang.org/grpc v1.42.0
google.golang.org/grpc v1.43.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0
)
Expand Down
Loading

0 comments on commit 76c0eaf

Please sign in to comment.