Add refactored SendTx, chain filter, and new error codes
This commit is contained in:
parent
c130603d10
commit
2c9123224e
|
@ -7,8 +7,13 @@ package errors
|
|||
import abci "github.com/tendermint/abci/types"
|
||||
|
||||
const (
|
||||
msgDecoding = "Error decoding input"
|
||||
msgUnauthorized = "Unauthorized"
|
||||
msgDecoding = "Error decoding input"
|
||||
msgUnauthorized = "Unauthorized"
|
||||
msgInvalidAddress = "Invalid Address"
|
||||
msgInvalidCoins = "Invalid Coins"
|
||||
msgInvalidSequence = "Invalid Sequence"
|
||||
msgNoInputs = "No Input Coins"
|
||||
msgNoOutputs = "No Output Coins"
|
||||
)
|
||||
|
||||
func DecodingError() TMError {
|
||||
|
@ -18,3 +23,23 @@ func DecodingError() TMError {
|
|||
func Unauthorized() TMError {
|
||||
return New(msgUnauthorized, abci.CodeType_Unauthorized)
|
||||
}
|
||||
|
||||
func InvalidAddress() TMError {
|
||||
return New(msgInvalidAddress, abci.CodeType_BaseInvalidInput)
|
||||
}
|
||||
|
||||
func InvalidCoins() TMError {
|
||||
return New(msgInvalidCoins, abci.CodeType_BaseInvalidInput)
|
||||
}
|
||||
|
||||
func InvalidSequence() TMError {
|
||||
return New(msgInvalidSequence, abci.CodeType_BaseInvalidInput)
|
||||
}
|
||||
|
||||
func NoInputs() TMError {
|
||||
return New(msgNoInputs, abci.CodeType_BaseInvalidInput)
|
||||
}
|
||||
|
||||
func NoOutputs() TMError {
|
||||
return New(msgNoOutputs, abci.CodeType_BaseInvalidOutput)
|
||||
}
|
||||
|
|
21
txs/base.go
21
txs/base.go
|
@ -11,6 +11,7 @@ const (
|
|||
ByteRaw = 0x1
|
||||
ByteFees = 0x2
|
||||
ByteMulti = 0x3
|
||||
ByteChain = 0x4
|
||||
|
||||
// for signatures
|
||||
ByteSig = 0x16
|
||||
|
@ -22,6 +23,7 @@ const (
|
|||
TypeRaw = "raw"
|
||||
TypeFees = "fee"
|
||||
TypeMulti = "multi"
|
||||
TypeChain = "chain"
|
||||
|
||||
// for signatures
|
||||
TypeSig = "sig"
|
||||
|
@ -32,7 +34,8 @@ func init() {
|
|||
basecoin.TxMapper.
|
||||
RegisterImplementation(Raw{}, TypeRaw, ByteRaw).
|
||||
RegisterImplementation(&Fee{}, TypeFees, ByteFees).
|
||||
RegisterImplementation(&MultiTx{}, TypeMulti, ByteMulti)
|
||||
RegisterImplementation(&MultiTx{}, TypeMulti, ByteMulti).
|
||||
RegisterImplementation(&Chain{}, TypeChain, ByteChain)
|
||||
}
|
||||
|
||||
// Raw just contains bytes that can be hex-ified
|
||||
|
@ -78,3 +81,19 @@ func NewMultiTx(txs ...basecoin.Tx) *MultiTx {
|
|||
func (mt *MultiTx) Wrap() basecoin.Tx {
|
||||
return basecoin.Tx{mt}
|
||||
}
|
||||
|
||||
/*** Chain ****/
|
||||
|
||||
// Chain locks this tx to one chain, wrap with this before signing
|
||||
type Chain struct {
|
||||
Tx basecoin.Tx `json:"tx"`
|
||||
ChainID string `json:"chain_id"`
|
||||
}
|
||||
|
||||
func NewChain(tx basecoin.Tx, chainID string) *Chain {
|
||||
return &Chain{Tx: tx, ChainID: chainID}
|
||||
}
|
||||
|
||||
func (c *Chain) Wrap() basecoin.Tx {
|
||||
return basecoin.Tx{c}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package txs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
|
||||
"github.com/tendermint/basecoin/errors"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type TxInput struct {
|
||||
Address data.Bytes `json:"address"`
|
||||
Coins types.Coins `json:"coins"`
|
||||
Sequence int `json:"sequence"` // Nonce: Must be 1 greater than the last committed TxInput
|
||||
}
|
||||
|
||||
func (txIn TxInput) ValidateBasic() error {
|
||||
if len(txIn.Address) != 20 {
|
||||
return errors.InvalidAddress()
|
||||
}
|
||||
if !txIn.Coins.IsValid() {
|
||||
return errors.InvalidCoins()
|
||||
}
|
||||
if txIn.Coins.IsZero() {
|
||||
return errors.InvalidCoins()
|
||||
}
|
||||
if txIn.Sequence <= 0 {
|
||||
return errors.InvalidSequence()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txIn TxInput) String() string {
|
||||
return fmt.Sprintf("TxInput{%v,%v,%v}", txIn.Address, txIn.Coins, txIn.Sequence)
|
||||
}
|
||||
|
||||
func NewTxInput(addr []byte, coins types.Coins, sequence int) TxInput {
|
||||
input := TxInput{
|
||||
Address: addr,
|
||||
Coins: coins,
|
||||
Sequence: sequence,
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type TxOutput struct {
|
||||
Address data.Bytes `json:"address"`
|
||||
Coins types.Coins `json:"coins"`
|
||||
}
|
||||
|
||||
func (txOut TxOutput) ValidateBasic() error {
|
||||
if len(txOut.Address) != 20 {
|
||||
return errors.InvalidAddress()
|
||||
}
|
||||
if !txOut.Coins.IsValid() {
|
||||
return errors.InvalidCoins()
|
||||
}
|
||||
if txOut.Coins.IsZero() {
|
||||
return errors.InvalidCoins()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txOut TxOutput) String() string {
|
||||
return fmt.Sprintf("TxOutput{%X,%v}", txOut.Address, txOut.Coins)
|
||||
}
|
||||
|
||||
func NewTxOutput(addr []byte, coins types.Coins) TxOutput {
|
||||
output := TxOutput{
|
||||
Address: addr,
|
||||
Coins: coins,
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type SendTx struct {
|
||||
Inputs []TxInput `json:"inputs"`
|
||||
Outputs []TxOutput `json:"outputs"`
|
||||
}
|
||||
|
||||
var _ basecoin.Tx = SendTx{}.Wrap()
|
||||
|
||||
func (tx SendTx) ValidateBasic() error {
|
||||
// this just makes sure all the inputs and outputs are properly formatted,
|
||||
// not that they actually have the money inside
|
||||
if len(tx.Inputs) == 0 {
|
||||
return errors.NoInputs()
|
||||
}
|
||||
if len(tx.Outputs) == 0 {
|
||||
return errors.NoOutputs()
|
||||
}
|
||||
for _, in := range tx.Inputs {
|
||||
if err := in.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, out := range tx.Outputs {
|
||||
if err := out.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx SendTx) String() string {
|
||||
return fmt.Sprintf("SendTx{%v->%v}", tx.Inputs, tx.Outputs)
|
||||
}
|
||||
|
||||
func (tx SendTx) Wrap() basecoin.Tx {
|
||||
return basecoin.Tx{tx}
|
||||
}
|
Loading…
Reference in New Issue