Merge pull request #470 from cosmos/basecoin-refactor-more

Basecoin refactor more
This commit is contained in:
Ethan Buchman 2018-02-17 16:39:00 -05:00 committed by GitHub
commit 3b826455c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 467 additions and 921 deletions

View File

@ -1,13 +1,12 @@
package baseapp
import (
"bytes"
"fmt"
"os"
"runtime/debug"
"github.com/golang/protobuf/proto"
"github.com/pkg/errors"
abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
@ -22,75 +21,38 @@ var mainHeaderKey = []byte("header")
// The ABCI application
type BaseApp struct {
logger log.Logger
// Application name from abci.Info
name string
// Common DB backend
db dbm.DB
// Main (uncached) state
cms sdk.CommitMultiStore
// unmarshal []byte into sdk.Tx
txDecoder sdk.TxDecoder
// 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
router Router
name string // application name from abci.Info
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
initChainer sdk.InitChainer //
anteHandler sdk.AnteHandler // ante handler for fee and auth
router Router // handle any kind of message
//--------------------
// Volatile
// .msCheck and .header are set on initialization.
// .msDeliver is only set (and reset) in BeginBlock.
// .header and .valUpdates are also reset in BeginBlock.
// .msCheck is only reset in Commit.
// CheckTx state, a cache-wrap of `.cms`
msCheck sdk.CacheMultiStore
// DeliverTx state, a cache-wrap of `.cms`
msDeliver sdk.CacheMultiStore
// current block header
header *abci.Header
// cached validator changes from DeliverTx
valUpdates []abci.Validator
header abci.Header // current block header
msCheck sdk.CacheMultiStore // CheckTx state, a cache-wrap of `.cms`
msDeliver sdk.CacheMultiStore // DeliverTx state, a cache-wrap of `.cms`
valUpdates []abci.Validator // cached validator changes from DeliverTx
}
var _ abci.Application = &BaseApp{}
// Create and name new BaseApp
func NewBaseApp(name string) *BaseApp {
var baseapp = &BaseApp{
logger: makeDefaultLogger(),
func NewBaseApp(name string, logger log.Logger, db dbm.DB) *BaseApp {
return &BaseApp{
logger: logger,
name: name,
db: nil,
cms: nil,
db: db,
cms: store.NewCommitMultiStore(db),
router: NewRouter(),
}
baseapp.initDB()
baseapp.initMultiStore()
return baseapp
}
// Create the underlying leveldb datastore which will
// persist the Merkle tree inner & leaf nodes.
func (app *BaseApp) initDB() {
db, err := dbm.NewGoLevelDB(app.name, "data")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
app.db = db
}
func (app *BaseApp) initMultiStore() {
cms := store.NewCommitMultiStore(app.db)
app.cms = cms
}
// BaseApp Name
@ -98,71 +60,79 @@ func (app *BaseApp) Name() string {
return app.name
}
// Mount a store to the provided key in the BaseApp multistore
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
for _, key := range keys {
app.MountStore(key, sdk.StoreTypeIAVL)
}
}
// 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
// nolint - Set functions
func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) {
app.txDecoder = txDecoder
}
func (app *BaseApp) SetInitStater(initStater sdk.InitStater) {
app.InitStater = initStater
func (app *BaseApp) SetInitChainer(initChainer sdk.InitChainer) {
app.initChainer = initChainer
}
func (app *BaseApp) SetDefaultAnteHandler(ah sdk.AnteHandler) {
app.defaultAnteHandler = ah
}
func (app *BaseApp) Router() Router {
return app.router
func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
// deducts fee from payer, verifies signatures and nonces, sets Signers to ctx.
app.anteHandler = ah
}
// nolint - Get functions
func (app *BaseApp) Router() Router { return app.router }
/* TODO consider:
func (app *BaseApp) SetBeginBlocker(...) {}
func (app *BaseApp) SetEndBlocker(...) {}
*/
// TODO add description
// load latest application version
func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error {
app.cms.LoadLatestVersion()
return app.initFromStore(mainKey)
}
// Load application version
// load application version
func (app *BaseApp) LoadVersion(version int64, mainKey sdk.StoreKey) error {
app.cms.LoadVersion(version)
return app.initFromStore(mainKey)
}
// The last CommitID of the multistore.
// the last CommitID of the multistore
func (app *BaseApp) LastCommitID() sdk.CommitID {
return app.cms.LastCommitID()
}
// The last commited block height.
// the last commited block height
func (app *BaseApp) LastBlockHeight() int64 {
return app.cms.LastCommitID().Version
}
// Initializes the remaining logic from app.cms.
// initializes the remaining logic from app.cms
func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
var lastCommitID = app.cms.LastCommitID()
var main = app.cms.GetKVStore(mainKey)
var header *abci.Header
var header abci.Header
// Main store should exist.
// main store should exist.
if main == nil {
return errors.New("BaseApp expects MultiStore with 'main' KVStore")
}
// If we've committed before, we expect main://<mainHeaderKey>.
// if we've committed before, we expect main://<mainHeaderKey>
if !lastCommitID.IsZero() {
headerBytes := main.Get(mainHeaderKey)
if len(headerBytes) == 0 {
errStr := fmt.Sprintf("Version > 0 but missing key %s", mainHeaderKey)
return errors.New(errStr)
}
err := proto.Unmarshal(headerBytes, header)
err := proto.Unmarshal(headerBytes, &header)
if err != nil {
return errors.Wrap(err, "Failed to parse Header")
}
@ -173,16 +143,27 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
}
}
// Set BaseApp state.
// set BaseApp state
app.header = header
app.msCheck = nil
app.msCheck = app.cms.CacheMultiStore()
app.msDeliver = nil
app.valUpdates = nil
return nil
}
// NewContext returns a new Context suitable for AnteHandler and Handler processing.
// NOTE: header is empty for checkTx
// NOTE: txBytes may be nil, for instance in tests (using app.Check or app.Deliver directly).
func (app *BaseApp) NewContext(isCheckTx bool, txBytes []byte) sdk.Context {
store := app.getMultiStore(isCheckTx)
// XXX CheckTx can't safely get the header
header := abci.Header{}
return sdk.NewContext(store, header, isCheckTx, txBytes)
}
//----------------------------------------
// ABCI
// Implements ABCI
func (app *BaseApp) Info(req abci.RequestInfo) abci.ResponseInfo {
@ -203,9 +184,27 @@ func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOp
}
// Implements ABCI
// InitChain runs the initialization logic directly on the CommitMultiStore and commits it.
func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
// TODO: Use req.Validators
// TODO: Use req.AppStateJSON (?)
if app.initChainer == nil {
// TODO: should we have some default handling of validators?
return
}
// make a context for the initialization.
// NOTE: we're writing to the cms directly, without a CacheWrap
ctx := sdk.NewContext(app.cms, abci.Header{}, false, nil)
err := app.initChainer(ctx, req)
if err != nil {
// TODO: something better https://github.com/cosmos/cosmos-sdk/issues/468
cmn.Exit(fmt.Sprintf("error initializing application genesis state: %v", err))
}
// XXX this commits everything and bumps the version.
// https://github.com/cosmos/cosmos-sdk/issues/442#issuecomment-366470148
app.cms.Commit()
return
}
@ -223,9 +222,8 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
// 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
app.header = req.Header
app.msDeliver = app.cms.CacheMultiStore()
app.msCheck = app.cms.CacheMultiStore()
app.valUpdates = nil
return
}
@ -253,7 +251,6 @@ func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {
},
Tags: result.Tags,
}
}
// Implements ABCI
@ -288,9 +285,16 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) {
}
}
// txBytes may be nil in some cases, for example, when tx is
// coming from TestApp. Also, in the future we may support
// "internal" transactions.
// Mostly for testing
func (app *BaseApp) Check(tx sdk.Tx) (result sdk.Result) {
return app.runTx(true, nil, tx)
}
func (app *BaseApp) Deliver(tx sdk.Tx) (result sdk.Result) {
return app.runTx(false, nil, tx)
}
// txBytes may be nil in some cases, eg. in tests.
// Also, in the future we may support "internal" transactions.
func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk.Result) {
// Handle any panics.
@ -319,7 +323,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
// TODO: override default ante handler w/ custom ante handler.
// Run the ante handler.
newCtx, result, abort := app.defaultAnteHandler(ctx, tx)
newCtx, result, abort := app.anteHandler(ctx, tx)
if isCheckTx || abort {
return result
}
@ -328,7 +332,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
}
// CacheWrap app.msDeliver in case it fails.
msCache := app.getMultiStore(isCheckTx).CacheMultiStore()
msCache := app.getMultiStore(false).CacheMultiStore()
ctx = ctx.WithMultiStore(msCache)
// Match and run route.
@ -348,9 +352,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) {
res.ValidatorUpdates = app.valUpdates
app.valUpdates = nil
app.header = nil
app.msDeliver = nil
app.msCheck = nil
return
}
@ -367,7 +369,7 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
}
//----------------------------------------
// Misc.
// Helpers
func (app *BaseApp) getMultiStore(isCheckTx bool) sdk.MultiStore {
if isCheckTx {
@ -375,20 +377,3 @@ func (app *BaseApp) getMultiStore(isCheckTx bool) sdk.MultiStore {
}
return app.msDeliver
}
// Return index of list with validator of same PubKey, or -1 if no match
func pubKeyIndex(val *abci.Validator, list []*abci.Validator) int {
for i, v := range list {
if bytes.Equal(val.PubKey, v.PubKey) {
return i
}
}
return -1
}
// Make a simple default logger
// TODO: Make log capturable for each transaction, and return it in
// ResponseDeliverTx.Log and ResponseCheckTx.Log.
func makeDefaultLogger() log.Logger {
return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
}

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"os"
"testing"
"github.com/stretchr/testify/assert"
@ -12,10 +13,83 @@ import (
"github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func defaultLogger() log.Logger {
return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
}
func newBaseApp(name string) *BaseApp {
logger := defaultLogger()
db := dbm.NewMemDB()
return NewBaseApp(name, logger, db)
}
func TestMountStores(t *testing.T) {
name := t.Name()
app := newBaseApp(name)
assert.Equal(t, name, app.Name())
// make some cap keys
capKey1 := sdk.NewKVStoreKey("key1")
capKey2 := sdk.NewKVStoreKey("key2")
// no stores are mounted
assert.Panics(t, func() { app.LoadLatestVersion(capKey1) })
app.MountStoresIAVL(capKey1, capKey2)
// both stores are mounted
err := app.LoadLatestVersion(capKey1)
assert.Nil(t, err)
err = app.LoadLatestVersion(capKey2)
assert.Nil(t, err)
}
func TestLoadVersion(t *testing.T) {
// TODO
}
func TestInitChainer(t *testing.T) {
app := newBaseApp(t.Name())
// make a cap key and mount the store
capKey := sdk.NewKVStoreKey("main")
app.MountStoresIAVL(capKey)
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
assert.Nil(t, err)
key, value := []byte("hello"), []byte("goodbye")
// initChainer sets a value in the store
var initChainer sdk.InitChainer = func(ctx sdk.Context, req abci.RequestInitChain) sdk.Error {
store := ctx.KVStore(capKey)
store.Set(key, value)
return nil
}
query := abci.RequestQuery{
Path: "/main/key",
Data: key,
}
// initChainer is nil - nothing happens
app.InitChain(abci.RequestInitChain{})
res := app.Query(query)
assert.Equal(t, 0, len(res.Value))
// set initChainer and try again - should see the value
app.SetInitChainer(initChainer)
app.InitChain(abci.RequestInitChain{})
res = app.Query(query)
assert.Equal(t, value, res.Value)
}
//----------------------
// A mock transaction to update a validator's voting power.
type testUpdatePowerTx struct {
Addr []byte
@ -33,10 +107,10 @@ func (tx testUpdatePowerTx) GetSigners() []crypto.Address { return ni
func (tx testUpdatePowerTx) GetFeePayer() crypto.Address { return nil }
func (tx testUpdatePowerTx) GetSignatures() []sdk.StdSignature { return nil }
func TestBasic(t *testing.T) {
func TestExecution(t *testing.T) {
// Create app.
app := NewBaseApp(t.Name())
app := newBaseApp(t.Name())
storeKeys := createMounts(app.cms)
app.SetTxDecoder(func(txBytes []byte) (sdk.Tx, sdk.Error) {
var ttx testUpdatePowerTx
@ -44,7 +118,7 @@ func TestBasic(t *testing.T) {
return ttx, nil
})
app.SetDefaultAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.Router().AddRoute(msgType, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
// TODO
return sdk.Result{}

View File

@ -1,33 +0,0 @@
package baseapp
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
// and TestApp.RunDeliverTx.
func (app *BaseApp) NewContext(isCheckTx bool, txBytes []byte) sdk.Context {
var store sdk.MultiStore
if isCheckTx {
store = app.msCheck
} else {
store = app.msDeliver
}
if store == nil {
panic("BaseApp.NewContext() requires BeginBlock(): missing store")
}
if app.header == nil {
panic("BaseApp.NewContext() requires BeginBlock(): missing header")
}
// Initialize arguments to Handler.
var ctx = sdk.NewContext(
store,
*app.header,
isCheckTx,
txBytes,
)
return ctx
}

View File

@ -1,32 +0,0 @@
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
}

24
baseapp/helpers.go Normal file
View File

@ -0,0 +1,24 @@
package baseapp
import (
"github.com/tendermint/abci/server"
abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
)
// RunForever - BasecoinApp execution and cleanup
func RunForever(app abci.Application) {
// Start the ABCI server
srv, err := server.NewServer("0.0.0.0:46658", "socket", app)
if err != nil {
cmn.Exit(err.Error())
}
srv.Start()
// Wait forever
cmn.TrapSignal(func() {
// Cleanup
srv.Stop()
})
}

View File

@ -6,12 +6,13 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Router - TODO add description
// Router provides handlers for each transaction type.
type Router interface {
AddRoute(r string, h sdk.Handler)
Route(path string) (h sdk.Handler)
}
// map a transaction type to a handler
type route struct {
r string
h sdk.Handler

View File

@ -1,116 +0,0 @@
package baseapp
import (
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// TestApp wraps BaseApp with helper methods,
// and exposes more functionality than otherwise needed.
type TestApp struct {
*BaseApp
// These get set as we receive them.
*abci.ResponseBeginBlock
*abci.ResponseEndBlock
}
func NewTestApp(bapp *BaseApp) *TestApp {
app := &TestApp{
BaseApp: bapp,
}
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.")
}
cms := tapp.CommitMultiStore()
lastCommit := cms.LastCommitID()
header := abci.Header{
ChainID: "chain_" + tapp.BaseApp.name,
Height: lastCommit.Version + 1,
Time: -1, // TODO
NumTxs: -1, // TODO
LastCommitHash: lastCommit.Hash,
DataHash: nil, // TODO
ValidatorsHash: nil, // TODO
AppHash: nil, // TODO
}
res := tapp.BeginBlock(abci.RequestBeginBlock{
Hash: nil, // TODO
Header: header,
AbsentValidators: nil, // TODO
ByzantineValidators: nil, // TODO
})
tapp.ResponseBeginBlock = &res
return
}
func (tapp *TestApp) ensureBeginBlock() {
if tapp.header == nil {
panic("TestApp.header was nil, call TestApp.RunBeginBlock()")
}
}
// 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
}
//----------------------------------------
// testTx
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
}

View File

@ -1,41 +1,19 @@
PACKAGES=$(shell go list ./... | grep -v '/vendor/')
BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/examples/basecoin/version.GitCommit=`git rev-parse --short HEAD`"
all: check_tools get_vendor_deps build test
########################################
### Build
all: get_vendor_deps build test
build:
go build $(BUILD_FLAGS) -o build/basecoin ./cmd/...
########################################
### Tools & dependencies
check_tools:
cd tools && $(MAKE) check
get_tools:
cd tools && $(MAKE)
get_vendor_deps:
@rm -rf vendor/
@echo "--> Running glide install"
@glide install
########################################
### Testing
test:
@go test $(PACKAGES)
benchmark:
@go test -bench=. $(PACKAGES)
# To avoid unintended conflicts with file names, always add to .PHONY
# unless there is a reason not to.
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
.PHONY: build check_tools get_tools get_vendor_deps test benchmark
.PHONY: build get_vendor_deps test benchmark

View File

@ -1,95 +1,114 @@
package app
import (
"fmt"
"os"
"encoding/json"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
bam "github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/tendermint/abci/server"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-wire"
cmn "github.com/tendermint/tmlibs/common"
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
"github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy"
)
const appName = "BasecoinApp"
const (
appName = "BasecoinApp"
)
// BasecoinApp - extended ABCI application
// Extended ABCI application
type BasecoinApp struct {
*bam.BaseApp
router bam.Router
cdc *wire.Codec
multiStore sdk.CommitMultiStore //TODO distinguish this store from *bam.BaseApp.cms <- is this one master?? confused
// The key to access the substores.
// keys to access the substores
capKeyMainStore *sdk.KVStoreKey
capKeyIBCStore *sdk.KVStoreKey
// Object mappers:
// Manage getting and setting accounts
accountMapper sdk.AccountMapper
}
// NewBasecoinApp - create new BasecoinApp
// TODO: This should take in more configuration options.
// TODO: This should be moved into baseapp to isolate complexity
func NewBasecoinApp(genesisPath string) *BasecoinApp {
// Create and configure app.
var app = &BasecoinApp{}
// 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
genesisiDoc, err := bam.GenesisDocFromFile(genesisPath)
if err != nil {
panic(fmt.Errorf("error loading genesis state: %v", err))
func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
// create your application object
var app = &BasecoinApp{
BaseApp: bam.NewBaseApp(appName, logger, db),
cdc: MakeTxCodec(),
capKeyMainStore: sdk.NewKVStoreKey("main"),
capKeyIBCStore: sdk.NewKVStoreKey("ibc"),
}
// 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
// define the accountMapper
app.accountMapper = auth.NewAccountMapperSealed(
app.capKeyMainStore, // target store
&types.AppAccount{}, // prototype
)
// TODO: combine with InitChain and let tendermint invoke it.
err = app.BaseApp.InitStater(ctx, genesisiDoc.AppState)
// add handlers
coinKeeper := bank.NewCoinKeeper(app.accountMapper)
app.Router().AddRoute("bank", bank.NewHandler(coinKeeper))
app.Router().AddRoute("sketchy", sketchy.NewHandler())
// initialize BaseApp
app.SetTxDecoder()
app.SetInitChainer()
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore)
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
err := app.LoadLatestVersion(app.capKeyMainStore)
if err != nil {
panic(fmt.Errorf("error initializing application genesis state: %v", err))
cmn.Exit(err.Error())
}
app.loadStores()
return app
}
// RunForever - BasecoinApp execution and cleanup
func (app *BasecoinApp) RunForever() {
// custom tx codec
func MakeTxCodec() *wire.Codec {
cdc := wire.NewCodec()
crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] types.
bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] types.
return cdc
}
// Start the ABCI server
srv, err := server.NewServer("0.0.0.0:46658", "socket", app)
// custom logic for transaction decoding
func (app *BasecoinApp) SetTxDecoder() {
app.BaseApp.SetTxDecoder(func(txBytes []byte) (sdk.Tx, sdk.Error) {
var tx = sdk.StdTx{}
// StdTx.Msg is an interface whose concrete
// types are registered in app/msgs.go.
err := app.cdc.UnmarshalBinary(txBytes, &tx)
if err != nil {
fmt.Println(err)
os.Exit(1)
return nil, sdk.ErrTxParse("").TraceCause(err, "")
}
srv.Start()
// Wait forever
cmn.TrapSignal(func() {
// Cleanup
srv.Stop()
return tx, nil
})
}
// Load the stores
func (app *BasecoinApp) loadStores() {
if err := app.LoadLatestVersion(app.capKeyMainStore); err != nil {
fmt.Println(err)
os.Exit(1)
// custom logic for basecoin initialization
func (app *BasecoinApp) SetInitChainer() {
app.BaseApp.SetInitChainer(func(ctx sdk.Context, req abci.RequestInitChain) sdk.Error {
stateJSON := req.AppStateBytes
genesisState := new(types.GenesisState)
err := json.Unmarshal(stateJSON, 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, "")
}
app.accountMapper.SetAccount(ctx, acc)
}
return nil
})
}

View File

@ -2,6 +2,7 @@ package app
import (
"encoding/json"
"os"
"testing"
"github.com/stretchr/testify/assert"
@ -12,12 +13,20 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
)
func newBasecoinApp() *BasecoinApp {
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
db := dbm.NewMemDB()
return NewBasecoinApp(logger, db)
}
func TestSendMsg(t *testing.T) {
tba := newTestBasecoinApp()
tba.RunBeginBlock()
bapp := newBasecoinApp()
// Construct a SendMsg.
var msg = bank.SendMsg{
@ -36,15 +45,25 @@ func TestSendMsg(t *testing.T) {
},
}
// Run a Check on SendMsg.
res := tba.RunCheckMsg(msg)
assert.Equal(t, sdk.CodeOK, res.Code, res.Log)
priv := crypto.GenPrivKeyEd25519()
sig := priv.Sign(msg.GetSignBytes())
tx := sdk.NewStdTx(msg, []sdk.StdSignature{{
PubKey: priv.PubKey(),
Signature: sig,
}})
// Run a Deliver on SendMsg.
res = tba.RunDeliverMsg(msg)
// Run a Check
res := bapp.Check(tx)
assert.Equal(t, sdk.CodeUnrecognizedAddress, res.Code, res.Log)
// TODO seperate this test, need a closer on db? keep getting resource unavailable
// Simulate a Block
bapp.BeginBlock(abci.RequestBeginBlock{})
res = bapp.Deliver(tx)
assert.Equal(t, sdk.CodeUnrecognizedAddress, res.Code, res.Log)
}
func TestGenesis(t *testing.T) {
bapp := newBasecoinApp()
// construct some genesis bytes to reflect basecoin/types/AppAccount
pk := crypto.GenPrivKeyEd25519().PubKey()
@ -57,18 +76,19 @@ func TestSendMsg(t *testing.T) {
}
acc := &types.AppAccount{baseAcc, "foobart"}
genesisState := GenesisState{
Accounts: []*GenesisAccount{
NewGenesisAccount(acc),
genesisState := types.GenesisState{
Accounts: []*types.GenesisAccount{
types.NewGenesisAccount(acc),
},
}
bytes, err := json.MarshalIndent(genesisState, "", "\t")
stateBytes, 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)
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
res1 := app.accountMapper.GetAccount(ctx, baseAcc.Address)
// a checkTx context
ctx := bapp.BaseApp.NewContext(true, nil)
res1 := bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
assert.Equal(t, acc, res1)
}

View File

@ -1,93 +0,0 @@
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.
func (app *BasecoinApp) initBaseApp() {
bapp := baseapp.NewBaseApp(appName)
app.BaseApp = bapp
app.router = bapp.Router()
app.initBaseAppTxDecoder()
app.initBaseAppInitStater()
}
func (app *BasecoinApp) initBaseAppTxDecoder() {
cdc := makeTxCodec()
app.BaseApp.SetTxDecoder(func(txBytes []byte) (sdk.Tx, sdk.Error) {
var tx = sdk.StdTx{}
// StdTx.Msg is an interface whose concrete
// types are registered in app/msgs.go.
err := cdc.UnmarshalBinary(txBytes, &tx)
if err != nil {
return nil, sdk.ErrTxParse("").TraceCause(err, "")
}
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
}

View File

@ -1,16 +0,0 @@
package app
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// initCapKeys, initBaseApp, initStores, initHandlers.
func (app *BasecoinApp) initCapKeys() {
// All top-level capabilities keys
// should be constructed here.
// For more information, see http://www.erights.org/elib/capability/ode/ode.pdf.
app.capKeyMainStore = sdk.NewKVStoreKey("main")
app.capKeyIBCStore = sdk.NewKVStoreKey("ibc")
}

View File

@ -1,30 +0,0 @@
package app
import (
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/sketchy"
)
// initCapKeys, initBaseApp, initStores, initHandlers.
func (app *BasecoinApp) initHandlers() {
app.initDefaultAnteHandler()
app.initRouterHandlers()
}
func (app *BasecoinApp) initDefaultAnteHandler() {
// Deducts fee from payer.
// Verifies signatures and nonces.
// Sets Signers to ctx.
app.BaseApp.SetDefaultAnteHandler(
auth.NewAnteHandler(app.accountMapper))
}
func (app *BasecoinApp) initRouterHandlers() {
// All handlers must be added here.
// The order matters.
app.router.AddRoute("bank", bank.NewHandler(bank.NewCoinKeeper(app.accountMapper)))
app.router.AddRoute("sketchy", sketchy.NewHandler())
}

View File

@ -1,38 +0,0 @@
package app
import (
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
)
// initCapKeys, initBaseApp, initStores, initHandlers.
func (app *BasecoinApp) initStores() {
app.mountStores()
app.initAccountMapper()
}
// Initialize root stores.
func (app *BasecoinApp) mountStores() {
// Create MultiStore mounts.
app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL)
app.BaseApp.MountStore(app.capKeyIBCStore, sdk.StoreTypeIAVL)
}
// Initialize the AccountMapper.
func (app *BasecoinApp) initAccountMapper() {
var accountMapper = auth.NewAccountMapper(
app.capKeyMainStore, // target store
&types.AppAccount{}, // prototype
)
// Register all interfaces and concrete types that
// implement those interfaces, here.
cdc := accountMapper.WireCodec()
auth.RegisterWireBaseAccount(cdc)
// Make accountMapper's WireCodec() inaccessible.
app.accountMapper = accountMapper.Seal()
}

View File

@ -1,22 +0,0 @@
package app
import (
"github.com/cosmos/cosmos-sdk/x/bank"
crypto "github.com/tendermint/go-crypto"
wire "github.com/tendermint/go-wire"
)
// Wire requires registration of interfaces & concrete types. All
// interfaces to be encoded/decoded in a Msg must be registered
// here, along with all the concrete types that implement them.
func makeTxCodec() (cdc *wire.Codec) {
cdc = wire.NewCodec()
// Register crypto.[PubKey,PrivKey,Signature] types.
crypto.RegisterWire(cdc)
// Register bank.[SendMsg,IssueMsg] types.
bank.RegisterWire(cdc)
return
}

View File

@ -1,19 +0,0 @@
package app
import (
bam "github.com/cosmos/cosmos-sdk/baseapp"
)
type testBasecoinApp struct {
*BasecoinApp
*bam.TestApp
}
func newTestBasecoinApp() *testBasecoinApp {
app := NewBasecoinApp("")
tba := &testBasecoinApp{
BasecoinApp: app,
}
tba.TestApp = bam.NewTestApp(app.BaseApp)
return tba
}

View File

@ -1,10 +1,27 @@
package main
import "github.com/cosmos/cosmos-sdk/examples/basecoin/app"
import (
"fmt"
"os"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
)
func main() {
// TODO CREATE CLI
bapp := app.NewBasecoinApp("")
bapp.RunForever()
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "main")
db, err := dbm.NewGoLevelDB("basecoind", "data")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
bapp := app.NewBasecoinApp(logger, db)
baseapp.RunForever(bapp)
}

View File

@ -1 +0,0 @@
bin/*

View File

@ -1,62 +0,0 @@
all: install_glide check get_vendor_deps install
########################################
### Glide
GLIDE = github.com/tendermint/glide
GLIDE_CHECK := $(shell command -v glide 2> /dev/null)
check:
ifndef GLIDE_CHECK
@echo "No glide in path. Install with 'make install_glide'."
else
@echo "Found glide in path."
endif
install_glide:
ifdef GLIDE_CHECK
@echo "Glide is already installed. Run 'make update_glide' to update."
else
@echo "$(ansi_grn)Installing glide$(ansi_end)"
go get -v $(GLIDE)
endif
update_glide:
@echo "$(ansi_grn)Updating glide$(ansi_end)"
go get -u -v $(GLIDE)
########################################
### Install tools
get_vendor_deps: check
@rm -rf vendor/
@echo "--> Running glide install"
@glide install
install: get_vendor_deps
@echo "$(ansi_grn)Installing tools$(ansi_end)"
@echo "$(ansi_yel)Install go-vendorinstall$(ansi_end)"
go build -o bin/go-vendorinstall go-vendorinstall/*.go
@echo "$(ansi_yel)Install gometalinter.v2$(ansi_end)"
GOBIN=$(CURDIR)/bin ./bin/go-vendorinstall gopkg.in/alecthomas/gometalinter.v2
@echo "$(ansi_grn)Done installing tools$(ansi_end)"
########################################
# ANSI colors
ansi_red=\033[0;31m
ansi_grn=\033[0;32m
ansi_yel=\033[0;33m
ansi_end=\033[0m
# To avoid unintended conflicts with file names, always add to .PHONY
# unless there is a reason not to.
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
.PHONY: check install_glide update_glide get_vendor_deps install

View File

@ -1,18 +0,0 @@
hash: a163b1c4806024cfc9062db75a0abed285ec40461243e59af0e147db2c4bf0ce
updated: 2018-01-15T19:02:49.834182027-08:00
imports:
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/rigelrozanski/common
version: f691f115798593d783b9999b1263c2f4ffecc439
- name: github.com/rigelrozanski/shelldown
version: 2e18b6eb9bf428aa524e71433296e0b7c73ae0a3
subpackages:
- cmd/shelldown
- name: github.com/spf13/cobra
version: 7b2c5ac9fc04fc5efafb60700713d4fa609b777b
- name: github.com/spf13/pflag
version: 97afa5e7ca8a08a383cb259e06636b5e2cc7897f
- name: gopkg.in/alecthomas/gometalinter.v2
version: 88d47c66988c5a5cb3945925da47c883800a94df
testImports: []

View File

@ -1,6 +0,0 @@
package: github.com/cosmos/cosmos-sdk/tools
import:
- package: github.com/rigelrozanski/shelldown
subpackages:
- cmd/shelldown
- package: gopkg.in/alecthomas/gometalinter.v2

View File

@ -1,129 +0,0 @@
// https://raw.githubusercontent.com/roboll/go-vendorinstall/a3e9f0a5d5861b3bb16b93200b2c359c9846b3c5/main.go
package main
import (
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
)
var (
source = flag.String("source", "vendor", "source directory")
target = flag.String("target", "", "target directory (defaults to $GOBIN, if not set $GOPATH/bin)")
commands = flag.String("commands", "", "comma separated list of commands to execute after go install in temporary environment")
quiet = flag.Bool("quiet", false, "disable output")
)
func main() {
flag.Parse()
packages := flag.Args()
if len(packages) < 1 {
fail(errors.New("no packages: specify a package"))
}
gopath, err := ioutil.TempDir("", "go-vendorinstall-gopath")
if err != nil {
fail(err)
}
print(fmt.Sprintf("gopath: %s", gopath))
defer func() {
if err := os.RemoveAll(gopath); err != nil {
fail(err)
}
}()
if len(*target) == 0 {
if gobin := os.Getenv("GOBIN"); len(gobin) > 0 {
target = &gobin
} else {
bin := fmt.Sprintf("%s/bin", os.Getenv("GOPATH"))
target = &bin
}
}
gobin, err := filepath.Abs(*target)
if err != nil {
fail(err)
}
print(fmt.Sprintf("gobin: %s", gobin))
if err := link(gopath, *source); err != nil {
fail(err)
}
oldpath := os.Getenv("PATH")
path := fmt.Sprintf("%s%s%s", gobin, string(os.PathListSeparator), os.Getenv("PATH"))
os.Setenv("PATH", fmt.Sprintf("%s%s%s", gobin, string(os.PathListSeparator), os.Getenv("PATH")))
defer os.Setenv("PATH", oldpath)
env := []string{fmt.Sprintf("PATH=%s", path), fmt.Sprintf("GOPATH=%s", gopath), fmt.Sprintf("GOBIN=%s", gobin)}
args := append([]string{"install"}, packages...)
if out, err := doexec("go", gopath, args, env); err != nil {
print(string(out))
fail(err)
}
if len(*commands) > 0 {
for _, cmd := range strings.Split(*commands, ",") {
split := strings.Split(cmd, " ")
if out, err := doexec(split[0], gopath, split[1:], env); err != nil {
print(string(out))
fail(err)
}
}
}
}
func print(msg string) {
if !*quiet {
fmt.Println(msg)
}
}
func fail(err error) {
fmt.Printf("error: %s", err.Error())
os.Exit(1)
}
func link(gopath, source string) error {
srcdir, err := filepath.Abs(source)
if err != nil {
return err
}
linkto := filepath.Join(gopath, "src")
if err := os.MkdirAll(linkto, 0777); err != nil {
return err
}
files, err := ioutil.ReadDir(srcdir)
if err != nil {
return err
}
for _, file := range files {
real := filepath.Join(srcdir, file.Name())
link := filepath.Join(linkto, file.Name())
if err := os.Symlink(real, link); err != nil {
return err
}
}
return nil
}
func doexec(bin, dir string, args []string, env []string) ([]byte, error) {
print(fmt.Sprintf("%s %s", bin, strings.Join(args, " ")))
cmd := exec.Command(bin, args...)
cmd.Env = env
cmd.Dir = dir
return cmd.CombinedOutput()
}

View File

@ -1,12 +0,0 @@
package main
import (
// Include dependencies here so glide picks them up
// and installs sub-dependencies.
// TODO: Ideally this gets auto-imported on glide update.
// Any way to make that happen?
_ "github.com/rigelrozanski/common"
)
func main() {}

View File

@ -3,25 +3,55 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
crypto "github.com/tendermint/go-crypto"
)
var _ sdk.Account = (*AppAccount)(nil)
// Custom extensions for this application. This is just an example of
// extending auth.BaseAccount with custom fields.
//
// This is compatible with the stock auth.AccountStore, since
// auth.AccountStore uses the flexible go-wire library.
type AppAccount struct {
auth.BaseAccount
// Custom extensions for this application. This is just an example of
// extending auth.BaseAccount with custom fields.
//
// This is compatible with the stock auth.AccountStore, since
// auth.AccountStore uses the flexible go-wire library.
Name string
}
func (acc AppAccount) GetName() string {
return acc.Name
// nolint
func (acc AppAccount) GetName() string { return acc.Name }
func (acc *AppAccount) SetName(name string) { acc.Name = name }
//___________________________________________________________________________________
// State to Unmarshal
type GenesisState struct {
Accounts []*GenesisAccount `json:"accounts"`
}
func (acc *AppAccount) SetName(name string) {
acc.Name = name
// 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 *AppAccount) *GenesisAccount {
return &GenesisAccount{
Name: aa.Name,
Address: aa.Address,
Coins: aa.Coins,
}
}
// convert GenesisAccount to AppAccount
func (ga *GenesisAccount) ToAppAccount() (acc *AppAccount, err error) {
baseAcc := auth.BaseAccount{
Address: ga.Address,
Coins: ga.Coins,
}
return &AppAccount{
BaseAccount: baseAcc,
Name: ga.Name,
}, nil
}

View File

@ -6,6 +6,8 @@ import (
"github.com/tendermint/abci/server"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
bam "github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -13,11 +15,19 @@ import (
func main() {
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "main")
db, err := dbm.NewGoLevelDB("basecoind", "data")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Capabilities key to access the main KVStore.
var capKeyMainStore = sdk.NewKVStoreKey("main")
// Create BaseApp.
var baseApp = bam.NewBaseApp("dummy")
var baseApp = bam.NewBaseApp("dummy", logger, db)
// Set mounts for BaseApp's MultiStore.
baseApp.MountStore(capKeyMainStore, sdk.StoreTypeIAVL)

10
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: 2b4ad3bf1489a7cb5e62c6cb4c1fa976d4ae21993743e4968418c4e81925fb99
updated: 2018-02-13T08:33:22.402132782-05:00
hash: 4d523b19f5b2f54caca37e196582c85d459fdfa5d5383d7e97ee81639b46129d
updated: 2018-02-16T19:52:42.711474619-05:00
imports:
- name: github.com/btcsuite/btcd
version: 50de9da05b50eb15658bb350f6ea24368a111ab7
@ -82,7 +82,7 @@ imports:
- name: github.com/spf13/viper
version: 25b30aa063fc18e48662b86996252eabdcf2f0c7
- name: github.com/syndtr/goleveldb
version: 211f780988068502fe874c44dae530528ebd840f
version: 34011bf325bce385408353a30b101fe5e923eb6e
subpackages:
- leveldb
- leveldb/cache
@ -97,7 +97,7 @@ imports:
- leveldb/table
- leveldb/util
- name: github.com/tendermint/abci
version: bf70f5e273bd7dd6e22e64186cd1ccc4e3a03df1
version: a6be687088a7158e9e431931c3769d6706f90c4c
subpackages:
- server
- types
@ -113,7 +113,7 @@ imports:
- name: github.com/tendermint/iavl
version: 1a59ec0c82dc940c25339dd7c834df5cb76a95cb
- name: github.com/tendermint/tmlibs
version: c858b3ba78316fdd9096a11409a7e7a493e7d974
version: a0f652dc2e131be86fc8d9e4e2beec9831a8a6ec
subpackages:
- cli
- common

View File

@ -8,7 +8,7 @@ import:
version: ^0.8.0
- package: github.com/rigelrozanski/common
- package: github.com/tendermint/abci
version: develop
version: feature/init-chain-app-state
subpackages:
- server
- types

View File

@ -19,7 +19,6 @@ const (
func LoadIAVLStore(db dbm.DB, id CommitID) (CommitStore, error) {
tree := iavl.NewVersionedTree(db, defaultIAVLCacheSize)
fmt.Println("LoadIAVLStore Version ", id.Version)
err := tree.LoadVersion(id.Version)
if err != nil {
return nil, err

6
types/abci.go Normal file
View File

@ -0,0 +1,6 @@
package types
import abci "github.com/tendermint/abci/types"
// initialize application state at genesis
type InitChainer func(ctx Context, req abci.RequestInitChain) Error

View File

@ -1,6 +0,0 @@
package types
import "encoding/json"
// function variable used to initialize application state at genesis
type InitStater func(ctx Context, state json.RawMessage) Error

View File

@ -61,7 +61,8 @@ type CommitMultiStore interface {
Committer
MultiStore
// Mount a store of type.
// Mount a store of type using the given db.
// If db == nil, the new store will use the CommitMultiStore db.
MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB)
// Panics on a nil key.

View File

@ -49,15 +49,23 @@ type Tx interface {
var _ Tx = (*StdTx)(nil)
// standard transaction form
// StdTx is a standard way to wrap a Msg with Signatures.
// NOTE: the first signature is the FeePayer (Signatures must not be nil).
type StdTx struct {
Msg
Signatures []StdSignature
}
func NewStdTx(msg Msg, sigs []StdSignature) StdTx {
return StdTx{
Msg: msg,
Signatures: sigs,
}
}
//nolint
func (tx StdTx) GetMsg() Msg { return tx.Msg }
func (tx StdTx) GetFeePayer() crypto.Address { return tx.Signatures[0].PubKey.Address() }
func (tx StdTx) GetFeePayer() crypto.Address { return tx.Signatures[0].PubKey.Address() } // XXX but PubKey is optional!
func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
//-------------------------------------

View File

@ -1,7 +1,6 @@
package auth
import (
bam "github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -25,20 +24,16 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
// TODO: accountMapper.SetAccount(ctx, payerAddr)
} else {
// TODO: Ensure that some other spam prevention is used.
// NOTE: bam.TestApp.RunDeliverMsg/RunCheckMsg will
// create a Tx with no payer.
}
var sigs = tx.GetSignatures()
// Assert that there are signatures.
if !bam.IsTestAppTx(tx) {
if len(sigs) == 0 {
return ctx,
sdk.ErrUnauthorized("no signers").Result(),
true
}
}
// Ensure that sigs are correct.
var msg = tx.GetMsg()
@ -46,7 +41,6 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
var signerAccs = make([]sdk.Account, len(signerAddrs))
// Assert that number of signatures is correct.
if !bam.IsTestAppTx(tx) {
if len(sigs) != len(signerAddrs) {
return ctx,
sdk.ErrUnauthorized("wrong number of signers").Result(),
@ -89,7 +83,6 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
// Save the account.
accountMapper.SetAccount(ctx, signerAcc)
}
}
ctx = WithSigners(ctx, signerAccs)
return ctx, sdk.Result{}, false // continue...

View File

@ -36,6 +36,20 @@ func NewAccountMapper(key sdk.StoreKey, proto sdk.Account) accountMapper {
}
}
// Create and return a sealed account mapper
func NewAccountMapperSealed(key sdk.StoreKey, proto sdk.Account) sealedAccountMapper {
cdc := wire.NewCodec()
am := accountMapper{
key: key,
proto: proto,
cdc: cdc,
}
RegisterWireBaseAccount(cdc)
// make accountMapper's WireCodec() inaccessible, return
return am.Seal()
}
// Returns the go-wire codec. You may need to register interfaces
// and concrete types here, if your app's sdk.Account
// implementation includes interface fields.