mirror of https://github.com/certusone/wasmd.git
Merge pull request #142 from CosmWasm/genesis_io_tests
Add genesis ex-/import for `lastContractId` sequence
This commit is contained in:
commit
8aad0c9630
1
go.mod
1
go.mod
|
@ -8,6 +8,7 @@ require (
|
||||||
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a // indirect
|
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a // indirect
|
||||||
github.com/cosmos/cosmos-sdk v0.38.3
|
github.com/cosmos/cosmos-sdk v0.38.3
|
||||||
github.com/golang/mock v1.4.3 // indirect
|
github.com/golang/mock v1.4.3 // indirect
|
||||||
|
github.com/google/gofuzz v1.0.0
|
||||||
github.com/gorilla/mux v1.7.4
|
github.com/gorilla/mux v1.7.4
|
||||||
github.com/onsi/ginkgo v1.8.0 // indirect
|
github.com/onsi/ginkgo v1.8.0 // indirect
|
||||||
github.com/onsi/gomega v1.5.0 // indirect
|
github.com/onsi/gomega v1.5.0 // indirect
|
||||||
|
|
|
@ -29,6 +29,9 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||||
keeper.setContractState(ctx, contract.ContractAddress, contract.ContractState)
|
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.
|
// 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
|
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
|
return genState
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||||
|
wasmTypes "github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/store"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||||
|
fuzz "github.com/google/gofuzz"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
dbm "github.com/tendermint/tm-db"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenesisExportImport(t *testing.T) {
|
||||||
|
srcKeeper, srcCtx, srcCleanup := setupKeeper(t)
|
||||||
|
defer srcCleanup()
|
||||||
|
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 < 25; i++ {
|
||||||
|
var (
|
||||||
|
codeInfo types.CodeInfo
|
||||||
|
contract types.ContractInfo
|
||||||
|
stateModels []types.Model
|
||||||
|
)
|
||||||
|
f.Fuzz(&codeInfo)
|
||||||
|
f.Fuzz(&contract)
|
||||||
|
f.Fuzz(&stateModels)
|
||||||
|
|
||||||
|
codeID, err := srcKeeper.Create(srcCtx, codeInfo.Creator, wasmCode, codeInfo.Source, codeInfo.Builder)
|
||||||
|
require.NoError(t, err)
|
||||||
|
contract.CodeID = codeID
|
||||||
|
contractAddr := srcKeeper.generateContractAddress(srcCtx, codeID)
|
||||||
|
srcKeeper.setContractInfo(srcCtx, contractAddr, &contract)
|
||||||
|
srcKeeper.setContractState(srcCtx, contractAddr, stateModels)
|
||||||
|
}
|
||||||
|
|
||||||
|
// export
|
||||||
|
genesisState := ExportGenesis(srcCtx, srcKeeper)
|
||||||
|
|
||||||
|
// re-import
|
||||||
|
dstKeeper, dstCtx, dstCleanup := setupKeeper(t)
|
||||||
|
defer dstCleanup()
|
||||||
|
InitGenesis(dstCtx, dstKeeper, genesisState)
|
||||||
|
|
||||||
|
// compare whole DB
|
||||||
|
srcIT := srcCtx.KVStore(srcKeeper.storeKey).Iterator(nil, nil)
|
||||||
|
dstIT := dstCtx.KVStore(dstKeeper.storeKey).Iterator(nil, nil)
|
||||||
|
|
||||||
|
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(), "element (%d): %s", i, srcIT.Key())
|
||||||
|
srcIT.Next()
|
||||||
|
dstIT.Next()
|
||||||
|
}
|
||||||
|
require.False(t, dstIT.Valid())
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupKeeper(t *testing.T) (Keeper, sdk.Context, func()) {
|
||||||
|
tempDir, err := ioutil.TempDir("", "wasm")
|
||||||
|
require.NoError(t, err)
|
||||||
|
cleanup := func() { os.RemoveAll(tempDir) }
|
||||||
|
//t.Cleanup(cleanup) todo: add with Go 1.14
|
||||||
|
|
||||||
|
keyContract := sdk.NewKVStoreKey(wasmTypes.StoreKey)
|
||||||
|
db := dbm.NewMemDB()
|
||||||
|
ms := store.NewCommitMultiStore(db)
|
||||||
|
ms.MountStoreWithDB(keyContract, sdk.StoreTypeIAVL, db)
|
||||||
|
require.NoError(t, ms.LoadLatestVersion())
|
||||||
|
|
||||||
|
ctx := sdk.NewContext(ms, abci.Header{
|
||||||
|
Height: 1234567,
|
||||||
|
Time: time.Date(2020, time.April, 22, 12, 0, 0, 0, time.UTC),
|
||||||
|
}, false, log.NewNopLogger())
|
||||||
|
|
||||||
|
cdc := MakeTestCodec()
|
||||||
|
wasmConfig := wasmTypes.DefaultWasmConfig()
|
||||||
|
|
||||||
|
srcKeeper := NewKeeper(cdc, keyContract, auth.AccountKeeper{}, nil, staking.Keeper{}, nil, tempDir, wasmConfig, "", nil, nil)
|
||||||
|
return srcKeeper, ctx, cleanup
|
||||||
|
}
|
|
@ -485,6 +485,23 @@ func (k Keeper) autoIncrementID(ctx sdk.Context, lastIDKey []byte) uint64 {
|
||||||
return id
|
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 {
|
func addrFromUint64(id uint64) sdk.AccAddress {
|
||||||
addr := make([]byte, 20)
|
addr := make([]byte, 20)
|
||||||
addr[0] = 'C'
|
addr[0] = 'C'
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
fuzz "github.com/google/gofuzz"
|
||||||
|
tmBytes "github.com/tendermint/tendermint/libs/bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FuzzAddr(m *sdk.AccAddress, c fuzz.Continue) {
|
||||||
|
*m = make([]byte, 20)
|
||||||
|
c.Read(*m)
|
||||||
|
}
|
||||||
|
func FuzzAbsoluteTxPosition(m *types.AbsoluteTxPosition, c fuzz.Continue) {
|
||||||
|
m.BlockHeight = int64(c.RandUint64()) // can't be negative
|
||||||
|
m.TxIndex = c.RandUint64()
|
||||||
|
}
|
||||||
|
|
||||||
|
func FuzzContractInfo(m *types.ContractInfo, c fuzz.Continue) {
|
||||||
|
const maxSize = 1024
|
||||||
|
m.CodeID = c.RandUint64()
|
||||||
|
FuzzAddr(&m.Creator, c)
|
||||||
|
FuzzAddr(&m.Admin, c)
|
||||||
|
m.Label = c.RandString()
|
||||||
|
m.InitMsg = make([]byte, c.RandUint64()%maxSize)
|
||||||
|
c.Read(m.InitMsg)
|
||||||
|
c.Fuzz(&m.Created)
|
||||||
|
c.Fuzz(&m.LastUpdated)
|
||||||
|
m.PreviousCodeID = c.RandUint64()
|
||||||
|
}
|
||||||
|
func FuzzStateModel(m *types.Model, c fuzz.Continue) {
|
||||||
|
m.Key = tmBytes.HexBytes(c.RandString())
|
||||||
|
c.Fuzz(&m.Value)
|
||||||
|
}
|
|
@ -2,10 +2,16 @@ package types
|
||||||
|
|
||||||
import sdk "github.com/cosmos/cosmos-sdk/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
|
// GenesisState is the struct representation of the export genesis
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
Codes []Code `json:"codes"`
|
Codes []Code `json:"codes"`
|
||||||
Contracts []Contract `json:"contracts"`
|
Contracts []Contract `json:"contracts"`
|
||||||
|
Sequences []Sequence `json:"sequences"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code struct encompasses CodeInfo and CodeBytes
|
// Code struct encompasses CodeInfo and CodeBytes
|
||||||
|
|
Loading…
Reference in New Issue