|
|
- package block
-
- import (
- "errors"
- "io"
- "reflect"
-
- . "github.com/tendermint/tendermint/account"
- . "github.com/tendermint/tendermint/binary"
- . "github.com/tendermint/tendermint/common"
- )
-
- var (
- ErrTxInvalidAddress = errors.New("Error invalid address")
- ErrTxDuplicateAddress = errors.New("Error duplicate address")
- ErrTxInvalidAmount = errors.New("Error invalid amount")
- ErrTxInsufficientFunds = errors.New("Error insufficient funds")
- ErrTxUnknownPubKey = errors.New("Error unknown pubkey")
- ErrTxInvalidPubKey = errors.New("Error invalid pubkey")
- ErrTxRedeclaredPubKey = errors.New("Error redeclared pubkey")
- ErrTxInvalidSignature = errors.New("Error invalid signature")
- ErrTxInvalidSequence = errors.New("Error invalid sequence")
- )
-
- /*
- Tx (Transaction) is an atomic operation on the ledger state.
-
- Account Txs:
- - SendTx Send coins to address
-
- Validation Txs:
- - BondTx New validator posts a bond
- - UnbondTx Validator leaves
- - DupeoutTx Validator dupes out (equivocates)
- */
- type Tx interface {
- WriteSignBytes(w io.Writer, n *int64, err *error)
- }
-
- // Types of Tx implementations
- const (
- // Account transactions
- TxTypeSend = byte(0x01)
-
- // Validation transactions
- TxTypeBond = byte(0x11)
- TxTypeUnbond = byte(0x12)
- TxTypeRebond = byte(0x13)
- TxTypeDupeout = byte(0x14)
- )
-
- //-------------------------------------
- // for binary.readReflect
-
- func TxDecoder(r Unreader, n *int64, err *error) interface{} {
- switch t := PeekByte(r, n, err); t {
- case TxTypeSend:
- return ReadBinary(&SendTx{}, r, n, err)
- case TxTypeBond:
- return ReadBinary(&BondTx{}, r, n, err)
- case TxTypeUnbond:
- return ReadBinary(&UnbondTx{}, r, n, err)
- case TxTypeRebond:
- return ReadBinary(&RebondTx{}, r, n, err)
- case TxTypeDupeout:
- return ReadBinary(&DupeoutTx{}, r, n, err)
- default:
- *err = Errorf("Unknown Tx type %X", t)
- return nil
- }
- }
-
- var _ = RegisterType(&TypeInfo{
- Type: reflect.TypeOf((*Tx)(nil)).Elem(),
- Decoder: TxDecoder,
- })
-
- //-----------------------------------------------------------------------------
-
- type TxInput struct {
- Address []byte // Hash of the PubKey
- Amount uint64 // Must not exceed account balance
- Sequence uint // Must be 1 greater than the last committed TxInput
- Signature Signature // Depends on the PubKey type and the whole Tx
- PubKey PubKey // Must not be nil, may be PubKeyNil.
- }
-
- func (txIn *TxInput) ValidateBasic() error {
- if len(txIn.Address) != 20 {
- return ErrTxInvalidAddress
- }
- if txIn.Amount == 0 {
- return ErrTxInvalidAmount
- }
- return nil
- }
-
- func (txIn *TxInput) WriteSignBytes(w io.Writer, n *int64, err *error) {
- WriteByteSlice(txIn.Address, w, n, err)
- WriteUint64(txIn.Amount, w, n, err)
- WriteUvarint(txIn.Sequence, w, n, err)
- }
-
- //-----------------------------------------------------------------------------
-
- type TxOutput struct {
- Address []byte // Hash of the PubKey
- Amount uint64 // The sum of all outputs must not exceed the inputs.
- }
-
- func (txOut *TxOutput) ValidateBasic() error {
- if len(txOut.Address) != 20 {
- return ErrTxInvalidAddress
- }
- if txOut.Amount == 0 {
- return ErrTxInvalidAmount
- }
- return nil
- }
-
- func (txOut *TxOutput) WriteSignBytes(w io.Writer, n *int64, err *error) {
- WriteByteSlice(txOut.Address, w, n, err)
- WriteUint64(txOut.Amount, w, n, err)
- }
-
- //-----------------------------------------------------------------------------
-
- type SendTx struct {
- Inputs []*TxInput
- Outputs []*TxOutput
- }
-
- func (tx *SendTx) TypeByte() byte { return TxTypeSend }
-
- func (tx *SendTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
- WriteUvarint(uint(len(tx.Inputs)), w, n, err)
- for _, in := range tx.Inputs {
- in.WriteSignBytes(w, n, err)
- }
- WriteUvarint(uint(len(tx.Outputs)), w, n, err)
- for _, out := range tx.Outputs {
- out.WriteSignBytes(w, n, err)
- }
- }
-
- //-----------------------------------------------------------------------------
-
- type BondTx struct {
- PubKey PubKeyEd25519
- Inputs []*TxInput
- UnbondTo []*TxOutput
- }
-
- func (tx *BondTx) TypeByte() byte { return TxTypeBond }
-
- func (tx *BondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
- WriteBinary(tx.PubKey, w, n, err)
- WriteUvarint(uint(len(tx.Inputs)), w, n, err)
- for _, in := range tx.Inputs {
- in.WriteSignBytes(w, n, err)
- }
- WriteUvarint(uint(len(tx.UnbondTo)), w, n, err)
- for _, out := range tx.UnbondTo {
- out.WriteSignBytes(w, n, err)
- }
- }
-
- //-----------------------------------------------------------------------------
-
- type UnbondTx struct {
- Address []byte
- Height uint
- Signature SignatureEd25519
- }
-
- func (tx *UnbondTx) TypeByte() byte { return TxTypeUnbond }
-
- func (tx *UnbondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
- WriteByteSlice(tx.Address, w, n, err)
- WriteUvarint(tx.Height, w, n, err)
- }
-
- //-----------------------------------------------------------------------------
-
- type RebondTx struct {
- Address []byte
- Height uint
- Signature SignatureEd25519
- }
-
- func (tx *RebondTx) TypeByte() byte { return TxTypeRebond }
-
- func (tx *RebondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
- WriteByteSlice(tx.Address, w, n, err)
- WriteUvarint(tx.Height, w, n, err)
- }
-
- //-----------------------------------------------------------------------------
-
- type DupeoutTx struct {
- Address []byte
- VoteA Vote
- VoteB Vote
- }
-
- func (tx *DupeoutTx) TypeByte() byte { return TxTypeDupeout }
-
- func (tx *DupeoutTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
- panic("DupeoutTx has no sign bytes")
- }
|