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

Call Pin during app inisitalization #5161

Merged
merged 15 commits into from
Nov 28, 2023
Merged
34 changes: 26 additions & 8 deletions docs/docs/03-light-clients/04-wasm/03-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The sample code below shows the relevant integration points in `app.go` required
import (
...
"github.com/cosmos/cosmos-sdk/runtime"

cmtos "github.com/cometbft/cometbft/libs/os"

wasm "github.com/cosmos/ibc-go/modules/light-clients/08-wasm"
wasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper"
Expand Down Expand Up @@ -54,13 +56,14 @@ func NewSimApp(
...
wasmtypes.StoreKey,
)
// Instantiate 08-wasm's keeper
// This sample code uses a constructor function that
// accepts a pointer to an existing instance of Wasm VM.
// This is the recommended approach when the chain
// also uses `x/wasm`, and then the Wasm VM instance
// can be shared.
// See the section below for more information.

// Instantiate 08-wasm's keeper
// This sample code uses a constructor function that
// accepts a pointer to an existing instance of Wasm VM.
// This is the recommended approach when the chain
// also uses `x/wasm`, and then the Wasm VM instance
// can be shared.
// See the section below for more information.
app.WasmClientKeeper = wasmkeeper.NewKeeperWithVM(
appCodec,
runtime.NewKVStoreService(keys[wasmtypes.StoreKey]),
Expand Down Expand Up @@ -106,6 +109,17 @@ func NewSimApp(
}
}
...

if loadLatest {
...

ctx := app.BaseApp.NewUncachedContext(true, cmtproto.Header{})

// Initialize pinned codes in wasmvm as they are not persisted there
if err := wasmkeeper.InitializePinnedCodes(ctx); err != nil {
cmtos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err))
}
}
}
```

Expand Down Expand Up @@ -245,4 +259,8 @@ Or alternatively the parameter can be updated via a governance proposal (see at

## Adding snapshot support

In order to use the `08-wasm` module chains are required to register the `WasmSnapshotter` extension in the snapshot manager. This snapshotter takes care of persisting the external state, in the form of contract code, of the Wasm VM instance to disk when the chain is snapshotted.
In order to use the `08-wasm` module chains are required to register the `WasmSnapshotter` extension in the snapshot manager. This snapshotter takes care of persisting the external state, in the form of contract code, of the Wasm VM instance to disk when the chain is snapshotted. [This code](https://github.com/cosmos/ibc-go/blob/2bd29c08fd1fe50b461fc33a25735aa792dc896e/modules/light-clients/08-wasm/testing/simapp/app.go#L768-L776) should be placed in `NewSimApp` function in `app.go`:

## Pin byte codes at start

Wasm byte codes should be pinned to the WasmVM cache on every application start, therefore [this code](https://github.com/cosmos/ibc-go/blob/0ed221f687ffce75984bc57402fd678e07aa6cc5/modules/light-clients/08-wasm/testing/simapp/app.go#L821-L826) should be placed in `NewSimApp` function in `app.go`.
15 changes: 15 additions & 0 deletions modules/light-clients/08-wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,18 @@ func (k Keeper) GetWasmClientState(ctx sdk.Context, clientID string) (*types.Cli

return wasmClientState, nil
}

// InitializePinnedCodes updates wasmvm to pin to cache all contracts marked as pinned
func InitializePinnedCodes(ctx sdk.Context) error {
checksums, err := types.GetAllChecksums(ctx)
if err != nil {
return err
}

for _, checksum := range checksums {
if err := ibcwasm.GetVM().Pin(checksum); err != nil {
return err
}
}
return nil
}
68 changes: 68 additions & 0 deletions modules/light-clients/08-wasm/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,71 @@ func (suite *KeeperTestSuite) TestNewKeeper() {
})
}
}

func (suite *KeeperTestSuite) TestInitializedPinnedCodes() {
var capturedChecksums []wasmvm.Checksum

testCases := []struct {
name string
malleate func()
expError error
}{
{
"success",
func() {
suite.mockVM.PinFn = func(checksum wasmvm.Checksum) error {
capturedChecksums = append(capturedChecksums, checksum)
return nil
}
},
nil,
},
{
"failure: pin error",
func() {
suite.mockVM.PinFn = func(checksum wasmvm.Checksum) error {
return wasmtesting.ErrMockVM
}
},
wasmtesting.ErrMockVM,
},
}

for _, tc := range testCases {
tc := tc

suite.Run(tc.name, func() {
suite.SetupWasmWithMockVM()

ctx := suite.chainA.GetContext()
wasmClientKeeper := GetSimApp(suite.chainA).WasmClientKeeper

contracts := [][]byte{wasmtesting.Code, wasmtesting.CreateMockContract([]byte("gzipped-contract"))}
checksumIDs := make([]types.Checksum, len(contracts))
signer := authtypes.NewModuleAddress(govtypes.ModuleName).String()

// store contract on chain
for i, contract := range contracts {
msg := types.NewMsgStoreCode(signer, contract)

res, err := wasmClientKeeper.StoreCode(ctx, msg)
suite.Require().NoError(err)

checksumIDs[i] = res.Checksum
}

// malleate after storing contracts
tc.malleate()

err := keeper.InitializePinnedCodes(ctx)

expPass := tc.expError == nil
if expPass {
suite.Require().NoError(err)
suite.ElementsMatch(checksumIDs, capturedChecksums)
} else {
suite.Require().ErrorIs(err, tc.expError)
}
})
}
}
9 changes: 9 additions & 0 deletions modules/light-clients/08-wasm/testing/simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

abci "github.com/cometbft/cometbft/abci/types"
cmtos "github.com/cometbft/cometbft/libs/os"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"

"github.com/cosmos/ibc-go/modules/capability"
capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper"
Expand Down Expand Up @@ -815,6 +817,13 @@ func NewSimApp(
if err := app.LoadLatestVersion(); err != nil {
panic(fmt.Errorf("error loading last version: %w", err))
}

ctx := app.BaseApp.NewUncachedContext(true, cmtproto.Header{})

// Initialize pinned codes in wasmvm as they are not persisted there
if err := wasmkeeper.InitializePinnedCodes(ctx); err != nil {
cmtos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err))
}
}

app.ScopedIBCKeeper = scopedIBCKeeper
Expand Down
Loading