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.

220 lines
5.8 KiB

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