mirror of https://github.com/certusone/wasmd.git
137 lines
4.4 KiB
Go
137 lines
4.4 KiB
Go
package integration
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
wasmvm "github.com/CosmWasm/wasmvm/v3"
|
|
wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types"
|
|
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
|
tmtypes "github.com/cometbft/cometbft/types"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
sdkmath "cosmossdk.io/math"
|
|
|
|
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
|
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
|
|
"github.com/CosmWasm/wasmd/app"
|
|
"github.com/CosmWasm/wasmd/x/wasm/keeper"
|
|
"github.com/CosmWasm/wasmd/x/wasm/types"
|
|
)
|
|
|
|
func TestSnapshotter(t *testing.T) {
|
|
specs := map[string]struct {
|
|
wasmFiles []string
|
|
}{
|
|
"single contract": {
|
|
wasmFiles: []string{"./testdata/reflect_1_5.wasm"},
|
|
},
|
|
"multiple contract": {
|
|
wasmFiles: []string{"./testdata/reflect_1_5.wasm", "./testdata/burner.wasm", "./testdata/reflect_1_5.wasm"},
|
|
},
|
|
"duplicate contracts": {
|
|
wasmFiles: []string{"./testdata/reflect_1_5.wasm", "./testdata/reflect_1_5.wasm"},
|
|
},
|
|
}
|
|
for name, spec := range specs {
|
|
t.Run(name, func(t *testing.T) {
|
|
// setup source app
|
|
srcWasmApp, genesisAddr := newWasmExampleApp(t)
|
|
|
|
// store wasm codes on chain
|
|
ctx := srcWasmApp.NewUncachedContext(false, tmproto.Header{
|
|
ChainID: "foo",
|
|
Height: srcWasmApp.LastBlockHeight() + 1,
|
|
Time: time.Now(),
|
|
})
|
|
wasmKeeper := srcWasmApp.WasmKeeper
|
|
contractKeeper := keeper.NewDefaultPermissionKeeper(&wasmKeeper)
|
|
|
|
srcCodeIDToChecksum := make(map[uint64][]byte, len(spec.wasmFiles))
|
|
for i, v := range spec.wasmFiles {
|
|
wasmCode, err := os.ReadFile(v)
|
|
require.NoError(t, err)
|
|
codeID, checksum, err := contractKeeper.Create(ctx, genesisAddr, wasmCode, nil)
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(i+1), codeID)
|
|
srcCodeIDToChecksum[codeID] = checksum
|
|
}
|
|
// create snapshot
|
|
_, err := srcWasmApp.Commit()
|
|
require.NoError(t, err)
|
|
|
|
snapshotHeight := uint64(srcWasmApp.LastBlockHeight())
|
|
snapshot, err := srcWasmApp.SnapshotManager().Create(snapshotHeight)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, snapshot)
|
|
|
|
originalMaxWasmSize := types.MaxWasmSize
|
|
types.MaxWasmSize = 1
|
|
t.Cleanup(func() {
|
|
types.MaxWasmSize = originalMaxWasmSize
|
|
})
|
|
|
|
// when snapshot imported into dest app instance
|
|
destWasmApp := app.SetupWithEmptyStore(t)
|
|
require.NoError(t, destWasmApp.SnapshotManager().Restore(*snapshot))
|
|
for i := uint32(0); i < snapshot.Chunks; i++ {
|
|
chunkBz, err := srcWasmApp.SnapshotManager().LoadChunk(snapshot.Height, snapshot.Format, i)
|
|
require.NoError(t, err)
|
|
end, err := destWasmApp.SnapshotManager().RestoreChunk(chunkBz)
|
|
require.NoError(t, err)
|
|
if end {
|
|
break
|
|
}
|
|
}
|
|
|
|
// then all wasm contracts are imported
|
|
wasmKeeper = destWasmApp.WasmKeeper
|
|
ctx = destWasmApp.NewUncachedContext(false, tmproto.Header{
|
|
ChainID: "foo",
|
|
Height: destWasmApp.LastBlockHeight() + 1,
|
|
Time: time.Now(),
|
|
})
|
|
|
|
destCodeIDToChecksum := make(map[uint64][]byte, len(spec.wasmFiles))
|
|
wasmKeeper.IterateCodeInfos(ctx, func(id uint64, info types.CodeInfo) bool {
|
|
bz, err := wasmKeeper.GetByteCode(ctx, id)
|
|
require.NoError(t, err)
|
|
|
|
hash, err := wasmvm.CreateChecksum(bz)
|
|
require.NoError(t, err)
|
|
destCodeIDToChecksum[id] = hash[:]
|
|
assert.Equal(t, hash[:], wasmvmtypes.Checksum(info.CodeHash))
|
|
return false
|
|
})
|
|
assert.Equal(t, srcCodeIDToChecksum, destCodeIDToChecksum)
|
|
})
|
|
}
|
|
}
|
|
|
|
func newWasmExampleApp(t *testing.T) (*app.WasmApp, sdk.AccAddress) {
|
|
senderPrivKey := ed25519.GenPrivKey()
|
|
pubKey, err := cryptocodec.ToCmtPubKeyInterface(senderPrivKey.PubKey())
|
|
require.NoError(t, err)
|
|
|
|
senderAddr := senderPrivKey.PubKey().Address().Bytes()
|
|
acc := authtypes.NewBaseAccount(senderAddr, senderPrivKey.PubKey(), 0, 0)
|
|
amount, ok := sdkmath.NewIntFromString("10000000000000000000")
|
|
require.True(t, ok)
|
|
|
|
balance := banktypes.Balance{
|
|
Address: acc.GetAddress().String(),
|
|
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)),
|
|
}
|
|
validator := tmtypes.NewValidator(pubKey, 1)
|
|
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
|
|
wasmApp := app.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, "testing", nil, balance)
|
|
|
|
return wasmApp, senderAddr
|
|
}
|