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.

230 lines
6.0 KiB

  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "time"
  7. abci "github.com/tendermint/tendermint/abci/types"
  8. "github.com/tendermint/tendermint/crypto"
  9. "github.com/tendermint/tendermint/crypto/ed25519"
  10. "github.com/tendermint/tendermint/crypto/secp256k1"
  11. )
  12. //-------------------------------------------------------
  13. // Use strings to distinguish types in ABCI messages
  14. const (
  15. ABCIEvidenceTypeDuplicateVote = "duplicate/vote"
  16. ABCIEvidenceTypeMockGood = "mock/good"
  17. )
  18. const (
  19. ABCIPubKeyTypeEd25519 = "ed25519"
  20. ABCIPubKeyTypeSecp256k1 = "secp256k1"
  21. )
  22. //-------------------------------------------------------
  23. // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
  24. // UNSTABLE
  25. var TM2PB = tm2pb{}
  26. type tm2pb struct{}
  27. func (tm2pb) Header(header *Header) abci.Header {
  28. return abci.Header{
  29. ChainID: header.ChainID,
  30. Height: header.Height,
  31. Time: header.Time,
  32. NumTxs: int32(header.NumTxs), // XXX: overflow
  33. TotalTxs: header.TotalTxs,
  34. LastBlockHash: header.LastBlockID.Hash,
  35. ValidatorsHash: header.ValidatorsHash,
  36. AppHash: header.AppHash,
  37. // Proposer: TODO
  38. }
  39. }
  40. func (tm2pb) ValidatorWithoutPubKey(val *Validator) abci.Validator {
  41. return abci.Validator{
  42. Address: val.PubKey.Address(),
  43. Power: val.VotingPower,
  44. }
  45. }
  46. // XXX: panics on unknown pubkey type
  47. func (tm2pb) Validator(val *Validator) abci.Validator {
  48. return abci.Validator{
  49. Address: val.PubKey.Address(),
  50. PubKey: TM2PB.PubKey(val.PubKey),
  51. Power: val.VotingPower,
  52. }
  53. }
  54. // XXX: panics on nil or unknown pubkey type
  55. // TODO: add cases when new pubkey types are added to crypto
  56. func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
  57. switch pk := pubKey.(type) {
  58. case ed25519.PubKeyEd25519:
  59. return abci.PubKey{
  60. Type: ABCIPubKeyTypeEd25519,
  61. Data: pk[:],
  62. }
  63. case secp256k1.PubKeySecp256k1:
  64. return abci.PubKey{
  65. Type: ABCIPubKeyTypeSecp256k1,
  66. Data: pk[:],
  67. }
  68. default:
  69. panic(fmt.Sprintf("unknown pubkey type: %v %v", pubKey, reflect.TypeOf(pubKey)))
  70. }
  71. }
  72. // XXX: panics on nil or unknown pubkey type
  73. func (tm2pb) Validators(vals *ValidatorSet) []abci.Validator {
  74. validators := make([]abci.Validator, vals.Size())
  75. for i, val := range vals.Validators {
  76. validators[i] = TM2PB.Validator(val)
  77. }
  78. return validators
  79. }
  80. func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams {
  81. return &abci.ConsensusParams{
  82. BlockSize: &abci.BlockSize{
  83. MaxBytes: int32(params.BlockSize.MaxBytes),
  84. MaxTxs: int32(params.BlockSize.MaxTxs),
  85. MaxGas: params.BlockSize.MaxGas,
  86. },
  87. TxSize: &abci.TxSize{
  88. MaxBytes: int32(params.TxSize.MaxBytes),
  89. MaxGas: params.TxSize.MaxGas,
  90. },
  91. BlockGossip: &abci.BlockGossip{
  92. BlockPartSizeBytes: int32(params.BlockGossip.BlockPartSizeBytes),
  93. },
  94. }
  95. }
  96. // ABCI Evidence includes information from the past that's not included in the evidence itself
  97. // so Evidence types stays compact.
  98. // XXX: panics on nil or unknown pubkey type
  99. func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
  100. _, val := valSet.GetByAddress(ev.Address())
  101. if val == nil {
  102. // should already have checked this
  103. panic(val)
  104. }
  105. // set type
  106. var evType string
  107. switch ev.(type) {
  108. case *DuplicateVoteEvidence:
  109. evType = ABCIEvidenceTypeDuplicateVote
  110. case MockGoodEvidence:
  111. // XXX: not great to have test types in production paths ...
  112. evType = ABCIEvidenceTypeMockGood
  113. default:
  114. panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
  115. }
  116. return abci.Evidence{
  117. Type: evType,
  118. Validator: TM2PB.ValidatorWithoutPubKey(val),
  119. Height: ev.Height(),
  120. Time: evTime,
  121. TotalVotingPower: valSet.TotalVotingPower(),
  122. }
  123. }
  124. // XXX: panics on nil or unknown pubkey type
  125. func (tm2pb) ValidatorFromPubKeyAndPower(pubkey crypto.PubKey, power int64) abci.Validator {
  126. pubkeyABCI := TM2PB.PubKey(pubkey)
  127. return abci.Validator{
  128. Address: pubkey.Address(),
  129. PubKey: pubkeyABCI,
  130. Power: power,
  131. }
  132. }
  133. //----------------------------------------------------------------------------
  134. // PB2TM is used for converting protobuf ABCI to Tendermint ABCI.
  135. // UNSTABLE
  136. var PB2TM = pb2tm{}
  137. type pb2tm struct{}
  138. func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) {
  139. // TODO: define these in crypto and use them
  140. sizeEd := 32
  141. sizeSecp := 33
  142. switch pubKey.Type {
  143. case ABCIPubKeyTypeEd25519:
  144. if len(pubKey.Data) != sizeEd {
  145. return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d", len(pubKey.Data), sizeEd)
  146. }
  147. var pk ed25519.PubKeyEd25519
  148. copy(pk[:], pubKey.Data)
  149. return pk, nil
  150. case ABCIPubKeyTypeSecp256k1:
  151. if len(pubKey.Data) != sizeSecp {
  152. return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d", len(pubKey.Data), sizeSecp)
  153. }
  154. var pk secp256k1.PubKeySecp256k1
  155. copy(pk[:], pubKey.Data)
  156. return pk, nil
  157. default:
  158. return nil, fmt.Errorf("Unknown pubkey type %v", pubKey.Type)
  159. }
  160. }
  161. func (pb2tm) Validators(vals []abci.Validator) ([]*Validator, error) {
  162. tmVals := make([]*Validator, len(vals))
  163. for i, v := range vals {
  164. pub, err := PB2TM.PubKey(v.PubKey)
  165. if err != nil {
  166. return nil, err
  167. }
  168. // If the app provided an address too, it must match.
  169. // This is just a sanity check.
  170. if len(v.Address) > 0 {
  171. if !bytes.Equal(pub.Address(), v.Address) {
  172. return nil, fmt.Errorf("Validator.Address (%X) does not match PubKey.Address (%X)",
  173. v.Address, pub.Address())
  174. }
  175. }
  176. tmVals[i] = &Validator{
  177. Address: pub.Address(),
  178. PubKey: pub,
  179. VotingPower: v.Power,
  180. }
  181. }
  182. return tmVals, nil
  183. }
  184. func (pb2tm) ConsensusParams(csp *abci.ConsensusParams) ConsensusParams {
  185. return ConsensusParams{
  186. BlockSize: BlockSize{
  187. MaxBytes: int(csp.BlockSize.MaxBytes), // XXX
  188. MaxTxs: int(csp.BlockSize.MaxTxs), // XXX
  189. MaxGas: csp.BlockSize.MaxGas,
  190. },
  191. TxSize: TxSize{
  192. MaxBytes: int(csp.TxSize.MaxBytes), // XXX
  193. MaxGas: csp.TxSize.MaxGas,
  194. },
  195. BlockGossip: BlockGossip{
  196. BlockPartSizeBytes: int(csp.BlockGossip.BlockPartSizeBytes), // XXX
  197. },
  198. // TODO: EvidenceParams: EvidenceParams{
  199. // MaxAge: int(csp.Evidence.MaxAge), // XXX
  200. // },
  201. }
  202. }