You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
4.9 KiB

10 years ago
11 years ago
  1. package block
  2. import (
  3. "errors"
  4. "io"
  5. . "github.com/tendermint/tendermint/account"
  6. . "github.com/tendermint/tendermint/binary"
  7. )
  8. var (
  9. ErrTxInvalidAddress = errors.New("Error invalid address")
  10. ErrTxDuplicateAddress = errors.New("Error duplicate address")
  11. ErrTxInvalidAmount = errors.New("Error invalid amount")
  12. ErrTxInsufficientFunds = errors.New("Error insufficient funds")
  13. ErrTxUnknownPubKey = errors.New("Error unknown pubkey")
  14. ErrTxInvalidPubKey = errors.New("Error invalid pubkey")
  15. ErrTxRedeclaredPubKey = errors.New("Error redeclared pubkey")
  16. ErrTxInvalidSignature = errors.New("Error invalid signature")
  17. ErrTxInvalidSequence = errors.New("Error invalid sequence")
  18. )
  19. /*
  20. Tx (Transaction) is an atomic operation on the ledger state.
  21. Account Txs:
  22. - SendTx Send coins to address
  23. Validation Txs:
  24. - BondTx New validator posts a bond
  25. - UnbondTx Validator leaves
  26. - DupeoutTx Validator dupes out (equivocates)
  27. */
  28. type Tx interface {
  29. WriteSignBytes(w io.Writer, n *int64, err *error)
  30. }
  31. // Types of Tx implementations
  32. const (
  33. // Account transactions
  34. TxTypeSend = byte(0x01)
  35. // Validation transactions
  36. TxTypeBond = byte(0x11)
  37. TxTypeUnbond = byte(0x12)
  38. TxTypeRebond = byte(0x13)
  39. TxTypeDupeout = byte(0x14)
  40. )
  41. // for binary.readReflect
  42. var _ = RegisterInterface(
  43. struct{ Tx }{},
  44. ConcreteType{&SendTx{}},
  45. ConcreteType{&BondTx{}},
  46. ConcreteType{&UnbondTx{}},
  47. ConcreteType{&RebondTx{}},
  48. ConcreteType{&DupeoutTx{}},
  49. )
  50. //-----------------------------------------------------------------------------
  51. type TxInput struct {
  52. Address []byte // Hash of the PubKey
  53. Amount uint64 // Must not exceed account balance
  54. Sequence uint // Must be 1 greater than the last committed TxInput
  55. Signature Signature // Depends on the PubKey type and the whole Tx
  56. PubKey PubKey // Must not be nil, may be PubKeyNil.
  57. }
  58. func (txIn *TxInput) ValidateBasic() error {
  59. if len(txIn.Address) != 20 {
  60. return ErrTxInvalidAddress
  61. }
  62. if txIn.Amount == 0 {
  63. return ErrTxInvalidAmount
  64. }
  65. return nil
  66. }
  67. func (txIn *TxInput) WriteSignBytes(w io.Writer, n *int64, err *error) {
  68. WriteByteSlice(txIn.Address, w, n, err)
  69. WriteUint64(txIn.Amount, w, n, err)
  70. WriteUvarint(txIn.Sequence, w, n, err)
  71. }
  72. //-----------------------------------------------------------------------------
  73. type TxOutput struct {
  74. Address []byte // Hash of the PubKey
  75. Amount uint64 // The sum of all outputs must not exceed the inputs.
  76. }
  77. func (txOut *TxOutput) ValidateBasic() error {
  78. if len(txOut.Address) != 20 {
  79. return ErrTxInvalidAddress
  80. }
  81. if txOut.Amount == 0 {
  82. return ErrTxInvalidAmount
  83. }
  84. return nil
  85. }
  86. func (txOut *TxOutput) WriteSignBytes(w io.Writer, n *int64, err *error) {
  87. WriteByteSlice(txOut.Address, w, n, err)
  88. WriteUint64(txOut.Amount, w, n, err)
  89. }
  90. //-----------------------------------------------------------------------------
  91. type SendTx struct {
  92. Inputs []*TxInput
  93. Outputs []*TxOutput
  94. }
  95. func (tx *SendTx) TypeByte() byte { return TxTypeSend }
  96. func (tx *SendTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  97. WriteUvarint(uint(len(tx.Inputs)), w, n, err)
  98. for _, in := range tx.Inputs {
  99. in.WriteSignBytes(w, n, err)
  100. }
  101. WriteUvarint(uint(len(tx.Outputs)), w, n, err)
  102. for _, out := range tx.Outputs {
  103. out.WriteSignBytes(w, n, err)
  104. }
  105. }
  106. //-----------------------------------------------------------------------------
  107. type BondTx struct {
  108. PubKey PubKeyEd25519
  109. Inputs []*TxInput
  110. UnbondTo []*TxOutput
  111. }
  112. func (tx *BondTx) TypeByte() byte { return TxTypeBond }
  113. func (tx *BondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  114. WriteBinary(tx.PubKey, w, n, err)
  115. WriteUvarint(uint(len(tx.Inputs)), w, n, err)
  116. for _, in := range tx.Inputs {
  117. in.WriteSignBytes(w, n, err)
  118. }
  119. WriteUvarint(uint(len(tx.UnbondTo)), w, n, err)
  120. for _, out := range tx.UnbondTo {
  121. out.WriteSignBytes(w, n, err)
  122. }
  123. }
  124. //-----------------------------------------------------------------------------
  125. type UnbondTx struct {
  126. Address []byte
  127. Height uint
  128. Signature SignatureEd25519
  129. }
  130. func (tx *UnbondTx) TypeByte() byte { return TxTypeUnbond }
  131. func (tx *UnbondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  132. WriteByteSlice(tx.Address, w, n, err)
  133. WriteUvarint(tx.Height, w, n, err)
  134. }
  135. //-----------------------------------------------------------------------------
  136. type RebondTx struct {
  137. Address []byte
  138. Height uint
  139. Signature SignatureEd25519
  140. }
  141. func (tx *RebondTx) TypeByte() byte { return TxTypeRebond }
  142. func (tx *RebondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  143. WriteByteSlice(tx.Address, w, n, err)
  144. WriteUvarint(tx.Height, w, n, err)
  145. }
  146. //-----------------------------------------------------------------------------
  147. type DupeoutTx struct {
  148. Address []byte
  149. VoteA Vote
  150. VoteB Vote
  151. }
  152. func (tx *DupeoutTx) TypeByte() byte { return TxTypeDupeout }
  153. func (tx *DupeoutTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  154. panic("DupeoutTx has no sign bytes")
  155. }