Start on coin handler
This commit is contained in:
parent
a0f1e5e66a
commit
37796002ae
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -26,8 +27,14 @@ const (
|
||||||
msgTooManySignatures = "Too many signatures"
|
msgTooManySignatures = "Too many signatures"
|
||||||
msgNoChain = "No chain id provided"
|
msgNoChain = "No chain id provided"
|
||||||
msgWrongChain = "Tx belongs to different chain - %s"
|
msgWrongChain = "Tx belongs to different chain - %s"
|
||||||
|
msgUnknownTxType = "We cannot handle this tx - %v"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func UnknownTxType(tx basecoin.Tx) TMError {
|
||||||
|
msg := fmt.Sprintf(msgUnknownTxType, tx)
|
||||||
|
return New(msg, abci.CodeType_UnknownRequest)
|
||||||
|
}
|
||||||
|
|
||||||
func InternalError(msg string) TMError {
|
func InternalError(msg string) TMError {
|
||||||
return New(msg, abci.CodeType_InternalError)
|
return New(msg, abci.CodeType_InternalError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package coin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
"github.com/tendermint/basecoin/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NameCoin = "coin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Handler writes
|
||||||
|
type Handler struct{}
|
||||||
|
|
||||||
|
var _ basecoin.Handler = Handler{}
|
||||||
|
|
||||||
|
func (_ Handler) Name() string {
|
||||||
|
return NameCoin
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckTx checks if there is enough money in the account
|
||||||
|
func (h Handler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
_, err = checkTx(ctx, tx)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// now make sure there is money
|
||||||
|
|
||||||
|
// otherwise, we are good
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeliverTx moves the money
|
||||||
|
func (h Handler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
_, err = checkTx(ctx, tx)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// now move the money
|
||||||
|
return basecoin.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (*SendTx, error) {
|
||||||
|
// check if the tx is proper type and valid
|
||||||
|
send, ok := tx.Unwrap().(*SendTx)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.UnknownTxType(tx)
|
||||||
|
}
|
||||||
|
err := send.ValidateBasic()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if all inputs have permission
|
||||||
|
for _, in := range send.Inputs {
|
||||||
|
if !ctx.HasPermission(in.Address) {
|
||||||
|
return nil, errors.Unauthorized()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return send, nil
|
||||||
|
}
|
|
@ -98,15 +98,23 @@ func (tx SendTx) ValidateBasic() error {
|
||||||
if len(tx.Outputs) == 0 {
|
if len(tx.Outputs) == 0 {
|
||||||
return errors.NoOutputs()
|
return errors.NoOutputs()
|
||||||
}
|
}
|
||||||
|
// make sure all inputs and outputs are individually valid
|
||||||
|
var totalIn, totalOut types.Coins
|
||||||
for _, in := range tx.Inputs {
|
for _, in := range tx.Inputs {
|
||||||
if err := in.ValidateBasic(); err != nil {
|
if err := in.ValidateBasic(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
totalIn.Plus(in.Coins)
|
||||||
}
|
}
|
||||||
for _, out := range tx.Outputs {
|
for _, out := range tx.Outputs {
|
||||||
if err := out.ValidateBasic(); err != nil {
|
if err := out.ValidateBasic(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
totalOut.Plus(out.Coins)
|
||||||
|
}
|
||||||
|
// make sure inputs and outputs match
|
||||||
|
if !totalIn.IsEqual(totalOut) {
|
||||||
|
return errors.InvalidCoins()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package stack
|
package stack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin"
|
"github.com/tendermint/basecoin"
|
||||||
"github.com/tendermint/basecoin/txs"
|
"github.com/tendermint/basecoin/txs"
|
||||||
"github.com/tendermint/basecoin/types"
|
"github.com/tendermint/basecoin/types"
|
||||||
|
wire "github.com/tendermint/go-wire"
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -45,7 +49,17 @@ func runAll(ctx basecoin.Context, store types.KVStore, txs []basecoin.Tx, next b
|
||||||
return combine(rs), nil
|
return combine(rs), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func combine(res []basecoin.Result) basecoin.Result {
|
// combines all data bytes as a go-wire array.
|
||||||
// TODO: how to combine???
|
// joins all log messages with \n
|
||||||
return res[0]
|
func combine(all []basecoin.Result) basecoin.Result {
|
||||||
|
datas := make([]data.Bytes, len(all))
|
||||||
|
logs := make([]string, len(all))
|
||||||
|
for i, r := range all {
|
||||||
|
datas[i] = r.Data
|
||||||
|
logs[i] = r.Log
|
||||||
|
}
|
||||||
|
return basecoin.Result{
|
||||||
|
Data: wire.BinaryBytes(datas),
|
||||||
|
Log: strings.Join(logs, "\n"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue