tendermint/blocks/tx.go

281 lines
6.0 KiB
Go
Raw Normal View History

2014-06-05 02:34:45 -07:00
package blocks
import (
2014-07-01 14:50:24 -07:00
. "github.com/tendermint/tendermint/binary"
. "github.com/tendermint/tendermint/common"
"io"
2014-06-05 02:34:45 -07:00
)
/*
Tx wire format:
|T|L...|MMM...|A...|SSS...|
T type of the tx (1 byte)
L length of M, varint encoded (1+ bytes)
M Tx bytes (L bytes)
A account number, varint encoded (1+ bytes)
S signature of all prior bytes (32 bytes)
2014-09-10 02:43:16 -07:00
Account Txs:
1. Send Send coins to account
2. Name Associate account with a name
Validation Txs:
2014-09-10 02:43:16 -07:00
3. Bond New validator posts a bond
4. Unbond Validator leaves
5. Timeout Validator times out
6. Dupeout Validator dupes out (signs twice)
2014-06-05 02:34:45 -07:00
*/
type Tx interface {
Type() byte
GetSequence() uint64
GetSignature() *Signature
//IsValidation() bool
2014-07-01 14:50:24 -07:00
Binary
2014-06-05 02:34:45 -07:00
}
const (
2014-09-10 02:43:16 -07:00
// Account transactions
TX_TYPE_SEND = byte(0x01)
TX_TYPE_NAME = byte(0x02)
2014-09-10 02:43:16 -07:00
// Validation transactions
2014-09-10 02:43:16 -07:00
TX_TYPE_BOND = byte(0x11)
TX_TYPE_UNBOND = byte(0x12)
TX_TYPE_TIMEOUT = byte(0x13)
TX_TYPE_DUPEOUT = byte(0x14)
2014-06-05 02:34:45 -07:00
)
func ReadTx(r io.Reader, n *int64, err *error) Tx {
switch t := ReadByte(r, n, err); t {
2014-07-01 14:50:24 -07:00
case TX_TYPE_SEND:
return &SendTx{
BaseTx: ReadBaseTx(r, n, err),
Fee: ReadUInt64(r, n, err),
To: ReadUInt64(r, n, err),
Amount: ReadUInt64(r, n, err),
2014-07-01 14:50:24 -07:00
}
case TX_TYPE_NAME:
return &NameTx{
BaseTx: ReadBaseTx(r, n, err),
Fee: ReadUInt64(r, n, err),
Name: ReadString(r, n, err),
PubKey: ReadByteSlice(r, n, err),
2014-07-01 14:50:24 -07:00
}
2014-09-10 02:43:16 -07:00
case TX_TYPE_BOND:
return &BondTx{
BaseTx: ReadBaseTx(r, n, err),
Fee: ReadUInt64(r, n, err),
UnbondTo: ReadUInt64(r, n, err),
Amount: ReadUInt64(r, n, err),
2014-09-10 02:43:16 -07:00
}
case TX_TYPE_UNBOND:
return &UnbondTx{
BaseTx: ReadBaseTx(r, n, err),
Fee: ReadUInt64(r, n, err),
Amount: ReadUInt64(r, n, err),
2014-09-10 02:43:16 -07:00
}
case TX_TYPE_TIMEOUT:
return &TimeoutTx{
BaseTx: ReadBaseTx(r, n, err),
2014-09-10 02:43:16 -07:00
AccountId: ReadUInt64(r, n, err),
Penalty: ReadUInt64(r, n, err),
}
case TX_TYPE_DUPEOUT:
return &DupeoutTx{
BaseTx: ReadBaseTx(r, n, err),
VoteA: *ReadBlockVote(r, n, err),
VoteB: *ReadBlockVote(r, n, err),
2014-09-10 02:43:16 -07:00
}
2014-07-01 14:50:24 -07:00
default:
Panicf("Unknown Tx type %x", t)
return nil
}
2014-06-05 02:34:45 -07:00
}
2014-09-10 02:43:16 -07:00
//-----------------------------------------------------------------------------
2014-06-05 02:34:45 -07:00
type BaseTx struct {
Sequence uint64
Signature
}
func ReadBaseTx(r io.Reader, n *int64, err *error) BaseTx {
return BaseTx{
Sequence: ReadUVarInt(r, n, err),
Signature: ReadSignature(r, n, err),
}
}
func (tx *BaseTx) GetSequence() uint64 {
return tx.Sequence
}
func (tx *BaseTx) GetSignature() *Signature {
return &tx.Signature
}
func (tx *BaseTx) WriteTo(w io.Writer) (n int64, err error) {
WriteUVarInt(w, tx.Sequence, &n, &err)
WriteBinary(w, tx.Signature, &n, &err)
return
}
//-----------------------------------------------------------------------------
2014-06-05 02:34:45 -07:00
type SendTx struct {
BaseTx
2014-08-31 01:48:40 -07:00
Fee uint64
To uint64
Amount uint64
2014-06-05 02:34:45 -07:00
}
func (tx *SendTx) Type() byte {
2014-07-01 14:50:24 -07:00
return TX_TYPE_SEND
2014-06-05 02:34:45 -07:00
}
func (tx *SendTx) WriteTo(w io.Writer) (n int64, err error) {
WriteByte(w, tx.Type(), &n, &err)
WriteBinary(w, &tx.BaseTx, &n, &err)
WriteUInt64(w, tx.Fee, &n, &err)
WriteUInt64(w, tx.To, &n, &err)
WriteUInt64(w, tx.Amount, &n, &err)
2014-07-01 14:50:24 -07:00
return
2014-06-05 02:34:45 -07:00
}
2014-09-10 02:43:16 -07:00
//-----------------------------------------------------------------------------
2014-06-05 02:34:45 -07:00
type NameTx struct {
BaseTx
2014-08-31 01:48:40 -07:00
Fee uint64
Name string
PubKey []byte
2014-06-05 02:34:45 -07:00
}
func (tx *NameTx) Type() byte {
2014-07-01 14:50:24 -07:00
return TX_TYPE_NAME
2014-06-05 02:34:45 -07:00
}
func (tx *NameTx) WriteTo(w io.Writer) (n int64, err error) {
WriteByte(w, tx.Type(), &n, &err)
WriteBinary(w, &tx.BaseTx, &n, &err)
WriteUInt64(w, tx.Fee, &n, &err)
WriteString(w, tx.Name, &n, &err)
WriteByteSlice(w, tx.PubKey, &n, &err)
2014-07-01 14:50:24 -07:00
return
2014-06-05 02:34:45 -07:00
}
2014-09-10 02:43:16 -07:00
//-----------------------------------------------------------------------------
type BondTx struct {
BaseTx
2014-09-10 02:43:16 -07:00
Fee uint64
UnbondTo uint64
Amount uint64
}
func (tx *BondTx) Type() byte {
2014-09-10 02:43:16 -07:00
return TX_TYPE_BOND
}
func (tx *BondTx) WriteTo(w io.Writer) (n int64, err error) {
WriteByte(w, tx.Type(), &n, &err)
WriteBinary(w, &tx.BaseTx, &n, &err)
WriteUInt64(w, tx.Fee, &n, &err)
WriteUInt64(w, tx.UnbondTo, &n, &err)
WriteUInt64(w, tx.Amount, &n, &err)
2014-09-10 02:43:16 -07:00
return
}
//-----------------------------------------------------------------------------
type UnbondTx struct {
BaseTx
2014-09-10 02:43:16 -07:00
Fee uint64
Amount uint64
}
func (tx *UnbondTx) Type() byte {
2014-09-10 02:43:16 -07:00
return TX_TYPE_UNBOND
}
func (tx *UnbondTx) WriteTo(w io.Writer) (n int64, err error) {
WriteByte(w, tx.Type(), &n, &err)
WriteBinary(w, &tx.BaseTx, &n, &err)
WriteUInt64(w, tx.Fee, &n, &err)
WriteUInt64(w, tx.Amount, &n, &err)
2014-09-10 02:43:16 -07:00
return
}
//-----------------------------------------------------------------------------
type TimeoutTx struct {
BaseTx
2014-09-10 02:43:16 -07:00
AccountId uint64
Penalty uint64
}
func (tx *TimeoutTx) Type() byte {
2014-09-10 02:43:16 -07:00
return TX_TYPE_TIMEOUT
}
func (tx *TimeoutTx) WriteTo(w io.Writer) (n int64, err error) {
WriteByte(w, tx.Type(), &n, &err)
WriteBinary(w, &tx.BaseTx, &n, &err)
WriteUInt64(w, tx.AccountId, &n, &err)
WriteUInt64(w, tx.Penalty, &n, &err)
2014-09-10 02:43:16 -07:00
return
}
//-----------------------------------------------------------------------------
/*
The full vote structure is only needed when presented as evidence.
Typically only the signature is passed around, as the hash & height are implied.
*/
type BlockVote struct {
Height uint64
BlockHash []byte
Signature
}
func ReadBlockVote(r io.Reader, n *int64, err *error) *BlockVote {
return &BlockVote{
2014-09-10 02:43:16 -07:00
Height: ReadUInt64(r, n, err),
BlockHash: ReadByteSlice(r, n, err),
Signature: ReadSignature(r, n, err),
}
}
func (tx BlockVote) WriteTo(w io.Writer) (n int64, err error) {
WriteUInt64(w, tx.Height, &n, &err)
WriteByteSlice(w, tx.BlockHash, &n, &err)
WriteBinary(w, tx.Signature, &n, &err)
2014-09-10 02:43:16 -07:00
return
}
//-----------------------------------------------------------------------------
type DupeoutTx struct {
BaseTx
2014-09-10 02:43:16 -07:00
VoteA BlockVote
VoteB BlockVote
}
func (tx *DupeoutTx) Type() byte {
2014-09-10 02:43:16 -07:00
return TX_TYPE_DUPEOUT
}
func (tx *DupeoutTx) WriteTo(w io.Writer) (n int64, err error) {
WriteByte(w, tx.Type(), &n, &err)
WriteBinary(w, &tx.BaseTx, &n, &err)
WriteBinary(w, tx.VoteA, &n, &err)
WriteBinary(w, tx.VoteB, &n, &err)
2014-09-10 02:43:16 -07:00
return
}