Update decorators/handler/results.go add tx_msg/signature.go

This commit is contained in:
Jae Kwon
2017-11-26 14:14:03 -08:00
parent 6a9b8c3a92
commit 458fba22d3
11 changed files with 198 additions and 340 deletions
+6
View File
@@ -0,0 +1,6 @@
package main
import (
_ "github.com/tendermint/go-wire/gen"
_ "github.com/clipperhouse/stringer"
)
+86
View File
@@ -0,0 +1,86 @@
package sdk
// A Decorator executes before/during/after a handler to enhance functionality.
type Decorator interface {
// Decorate Handler.CheckTx
CheckTx(ctx Context, ms MultiStore, tx Tx,
next CheckTxFunc) CheckResult
// Decorate Handler.DeliverTx
DeliverTx(ctx Context, ms MultiStore, tx Tx,
next DeliverTxFunc) DeliverResult
}
// A Decorator tied to its base handler "next" is itself a handler.
func Decorate(dec Decorator, next Handler) Handler {
return &decHandler{
decorator: dec,
next: next,
}
}
//----------------------------------------
/*
Helper to construct a decorated Handler from a stack of Decorators
(first-decorator-first-call as in Python @decorators) , w/ Handler provided
last for syntactic sugar of Stack().WithHandler()
Usage:
handler := sdk.Stack(
decorator1,
decorator2,
...,
).WithHandler(myHandler)
*/
func Stack(decorators ...Decorator) stack {
return stack{
decs: decorators,
}
}
// No need to expose this.
type stack struct {
decs []Decorator
}
// WithHandler sets the final handler for the stack and
// returns the decoratored Handler.
func (s *Stack) WithHandler(handler Handler) Handler {
if handler == nil {
panic("WithHandler() requires a non-nil Handler")
}
return build(s.decs, handler)
}
// build wraps each decorator around the next, so that
// the last in the list is closest to the handler
func build(stack []Decorator, end Handler) Handler {
if len(stack) == 0 {
return end
}
return decHandler{
decorator: stack[0],
next: build(stack[1:], end),
}
}
//----------------------------------------
type decHandler struct {
decorator Decorator
next Handler
}
var _ Handler = &decHandler{}
func (dh *decHandler) CheckTx(ctx Context, ms MultiStore, tx Tx) CheckResult {
return dh.decorator.CheckTx(ctx, ms, tx, dh.next)
}
func (dh *decHandler) DeliverTx(ctx Context, ms MultiStore, tx Tx) DeliverResult {
return dh.decorator.DeliverTx(ctx, ms, tx, dh.next)
}
+24
View File
@@ -0,0 +1,24 @@
package sdk
import (
abci "github.com/tendermint/abci/types"
"github.com/tendermint/tmlibs/log"
)
// Handler is something that processes a transaction.
type Handler interface {
// Checker verifies there are valid fees and estimates work.
CheckTx(ctx Context, ms MultiStore, tx Tx) CheckResult
// Deliverer performs the tx once it makes it in the block.
DeliverTx(ctx Context, ms MultiStore, tx Tx) DeliverResult
}
// Checker verifies there are valid fees and estimates work.
// NOTE: Keep in sync with Handler.CheckTx
type CheckTxFunc func(ctx Context, ms MultiStore, tx Tx) CheckResult
// Deliverer performs the tx once it makes it in the block.
// NOTE: Keep in sync with Handler.DeliverTx
type DeliverTxFunc func(ctx Context, ms MultiStore, tx Tx) DeliverResult
-27
View File
@@ -1,27 +0,0 @@
package types
import crypto "github.com/tendermint/go-crypto"
// The parsed tx bytes is called a Msg.
type Msg interface {
Get(key interface{}) (value interface{})
Origin() (tx []byte)
// Signers() returns the crypto.PubKey of signers
// responsible for signing the Msg.
// CONTRACT: All signatures must be present to be valid.
// CONTRACT: Returns pubkeys in some deterministic order
// CONTRACT: Get(MsgKeySigners) compatible.
Signers() []crypto.PubKey
// Signatures() returns the crypto.Signature of sigenrs
// who signed the Msg.
// CONTRACT: Length returned is same as length of
// pubkeys returned from MsgKeySigners, and the order
// matches.
// CONTRACT: If the signature is missing (ie the Msg is
// invalid), then the corresponding signature is
// .Empty().
// CONTRACT: Get(MsgKeySignatures) compatible.
Signatures() []crypto.Signature
}
+29
View File
@@ -0,0 +1,29 @@
package types
import (
abci "github.com/tendermint/abci/types"
)
// CheckResult captures any non-error ABCI result
// to make sure people use error for error cases.
type CheckResult struct {
abci.Result
// GasAllocated is the maximum units of work we allow this tx to perform
GasAllocated uint64
// GasPayment is the total fees for this tx (or other source of payment)
GasPayment uint64
}
// DeliverResult captures any non-error abci result
// to make sure people use error for error cases
type DeliverResult struct {
abci.Result
// TODO comment
Diff []*abci.Validator
// TODO comment
GasUsed uint64
}
+23
View File
@@ -0,0 +1,23 @@
package types
import crypto "github.com/tendermint/go-crypto"
type Signature interface {
CryptoSig() crypto.Signature
Sequence() int
}
// StdSignature is a simple way to prevent replay attacks.
// There must be better strategies, but this is simplest.
type StdSignature struct {
crypto.Signature
Sequence int
}
func (ss StdSignature) CryptoSig() crypto.Signature {
return ss.Signature
}
func (ss StdSignature) Sequence() int {
return ss.Sequence
}
+36
View File
@@ -0,0 +1,36 @@
package types
type Msg interface {
// Get some property of the Msg.
Get(key interface{}) (value interface{})
// Get the canonical byte representation of the Msg.
SignBytes() []byte
// ValidateBasic does a simple validation check that
// doesn't require access to any other information.
ValidateBasic() error
// Signers returns the addrs of signers that must sign.
// CONTRACT: All signatures must be present to be valid.
// CONTRACT: Returns addrs in some deterministic order.
Signers() [][]byte
}
type Tx interface {
Msg
// Get the canonical byte representation of the Tx.
// Includes any signatures (or empty slots).
TxBytes() []byte
// Signatures returns the signature of signers who signed the Msg.
// CONTRACT: Length returned is same as length of
// pubkeys returned from MsgKeySigners, and the order
// matches.
// CONTRACT: If the signature is missing (ie the Msg is
// invalid), then the corresponding signature is
// .Empty().
Signatures() []Signature
}