Skip to content

Commit

Permalink
Merge pull request #6 from sikkatech/master
Browse files Browse the repository at this point in the history
Added genesis functions
  • Loading branch information
ethanfrey authored Jan 13, 2020
2 parents d12c434 + 1956070 commit 3fae154
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 51 deletions.
12 changes: 10 additions & 2 deletions x/wasm/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@ var (
ErrInstantiateFailed = types.ErrInstantiateFailed
ErrExecuteFailed = types.ErrExecuteFailed
ErrGasLimit = types.ErrGasLimit
ErrInvalidGenesis = types.ErrInvalidGenesis
GetCodeKey = types.GetCodeKey
GetContractAddressKey = types.GetContractAddressKey
GetContractStorePrefixKey = types.GetContractStorePrefixKey
NewCodeInfo = types.NewCodeInfo
NewParams = types.NewParams
NewWasmCoins = types.NewWasmCoins
NewContract = types.NewContract
NewContractInfo = types.NewContractInfo
CosmosResult = types.CosmosResult

// genesis aliases
ValidateGenesis = types.ValidateGenesis
InitGenesis = keeper.InitGenesis
ExportGenesis = keeper.ExportGenesis

// variable aliases
ModuleCdc = types.ModuleCdc
KeyLastCodeID = types.KeyLastCodeID
Expand All @@ -70,5 +76,7 @@ type (
MsgInstantiateContract = types.MsgInstantiateContract
MsgExecuteContract = types.MsgExecuteContract
CodeInfo = types.CodeInfo
Contract = types.Contract
ContractInfo = types.ContractInfo

GenesisState = types.GenesisState
)
29 changes: 0 additions & 29 deletions x/wasm/genesis.go

This file was deleted.

71 changes: 71 additions & 0 deletions x/wasm/internal/keeper/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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 _, code := range data.Codes {
newId, err := keeper.Create(ctx, code.CodeInfo.Creator, code.CodesBytes)
if err != nil {
panic(err)
}
newInfo := keeper.GetCodeInfo(ctx, newId)
if !bytes.Equal(code.CodeInfo.CodeHash, newInfo.CodeHash) {
panic("code hashes not same")
}
}

for _, contract := range data.Contracts {
keeper.setContractInfo(ctx, contract.ContractAddress, contract.ContractInfo)
keeper.setContractState(ctx, contract.ContractAddress, contract.ContractState)
}

}

// 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.GetNextCodeID(ctx)
for i := uint64(1); i < maxCodeID; i++ {
bytecode, err := keeper.GetByteCode(ctx, i)
if err != nil {
panic(err)
}
genState.Codes = append(genState.Codes, types.Code{
CodeInfo: *keeper.GetCodeInfo(ctx, i),
CodesBytes: bytecode,
})
}

keeper.ListContractInfo(ctx, func(addr sdk.AccAddress, contract types.ContractInfo) bool {
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.Contracts = append(genState.Contracts, types.Contract{
ContractAddress: addr,
ContractInfo: contract,
ContractState: state,
})

return false
})

return genState
}
35 changes: 29 additions & 6 deletions x/wasm/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, creator sdk.AccAddress, codeID uint
}

// persist instance
instance := types.NewContract(codeID, creator, string(initMsg))
instance := types.NewContractInfo(codeID, creator, string(initMsg))
// 0x02 | contractAddress (sdk.AccAddress) -> Instance
store.Set(types.GetContractAddressKey(contractAddress), k.cdc.MustMarshalBinaryBare(instance))

Expand All @@ -129,7 +129,7 @@ func (k Keeper) Instantiate(ctx sdk.Context, creator sdk.AccAddress, codeID uint
func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, coins sdk.Coins, msgs []byte) (sdk.Result, sdk.Error) {
store := ctx.KVStore(k.storeKey)

var contract types.Contract
var contract types.ContractInfo
contractBz := store.Get(types.GetContractAddressKey(contractAddress))
if contractBz != nil {
k.cdc.MustUnmarshalBinaryBare(contractBz, &contract)
Expand Down Expand Up @@ -167,9 +167,9 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller
return types.CosmosResult(*res), nil
}

func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.Contract {
func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *types.ContractInfo {
store := ctx.KVStore(k.storeKey)
var contract types.Contract
var contract types.ContractInfo
contractBz := store.Get(types.GetContractAddressKey(contractAddress))
if contractBz == nil {
return nil
Expand All @@ -178,11 +178,16 @@ func (k Keeper) GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress)
return &contract
}

func (k Keeper) ListContractInfo(ctx sdk.Context, cb func(sdk.AccAddress, types.Contract) bool) {
func (k Keeper) setContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress, contract types.ContractInfo) {
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.ContractInfo) bool) {
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractKeyPrefix)
iter := prefixStore.Iterator(nil, nil)
for ; iter.Valid(); iter.Next() {
var contract types.Contract
var contract types.ContractInfo
k.cdc.MustUnmarshalBinaryBare(iter.Value(), &contract)
// cb returns true to stop early
if cb(iter.Key(), contract) {
Expand All @@ -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
Expand Down Expand Up @@ -328,6 +341,16 @@ func (k Keeper) generateContractAddress(ctx sdk.Context, codeID uint64) sdk.AccA
return addrFromUint64(contractID)
}

func (k Keeper) GetNextCodeID(ctx sdk.Context) uint64 {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyLastCodeID)
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)
Expand Down
11 changes: 3 additions & 8 deletions x/wasm/internal/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func queryContractInfo(ctx sdk.Context, bech string, req abci.RequestQuery, keep

func queryContractList(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
var addrs []string
keeper.ListContractInfo(ctx, func(addr sdk.AccAddress, _ types.Contract) bool {
keeper.ListContractInfo(ctx, func(addr sdk.AccAddress, _ types.ContractInfo) bool {
addrs = append(addrs, addr.String())
return false
})
Expand All @@ -67,21 +67,16 @@ 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 {
return nil, sdk.ErrUnknownRequest(err.Error())
}
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()),
}
Expand Down
6 changes: 6 additions & 0 deletions x/wasm/internal/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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))
}
28 changes: 28 additions & 0 deletions x/wasm/internal/types/genesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package types

import sdk "github.com/cosmos/cosmos-sdk/types"

// GenesisState is the struct representation of the export genesis
type GenesisState struct {
Codes []Code `json:"codes"`
Contracts []Contract `json:"contracts"`
}

// Code struct encompasses CodeInfo and CodeBytes
type Code struct {
CodeInfo CodeInfo `json:"code_info"`
CodesBytes []byte `json:"code_bytes"`
}

// Contract struct encompasses ContractAddress, ContractInfo, and ContractState
type Contract struct {
ContractAddress sdk.AccAddress `json:"contract_address"`
ContractInfo ContractInfo `json:"contract_info"`
ContractState []Model `json:"contract_state"`
}

// ValidateGenesis performs basic validation of supply genesis data returning an
// error for any failed validation criteria.
func ValidateGenesis(data GenesisState) error {
return nil
}
16 changes: 11 additions & 5 deletions x/wasm/internal/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -20,8 +26,8 @@ func NewCodeInfo(codeHash []byte, creator sdk.AccAddress) CodeInfo {
}
}

// Contract stores a WASM contract instance
type Contract struct {
// ContractInfo stores a WASM contract instance
type ContractInfo struct {
CodeID uint64 `json:"code_id"`
Creator sdk.AccAddress `json:"creator"`
InitMsg string `json:"init_msg"`
Expand Down Expand Up @@ -58,9 +64,9 @@ func NewWasmCoins(cosmosCoins sdk.Coins) (wasmCoins []wasmTypes.Coin) {
return wasmCoins
}

// NewContract creates a new instance of a given WASM contract
func NewContract(codeID uint64, creator sdk.AccAddress, initMsg string) Contract {
return Contract{
// NewContractInfo creates a new instance of a given WASM contract info
func NewContractInfo(codeID uint64, creator sdk.AccAddress, initMsg string) ContractInfo {
return ContractInfo{
CodeID: codeID,
Creator: creator,
InitMsg: initMsg,
Expand Down
2 changes: 1 addition & 1 deletion x/wasm/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ func assertContractInfo(t *testing.T, q sdk.Querier, ctx sdk.Context, addr sdk.A
bz, sdkerr := q(ctx, path, abci.RequestQuery{})
require.NoError(t, sdkerr)

var res Contract
var res ContractInfo
err := json.Unmarshal(bz, &res)
require.NoError(t, err)

Expand Down

0 comments on commit 3fae154

Please sign in to comment.