Skip to content

Commit

Permalink
imp: use wasm VM CreateChecksum (#5123)
Browse files Browse the repository at this point in the history
* use wasm VM CreateChecksum

* review comments

* lint

* lint 2

* Remove raw calls to sha256, clean up handling of Checksums.

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

Co-authored-by: Damian Nolan <damiannolan@gmail.com>

* Document this bad boy.

---------

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
Co-authored-by: Damian Nolan <damiannolan@gmail.com>
(cherry picked from commit a231fea)
  • Loading branch information
crodriguezvega authored and mergify[bot] committed Nov 29, 2023
1 parent 8ce1911 commit 66be0f3
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 100 deletions.
4 changes: 2 additions & 2 deletions modules/light-clients/08-wasm/keeper/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

// emitStoreWasmCodeEvent emits a store wasm code event
func emitStoreWasmCodeEvent(ctx sdk.Context, checksum []byte) {
func emitStoreWasmCodeEvent(ctx sdk.Context, checksum types.Checksum) {
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeStoreWasmCode,
Expand All @@ -23,7 +23,7 @@ func emitStoreWasmCodeEvent(ctx sdk.Context, checksum []byte) {
}

// emitMigrateContractEvent emits a migrate contract event
func emitMigrateContractEvent(ctx sdk.Context, clientID string, checksum, newChecksum []byte) {
func emitMigrateContractEvent(ctx sdk.Context, clientID string, checksum, newChecksum types.Checksum) {
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeMigrateContract,
Expand Down
9 changes: 0 additions & 9 deletions modules/light-clients/08-wasm/keeper/export_test.go

This file was deleted.

4 changes: 1 addition & 3 deletions modules/light-clients/08-wasm/keeper/genesis.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package keeper

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

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

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
Expand Down Expand Up @@ -31,7 +29,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) types.GenesisState {
// Grab code from wasmVM and add to genesis state.
var genesisState types.GenesisState
for _, checksum := range checksums {
code, err := k.wasmVM.GetCode(wasmvmtypes.Checksum(checksum))
code, err := k.wasmVM.GetCode(checksum)
if err != nil {
panic(err)
}
Expand Down
12 changes: 5 additions & 7 deletions modules/light-clients/08-wasm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package keeper

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
Expand Down Expand Up @@ -94,11 +93,6 @@ func (k Keeper) GetAuthority() string {
return k.authority
}

func generateWasmChecksum(code []byte) []byte {
hash := sha256.Sum256(code)
return hash[:]
}

func (k Keeper) storeWasmCode(ctx sdk.Context, code []byte) ([]byte, error) {
var err error
if types.IsGzip(code) {
Expand All @@ -110,7 +104,11 @@ func (k Keeper) storeWasmCode(ctx sdk.Context, code []byte) ([]byte, error) {
}

// Check to see if store already has checksum.
checksum := generateWasmChecksum(code)
checksum, err := types.CreateChecksum(code)
if err != nil {
return nil, errorsmod.Wrap(err, "wasm bytecode checksum failed")
}

if types.HasChecksum(ctx, checksum) {
return nil, types.ErrWasmCodeExists
}
Expand Down
53 changes: 37 additions & 16 deletions modules/light-clients/08-wasm/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package keeper_test

import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"os"

wasmvm "github.com/CosmWasm/wasmvm"
Expand Down Expand Up @@ -53,11 +53,25 @@ func (suite *KeeperTestSuite) TestMsgStoreCode() {
types.ErrWasmCodeExists,
},
{
"fails with invalid wasm code",
"fails with zero-length wasm code",
func() {
msg = types.NewMsgStoreCode(signer, []byte{})
},
types.ErrWasmEmptyCode,
errors.New("Wasm bytes nil or empty"),
},
{
"fails with checksum",
func() {
msg = types.NewMsgStoreCode(signer, []byte{0, 1, 3, 4})
},
errors.New("Wasm bytes do not not start with Wasm magic number"),
},
{
"fails with wasm code too large",
func() {
msg = types.NewMsgStoreCode(signer, append(wasmtesting.WasmMagicNumber, []byte(ibctesting.GenerateString(uint(types.MaxWasmByteSize())))...))
},
types.ErrWasmCodeTooLarge,
},
{
"fails with unauthorized signer",
Expand Down Expand Up @@ -114,7 +128,7 @@ func (suite *KeeperTestSuite) TestMsgStoreCode() {
suite.Require().Contains(events, evt)
}
} else {
suite.Require().ErrorIs(err, tc.expError)
suite.Require().Contains(err.Error(), tc.expError.Error())
suite.Require().Nil(res)
suite.Require().Empty(events)
}
Expand All @@ -123,9 +137,11 @@ func (suite *KeeperTestSuite) TestMsgStoreCode() {
}

func (suite *KeeperTestSuite) TestMsgMigrateContract() {
oldChecksum := sha256.Sum256(wasmtesting.Code)
oldChecksum, err := types.CreateChecksum(wasmtesting.Code)
suite.Require().NoError(err)

newByteCode := []byte("MockByteCode-TestMsgMigrateContract")
newByteCode := wasmtesting.WasmMagicNumber
newByteCode = append(newByteCode, []byte("MockByteCode-TestMsgMigrateContract")...)

govAcc := authtypes.NewModuleAddress(govtypes.ModuleName).String()

Expand Down Expand Up @@ -175,7 +191,7 @@ func (suite *KeeperTestSuite) TestMsgMigrateContract() {
{
"failure: same checksum",
func() {
msg = types.NewMsgMigrateContract(govAcc, defaultWasmClientID, oldChecksum[:], []byte("{}"))
msg = types.NewMsgMigrateContract(govAcc, defaultWasmClientID, oldChecksum, []byte("{}"))

suite.mockVM.MigrateFn = func(_ wasmvm.Checksum, _ wasmvmtypes.Env, _ []byte, _ wasmvm.KVStore, _ wasmvm.GoAPI, _ wasmvm.Querier, _ wasmvm.GasMeter, _ uint64, _ wasmvmtypes.UFraction) (*wasmvmtypes.Response, uint64, error) {
panic("unreachable")
Expand Down Expand Up @@ -272,7 +288,7 @@ func (suite *KeeperTestSuite) TestMsgMigrateContract() {
sdk.NewEvent(
"migrate_contract",
sdk.NewAttribute(types.AttributeKeyClientID, defaultWasmClientID),
sdk.NewAttribute(types.AttributeKeyWasmChecksum, hex.EncodeToString(oldChecksum[:])),
sdk.NewAttribute(types.AttributeKeyWasmChecksum, hex.EncodeToString(oldChecksum)),
sdk.NewAttribute(types.AttributeKeyNewChecksum, hex.EncodeToString(newChecksum)),
),
sdk.NewEvent(
Expand All @@ -293,7 +309,8 @@ func (suite *KeeperTestSuite) TestMsgMigrateContract() {
}

func (suite *KeeperTestSuite) TestMsgRemoveChecksum() {
checksum := sha256.Sum256(wasmtesting.Code)
checksum, err := types.CreateChecksum(wasmtesting.Code)
suite.Require().NoError(err)

govAcc := authtypes.NewModuleAddress(govtypes.ModuleName).String()

Expand All @@ -310,7 +327,7 @@ func (suite *KeeperTestSuite) TestMsgRemoveChecksum() {
{
"success",
func() {
msg = types.NewMsgRemoveChecksum(govAcc, checksum[:])
msg = types.NewMsgRemoveChecksum(govAcc, checksum)

expChecksums = []types.Checksum{}
},
Expand All @@ -319,16 +336,20 @@ func (suite *KeeperTestSuite) TestMsgRemoveChecksum() {
{
"success: many checksums",
func() {
msg = types.NewMsgRemoveChecksum(govAcc, checksum[:])
msg = types.NewMsgRemoveChecksum(govAcc, checksum)

expChecksums = []types.Checksum{}

for i := 0; i < 20; i++ {
checksum := sha256.Sum256([]byte{byte(i)})
err := ibcwasm.Checksums.Set(suite.chainA.GetContext(), checksum[:])
mockCode := []byte{byte(i)}
mockCode = append(wasmtesting.WasmMagicNumber, mockCode...)
checksum, err := types.CreateChecksum(mockCode)
suite.Require().NoError(err)

err = ibcwasm.Checksums.Set(suite.chainA.GetContext(), checksum)
suite.Require().NoError(err)

expChecksums = append(expChecksums, checksum[:])
expChecksums = append(expChecksums, checksum)
}
},
nil,
Expand All @@ -343,14 +364,14 @@ func (suite *KeeperTestSuite) TestMsgRemoveChecksum() {
{
"failure: unauthorized signer",
func() {
msg = types.NewMsgRemoveChecksum(suite.chainA.SenderAccount.GetAddress().String(), checksum[:])
msg = types.NewMsgRemoveChecksum(suite.chainA.SenderAccount.GetAddress().String(), checksum)
},
ibcerrors.ErrUnauthorized,
},
{
"failure: code has could not be unpinned",
func() {
msg = types.NewMsgRemoveChecksum(govAcc, checksum[:])
msg = types.NewMsgRemoveChecksum(govAcc, checksum)

suite.mockVM.UnpinFn = func(_ wasmvm.Checksum) error {
return wasmtesting.ErrMockVM
Expand Down
4 changes: 1 addition & 3 deletions modules/light-clients/08-wasm/keeper/snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"encoding/hex"
"io"

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

errorsmod "cosmossdk.io/errors"
snapshot "cosmossdk.io/store/snapshots/types"
storetypes "cosmossdk.io/store/types"
Expand Down Expand Up @@ -74,7 +72,7 @@ func (ws *WasmSnapshotter) SnapshotExtension(height uint64, payloadWriter snapsh
}

for _, checksum := range checksums {
wasmCode, err := ws.keeper.wasmVM.GetCode(wasmvmtypes.Checksum(checksum))
wasmCode, err := ws.keeper.wasmVM.GetCode(checksum)
if err != nil {
return err
}
Expand Down
8 changes: 5 additions & 3 deletions modules/light-clients/08-wasm/keeper/snapshotter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import (

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper"
wasmtesting "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/testing/simapp"
"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
)

func (suite *KeeperTestSuite) TestSnapshotter() {
gzippedContract, err := types.GzipIt([]byte("gzipped-contract"))
gzippedContract, err := types.GzipIt(append(wasmtesting.WasmMagicNumber, []byte("gzipped-contract")...))
suite.Require().NoError(err)

testCases := []struct {
Expand Down Expand Up @@ -110,7 +109,10 @@ func (suite *KeeperTestSuite) TestSnapshotter() {
resp, err := destWasmClientApp.WasmClientKeeper.Code(ctx, &types.QueryCodeRequest{Checksum: hex.EncodeToString(checksum)})
suite.Require().NoError(err)

allDestAppChecksumsInWasmVMStore = append(allDestAppChecksumsInWasmVMStore, keeper.GenerateWasmChecksum(resp.Data)...)
checksum, err := types.CreateChecksum(resp.Data)
suite.Require().NoError(err)

allDestAppChecksumsInWasmVMStore = append(allDestAppChecksumsInWasmVMStore, checksum...)
}

suite.Require().Equal(srcChecksumCodes, allDestAppChecksumsInWasmVMStore)
Expand Down
4 changes: 1 addition & 3 deletions modules/light-clients/08-wasm/testing/mock_engine.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package testing

import (
"crypto/sha256"
"encoding/binary"
"encoding/json"
"errors"
Expand Down Expand Up @@ -58,8 +57,7 @@ func NewMockWasmEngine() *MockWasmEngine {

// Set up default behavior for Store/Pin/Get
m.StoreCodeFn = func(code wasmvm.WasmCode) (wasmvm.Checksum, error) {
hash := sha256.Sum256(code)
checkSum := wasmvm.Checksum(hash[:])
checkSum, _ := types.CreateChecksum(code)

m.storedContracts[binary.LittleEndian.Uint32(checkSum)] = code
return checkSum, nil
Expand Down
5 changes: 3 additions & 2 deletions modules/light-clients/08-wasm/testing/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (

var (
// Represents the code of the wasm contract used in the tests with a mock vm.
Code = []byte("01234567012345670123456701234567")
WasmMagicNumber = []byte("\x00\x61\x73\x6D")
Code = append(WasmMagicNumber, []byte("0123456780123456780123456780")...)
contractClientState = []byte{1}
contractConsensusState = []byte{2}
MockClientStateBz = []byte("client-state-data")
Expand All @@ -26,7 +27,7 @@ var (
)

// CreateMockClientStateBz returns valid client state bytes for use in tests.
func CreateMockClientStateBz(cdc codec.BinaryCodec, checksum []byte) []byte {
func CreateMockClientStateBz(cdc codec.BinaryCodec, checksum types.Checksum) []byte {
mockClientSate := types.NewClientState([]byte{1}, checksum, clienttypes.NewHeight(2000, 2))
return clienttypes.MustMarshalClientState(cdc, mockClientSate)
}
8 changes: 4 additions & 4 deletions modules/light-clients/08-wasm/testing/wasm_endpoint.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package testing

import (
"crypto/sha256"

"github.com/stretchr/testify/require"

"github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types"
Expand All @@ -28,8 +26,10 @@ func NewWasmEndpoint(chain *ibctesting.TestChain) *WasmEndpoint {
// The client and consensus states are represented by byte slices
// and the starting height is 1.
func (endpoint *WasmEndpoint) CreateClient() error {
checksum := sha256.Sum256(Code)
clientState := types.NewClientState(contractClientState, checksum[:], clienttypes.NewHeight(0, 1))
checksum, err := types.CreateChecksum(Code)
require.NoError(endpoint.Chain.TB, err)

clientState := types.NewClientState(contractClientState, checksum, clienttypes.NewHeight(0, 1))
consensusState := types.NewConsensusState(contractConsensusState, 0)

msg, err := clienttypes.NewMsgCreateClient(
Expand Down
9 changes: 5 additions & 4 deletions modules/light-clients/08-wasm/types/client_state_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package types_test

import (
"crypto/sha256"
"encoding/json"
"time"

Expand Down Expand Up @@ -306,16 +305,18 @@ func (suite *TypesTestSuite) TestInitialize() {
suite.Run(tc.name, func() {
suite.SetupWasmWithMockVM()

checksum := sha256.Sum256(wasmtesting.Code)
clientState = types.NewClientState([]byte{1}, checksum[:], clienttypes.NewHeight(0, 1))
checksum, err := types.CreateChecksum(wasmtesting.Code)
suite.Require().NoError(err)

clientState = types.NewClientState([]byte{1}, checksum, clienttypes.NewHeight(0, 1))
consensusState = types.NewConsensusState([]byte{2}, 0)

clientID := suite.chainA.App.GetIBCKeeper().ClientKeeper.GenerateClientIdentifier(suite.chainA.GetContext(), clientState.ClientType())
clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID)

tc.malleate()

err := clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, clientStore, consensusState)
err = clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, clientStore, consensusState)

expPass := tc.expError == nil
if expPass {
Expand Down
Loading

0 comments on commit 66be0f3

Please sign in to comment.