Skip to content

Commit

Permalink
imp: adding 08-wasm build opts with libwasmvm linking disabled (backp…
Browse files Browse the repository at this point in the history
…ort #5923) (#6548)

* imp: adding 08-wasm build opts with libwasmvm linking disabled (#5923)

* wip: messing with build options for wasm cgo

* chore: mv type assertion to wasm_cgo with build flags

* chore: mv make target to build section

* chore: revert cgo enabled 0 build opt for testing

* chore: rm unneeded file

* update build tag

* linter

* update panic message

* add Codec back

* refactor: adapt build tags to match wasmvm

* Update modules/light-clients/08-wasm/doc.go

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update modules/light-clients/08-wasm/keeper/keeper_vm.go

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: make lint-fix

* chore: make lint-fix

---------

Co-authored-by: Charly <[email protected]>
Co-authored-by: Charly <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Cian Hatton <[email protected]>
(cherry picked from commit 031c2b8)

# Conflicts:
#	Makefile
#	modules/light-clients/08-wasm/keeper/keeper.go

* chore: resolve merge conflicts from backport

* chore: update changelog

---------

Co-authored-by: Damian Nolan <[email protected]>
  • Loading branch information
mergify[bot] and damiannolan authored Jun 12, 2024
1 parent 4ea883f commit bf158a5
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 76 deletions.
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ clean:

.PHONY: distclean clean

#? build-docker-wasm: Build wasm simapp with specified tag.
build-docker-wasm:
./scripts/build-wasm-simapp-docker.sh $(tag)

.PHONY: build-docker-wasm

###############################################################################
### Tools & Dependencies ###
###############################################################################
Expand Down Expand Up @@ -339,3 +345,9 @@ proto-update-deps:
$(DOCKER) run --rm -v $(CURDIR)/proto:/workspace --workdir /workspace $(protoImageName) buf mod update

.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps

#? help: Get more info on make commands
help: Makefile
@echo " Choose a command run in "$(PROJECT_NAME)":"
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'
.PHONY: help
2 changes: 2 additions & 0 deletions modules/light-clients/08-wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* [\#5923](https://github.com/cosmos/ibc-go/pull/5923) imp: adding 08-wasm build opts for libwasmvm linking disabled

### Features

### Bug Fixes
Expand Down
7 changes: 7 additions & 0 deletions modules/light-clients/08-wasm/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,12 @@ ClientMessage and types for the proxy light client module communicating
with underlying Wasm light clients.
This implementation is based off the ICS 08 specification
(https://github.com/cosmos/ibc/blob/main/spec/client/ics-008-wasm-client)
By default the 08-wasm module requires cgo and libwasmvm dependencies available on the system.
However, users of this module may want to depend only on types, without incurring the dependency on cgo or libwasmvm.
In this case, it is possible to build the code with either cgo disabled or a custom build directive: nolink_libwasmvm.
This allows disabling linking of libwasmvm and not forcing users to have specific libraries available on their systems.
Please refer to the 08-wasm module documentation for more information.
*/
package wasm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ WasmEngine = (*wasmvm.VM)(nil)

type WasmEngine interface {
// StoreCode will compile the Wasm code, and store the resulting compiled module
// as well as the original code. Both can be referenced later via Checksum.
Expand Down
7 changes: 7 additions & 0 deletions modules/light-clients/08-wasm/internal/ibcwasm/wasm_vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build cgo && !nolink_libwasmvm

package ibcwasm

import wasmvm "github.com/CosmWasm/wasmvm/v2"

var _ WasmEngine = (*wasmvm.VM)(nil)
73 changes: 3 additions & 70 deletions modules/light-clients/08-wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ package keeper
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"strings"

wasmvm "github.com/CosmWasm/wasmvm/v2"

Expand Down Expand Up @@ -33,73 +30,9 @@ type Keeper struct {
authority string
}

// NewKeeperWithVM creates a new Keeper instance with the provided Wasm VM.
// This constructor function is meant to be used when the chain uses x/wasm
// and the same Wasm VM instance should be shared with it.
func NewKeeperWithVM(
cdc codec.BinaryCodec,
storeService storetypes.KVStoreService,
clientKeeper types.ClientKeeper,
authority string,
vm ibcwasm.WasmEngine,
queryRouter ibcwasm.QueryRouter,
opts ...Option,
) Keeper {
if clientKeeper == nil {
panic(errors.New("client keeper must be not nil"))
}

if vm == nil {
panic(errors.New("wasm VM must be not nil"))
}

if storeService == nil {
panic(errors.New("store service must be not nil"))
}

if strings.TrimSpace(authority) == "" {
panic(errors.New("authority must be non-empty"))
}

keeper := &Keeper{
cdc: cdc,
storeService: storeService,
clientKeeper: clientKeeper,
authority: authority,
}

// set query plugins to ensure there is a non-nil query plugin
// regardless of what options the user provides
ibcwasm.SetQueryPlugins(types.NewDefaultQueryPlugins())
for _, opt := range opts {
opt.apply(keeper)
}

ibcwasm.SetVM(vm)
ibcwasm.SetQueryRouter(queryRouter)
ibcwasm.SetupWasmStoreService(storeService)

return *keeper
}

// NewKeeperWithConfig creates a new Keeper instance with the provided Wasm configuration.
// This constructor function is meant to be used when the chain does not use x/wasm
// and a Wasm VM needs to be instantiated using the provided parameters.
func NewKeeperWithConfig(
cdc codec.BinaryCodec,
storeService storetypes.KVStoreService,
clientKeeper types.ClientKeeper,
authority string,
wasmConfig types.WasmConfig,
queryRouter ibcwasm.QueryRouter,
opts ...Option,
) Keeper {
vm, err := wasmvm.NewVM(wasmConfig.DataDir, wasmConfig.SupportedCapabilities, types.ContractMemoryLimit, wasmConfig.ContractDebugMode, types.MemoryCacheSize)
if err != nil {
panic(fmt.Errorf("failed to instantiate new Wasm VM instance: %v", err))
}

return NewKeeperWithVM(cdc, storeService, clientKeeper, authority, vm, queryRouter, opts...)
// Codec returns the 08-wasm module's codec.
func (k Keeper) Codec() codec.BinaryCodec {
return k.cdc
}

// GetAuthority returns the 08-wasm module's authority.
Expand Down
44 changes: 44 additions & 0 deletions modules/light-clients/08-wasm/keeper/keeper_no_vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//go:build !cgo || nolink_libwasmvm

package keeper

import (
storetypes "cosmossdk.io/core/store"

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

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/ibcwasm"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
)

// NewKeeperWithVM creates a new Keeper instance with the provided Wasm VM.
// This constructor function is used when binaries are compiled with cgo disabled or the
// custom build directive: nolink_libwasmvm.
// This function is intended to panic and notify users that 08-wasm keeper functionality is not available.
func NewKeeperWithVM(
_ codec.BinaryCodec,
_ storetypes.KVStoreService,
_ types.ClientKeeper,
_ string,
_ ibcwasm.WasmEngine,
_ ibcwasm.QueryRouter,
_ ...Option,
) Keeper {
panic("not implemented, please build with cgo enabled or nolink_libwasmvm disabled")
}

// NewKeeperWithConfig creates a new Keeper instance with the provided Wasm configuration.
// This constructor function is used when binaries are compiled with cgo disabled or the
// custom build directive: nolink_libwasmvm.
// This function is intended to panic and notify users that 08-wasm keeper functionality is not available.
func NewKeeperWithConfig(
_ codec.BinaryCodec,
_ storetypes.KVStoreService,
_ types.ClientKeeper,
_ string,
_ types.WasmConfig,
_ ibcwasm.QueryRouter,
_ ...Option,
) Keeper {
panic("not implemented, please build with cgo enabled or nolink_libwasmvm disabled")
}
8 changes: 4 additions & 4 deletions modules/light-clients/08-wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
)
},
false,
errors.New("client keeper must be not nil"),
errors.New("client keeper must not be nil"),
},
{
"failure: nil wasm VM",
Expand All @@ -207,7 +207,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
)
},
false,
errors.New("wasm VM must be not nil"),
errors.New("wasm VM must not be nil"),
},
{
"failure: nil store service",
Expand All @@ -222,7 +222,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
)
},
false,
errors.New("store service must be not nil"),
errors.New("store service must not be nil"),
},
{
"failure: nil query router",
Expand All @@ -237,7 +237,7 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
)
},
false,
errors.New("query router must be not nil"),
errors.New("query router must not be nil"),
},
}

Expand Down
91 changes: 91 additions & 0 deletions modules/light-clients/08-wasm/keeper/keeper_vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//go:build cgo && !nolink_libwasmvm

package keeper

import (
"errors"
"fmt"
"strings"

wasmvm "github.com/CosmWasm/wasmvm/v2"

"cosmossdk.io/core/store"

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

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/ibcwasm"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
)

// NewKeeperWithVM creates a new Keeper instance with the provided Wasm VM.
// This constructor function is meant to be used when the chain uses x/wasm
// and the same Wasm VM instance should be shared with it.
func NewKeeperWithVM(
cdc codec.BinaryCodec,
storeService store.KVStoreService,
clientKeeper types.ClientKeeper,
authority string,
vm ibcwasm.WasmEngine,
queryRouter ibcwasm.QueryRouter,
opts ...Option,
) Keeper {
if clientKeeper == nil {
panic(errors.New("client keeper must not be nil"))
}

if queryRouter == nil {
panic(errors.New("query router must not be nil"))
}

if vm == nil {
panic(errors.New("wasm VM must not be nil"))
}

if storeService == nil {
panic(errors.New("store service must not be nil"))
}

if strings.TrimSpace(authority) == "" {
panic(errors.New("authority must be non-empty"))
}

keeper := &Keeper{
cdc: cdc,
storeService: storeService,
clientKeeper: clientKeeper,
authority: authority,
}

// set query plugins to ensure there is a non-nil query plugin
// regardless of what options the user provides
ibcwasm.SetQueryPlugins(types.NewDefaultQueryPlugins())
for _, opt := range opts {
opt.apply(keeper)
}

ibcwasm.SetVM(vm)
ibcwasm.SetQueryRouter(queryRouter)
ibcwasm.SetupWasmStoreService(storeService)

return *keeper
}

// NewKeeperWithConfig creates a new Keeper instance with the provided Wasm configuration.
// This constructor function is meant to be used when the chain does not use x/wasm
// and a Wasm VM needs to be instantiated using the provided parameters.
func NewKeeperWithConfig(
cdc codec.BinaryCodec,
storeService store.KVStoreService,
clientKeeper types.ClientKeeper,
authority string,
wasmConfig types.WasmConfig,
queryRouter ibcwasm.QueryRouter,
opts ...Option,
) Keeper {
vm, err := wasmvm.NewVM(wasmConfig.DataDir, wasmConfig.SupportedCapabilities, types.ContractMemoryLimit, wasmConfig.ContractDebugMode, types.MemoryCacheSize)
if err != nil {
panic(fmt.Errorf("failed to instantiate new Wasm VM instance: %v", err))
}

return NewKeeperWithVM(cdc, storeService, clientKeeper, authority, vm, queryRouter, opts...)
}
16 changes: 16 additions & 0 deletions scripts/build-wasm-simapp-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

set -eou pipefail

# build_wasm_image extracts the correct libwasm version and checksum
# based on the go.mod and builds a docker image with the provided tag.
function build_wasm_image(){
local version="$(scripts/get-libwasm-version.py --get-version)"
local checksum="$(scripts/get-libwasm-version.py --get-checksum)"
docker build . -t "${1}" -f modules/light-clients/08-wasm/Dockerfile --build-arg LIBWASM_VERSION=${version} --build-arg LIBWASM_CHECKSUM=${checksum}
}

# default to latest if no tag is specified.
TAG="${1:-ibc-go-wasm-simd:latest}"

build_wasm_image "${TAG}"

0 comments on commit bf158a5

Please sign in to comment.