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
|
|
|
|
|
|
|
|
Consensus Txs:
|
|
|
|
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 {
|
2014-09-03 20:41:57 -07:00
|
|
|
Type() byte
|
2014-09-10 16:56:02 -07:00
|
|
|
GetSequence() uint64
|
|
|
|
GetSignature() *Signature
|
|
|
|
//IsConsensus() 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
|
2014-09-03 20:41:57 -07:00
|
|
|
TX_TYPE_SEND = byte(0x01)
|
|
|
|
TX_TYPE_NAME = byte(0x02)
|
2014-09-10 02:43:16 -07:00
|
|
|
|
|
|
|
// Consensus transactions
|
|
|
|
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
|
|
|
)
|
|
|
|
|
2014-09-03 20:41:57 -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{
|
2014-09-10 16:56:02 -07:00
|
|
|
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{
|
2014-09-10 16:56:02 -07:00
|
|
|
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{
|
2014-09-10 16:56:02 -07:00
|
|
|
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{
|
2014-09-10 16:56:02 -07:00
|
|
|
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{
|
2014-09-10 16:56:02 -07:00
|
|
|
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{
|
2014-09-10 16:56:02 -07:00
|
|
|
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
|
|
|
|
2014-09-10 16:56:02 -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 {
|
2014-09-10 16:56:02 -07:00
|
|
|
BaseTx
|
2014-08-31 01:48:40 -07:00
|
|
|
Fee uint64
|
|
|
|
To uint64
|
|
|
|
Amount uint64
|
2014-06-05 02:34:45 -07:00
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -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
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -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 {
|
2014-09-10 16:56:02 -07:00
|
|
|
BaseTx
|
2014-08-31 01:48:40 -07:00
|
|
|
Fee uint64
|
2014-09-03 20:41:57 -07:00
|
|
|
Name string
|
|
|
|
PubKey []byte
|
2014-06-05 02:34:45 -07:00
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -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
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -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 {
|
2014-09-10 16:56:02 -07:00
|
|
|
BaseTx
|
2014-09-10 02:43:16 -07:00
|
|
|
Fee uint64
|
|
|
|
UnbondTo uint64
|
|
|
|
Amount uint64
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
func (tx *BondTx) Type() byte {
|
2014-09-10 02:43:16 -07:00
|
|
|
return TX_TYPE_BOND
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
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 {
|
2014-09-10 16:56:02 -07:00
|
|
|
BaseTx
|
2014-09-10 02:43:16 -07:00
|
|
|
Fee uint64
|
|
|
|
Amount uint64
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
func (tx *UnbondTx) Type() byte {
|
2014-09-10 02:43:16 -07:00
|
|
|
return TX_TYPE_UNBOND
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
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 {
|
2014-09-10 16:56:02 -07:00
|
|
|
BaseTx
|
2014-09-10 02:43:16 -07:00
|
|
|
AccountId uint64
|
|
|
|
Penalty uint64
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
func (tx *TimeoutTx) Type() byte {
|
2014-09-10 02:43:16 -07:00
|
|
|
return TX_TYPE_TIMEOUT
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
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 {
|
2014-09-10 16:56:02 -07:00
|
|
|
BaseTx
|
2014-09-10 02:43:16 -07:00
|
|
|
VoteA BlockVote
|
|
|
|
VoteB BlockVote
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
func (tx *DupeoutTx) Type() byte {
|
2014-09-10 02:43:16 -07:00
|
|
|
return TX_TYPE_DUPEOUT
|
|
|
|
}
|
|
|
|
|
2014-09-10 16:56:02 -07:00
|
|
|
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
|
|
|
|
}
|