parent
fdc7316fda
commit
14a0dce920
|
@ -261,6 +261,8 @@ func (app *App) runTx(isCheckTx bool, txBytes []byte) (result sdk.Result) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: override default ante handler w/ custom ante handler.
|
||||
|
||||
// Run the ante handler.
|
||||
ctx, result, abort := app.defaultAnteHandler(ctx, tx)
|
||||
if isCheckTx || abort {
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
apm "github.com/cosmos/cosmos-sdk/app"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/go-wire"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
const appName = "BasecoinApp"
|
||||
|
||||
type BasecoinApp struct {
|
||||
*apm.App
|
||||
cdc *wire.Codec
|
||||
multiStore sdk.CommitMultiStore
|
||||
|
||||
// The key to access the substores.
|
||||
mainStoreKey *sdk.KVStoreKey
|
||||
ibcStoreKey *sdk.KVStoreKey
|
||||
|
||||
// Additional stores:
|
||||
accStore sdk.AccountStore
|
||||
}
|
||||
|
||||
// TODO: This should take in more configuration options.
|
||||
func NewBasecoinApp() *BasecoinApp {
|
||||
|
||||
// Create and configure app.
|
||||
var app = &BasecoinApp{}
|
||||
app.initKeys()
|
||||
app.initMultiStore()
|
||||
app.initAppStore()
|
||||
app.initSDKApp()
|
||||
app.initCodec()
|
||||
app.initTxDecoder()
|
||||
app.initAnteHandler()
|
||||
app.initRoutes()
|
||||
|
||||
// TODO: Load genesis
|
||||
// TODO: InitChain with validators
|
||||
// TODO: Set the genesis accounts
|
||||
app.loadStores()
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func (app *BasecoinApp) RunForever() {
|
||||
|
||||
// Start the ABCI server
|
||||
srv, err := server.NewServer("0.0.0.0:46658", "socket", app)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
srv.Start()
|
||||
|
||||
// Wait forever
|
||||
cmn.TrapSignal(func() {
|
||||
// Cleanup
|
||||
srv.Stop()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (app *BasecoinApp) initKeys() {
|
||||
app.mainStoreKey = sdk.NewKVStoreKey("main")
|
||||
app.ibcStoreKey = sdk.NewKVStoreKey("ibc")
|
||||
}
|
||||
|
||||
// depends on initMultiStore()
|
||||
func (app *BasecoinApp) initSDKApp() {
|
||||
app.App = apm.NewApp(appName, app.multiStore)
|
||||
}
|
||||
|
||||
func (app *BasecoinApp) initCodec() {
|
||||
app.cdc = wire.NewCodec()
|
||||
}
|
||||
|
||||
// depends on initSDKApp()
|
||||
func (app *BasecoinApp) initTxDecoder() {
|
||||
app.App.SetTxDecoder(app.decodeTx)
|
||||
}
|
||||
|
||||
// initAnteHandler defined in app/routes.go
|
||||
// initRoutes defined in app/routes.go
|
||||
|
||||
// Load the stores.
|
||||
func (app *BasecoinApp) loadStores() {
|
||||
if err := app.LoadLatestVersion(app.mainStoreKey); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
|
||||
// Set via `app.App.SetTxDecoder(app.decodeTx)`
|
||||
func (app *BasecoinApp) decodeTx(txBytes []byte) (sdk.Tx, error) {
|
||||
var tx = sdk.StdTx{}
|
||||
err := app.cdc.UnmarshalBinary(txBytes, &tx)
|
||||
return tx, err
|
||||
}
|
||||
|
||||
// Wire requires registration of interfaces & concrete types.
|
||||
func (app *BasecoinApp) registerMsgs() {
|
||||
cdc := app.cdc
|
||||
|
||||
// Register the Msg interface.
|
||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil) // XXX refactor out
|
||||
cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil) // XXX refactor out to bank/msgs.go
|
||||
// more msgs here...
|
||||
|
||||
// All interfaces to be encoded/decoded in a Msg must be
|
||||
// registered here, along with all the concrete types that
|
||||
// implement them.
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
|
||||
// Handle charging tx fees and checking signatures.
|
||||
func (app *BasecoinApp) initAnteHandler() {
|
||||
var authAnteHandler = auth.NewAnteHandler(app.accStore)
|
||||
app.App.SetDefaultAnteHandler(authAnteHandler)
|
||||
}
|
||||
|
||||
// Constructs router to route handling of msgs.
|
||||
func (app *BasecoinApp) initRoutes() {
|
||||
var router = app.App.Router()
|
||||
// var multiStore = app.multiStore
|
||||
var accStore = app.accStore
|
||||
|
||||
router.AddRoute("bank", bank.NewHandler(accStore))
|
||||
// more routes here... (order matters)
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
// depends on initKeys()
|
||||
func (app *BasecoinApp) initMultiStore() {
|
||||
|
||||
// Create the underlying leveldb datastore which will
|
||||
// persist the Merkle tree inner & leaf nodes.
|
||||
db, err := dbm.NewGoLevelDB("basecoin", "basecoin-data")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create CommitStoreLoader.
|
||||
cacheSize := 10000
|
||||
numHistory := int64(100)
|
||||
mainLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
|
||||
ibcLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
|
||||
|
||||
// Create MultiStore
|
||||
multiStore := store.NewCommitMultiStore(db)
|
||||
multiStore.SetSubstoreLoader(app.mainStoreKey, mainLoader)
|
||||
multiStore.SetSubstoreLoader(app.ibcStoreKey, ibcLoader)
|
||||
|
||||
// Finally,
|
||||
app.multiStore = multiStore
|
||||
}
|
||||
|
||||
// depends on initKeys()
|
||||
func (app *BasecoinApp) initAppStore() {
|
||||
app.accStore = auth.NewAccountStore(
|
||||
app.mainStoreKey,
|
||||
types.AppAccountCodec{},
|
||||
)
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/app"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/go-wire"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
|
||||
bcm "github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// Create the underlying leveldb datastore which will
|
||||
// persist the Merkle tree inner & leaf nodes.
|
||||
db, err := dbm.NewGoLevelDB("basecoin", "basecoin-data")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create CommitStoreLoader.
|
||||
cacheSize := 10000
|
||||
numHistory := int64(100)
|
||||
mainLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
|
||||
ibcLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
|
||||
|
||||
// The key to access the main KVStore.
|
||||
var mainStoreKey = sdk.NewKVStoreKey("main")
|
||||
var ibcStoreKey = sdk.NewKVStoreKey("ibc")
|
||||
|
||||
// Create MultiStore
|
||||
multiStore := store.NewCommitMultiStore(db)
|
||||
multiStore.SetSubstoreLoader(mainStoreKey, mainLoader)
|
||||
multiStore.SetSubstoreLoader(ibcStoreKey, ibcLoader)
|
||||
|
||||
// Create the Application.
|
||||
app := app.NewApp("basecoin", multiStore)
|
||||
|
||||
// Set Tx decoder
|
||||
app.SetTxDecoder(decodeTx)
|
||||
|
||||
var accStore = auth.NewAccountStore(mainStoreKey, bcm.AppAccountCodec{})
|
||||
var authAnteHandler = auth.NewAnteHandler(accStore)
|
||||
|
||||
// Handle charging fees and checking signatures.
|
||||
app.SetDefaultAnteHandler(authAnteHandler)
|
||||
|
||||
// Add routes to App.
|
||||
app.Router().AddRoute("bank", bank.NewHandler(accStore))
|
||||
|
||||
// TODO: load genesis
|
||||
// TODO: InitChain with validators
|
||||
// accounts := auth.NewAccountStore(multiStore.GetKVStore("main"))
|
||||
// TODO: set the genesis accounts
|
||||
|
||||
// Load the stores.
|
||||
if err := app.LoadLatestVersion(mainStoreKey); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Start the ABCI server
|
||||
srv, err := server.NewServer("0.0.0.0:46658", "socket", app)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
srv.Start()
|
||||
|
||||
// Wait forever
|
||||
cmn.TrapSignal(func() {
|
||||
// Cleanup
|
||||
srv.Stop()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Misc.
|
||||
|
||||
func registerMsgs() {
|
||||
wire.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
wire.RegisterConcrete(&bank.SendMsg{}, "com.cosmos.basecoin.send_msg", nil)
|
||||
}
|
||||
|
||||
func decodeTx(txBytes []byte) (sdk.Tx, error) {
|
||||
var tx = sdk.StdTx{}
|
||||
err := wire.UnmarshalBinary(txBytes, &tx)
|
||||
return tx, err
|
||||
}
|
|
@ -39,6 +39,9 @@ func NewCommitMultiStore(db dbm.DB) *rootMultiStore {
|
|||
|
||||
// Implements CommitMultiStore.
|
||||
func (rs *rootMultiStore) SetSubstoreLoader(key SubstoreKey, loader CommitStoreLoader) {
|
||||
if key == nil {
|
||||
panic("SetSubstoreLoader() key cannot be nil")
|
||||
}
|
||||
if _, ok := rs.storeLoaders[key]; ok {
|
||||
panic(fmt.Sprintf("rootMultiStore duplicate substore key", key))
|
||||
}
|
||||
|
|
|
@ -54,9 +54,11 @@ type CommitMultiStore interface {
|
|||
MultiStore
|
||||
|
||||
// Add a substore loader.
|
||||
// Panics on a nil key.
|
||||
SetSubstoreLoader(key SubstoreKey, loader CommitStoreLoader)
|
||||
|
||||
// Gets the substore, which is a CommitSubstore.
|
||||
// Panics on a nil key.
|
||||
GetSubstore(key SubstoreKey) CommitStore
|
||||
|
||||
// Load the latest persisted version.
|
||||
|
|
|
@ -55,7 +55,7 @@ func NewAnteHandler(store sdk.AccountStore) sdk.AnteHandler {
|
|||
}
|
||||
}
|
||||
|
||||
// Check and incremenet sequence number.
|
||||
// Check and increment sequence number.
|
||||
seq := signerAcc.GetSequence()
|
||||
if seq != sig.Sequence {
|
||||
return ctx, sdk.Result{
|
||||
|
|
|
@ -2,21 +2,35 @@ package bank
|
|||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Handle all "bank" type messages.
|
||||
func NewHandler(accStore sdk.AccountStore) sdk.Handler {
|
||||
|
||||
return func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
|
||||
cs := CoinStore{accStore}
|
||||
|
||||
sendTx, ok := tx.(sdk.Msg).(SendMsg)
|
||||
if !ok {
|
||||
panic("tx is not SendTx") // ?
|
||||
msg := tx.(sdk.Msg)
|
||||
switch msg := msg.(type) {
|
||||
case SendMsg:
|
||||
return handleSendMsg(ctx, cs, msg)
|
||||
case IssueMsg:
|
||||
return handleIssueMsg(ctx, cs, msg)
|
||||
default:
|
||||
return sdk.Result{
|
||||
Code: 1, // TODO
|
||||
Log: "Unrecognized bank Tx type: " + reflect.TypeOf(tx).Name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Handle SendMsg.
|
||||
func handleSendMsg(ctx sdk.Context, cs CoinStore, msg SendMsg) sdk.Result {
|
||||
// NOTE: totalIn == totalOut should already have been checked
|
||||
|
||||
for _, in := range sendTx.Inputs {
|
||||
for _, in := range msg.Inputs {
|
||||
_, err := cs.SubtractCoins(ctx, in.Address, in.Coins)
|
||||
if err != nil {
|
||||
return sdk.Result{
|
||||
|
@ -25,7 +39,7 @@ func NewHandler(accStore sdk.AccountStore) sdk.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
for _, out := range sendTx.Outputs {
|
||||
for _, out := range msg.Outputs {
|
||||
_, err := cs.AddCoins(ctx, out.Address, out.Coins)
|
||||
if err != nil {
|
||||
return sdk.Result{
|
||||
|
@ -36,4 +50,8 @@ func NewHandler(accStore sdk.AccountStore) sdk.Handler {
|
|||
|
||||
return sdk.Result{} // TODO
|
||||
}
|
||||
|
||||
// Handle IssueMsg.
|
||||
func handleIssueMsg(ctx sdk.Context, cs CoinStore, msg IssueMsg) sdk.Result {
|
||||
panic("not implemented yet")
|
||||
}
|
||||
|
|
54
x/bank/tx.go
54
x/bank/tx.go
|
@ -81,6 +81,60 @@ func (msg SendMsg) GetSigners() []crypto.Address {
|
|||
return addrs
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// IssueMsg
|
||||
|
||||
// IssueMsg - high level transaction of the coin module
|
||||
type IssueMsg struct {
|
||||
Banker crypto.Address `json:"banker"`
|
||||
Outputs []Output `json:"outputs"`
|
||||
}
|
||||
|
||||
// NewIssueMsg - construct arbitrary multi-in, multi-out send msg.
|
||||
func NewIssueMsg(banker crypto.Address, out []Output) IssueMsg {
|
||||
return IssueMsg{Banker: banker, Outputs: out}
|
||||
}
|
||||
|
||||
// Implements Msg.
|
||||
func (msg IssueMsg) Type() string { return "bank" } // TODO: "bank/send"
|
||||
|
||||
// Implements Msg.
|
||||
func (msg IssueMsg) ValidateBasic() error {
|
||||
// XXX
|
||||
if len(msg.Outputs) == 0 {
|
||||
return ErrNoOutputs()
|
||||
}
|
||||
for _, out := range msg.Outputs {
|
||||
if err := out.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg IssueMsg) String() string {
|
||||
return fmt.Sprintf("IssueMsg{%v#%v}", msg.Banker, msg.Outputs)
|
||||
}
|
||||
|
||||
// Implements Msg.
|
||||
func (msg IssueMsg) Get(key interface{}) (value interface{}) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Implements Msg.
|
||||
func (msg IssueMsg) GetSignBytes() []byte {
|
||||
b, err := json.Marshal(msg) // XXX: ensure some canonical form
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Implements Msg.
|
||||
func (msg IssueMsg) GetSigners() []crypto.Address {
|
||||
return []crypto.Address{msg.Banker}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Input
|
||||
|
||||
|
|
Loading…
Reference in New Issue