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.

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