Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: address vanity nits in 08-wasm (code structure, godocs) (backport #5320) #5322

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 25 additions & 20 deletions modules/light-clients/08-wasm/testing/mock_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,31 @@ type (
sudoFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, sudoMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
)

// MockWasmEngine implements types.WasmEngine for testing purposes. One or multiple messages can be stubbed.
// Without a stub function a panic is thrown.
// ref: https://github.com/CosmWasm/wasmd/blob/v0.42.0/x/wasm/keeper/wasmtesting/mock_engine.go#L19
type MockWasmEngine struct {
StoreCodeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)
StoreCodeUncheckedFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)
InstantiateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
MigrateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
GetCodeFn func(checksum wasmvm.Checksum) (wasmvm.WasmCode, error)
PinFn func(checksum wasmvm.Checksum) error
UnpinFn func(checksum wasmvm.Checksum) error

// queryCallbacks contains a mapping of queryMsg field type name to callback function.
queryCallbacks map[string]queryFn
sudoCallbacks map[string]sudoFn

// contracts contains a mapping of checksum to code.
storedContracts map[uint32][]byte
}

// NewMockWasmEngine creates and returns a new instance of the mock wasmvm for testing purposes.
// Each callback method of the mock wasmvm can be overridden to assign specific functionality.
// Default functionality is assigned for StoreCode, StoreCodeUnchecked and GetCode. Both Pin and Unpin are implemented as no-op methods.
// All other callbacks stored in the query and sudo callback maps panic. Use RegisterQueryCallback and RegisterSudoCallback methods
// to assign expected behaviour for test cases.
func NewMockWasmEngine() *MockWasmEngine {
m := &MockWasmEngine{
queryCallbacks: map[string]queryFn{},
Expand Down Expand Up @@ -107,26 +132,6 @@ func (m *MockWasmEngine) RegisterSudoCallback(sudoMessage any, fn sudoFn) {
m.sudoCallbacks[typeName] = fn
}

// MockWasmEngine implements types.WasmEngine for testing purpose. One or multiple messages can be stubbed.
// Without a stub function a panic is thrown.
// ref: https://github.com/CosmWasm/wasmd/blob/v0.42.0/x/wasm/keeper/wasmtesting/mock_engine.go#L19
type MockWasmEngine struct {
StoreCodeFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)
StoreCodeUncheckedFn func(code wasmvm.WasmCode) (wasmvm.Checksum, error)
InstantiateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, info wasmvmtypes.MessageInfo, initMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
MigrateFn func(checksum wasmvm.Checksum, env wasmvmtypes.Env, migrateMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error)
GetCodeFn func(checksum wasmvm.Checksum) (wasmvm.WasmCode, error)
PinFn func(checksum wasmvm.Checksum) error
UnpinFn func(checksum wasmvm.Checksum) error

// queryCallbacks contains a mapping of queryMsg field type name to callback function.
queryCallbacks map[string]queryFn
sudoCallbacks map[string]sudoFn

// contracts contains a mapping of checksum to code.
storedContracts map[uint32][]byte
}

// StoreCode implements the WasmEngine interface.
func (m *MockWasmEngine) StoreCode(code wasmvm.WasmCode) (wasmvm.Checksum, error) {
if m.StoreCodeFn == nil {
Expand Down
6 changes: 0 additions & 6 deletions modules/light-clients/08-wasm/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgStoreCode{},
)
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgMigrateContract{},
)
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgRemoveChecksum{},
)

Expand Down
3 changes: 3 additions & 0 deletions modules/light-clients/08-wasm/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const (
defaultContractDebugMode = false
)

// WasmConfig defines configuration parameters for the 08-wasm wasm virtual machine instance.
// It includes the `dataDir` intended to be used for wasm blobs and internal caches, as well as a comma separated list
// of features or capabilities the user wishes to enable. A boolean flag is provided to enable debug mode.
type WasmConfig struct {
// DataDir is the directory for Wasm blobs and various caches
DataDir string
Expand Down
53 changes: 53 additions & 0 deletions modules/light-clients/08-wasm/types/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ package types

import (
"bytes"
"context"
"errors"
"io"
"reflect"
"strings"

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

errorsmod "cosmossdk.io/errors"
"cosmossdk.io/store/cachekv"
storeprefix "cosmossdk.io/store/prefix"
"cosmossdk.io/store/tracekv"
storetypes "cosmossdk.io/store/types"

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

var (
Expand All @@ -24,6 +28,50 @@ var (
substitutePrefix = []byte("substitute/")
)

// Checksum is a type alias used for wasm byte code checksums.
type Checksum = wasmvmtypes.Checksum

// CreateChecksum creates a sha256 checksum from the given wasm code, it forwards the
// call to the wasmvm package. The code is checked for the following conditions:
// - code length is zero.
// - code length is less than 4 bytes (magic number length).
// - code does not start with the wasm magic number.
func CreateChecksum(code []byte) (Checksum, error) {
return wasmvm.CreateChecksum(code)
}

// GetAllChecksums is a helper to get all checksums from the store.
// It returns an empty slice if no checksums are found
func GetAllChecksums(ctx context.Context) ([]Checksum, error) {
iterator, err := ibcwasm.Checksums.Iterate(ctx, nil)
if err != nil {
return nil, err
}

keys, err := iterator.Keys()
if err != nil {
return nil, err
}

checksums := []Checksum{}
for _, key := range keys {
checksums = append(checksums, key)
}

return checksums, nil
}

// HasChecksum returns true if the given checksum exists in the store and
// false otherwise.
func HasChecksum(ctx context.Context, checksum Checksum) bool {
found, err := ibcwasm.Checksums.Has(ctx, checksum)
if err != nil {
return false
}

return found
}

// migrateClientWrappedStore combines two KVStores into one.
//
// Both stores are used for reads, but only the subjectStore is used for writes. For all operations, the key
Expand Down Expand Up @@ -205,22 +253,27 @@ func newStoreAdapter(s storetypes.KVStore) *storeAdapter {
return &storeAdapter{parent: s}
}

// Get implements the wasmvmtypes.KVStore interface.
func (s storeAdapter) Get(key []byte) []byte {
return s.parent.Get(key)
}

// Set implements the wasmvmtypes.KVStore interface.
func (s storeAdapter) Set(key, value []byte) {
s.parent.Set(key, value)
}

// Delete implements the wasmvmtypes.KVStore interface.
func (s storeAdapter) Delete(key []byte) {
s.parent.Delete(key)
}

// Iterator implements the wasmvmtypes.KVStore interface.
func (s storeAdapter) Iterator(start, end []byte) wasmvmtypes.Iterator {
return s.parent.Iterator(start, end)
}

// ReverseIterator implements the wasmvmtypes.KVStore interface.
func (s storeAdapter) ReverseIterator(start, end []byte) wasmvmtypes.Iterator {
return s.parent.ReverseIterator(start, end)
}
Expand Down
118 changes: 118 additions & 0 deletions modules/light-clients/08-wasm/types/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,131 @@ import (
prefixstore "cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/internal/ibcwasm"
wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
)

var invalidPrefix = []byte("invalid/")

func (suite *TypesTestSuite) TestGetChecksums() {
testCases := []struct {
name string
malleate func()
expResult func(checksums []types.Checksum)
}{
{
"success: no contract stored.",
func() {},
func(checksums []types.Checksum) {
suite.Require().Len(checksums, 0)
},
},
{
"success: default mock vm contract stored.",
func() {
suite.SetupWasmWithMockVM()
},
func(checksums []types.Checksum) {
suite.Require().Len(checksums, 1)
expectedChecksum, err := types.CreateChecksum(wasmtesting.Code)
suite.Require().NoError(err)
suite.Require().Equal(expectedChecksum, checksums[0])
},
},
{
"success: non-empty checksums",
func() {
suite.SetupWasmWithMockVM()

err := ibcwasm.Checksums.Set(suite.chainA.GetContext(), types.Checksum("checksum"))
suite.Require().NoError(err)
},
func(checksums []types.Checksum) {
suite.Require().Len(checksums, 2)
suite.Require().Contains(checksums, types.Checksum("checksum"))
},
},
}

for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
tc.malleate()

checksums, err := types.GetAllChecksums(suite.chainA.GetContext())
suite.Require().NoError(err)
tc.expResult(checksums)
})
}
}

func (suite *TypesTestSuite) TestAddChecksum() {
suite.SetupWasmWithMockVM()

checksums, err := types.GetAllChecksums(suite.chainA.GetContext())
suite.Require().NoError(err)
// default mock vm contract is stored
suite.Require().Len(checksums, 1)

checksum1 := types.Checksum("checksum1")
checksum2 := types.Checksum("checksum2")
err = ibcwasm.Checksums.Set(suite.chainA.GetContext(), checksum1)
suite.Require().NoError(err)
err = ibcwasm.Checksums.Set(suite.chainA.GetContext(), checksum2)
suite.Require().NoError(err)

// Test adding the same checksum twice
err = ibcwasm.Checksums.Set(suite.chainA.GetContext(), checksum1)
suite.Require().NoError(err)

checksums, err = types.GetAllChecksums(suite.chainA.GetContext())
suite.Require().NoError(err)
suite.Require().Len(checksums, 3)
suite.Require().Contains(checksums, checksum1)
suite.Require().Contains(checksums, checksum2)
}

func (suite *TypesTestSuite) TestHasChecksum() {
var checksum types.Checksum

testCases := []struct {
name string
malleate func()
exprResult bool
}{
{
"success: checksum exists",
func() {
checksum = types.Checksum("checksum")
err := ibcwasm.Checksums.Set(suite.chainA.GetContext(), checksum)
suite.Require().NoError(err)
},
true,
},
{
"success: checksum does not exist",
func() {
checksum = types.Checksum("non-existent-checksum")
},
false,
},
}

for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
suite.SetupWasmWithMockVM()

tc.malleate()

result := types.HasChecksum(suite.chainA.GetContext(), checksum)
suite.Require().Equal(tc.exprResult, result)
})
}
}

// TestMigrateClientWrappedStoreGetStore tests the getStore method of the migrateClientWrappedStore.
func (suite *TypesTestSuite) TestMigrateClientWrappedStoreGetStore() {
// calls suite.SetupWasmWithMockVM() and creates two clients with their respective stores
Expand Down
54 changes: 0 additions & 54 deletions modules/light-clients/08-wasm/types/wasm.go

This file was deleted.

Loading
Loading