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.

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