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.

251 lines
6.7 KiB

10 years ago
  1. package types
  2. import (
  3. "errors"
  4. "io"
  5. "github.com/tendermint/tendermint/account"
  6. "github.com/tendermint/tendermint/binary"
  7. . "github.com/tendermint/tendermint/common"
  8. )
  9. var (
  10. ErrTxInvalidAddress = errors.New("Error invalid address")
  11. ErrTxDuplicateAddress = errors.New("Error duplicate address")
  12. ErrTxInvalidAmount = errors.New("Error invalid amount")
  13. ErrTxInsufficientFunds = errors.New("Error insufficient funds")
  14. ErrTxInsufficientGasPrice = errors.New("Error insufficient gas price")
  15. ErrTxUnknownPubKey = errors.New("Error unknown pubkey")
  16. ErrTxInvalidPubKey = errors.New("Error invalid pubkey")
  17. ErrTxInvalidSignature = errors.New("Error invalid signature")
  18. )
  19. type ErrTxInvalidSequence struct {
  20. Got uint64
  21. Expected uint64
  22. }
  23. func (e ErrTxInvalidSequence) Error() string {
  24. return Fmt("Error invalid sequence. Got %d, expected %d", e.Got, e.Expected)
  25. }
  26. /*
  27. Tx (Transaction) is an atomic operation on the ledger state.
  28. Account Txs:
  29. - SendTx Send coins to address
  30. - CallTx Send a msg to a contract that runs in the vm
  31. Validation Txs:
  32. - BondTx New validator posts a bond
  33. - UnbondTx Validator leaves
  34. - DupeoutTx Validator dupes out (equivocates)
  35. */
  36. type Tx interface {
  37. WriteSignBytes(w io.Writer, n *int64, err *error)
  38. }
  39. // Types of Tx implementations
  40. const (
  41. // Account transactions
  42. TxTypeSend = byte(0x01)
  43. TxTypeCall = byte(0x02)
  44. // Validation transactions
  45. TxTypeBond = byte(0x11)
  46. TxTypeUnbond = byte(0x12)
  47. TxTypeRebond = byte(0x13)
  48. TxTypeDupeout = byte(0x14)
  49. )
  50. // for binary.readReflect
  51. var _ = binary.RegisterInterface(
  52. struct{ Tx }{},
  53. binary.ConcreteType{&SendTx{}, TxTypeSend},
  54. binary.ConcreteType{&CallTx{}, TxTypeCall},
  55. binary.ConcreteType{&BondTx{}, TxTypeBond},
  56. binary.ConcreteType{&UnbondTx{}, TxTypeUnbond},
  57. binary.ConcreteType{&RebondTx{}, TxTypeRebond},
  58. binary.ConcreteType{&DupeoutTx{}, TxTypeDupeout},
  59. )
  60. //-----------------------------------------------------------------------------
  61. type TxInput struct {
  62. Address []byte // Hash of the PubKey
  63. Amount uint64 // Must not exceed account balance
  64. Sequence uint // Must be 1 greater than the last committed TxInput
  65. Signature account.Signature // Depends on the PubKey type and the whole Tx
  66. PubKey account.PubKey // Must not be nil, may be nil
  67. }
  68. func (txIn *TxInput) ValidateBasic() error {
  69. if len(txIn.Address) != 20 {
  70. return ErrTxInvalidAddress
  71. }
  72. if txIn.Amount == 0 {
  73. return ErrTxInvalidAmount
  74. }
  75. return nil
  76. }
  77. func (txIn *TxInput) WriteSignBytes(w io.Writer, n *int64, err *error) {
  78. binary.WriteByteSlice(txIn.Address, w, n, err)
  79. binary.WriteUint64(txIn.Amount, w, n, err)
  80. binary.WriteUvarint(txIn.Sequence, w, n, err)
  81. }
  82. func (txIn *TxInput) String() string {
  83. return Fmt("TxInput{%X,%v,%v,%v,%v}", txIn.Address, txIn.Amount, txIn.Sequence, txIn.Signature, txIn.PubKey)
  84. }
  85. //-----------------------------------------------------------------------------
  86. type TxOutput struct {
  87. Address []byte // Hash of the PubKey
  88. Amount uint64 // The sum of all outputs must not exceed the inputs.
  89. }
  90. func (txOut *TxOutput) ValidateBasic() error {
  91. if len(txOut.Address) != 20 {
  92. return ErrTxInvalidAddress
  93. }
  94. if txOut.Amount == 0 {
  95. return ErrTxInvalidAmount
  96. }
  97. return nil
  98. }
  99. func (txOut *TxOutput) WriteSignBytes(w io.Writer, n *int64, err *error) {
  100. binary.WriteByteSlice(txOut.Address, w, n, err)
  101. binary.WriteUint64(txOut.Amount, w, n, err)
  102. }
  103. func (txOut *TxOutput) String() string {
  104. return Fmt("TxOutput{%X,%v}", txOut.Address, txOut.Amount)
  105. }
  106. //-----------------------------------------------------------------------------
  107. type SendTx struct {
  108. Inputs []*TxInput
  109. Outputs []*TxOutput
  110. }
  111. func (tx *SendTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  112. binary.WriteUvarint(uint(len(tx.Inputs)), w, n, err)
  113. for _, in := range tx.Inputs {
  114. in.WriteSignBytes(w, n, err)
  115. }
  116. binary.WriteUvarint(uint(len(tx.Outputs)), w, n, err)
  117. for _, out := range tx.Outputs {
  118. out.WriteSignBytes(w, n, err)
  119. }
  120. }
  121. func (tx *SendTx) String() string {
  122. return Fmt("SendTx{%v -> %v}", tx.Inputs, tx.Outputs)
  123. }
  124. //-----------------------------------------------------------------------------
  125. type CallTx struct {
  126. Input *TxInput
  127. Address []byte
  128. GasLimit uint64
  129. Fee uint64
  130. Data []byte
  131. }
  132. func (tx *CallTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  133. tx.Input.WriteSignBytes(w, n, err)
  134. binary.WriteByteSlice(tx.Address, w, n, err)
  135. binary.WriteUint64(tx.GasLimit, w, n, err)
  136. binary.WriteUint64(tx.Fee, w, n, err)
  137. binary.WriteByteSlice(tx.Data, w, n, err)
  138. }
  139. func (tx *CallTx) String() string {
  140. return Fmt("CallTx{%v -> %x: %x}", tx.Input, tx.Address, tx.Data)
  141. }
  142. //-----------------------------------------------------------------------------
  143. type BondTx struct {
  144. PubKey account.PubKeyEd25519
  145. Inputs []*TxInput
  146. UnbondTo []*TxOutput
  147. }
  148. func (tx *BondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  149. binary.WriteBinary(tx.PubKey, w, n, err)
  150. binary.WriteUvarint(uint(len(tx.Inputs)), w, n, err)
  151. for _, in := range tx.Inputs {
  152. in.WriteSignBytes(w, n, err)
  153. }
  154. binary.WriteUvarint(uint(len(tx.UnbondTo)), w, n, err)
  155. for _, out := range tx.UnbondTo {
  156. out.WriteSignBytes(w, n, err)
  157. }
  158. }
  159. func (tx *BondTx) String() string {
  160. return Fmt("BondTx{%v: %v -> %v}", tx.PubKey, tx.Inputs, tx.UnbondTo)
  161. }
  162. //-----------------------------------------------------------------------------
  163. type UnbondTx struct {
  164. Address []byte
  165. Height uint
  166. Signature account.SignatureEd25519
  167. }
  168. func (tx *UnbondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  169. binary.WriteByteSlice(tx.Address, w, n, err)
  170. binary.WriteUvarint(tx.Height, w, n, err)
  171. }
  172. func (tx *UnbondTx) String() string {
  173. return Fmt("UnbondTx{%X,%v,%v}", tx.Address, tx.Height, tx.Signature)
  174. }
  175. //-----------------------------------------------------------------------------
  176. type RebondTx struct {
  177. Address []byte
  178. Height uint
  179. Signature account.SignatureEd25519
  180. }
  181. func (tx *RebondTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  182. binary.WriteByteSlice(tx.Address, w, n, err)
  183. binary.WriteUvarint(tx.Height, w, n, err)
  184. }
  185. func (tx *RebondTx) String() string {
  186. return Fmt("RebondTx{%X,%v,%v}", tx.Address, tx.Height, tx.Signature)
  187. }
  188. //-----------------------------------------------------------------------------
  189. type DupeoutTx struct {
  190. Address []byte
  191. VoteA Vote
  192. VoteB Vote
  193. }
  194. func (tx *DupeoutTx) WriteSignBytes(w io.Writer, n *int64, err *error) {
  195. panic("DupeoutTx has no sign bytes")
  196. }
  197. func (tx *DupeoutTx) String() string {
  198. return Fmt("DupeoutTx{%X,%v,%v}", tx.Address, tx.VoteA, tx.VoteB)
  199. }
  200. //-----------------------------------------------------------------------------
  201. func TxId(tx Tx) []byte {
  202. signBytes := account.SignBytes(tx)
  203. return binary.BinaryRipemd160(signBytes)
  204. }