First demo of handlers
This commit is contained in:
parent
be89f1f582
commit
f4393511ee
|
@ -0,0 +1,53 @@
|
||||||
|
package basecoin
|
||||||
|
|
||||||
|
import (
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Handler is anything that processes a transaction
|
||||||
|
type Handler interface {
|
||||||
|
CheckTx(ctx Context, store types.KVStore, tx Tx) (Result, error)
|
||||||
|
DeliverTx(ctx Context, store types.KVStore, tx Tx) (Result, error)
|
||||||
|
|
||||||
|
// TODO: flesh these out as well
|
||||||
|
// SetOption(store types.KVStore, key, value string) (log string)
|
||||||
|
// InitChain(store types.KVStore, vals []*abci.Validator)
|
||||||
|
// BeginBlock(store types.KVStore, hash []byte, header *abci.Header)
|
||||||
|
// EndBlock(store types.KVStore, height uint64) abci.ResponseEndBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Context is a place-holder, soon we add some request data here from the
|
||||||
|
// higher-levels (like tell an app who signed).
|
||||||
|
// Trust me, we will need it like CallContext now...
|
||||||
|
type Context struct {
|
||||||
|
sigs []crypto.PubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOTALLY insecure. will redo later, but you get the point
|
||||||
|
func (c Context) AddSigners(keys ...crypto.PubKey) Context {
|
||||||
|
return Context{
|
||||||
|
sigs: append(c.sigs, keys...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Context) GetSigners() []crypto.PubKey {
|
||||||
|
return c.sigs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result captures any non-error abci result
|
||||||
|
// to make sure people use error for error cases
|
||||||
|
type Result struct {
|
||||||
|
Data data.Bytes
|
||||||
|
Log string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Result) ToABCI() abci.Result {
|
||||||
|
return abci.Result{
|
||||||
|
Data: r.Data,
|
||||||
|
Log: r.Log,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin"
|
||||||
|
"github.com/tendermint/basecoin/errors"
|
||||||
|
"github.com/tendermint/basecoin/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SignedHandler struct {
|
||||||
|
AllowMultiSig bool
|
||||||
|
Inner basecoin.Handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h SignedHandler) Next() basecoin.Handler {
|
||||||
|
return h.Inner
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basecoin.Handler = SignedHandler{}
|
||||||
|
|
||||||
|
type Signed interface {
|
||||||
|
basecoin.TxLayer
|
||||||
|
Signers() ([]crypto.PubKey, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h SignedHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
var sigs []crypto.PubKey
|
||||||
|
|
||||||
|
stx, ok := tx.Unwrap().(Signed)
|
||||||
|
if !ok {
|
||||||
|
return res, errors.Unauthorized()
|
||||||
|
}
|
||||||
|
|
||||||
|
sigs, err = stx.Signers()
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the signers to the context and continue
|
||||||
|
ctx2 := ctx.AddSigners(sigs...)
|
||||||
|
return h.Next().CheckTx(ctx2, store, stx.Next())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h SignedHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
var sigs []crypto.PubKey
|
||||||
|
|
||||||
|
stx, ok := tx.Unwrap().(Signed)
|
||||||
|
if !ok {
|
||||||
|
return res, errors.Unauthorized()
|
||||||
|
}
|
||||||
|
|
||||||
|
sigs, err = stx.Signers()
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the signers to the context and continue
|
||||||
|
ctx2 := ctx.AddSigners(sigs...)
|
||||||
|
return h.Next().DeliverTx(ctx2, store, stx.Next())
|
||||||
|
}
|
Loading…
Reference in New Issue