From 7dc2d0cfbc054db2743fefec3972a9caa1fc2e68 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 18 Sep 2023 06:26:19 +0200 Subject: [PATCH] Fix genesis import with predictable addresses --- x/wasm/keeper/genesis.go | 11 ++++++----- x/wasm/keeper/genesis_test.go | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/x/wasm/keeper/genesis.go b/x/wasm/keeper/genesis.go index f6953e8238..6df469c16e 100644 --- a/x/wasm/keeper/genesis.go +++ b/x/wasm/keeper/genesis.go @@ -41,7 +41,6 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) ([]ab } } - var maxContractID int for i, contract := range data.Contracts { contractAddr, err := sdk.AccAddressFromBech32(contract.ContractAddress) if err != nil { @@ -51,7 +50,6 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) ([]ab if err != nil { return nil, errorsmod.Wrapf(err, "contract number %d", i) } - maxContractID = i + 1 // not ideal but max(contractID) is not persisted otherwise } for i, seq := range data.Sequences { @@ -66,9 +64,12 @@ func InitGenesis(ctx sdk.Context, keeper *Keeper, data types.GenesisState) ([]ab if seqVal <= maxCodeID { return nil, errorsmod.Wrapf(types.ErrInvalid, "seq %s with value: %d must be greater than: %d ", string(types.KeySequenceCodeID), seqVal, maxCodeID) } - seqVal = keeper.PeekAutoIncrementID(ctx, types.KeySequenceInstanceID) - if seqVal <= uint64(maxContractID) { - return nil, errorsmod.Wrapf(types.ErrInvalid, "seq %s with value: %d must be greater than: %d ", string(types.KeySequenceInstanceID), seqVal, maxContractID) + // ensure next classic address is unused so that we know the sequence is good + rCtx, _ := ctx.CacheContext() + seqVal = keeper.PeekAutoIncrementID(rCtx, types.KeySequenceInstanceID) + addr := keeper.ClassicAddressGenerator()(rCtx, seqVal, nil) + if keeper.HasContractInfo(ctx, addr) { + return nil, errorsmod.Wrapf(types.ErrInvalid, "value: %d for seq %s was used already", seqVal, string(types.KeySequenceInstanceID)) } return nil, nil } diff --git a/x/wasm/keeper/genesis_test.go b/x/wasm/keeper/genesis_test.go index 3b4e51cbad..2ad87f7e5f 100644 --- a/x/wasm/keeper/genesis_test.go +++ b/x/wasm/keeper/genesis_test.go @@ -154,6 +154,20 @@ func TestGenesisExportImport(t *testing.T) { } } +func TestGenesisExportImportWithPredictableAddress(t *testing.T) { + ctx, keepers := CreateTestInput(t, false, AvailableCapabilities) + k := keepers.WasmKeeper + eCtx, _ := ctx.CacheContext() + codeID := StoreReflectContract(t, eCtx, keepers).CodeID + creator := RandomAccountAddress(t) + _, _, err := keepers.ContractKeeper.Instantiate2(eCtx, codeID, creator, nil, []byte("{}"), "testing", nil, []byte("my_salt"), false) + require.NoError(t, err) + genesisState := ExportGenesis(eCtx, k) + // when imported + _, err = InitGenesis(ctx, k, *genesisState) + require.NoError(t, err) +} + func TestGenesisInit(t *testing.T) { wasmCode, err := os.ReadFile("./testdata/hackatom.wasm") require.NoError(t, err) @@ -438,7 +452,7 @@ func TestGenesisInit(t *testing.T) { Params: types.DefaultParams(), }, }, - "prevent contract id seq init value == count contracts": { + "prevent contract id seq init value not high enough": { src: types.GenesisState{ Codes: []types.Code{{ CodeID: firstCodeID,