mirror of https://github.com/certusone/wasmd.git
added genesis functions
This commit is contained in:
parent
d12c434ab6
commit
5d21232326
|
@ -45,6 +45,7 @@ var (
|
|||
ErrInstantiateFailed = types.ErrInstantiateFailed
|
||||
ErrExecuteFailed = types.ErrExecuteFailed
|
||||
ErrGasLimit = types.ErrGasLimit
|
||||
ErrInvalidGenesis = types.ErrInvalidGenesis
|
||||
GetCodeKey = types.GetCodeKey
|
||||
GetContractAddressKey = types.GetContractAddressKey
|
||||
GetContractStorePrefixKey = types.GetContractStorePrefixKey
|
||||
|
@ -54,6 +55,11 @@ var (
|
|||
NewContract = types.NewContract
|
||||
CosmosResult = types.CosmosResult
|
||||
|
||||
// genesis aliases
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
InitGenesis = keeper.InitGenesis
|
||||
ExportGenesis = keeper.ExportGenesis
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
KeyLastCodeID = types.KeyLastCodeID
|
||||
|
@ -71,4 +77,6 @@ type (
|
|||
MsgExecuteContract = types.MsgExecuteContract
|
||||
CodeInfo = types.CodeInfo
|
||||
Contract = types.Contract
|
||||
|
||||
GenesisState = types.GenesisState
|
||||
)
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package wasm
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
// authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
// "github.com/cosmwasm/wasmd/x/wasm/internal/types"
|
||||
)
|
||||
|
||||
type GenesisState struct {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// InitGenesis sets supply information for genesis.
|
||||
//
|
||||
// CONTRACT: all types of accounts must have been already initialized/created
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// ExportGenesis returns a GenesisState for a given context and keeper.
|
||||
func ExportGenesis(ctx sdk.Context, keeper Keeper) GenesisState {
|
||||
return GenesisState{}
|
||||
}
|
||||
|
||||
// ValidateGenesis performs basic validation of supply genesis data returning an
|
||||
// error for any failed validation criteria.
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmwasm/wasmd/x/wasm/internal/types"
|
||||
// authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
// "github.com/cosmwasm/wasmd/x/wasm/internal/types"
|
||||
)
|
||||
|
||||
// InitGenesis sets supply information for genesis.
|
||||
//
|
||||
// CONTRACT: all types of accounts must have been already initialized/created
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||
for id, info := range data.CodeInfos {
|
||||
bytecode := data.CodesBytes[id]
|
||||
newId, err := keeper.Create(ctx, info.Creator, bytecode)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newInfo := keeper.GetCodeInfo(ctx, newId)
|
||||
if !info.Creator.Equals(newInfo.Creator) {
|
||||
panic("code creators not same")
|
||||
}
|
||||
if bytes.Compare(info.CodeHash, newInfo.CodeHash) != 0 {
|
||||
panic("code hashes not same")
|
||||
}
|
||||
}
|
||||
|
||||
for i, addr := range data.ContractAddresses {
|
||||
info := data.ContractInfos[i]
|
||||
state := data.ContractStates[i]
|
||||
|
||||
keeper.setContractInfo(ctx, addr, info)
|
||||
keeper.setContractState(ctx, addr, state)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ExportGenesis returns a GenesisState for a given context and keeper.
|
||||
func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
||||
var genState types.GenesisState
|
||||
|
||||
maxCodeID := keeper.GetLastID(ctx, types.KeyLastCodeID)
|
||||
for i := uint64(0); i < maxCodeID; i++ {
|
||||
genState.CodeInfos = append(genState.CodeInfos, *keeper.GetCodeInfo(ctx, i))
|
||||
bytecode, err := keeper.GetByteCode(ctx, i)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
genState.CodesBytes = append(genState.CodesBytes, bytecode)
|
||||
}
|
||||
|
||||
keeper.ListContractInfo(ctx, func(addr sdk.AccAddress, contract types.Contract) bool {
|
||||
genState.ContractAddresses = append(genState.ContractAddresses, addr)
|
||||
genState.ContractInfos = append(genState.ContractInfos, contract)
|
||||
|
||||
contractStateIterator := keeper.GetContractState(ctx, addr)
|
||||
var state []types.Model
|
||||
for ; contractStateIterator.Valid(); contractStateIterator.Next() {
|
||||
m := types.Model{
|
||||
Key: string(contractStateIterator.Key()),
|
||||
Value: string(contractStateIterator.Value()),
|
||||
}
|
||||
state = append(state, m)
|
||||
}
|
||||
genState.ContractStates = append(genState.ContractStates, state)
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
return genState
|
||||
}
|
|
@ -178,6 +178,11 @@ func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress)
|
|||
return &contract
|
||||
}
|
||||
|
||||
func (k Keeper) setContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress, contract types.Contract) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshalBinaryBare(contract))
|
||||
}
|
||||
|
||||
func (k Keeper) ListContractInfo(ctx sdk.Context, cb func(sdk.AccAddress, types.Contract) bool) {
|
||||
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractKeyPrefix)
|
||||
iter := prefixStore.Iterator(nil, nil)
|
||||
|
@ -197,6 +202,14 @@ func (k Keeper) GetContractState(ctx sdk.Context, contractAddress sdk.AccAddress
|
|||
return prefixStore.Iterator(nil, nil)
|
||||
}
|
||||
|
||||
func (k Keeper) setContractState(ctx sdk.Context, contractAddress sdk.AccAddress, models []types.Model) {
|
||||
prefixStoreKey := types.GetContractStorePrefixKey(contractAddress)
|
||||
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), prefixStoreKey)
|
||||
for _, model := range models {
|
||||
prefixStore.Set([]byte(model.Key), []byte(model.Value))
|
||||
}
|
||||
}
|
||||
|
||||
func (k Keeper) GetCodeInfo(ctx sdk.Context, codeID uint64) *types.CodeInfo {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
var codeInfo types.CodeInfo
|
||||
|
@ -328,6 +341,16 @@ func (k Keeper) generateContractAddress(ctx sdk.Context, codeID uint64) sdk.AccA
|
|||
return addrFromUint64(contractID)
|
||||
}
|
||||
|
||||
func (k Keeper) GetLastID(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) autoIncrementID(ctx sdk.Context, lastIDKey []byte) uint64 {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(lastIDKey)
|
||||
|
|
|
@ -67,11 +67,6 @@ func queryContractList(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([
|
|||
return bz, nil
|
||||
}
|
||||
|
||||
type model struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func queryContractState(ctx sdk.Context, bech string, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
|
||||
addr, err := sdk.AccAddressFromBech32(bech)
|
||||
if err != nil {
|
||||
|
@ -79,9 +74,9 @@ func queryContractState(ctx sdk.Context, bech string, req abci.RequestQuery, kee
|
|||
}
|
||||
iter := keeper.GetContractState(ctx, addr)
|
||||
|
||||
var state []model
|
||||
var state []types.Model
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
m := model{
|
||||
m := types.Model{
|
||||
Key: string(iter.Key()),
|
||||
Value: string(iter.Value()),
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ const (
|
|||
CodeInstantiateFailed sdk.CodeType = 3
|
||||
CodeExecuteFailed sdk.CodeType = 4
|
||||
CodeGasLimit sdk.CodeType = 5
|
||||
CodeInvalidGenesis sdk.CodeType = 6
|
||||
)
|
||||
|
||||
// ErrCreateFailed error for wasm code that has already been uploaded or failed
|
||||
|
@ -41,3 +42,8 @@ func ErrExecuteFailed(err error) sdk.Error {
|
|||
func ErrGasLimit(msg string) sdk.Error {
|
||||
return sdk.NewError(DefaultCodespace, CodeGasLimit, fmt.Sprintf("insufficient gas: %s", msg))
|
||||
}
|
||||
|
||||
// ErrInvalidGenesis error for out of gas
|
||||
func ErrInvalidGenesis(msg string) sdk.Error {
|
||||
return sdk.NewError(DefaultCodespace, CodeInvalidGenesis, fmt.Sprintf("invalid genesis: %s", msg))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// GenesisState is the struct representation of the export genesis
|
||||
type GenesisState struct {
|
||||
CodeInfos []CodeInfo `json:"code_infos"`
|
||||
CodesBytes [][]byte `json:"code_bytes"`
|
||||
ContractAddresses []sdk.AccAddress `json:"contract_addresses"`
|
||||
ContractInfos []Contract `json:"contract_infos"`
|
||||
ContractStates [][]Model `json:"contract_states"`
|
||||
}
|
||||
|
||||
// ValidateGenesis performs basic validation of supply genesis data returning an
|
||||
// error for any failed validation criteria.
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
if len(data.CodesBytes) != len(data.CodeInfos) {
|
||||
return ErrInvalidGenesis("length of Codes != length of Code Infos")
|
||||
}
|
||||
if len(data.ContractAddresses) != len(data.ContractInfos) {
|
||||
return ErrInvalidGenesis("invalid number of Contract Infos")
|
||||
}
|
||||
if len(data.ContractAddresses) != len(data.ContractStates) {
|
||||
return ErrInvalidGenesis("invalid number of Contract States")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -6,6 +6,12 @@ import (
|
|||
auth "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
)
|
||||
|
||||
// Model is a struct that holds a KV pair
|
||||
type Model struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// CodeInfo is data for the uploaded contract WASM code
|
||||
type CodeInfo struct {
|
||||
CodeHash []byte `json:"code_hash"`
|
||||
|
|
Loading…
Reference in New Issue