Merge pull request #416 from cosmos/feature/initgen
Initialize Genesis State
This commit is contained in:
commit
69c316f5de
@ -19,7 +19,7 @@ import (
|
||||
|
||||
var mainHeaderKey = []byte("header")
|
||||
|
||||
// BaseApp - The ABCI application
|
||||
// The ABCI application
|
||||
type BaseApp struct {
|
||||
logger log.Logger
|
||||
|
||||
@ -32,33 +32,38 @@ type BaseApp struct {
|
||||
// Main (uncached) state
|
||||
cms sdk.CommitMultiStore
|
||||
|
||||
// Unmarshal []byte into sdk.Tx
|
||||
// unmarshal []byte into sdk.Tx
|
||||
txDecoder sdk.TxDecoder
|
||||
|
||||
// Ante handler for fee and auth.
|
||||
// unmarshal rawjsonbytes to initialize the application
|
||||
// TODO unexpose and call from InitChain
|
||||
InitStater sdk.InitStater
|
||||
|
||||
// ante handler for fee and auth
|
||||
defaultAnteHandler sdk.AnteHandler
|
||||
|
||||
// Handle any kind of message.
|
||||
// handle any kind of message
|
||||
router Router
|
||||
|
||||
//--------------------
|
||||
// Volatile
|
||||
|
||||
// CheckTx state, a cache-wrap of `.cms`.
|
||||
// CheckTx state, a cache-wrap of `.cms`
|
||||
msCheck sdk.CacheMultiStore
|
||||
|
||||
// DeliverTx state, a cache-wrap of `.cms`.
|
||||
// DeliverTx state, a cache-wrap of `.cms`
|
||||
msDeliver sdk.CacheMultiStore
|
||||
|
||||
// Current block header
|
||||
// current block header
|
||||
header *abci.Header
|
||||
|
||||
// Cached validator changes from DeliverTx.
|
||||
// cached validator changes from DeliverTx
|
||||
valUpdates []abci.Validator
|
||||
}
|
||||
|
||||
var _ abci.Application = &BaseApp{}
|
||||
|
||||
// Create and name new BaseApp
|
||||
func NewBaseApp(name string) *BaseApp {
|
||||
var baseapp = &BaseApp{
|
||||
logger: makeDefaultLogger(),
|
||||
@ -88,22 +93,26 @@ func (app *BaseApp) initMultiStore() {
|
||||
app.cms = cms
|
||||
}
|
||||
|
||||
// BaseApp Name
|
||||
func (app *BaseApp) Name() string {
|
||||
return app.name
|
||||
}
|
||||
|
||||
// Mount a store to the provided key in the BaseApp multistore
|
||||
func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
|
||||
app.cms.MountStoreWithDB(key, typ, app.db)
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) {
|
||||
app.txDecoder = txDecoder
|
||||
}
|
||||
|
||||
func (app *BaseApp) SetInitStater(initStater sdk.InitStater) {
|
||||
app.InitStater = initStater
|
||||
}
|
||||
func (app *BaseApp) SetDefaultAnteHandler(ah sdk.AnteHandler) {
|
||||
app.defaultAnteHandler = ah
|
||||
}
|
||||
|
||||
func (app *BaseApp) Router() Router {
|
||||
return app.router
|
||||
}
|
||||
@ -111,14 +120,15 @@ func (app *BaseApp) Router() Router {
|
||||
/* TODO consider:
|
||||
func (app *BaseApp) SetBeginBlocker(...) {}
|
||||
func (app *BaseApp) SetEndBlocker(...) {}
|
||||
func (app *BaseApp) SetInitStater(...) {}
|
||||
*/
|
||||
|
||||
// TODO add description
|
||||
func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error {
|
||||
app.cms.LoadLatestVersion()
|
||||
return app.initFromStore(mainKey)
|
||||
}
|
||||
|
||||
// Load application version
|
||||
func (app *BaseApp) LoadVersion(version int64, mainKey sdk.StoreKey) error {
|
||||
app.cms.LoadVersion(version)
|
||||
return app.initFromStore(mainKey)
|
||||
@ -174,7 +184,7 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo {
|
||||
|
||||
lastCommitID := app.cms.LastCommitID()
|
||||
@ -186,15 +196,16 @@ func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOption) {
|
||||
// TODO: Implement
|
||||
return
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
|
||||
// TODO: Use req.Validators
|
||||
// TODO: Use req.AppStateJSON (?)
|
||||
return
|
||||
}
|
||||
|
||||
@ -209,7 +220,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
return queryable.Query(req)
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) {
|
||||
// NOTE: For consistency we should unset these upon EndBlock.
|
||||
app.header = &req.Header
|
||||
@ -219,7 +230,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
|
||||
return
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {
|
||||
|
||||
// Decode the Tx.
|
||||
@ -245,7 +256,7 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {
|
||||
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
|
||||
|
||||
// Decode the Tx.
|
||||
@ -333,7 +344,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
return result
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) {
|
||||
res.ValidatorUpdates = app.valUpdates
|
||||
app.valUpdates = nil
|
||||
@ -343,7 +354,7 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc
|
||||
return
|
||||
}
|
||||
|
||||
// Implements ABCI.
|
||||
// Implements ABCI
|
||||
func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||
app.msDeliver.Write()
|
||||
commitID := app.cms.Commit()
|
||||
@ -361,9 +372,8 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
||||
func (app *BaseApp) getMultiStore(isCheckTx bool) sdk.MultiStore {
|
||||
if isCheckTx {
|
||||
return app.msCheck
|
||||
} else {
|
||||
return app.msDeliver
|
||||
}
|
||||
return app.msDeliver
|
||||
}
|
||||
|
||||
// Return index of list with validator of same PubKey, or -1 if no match
|
||||
|
||||
@ -106,7 +106,7 @@ func TestBasic(t *testing.T) {
|
||||
}
|
||||
|
||||
// Not matched.
|
||||
j += 1
|
||||
j++
|
||||
}
|
||||
}
|
||||
assert.Equal(t, len(valUpdates), 0, "Some validator updates were unexpected")
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package baseapp
|
||||
|
||||
import sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// NewContext returns a new Context suitable for AnteHandler (and indirectly Handler) processing.
|
||||
// NOTE: txBytes may be nil to support TestApp.RunCheckTx
|
||||
@ -12,6 +14,7 @@ func (app *BaseApp) NewContext(isCheckTx bool, txBytes []byte) sdk.Context {
|
||||
} else {
|
||||
store = app.msDeliver
|
||||
}
|
||||
|
||||
if store == nil {
|
||||
panic("BaseApp.NewContext() requires BeginBlock(): missing store")
|
||||
}
|
||||
|
||||
32
baseapp/genesis.go
Normal file
32
baseapp/genesis.go
Normal file
@ -0,0 +1,32 @@
|
||||
package baseapp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// TODO: remove from here and pass the AppState
|
||||
// through InitChain
|
||||
|
||||
// GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set.
|
||||
type GenesisDoc struct {
|
||||
AppState json.RawMessage `json:"app_state,omitempty"`
|
||||
}
|
||||
|
||||
// GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc.
|
||||
func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) {
|
||||
if genDocFile == "" {
|
||||
var g GenesisDoc
|
||||
return &g, nil
|
||||
}
|
||||
jsonBlob, err := ioutil.ReadFile(genDocFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
genDoc := GenesisDoc{}
|
||||
err = json.Unmarshal(jsonBlob, &genDoc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &genDoc, nil
|
||||
}
|
||||
@ -6,6 +6,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Router - TODO add description
|
||||
type Router interface {
|
||||
AddRoute(r string, h sdk.Handler)
|
||||
Route(path string) (h sdk.Handler)
|
||||
@ -20,6 +21,9 @@ type router struct {
|
||||
routes []route
|
||||
}
|
||||
|
||||
// nolint
|
||||
// NewRouter - create new router
|
||||
// TODO either make Function unexported or make return type (router) Exported
|
||||
func NewRouter() *router {
|
||||
return &router{
|
||||
routes: make([]route, 0),
|
||||
@ -28,6 +32,7 @@ func NewRouter() *router {
|
||||
|
||||
var isAlpha = regexp.MustCompile(`^[a-zA-Z]+$`).MatchString
|
||||
|
||||
// AddRoute - TODO add description
|
||||
func (rtr *router) AddRoute(r string, h sdk.Handler) {
|
||||
if !isAlpha(r) {
|
||||
panic("route expressions can only contain alphanumeric characters")
|
||||
@ -35,6 +40,7 @@ func (rtr *router) AddRoute(r string, h sdk.Handler) {
|
||||
rtr.routes = append(rtr.routes, route{r, h})
|
||||
}
|
||||
|
||||
// Route - TODO add description
|
||||
// TODO handle expressive matches.
|
||||
func (rtr *router) Route(path string) (h sdk.Handler) {
|
||||
for _, route := range rtr.routes {
|
||||
|
||||
@ -24,6 +24,7 @@ func NewTestApp(bapp *BaseApp) *TestApp {
|
||||
return app
|
||||
}
|
||||
|
||||
// execute BaseApp BeginBlock
|
||||
func (tapp *TestApp) RunBeginBlock() {
|
||||
if tapp.header != nil {
|
||||
panic("TestApp.header not nil, BeginBlock already run, or EndBlock not yet run.")
|
||||
@ -56,36 +57,43 @@ func (tapp *TestApp) ensureBeginBlock() {
|
||||
}
|
||||
}
|
||||
|
||||
// run tx through CheckTx of TestApp
|
||||
func (tapp *TestApp) RunCheckTx(tx sdk.Tx) sdk.Result {
|
||||
tapp.ensureBeginBlock()
|
||||
return tapp.BaseApp.runTx(true, nil, tx)
|
||||
}
|
||||
|
||||
// run tx through DeliverTx of TestApp
|
||||
func (tapp *TestApp) RunDeliverTx(tx sdk.Tx) sdk.Result {
|
||||
tapp.ensureBeginBlock()
|
||||
return tapp.BaseApp.runTx(false, nil, tx)
|
||||
}
|
||||
|
||||
// run tx through CheckTx of TestApp
|
||||
// NOTE: Skips authentication by wrapping msg in testTx{}.
|
||||
func (tapp *TestApp) RunCheckMsg(msg sdk.Msg) sdk.Result {
|
||||
var tx = testTx{msg}
|
||||
return tapp.RunCheckTx(tx)
|
||||
}
|
||||
|
||||
// run tx through DeliverTx of TestApp
|
||||
// NOTE: Skips authentication by wrapping msg in testTx{}.
|
||||
func (tapp *TestApp) RunDeliverMsg(msg sdk.Msg) sdk.Result {
|
||||
var tx = testTx{msg}
|
||||
return tapp.RunDeliverTx(tx)
|
||||
}
|
||||
|
||||
// return the commited multistore
|
||||
func (tapp *TestApp) CommitMultiStore() sdk.CommitMultiStore {
|
||||
return tapp.BaseApp.cms
|
||||
}
|
||||
|
||||
// return a cache-wrap CheckTx state of multistore
|
||||
func (tapp *TestApp) MultiStoreCheck() sdk.MultiStore {
|
||||
return tapp.BaseApp.msCheck
|
||||
}
|
||||
|
||||
// return a cache-wrap DeliverTx state of multistore
|
||||
func (tapp *TestApp) MultiStoreDeliver() sdk.MultiStore {
|
||||
return tapp.BaseApp.msDeliver
|
||||
}
|
||||
@ -97,11 +105,11 @@ type testTx struct {
|
||||
sdk.Msg
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (tx testTx) GetMsg() sdk.Msg { return tx.Msg }
|
||||
func (tx testTx) GetSigners() []crypto.Address { return nil }
|
||||
func (tx testTx) GetFeePayer() crypto.Address { return nil }
|
||||
func (tx testTx) GetSignatures() []sdk.StdSignature { return nil }
|
||||
|
||||
func IsTestAppTx(tx sdk.Tx) bool {
|
||||
_, ok := tx.(testTx)
|
||||
return ok
|
||||
|
||||
@ -6,18 +6,21 @@ import (
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/tendermint/abci/server"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
const appName = "BasecoinApp"
|
||||
|
||||
// BasecoinApp - extended ABCI application
|
||||
type BasecoinApp struct {
|
||||
*bam.BaseApp
|
||||
router bam.Router
|
||||
cdc *wire.Codec
|
||||
multiStore sdk.CommitMultiStore
|
||||
multiStore sdk.CommitMultiStore //TODO distinguish this store from *bam.BaseApp.cms <- is this one master?? confused
|
||||
|
||||
// The key to access the substores.
|
||||
capKeyMainStore *sdk.KVStoreKey
|
||||
@ -27,25 +30,44 @@ type BasecoinApp struct {
|
||||
accountMapper sdk.AccountMapper
|
||||
}
|
||||
|
||||
// NewBasecoinApp - create new BasecoinApp
|
||||
// TODO: This should take in more configuration options.
|
||||
func NewBasecoinApp() *BasecoinApp {
|
||||
// TODO: This should be moved into baseapp to isolate complexity
|
||||
func NewBasecoinApp(genesisPath string) *BasecoinApp {
|
||||
|
||||
// Create and configure app.
|
||||
var app = &BasecoinApp{}
|
||||
app.initCapKeys() // ./init_capkeys.go
|
||||
app.initBaseApp() // ./init_baseapp.go
|
||||
app.initStores() // ./init_stores.go
|
||||
|
||||
// TODO open up out of functions, or introduce clarity,
|
||||
// interdependancies are a nightmare to debug
|
||||
app.initCapKeys() // ./init_capkeys.go
|
||||
app.initBaseApp() // ./init_baseapp.go
|
||||
app.initStores() // ./init_stores.go
|
||||
app.initBaseAppInitStater()
|
||||
app.initHandlers() // ./init_handlers.go
|
||||
|
||||
// TODO: Load genesis
|
||||
// TODO: InitChain with validators
|
||||
// TODO: Set the genesis accounts
|
||||
genesisiDoc, err := bam.GenesisDocFromFile(genesisPath)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error loading genesis state: %v", err))
|
||||
}
|
||||
|
||||
// set up the cache store for ctx, get ctx
|
||||
// TODO: can InitChain handle this too ?
|
||||
app.BaseApp.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{}})
|
||||
ctx := app.BaseApp.NewContext(false, nil) // context for DeliverTx
|
||||
|
||||
// TODO: combine with InitChain and let tendermint invoke it.
|
||||
err = app.BaseApp.InitStater(ctx, genesisiDoc.AppState)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error initializing application genesis state: %v", err))
|
||||
}
|
||||
|
||||
app.loadStores()
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// RunForever - BasecoinApp execution and cleanup
|
||||
func (app *BasecoinApp) RunForever() {
|
||||
|
||||
// Start the ABCI server
|
||||
@ -64,7 +86,7 @@ func (app *BasecoinApp) RunForever() {
|
||||
|
||||
}
|
||||
|
||||
// Load the stores.
|
||||
// Load the stores
|
||||
func (app *BasecoinApp) loadStores() {
|
||||
if err := app.LoadLatestVersion(app.capKeyMainStore); err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
@ -37,4 +43,32 @@ func TestSendMsg(t *testing.T) {
|
||||
// Run a Deliver on SendMsg.
|
||||
res = tba.RunDeliverMsg(msg)
|
||||
assert.Equal(t, sdk.CodeUnrecognizedAddress, res.Code, res.Log)
|
||||
|
||||
// TODO seperate this test, need a closer on db? keep getting resource unavailable
|
||||
|
||||
// construct some genesis bytes to reflect basecoin/types/AppAccount
|
||||
pk := crypto.GenPrivKeyEd25519().PubKey()
|
||||
addr := pk.Address()
|
||||
coins, err := sdk.ParseCoins("77foocoin,99barcoin")
|
||||
require.Nil(t, err)
|
||||
baseAcc := auth.BaseAccount{
|
||||
Address: addr,
|
||||
Coins: coins,
|
||||
}
|
||||
acc := &types.AppAccount{baseAcc, "foobart"}
|
||||
|
||||
genesisState := GenesisState{
|
||||
Accounts: []*GenesisAccount{
|
||||
NewGenesisAccount(acc),
|
||||
},
|
||||
}
|
||||
bytes, err := json.MarshalIndent(genesisState, "", "\t")
|
||||
|
||||
app := tba.BasecoinApp
|
||||
ctx := app.BaseApp.NewContext(false, nil) // context for DeliverTx
|
||||
err = app.BaseApp.InitStater(ctx, bytes)
|
||||
require.Nil(t, err)
|
||||
|
||||
res1 := app.accountMapper.GetAccount(ctx, baseAcc.Address)
|
||||
assert.Equal(t, acc, res1)
|
||||
}
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
// initCapKeys, initBaseApp, initStores, initHandlers.
|
||||
@ -11,6 +16,7 @@ func (app *BasecoinApp) initBaseApp() {
|
||||
app.BaseApp = bapp
|
||||
app.router = bapp.Router()
|
||||
app.initBaseAppTxDecoder()
|
||||
app.initBaseAppInitStater()
|
||||
}
|
||||
|
||||
func (app *BasecoinApp) initBaseAppTxDecoder() {
|
||||
@ -26,3 +32,62 @@ func (app *BasecoinApp) initBaseAppTxDecoder() {
|
||||
return tx, nil
|
||||
})
|
||||
}
|
||||
|
||||
// define the custom logic for basecoin initialization
|
||||
func (app *BasecoinApp) initBaseAppInitStater() {
|
||||
accountMapper := app.accountMapper
|
||||
|
||||
app.BaseApp.SetInitStater(func(ctx sdk.Context, state json.RawMessage) sdk.Error {
|
||||
if state == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
genesisState := new(GenesisState)
|
||||
err := json.Unmarshal(state, genesisState)
|
||||
if err != nil {
|
||||
return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
for _, gacc := range genesisState.Accounts {
|
||||
acc, err := gacc.toAppAccount()
|
||||
if err != nil {
|
||||
return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
accountMapper.SetAccount(ctx, acc)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
||||
type GenesisState struct {
|
||||
Accounts []*GenesisAccount `accounts`
|
||||
}
|
||||
|
||||
// GenesisAccount doesn't need pubkey or sequence
|
||||
type GenesisAccount struct {
|
||||
Name string `json:"name"`
|
||||
Address crypto.Address `json:"address"`
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
}
|
||||
|
||||
func NewGenesisAccount(aa *types.AppAccount) *GenesisAccount {
|
||||
return &GenesisAccount{
|
||||
Name: aa.Name,
|
||||
Address: aa.Address,
|
||||
Coins: aa.Coins,
|
||||
}
|
||||
}
|
||||
|
||||
// convert GenesisAccount to AppAccount
|
||||
func (ga *GenesisAccount) toAppAccount() (acc *types.AppAccount, err error) {
|
||||
baseAcc := auth.BaseAccount{
|
||||
Address: ga.Address,
|
||||
Coins: ga.Coins,
|
||||
}
|
||||
return &types.AppAccount{
|
||||
BaseAccount: baseAcc,
|
||||
Name: ga.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ type testBasecoinApp struct {
|
||||
}
|
||||
|
||||
func newTestBasecoinApp() *testBasecoinApp {
|
||||
app := NewBasecoinApp()
|
||||
app := NewBasecoinApp("")
|
||||
tba := &testBasecoinApp{
|
||||
BasecoinApp: app,
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
import "github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
||||
|
||||
func main() {
|
||||
fmt.Println("TODO: move examples/basecoin/main.go here and refactor")
|
||||
// TODO CREATE CLI
|
||||
|
||||
bapp := app.NewBasecoinApp("")
|
||||
bapp.RunForever()
|
||||
}
|
||||
|
||||
@ -184,6 +184,7 @@ func (coins Coins) IsNotNegative() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Returns the amount of a denom from coins
|
||||
func (coins Coins) AmountOf(denom string) int64 {
|
||||
switch len(coins) {
|
||||
case 0:
|
||||
@ -192,9 +193,8 @@ func (coins Coins) AmountOf(denom string) int64 {
|
||||
coin := coins[0]
|
||||
if coin.Denom == denom {
|
||||
return coin.Amount
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
default:
|
||||
midIdx := len(coins) / 2 // 2:1, 3:1, 4:2
|
||||
coin := coins[midIdx]
|
||||
|
||||
@ -192,7 +192,7 @@ func TestAmountOf(t *testing.T) {
|
||||
cases := []struct {
|
||||
coins Coins
|
||||
amountOf int64
|
||||
amountOf_ int64
|
||||
amountOfSpace int64
|
||||
amountOfGAS int64
|
||||
amountOfMINERAL int64
|
||||
amountOfTREE int64
|
||||
@ -210,7 +210,7 @@ func TestAmountOf(t *testing.T) {
|
||||
|
||||
for _, tc := range cases {
|
||||
assert.Equal(t, tc.amountOf, tc.coins.AmountOf(""))
|
||||
assert.Equal(t, tc.amountOf_, tc.coins.AmountOf(" "))
|
||||
assert.Equal(t, tc.amountOfSpace, tc.coins.AmountOf(" "))
|
||||
assert.Equal(t, tc.amountOfGAS, tc.coins.AmountOf("GAS"))
|
||||
assert.Equal(t, tc.amountOfMINERAL, tc.coins.AmountOf("MINERAL"))
|
||||
assert.Equal(t, tc.amountOfTREE, tc.coins.AmountOf("TREE"))
|
||||
|
||||
@ -30,6 +30,7 @@ type Context struct {
|
||||
// it's probably not what you want to do.
|
||||
}
|
||||
|
||||
// create a new context
|
||||
func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byte) Context {
|
||||
c := Context{
|
||||
Context: context.Background(),
|
||||
@ -45,6 +46,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byt
|
||||
return c
|
||||
}
|
||||
|
||||
// is context nil
|
||||
func (c Context) IsZero() bool {
|
||||
return c.Context == nil
|
||||
}
|
||||
@ -52,6 +54,7 @@ func (c Context) IsZero() bool {
|
||||
//----------------------------------------
|
||||
// Getting a value
|
||||
|
||||
// context value for the provided key
|
||||
func (c Context) Value(key interface{}) interface{} {
|
||||
value := c.Context.Value(key)
|
||||
if cloner, ok := value.(cloner); ok {
|
||||
@ -71,34 +74,28 @@ func (c Context) KVStore(key StoreKey) KVStore {
|
||||
//----------------------------------------
|
||||
// With* (setting a value)
|
||||
|
||||
// nolint
|
||||
func (c Context) WithValue(key interface{}, value interface{}) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithCloner(key interface{}, value cloner) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithCacheWrapper(key interface{}, value CacheWrapper) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithProtoMsg(key interface{}, value proto.Message) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithString(key interface{}, value string) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithInt32(key interface{}, value int32) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithUint32(key interface{}, value uint32) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
|
||||
func (c Context) WithUint64(key interface{}, value uint64) Context {
|
||||
return c.withValue(key, value)
|
||||
}
|
||||
@ -138,47 +135,38 @@ func (c Context) multiStore() MultiStore {
|
||||
return c.Value(contextKeyMultiStore).(MultiStore)
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (c Context) BlockHeader() abci.Header {
|
||||
return c.Value(contextKeyBlockHeader).(abci.Header)
|
||||
}
|
||||
|
||||
func (c Context) BlockHeight() int64 {
|
||||
return c.Value(contextKeyBlockHeight).(int64)
|
||||
}
|
||||
|
||||
func (c Context) ChainID() string {
|
||||
return c.Value(contextKeyChainID).(string)
|
||||
}
|
||||
|
||||
func (c Context) IsCheckTx() bool {
|
||||
return c.Value(contextKeyIsCheckTx).(bool)
|
||||
}
|
||||
|
||||
func (c Context) TxBytes() []byte {
|
||||
return c.Value(contextKeyTxBytes).([]byte)
|
||||
}
|
||||
|
||||
func (c Context) WithMultiStore(ms MultiStore) Context {
|
||||
return c.withValue(contextKeyMultiStore, ms)
|
||||
}
|
||||
|
||||
func (c Context) WithBlockHeader(header abci.Header) Context {
|
||||
var _ proto.Message = &header // for cloning.
|
||||
return c.withValue(contextKeyBlockHeader, header)
|
||||
}
|
||||
|
||||
func (c Context) WithBlockHeight(height int64) Context {
|
||||
return c.withValue(contextKeyBlockHeight, height)
|
||||
}
|
||||
|
||||
func (c Context) WithChainID(chainID string) Context {
|
||||
return c.withValue(contextKeyChainID, chainID)
|
||||
}
|
||||
|
||||
func (c Context) WithIsCheckTx(isCheckTx bool) Context {
|
||||
return c.withValue(contextKeyIsCheckTx, isCheckTx)
|
||||
}
|
||||
|
||||
func (c Context) WithTxBytes(txBytes []byte) Context {
|
||||
return c.withValue(contextKeyTxBytes, txBytes)
|
||||
}
|
||||
@ -199,6 +187,7 @@ type cloner interface {
|
||||
Clone() interface{} // deep copy
|
||||
}
|
||||
|
||||
// XXX add description
|
||||
type Op struct {
|
||||
// type is always 'with'
|
||||
gen int
|
||||
@ -221,7 +210,7 @@ func newThePast() *thePast {
|
||||
|
||||
func (pst *thePast) bump(op Op) {
|
||||
pst.mtx.Lock()
|
||||
pst.ver += 1
|
||||
pst.ver++
|
||||
pst.ops = append(pst.ops, op)
|
||||
pst.mtx.Unlock()
|
||||
}
|
||||
@ -240,7 +229,6 @@ func (pst *thePast) getOp(ver int64) (Op, bool) {
|
||||
l := int64(len(pst.ops))
|
||||
if l < ver || ver <= 0 {
|
||||
return Op{}, false
|
||||
} else {
|
||||
return pst.ops[ver-1], true
|
||||
}
|
||||
return pst.ops[ver-1], true
|
||||
}
|
||||
|
||||
@ -7,19 +7,20 @@ import (
|
||||
"github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
// ABCI Response Code
|
||||
type CodeType uint32
|
||||
|
||||
// is everything okay?
|
||||
func (code CodeType) IsOK() bool {
|
||||
if code == CodeOK {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ABCI Response Codes
|
||||
// Base SDK reserves 0 ~ 99.
|
||||
const (
|
||||
// ABCI Response Codes
|
||||
// Base SDK reserves 0 ~ 99.
|
||||
CodeOK CodeType = 0
|
||||
CodeInternal CodeType = 1
|
||||
CodeTxParse CodeType = 2
|
||||
@ -29,6 +30,8 @@ const (
|
||||
CodeUnknownRequest CodeType = 6
|
||||
CodeUnrecognizedAddress CodeType = 7
|
||||
CodeInvalidSequence CodeType = 8
|
||||
|
||||
CodeGenesisParse CodeType = 0xdead // TODO: remove ?
|
||||
)
|
||||
|
||||
// NOTE: Don't stringer this, we'll put better messages in later.
|
||||
@ -38,6 +41,8 @@ func CodeToDefaultMsg(code CodeType) string {
|
||||
return "Internal error"
|
||||
case CodeTxParse:
|
||||
return "Tx parse error"
|
||||
case CodeGenesisParse:
|
||||
return "Genesis parse error"
|
||||
case CodeBadNonce:
|
||||
return "Bad nonce"
|
||||
case CodeUnauthorized:
|
||||
@ -59,34 +64,31 @@ func CodeToDefaultMsg(code CodeType) string {
|
||||
// All errors are created via constructors so as to enable us to hijack them
|
||||
// and inject stack traces if we really want to.
|
||||
|
||||
// nolint
|
||||
func ErrInternal(msg string) Error {
|
||||
return newError(CodeInternal, msg)
|
||||
}
|
||||
|
||||
func ErrTxParse(msg string) Error {
|
||||
return newError(CodeTxParse, msg)
|
||||
}
|
||||
|
||||
func ErrGenesisParse(msg string) Error {
|
||||
return newError(CodeGenesisParse, msg)
|
||||
}
|
||||
func ErrBadNonce(msg string) Error {
|
||||
return newError(CodeBadNonce, msg)
|
||||
}
|
||||
|
||||
func ErrUnauthorized(msg string) Error {
|
||||
return newError(CodeUnauthorized, msg)
|
||||
}
|
||||
|
||||
func ErrInsufficientFunds(msg string) Error {
|
||||
return newError(CodeInsufficientFunds, msg)
|
||||
}
|
||||
|
||||
func ErrUnknownRequest(msg string) Error {
|
||||
return newError(CodeUnknownRequest, msg)
|
||||
}
|
||||
|
||||
func ErrUnrecognizedAddress(addr crypto.Address) Error {
|
||||
return newError(CodeUnrecognizedAddress, addr.String())
|
||||
}
|
||||
|
||||
func ErrInvalidSequence(msg string) Error {
|
||||
return newError(CodeInvalidSequence, msg)
|
||||
}
|
||||
@ -94,6 +96,7 @@ func ErrInvalidSequence(msg string) Error {
|
||||
//----------------------------------------
|
||||
// Error & sdkError
|
||||
|
||||
// sdk Error type
|
||||
type Error interface {
|
||||
Error() string
|
||||
ABCICode() CodeType
|
||||
|
||||
6
types/genesis.go
Normal file
6
types/genesis.go
Normal file
@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// function variable used to initialize application state at genesis
|
||||
type InitStater func(ctx Context, state json.RawMessage) Error
|
||||
@ -1,5 +1,6 @@
|
||||
package types
|
||||
|
||||
// core function variable which application runs for transactions
|
||||
type Handler func(ctx Context, msg Msg) Result
|
||||
|
||||
// If newCtx.IsZero(), ctx is used instead.
|
||||
|
||||
@ -2,6 +2,7 @@ package types
|
||||
|
||||
import crypto "github.com/tendermint/go-crypto"
|
||||
|
||||
// Standard Signature
|
||||
type StdSignature struct {
|
||||
crypto.PubKey // optional
|
||||
crypto.Signature
|
||||
|
||||
@ -9,12 +9,12 @@ import (
|
||||
|
||||
// NOTE: These are implemented in cosmos-sdk/store.
|
||||
|
||||
type Store interface {
|
||||
type Store interface { //nolint
|
||||
GetStoreType() StoreType
|
||||
CacheWrapper
|
||||
}
|
||||
|
||||
// Something that can persist to disk.
|
||||
// something that can persist to disk
|
||||
type Committer interface {
|
||||
Commit() CommitID
|
||||
LastCommitID() CommitID
|
||||
@ -37,7 +37,7 @@ type Queryable interface {
|
||||
//----------------------------------------
|
||||
// MultiStore
|
||||
|
||||
type MultiStore interface {
|
||||
type MultiStore interface { //nolint
|
||||
Store
|
||||
|
||||
// Cache wrap MultiStore.
|
||||
@ -139,10 +139,6 @@ type CacheKVStore interface {
|
||||
cache-wraps make no sense. It can return KVStore, HeapStore,
|
||||
SpaceStore, etc.
|
||||
*/
|
||||
type CacheWrapper interface {
|
||||
CacheWrap() CacheWrap
|
||||
}
|
||||
|
||||
type CacheWrap interface {
|
||||
|
||||
// Write syncs with the underlying store.
|
||||
@ -152,6 +148,10 @@ type CacheWrap interface {
|
||||
CacheWrap() CacheWrap
|
||||
}
|
||||
|
||||
type CacheWrapper interface { //nolint
|
||||
CacheWrap() CacheWrap
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// CommitID
|
||||
|
||||
@ -161,7 +161,7 @@ type CommitID struct {
|
||||
Hash []byte
|
||||
}
|
||||
|
||||
func (cid CommitID) IsZero() bool {
|
||||
func (cid CommitID) IsZero() bool { //nolint
|
||||
return cid.Version == 0 && len(cid.Hash) == 0
|
||||
}
|
||||
|
||||
@ -172,9 +172,11 @@ func (cid CommitID) String() string {
|
||||
//----------------------------------------
|
||||
// Store types
|
||||
|
||||
// kind of store
|
||||
type StoreType int
|
||||
|
||||
const (
|
||||
//nolint
|
||||
StoreTypeMulti StoreType = iota
|
||||
StoreTypeDB
|
||||
StoreTypeIAVL
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
// Transactions messages must fulfill the Msg
|
||||
type Msg interface {
|
||||
|
||||
// Return the message type.
|
||||
@ -26,6 +27,7 @@ type Msg interface {
|
||||
GetSigners() []crypto.Address
|
||||
}
|
||||
|
||||
// Transactions objects must fulfill the Tx
|
||||
type Tx interface {
|
||||
|
||||
// Gets the Msg.
|
||||
@ -47,13 +49,18 @@ type Tx interface {
|
||||
|
||||
var _ Tx = (*StdTx)(nil)
|
||||
|
||||
// standard transaction form
|
||||
type StdTx struct {
|
||||
Msg
|
||||
Signatures []StdSignature
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (tx StdTx) GetMsg() Msg { return tx.Msg }
|
||||
func (tx StdTx) GetFeePayer() crypto.Address { return tx.Signatures[0].PubKey.Address() }
|
||||
func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
// Application function variable used to unmarshal transaction bytes
|
||||
type TxDecoder func(txBytes []byte) (Tx, Error)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user