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.

221 lines
5.8 KiB

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