diff --git a/x/wasm/internal/keeper/genesis.go b/x/wasm/internal/keeper/genesis.go index d3341de5f1..96e39022b8 100644 --- a/x/wasm/internal/keeper/genesis.go +++ b/x/wasm/internal/keeper/genesis.go @@ -29,6 +29,9 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) { keeper.setContractState(ctx, contract.ContractAddress, contract.ContractState) } + for _, seq := range data.Sequences { + keeper.setAutoIncrementID(ctx, seq.IDKey, seq.Value) + } } // ExportGenesis returns a GenesisState for a given context and keeper. @@ -67,5 +70,13 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { return false }) + // types.KeyLastCodeID is updated via keeper create + for _, k := range [][]byte{types.KeyLastInstanceID} { + genState.Sequences = append(genState.Sequences, types.Sequence{ + IDKey: k, + Value: keeper.peekAutoIncrementID(ctx, k), + }) + } + return genState } diff --git a/x/wasm/internal/keeper/genesis_test.go b/x/wasm/internal/keeper/genesis_test.go index 67694d9564..9e2fb3bd0c 100644 --- a/x/wasm/internal/keeper/genesis_test.go +++ b/x/wasm/internal/keeper/genesis_test.go @@ -24,8 +24,9 @@ func TestGenesisExportImport(t *testing.T) { wasmCode, err := ioutil.ReadFile("./testdata/contract.wasm") require.NoError(t, err) + // store some test data f := fuzz.New().Funcs(FuzzAddr, FuzzAbsoluteTxPosition, FuzzContractInfo, FuzzStateModel) - for i := 0; i < 20; i++ { + for i := 0; i < 25; i++ { var ( codeInfo types.CodeInfo contract types.ContractInfo @@ -57,7 +58,7 @@ func TestGenesisExportImport(t *testing.T) { for i := 0; srcIT.Valid(); i++ { require.True(t, dstIT.Valid(), "destination DB has less elements than source. Missing: %q", srcIT.Key()) require.Equal(t, srcIT.Key(), dstIT.Key(), i) - require.Equal(t, srcIT.Value(), dstIT.Value(), i) + require.Equal(t, srcIT.Value(), dstIT.Value(), "element (%d): %s", i, srcIT.Key()) srcIT.Next() dstIT.Next() } diff --git a/x/wasm/internal/keeper/keeper.go b/x/wasm/internal/keeper/keeper.go index 69e278667b..b2b9756043 100644 --- a/x/wasm/internal/keeper/keeper.go +++ b/x/wasm/internal/keeper/keeper.go @@ -485,6 +485,23 @@ func (k Keeper) autoIncrementID(ctx sdk.Context, lastIDKey []byte) uint64 { return id } +// peekAutoIncrementID reads the current value without incrementing it. +func (k Keeper) peekAutoIncrementID(ctx sdk.Context, lastIDKey []byte) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(lastIDKey) + id := uint64(1) + if bz != nil { + id = binary.BigEndian.Uint64(bz) + } + return id +} + +func (k Keeper) setAutoIncrementID(ctx sdk.Context, lastIDKey []byte, val uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(val) + store.Set(lastIDKey, bz) +} + func addrFromUint64(id uint64) sdk.AccAddress { addr := make([]byte, 20) addr[0] = 'C' diff --git a/x/wasm/internal/types/genesis.go b/x/wasm/internal/types/genesis.go index 12ee39597f..1a36fff6ec 100644 --- a/x/wasm/internal/types/genesis.go +++ b/x/wasm/internal/types/genesis.go @@ -2,10 +2,16 @@ package types import sdk "github.com/cosmos/cosmos-sdk/types" +type Sequence struct { + IDKey []byte `json:"id_key"` + Value uint64 `json:"value"` +} + // GenesisState is the struct representation of the export genesis type GenesisState struct { Codes []Code `json:"codes"` Contracts []Contract `json:"contracts"` + Sequences []Sequence `json:"sequences"` } // Code struct encompasses CodeInfo and CodeBytes