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. tmproto "github.com/tendermint/tendermint/proto/types"
  12. )
  13. //-------------------------------------------------------
  14. // Use strings to distinguish types in ABCI messages
  15. const (
  16. ABCIEvidenceTypeDuplicateVote = "duplicate/vote"
  17. ABCIEvidenceTypeMock = "mock/evidence"
  18. )
  19. const (
  20. ABCIPubKeyTypeEd25519 = "ed25519"
  21. ABCIPubKeyTypeSr25519 = "sr25519"
  22. ABCIPubKeyTypeSecp256k1 = "secp256k1"
  23. )
  24. // TODO: Make non-global by allowing for registration of more pubkey types
  25. var ABCIPubKeyTypesToAminoNames = map[string]string{
  26. ABCIPubKeyTypeEd25519: ed25519.PubKeyAminoName,
  27. ABCIPubKeyTypeSr25519: sr25519.PubKeyAminoName,
  28. ABCIPubKeyTypeSecp256k1: secp256k1.PubKeyAminoName,
  29. }
  30. //-------------------------------------------------------
  31. // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
  32. // UNSTABLE
  33. var TM2PB = tm2pb{}
  34. type tm2pb struct{}
  35. func (tm2pb) Header(header *Header) tmproto.Header {
  36. return tmproto.Header{
  37. Version: header.Version,
  38. ChainID: header.ChainID,
  39. Height: header.Height,
  40. Time: header.Time,
  41. LastBlockId: header.LastBlockID.ToProto(),
  42. LastCommitHash: header.LastCommitHash,
  43. DataHash: header.DataHash,
  44. ValidatorsHash: header.ValidatorsHash,
  45. NextValidatorsHash: header.NextValidatorsHash,
  46. ConsensusHash: header.ConsensusHash,
  47. AppHash: header.AppHash,
  48. LastResultsHash: header.LastResultsHash,
  49. EvidenceHash: header.EvidenceHash,
  50. ProposerAddress: header.ProposerAddress,
  51. }
  52. }
  53. func (tm2pb) Validator(val *Validator) abci.Validator {
  54. return abci.Validator{
  55. Address: val.PubKey.Address(),
  56. Power: val.VotingPower,
  57. }
  58. }
  59. func (tm2pb) BlockID(blockID BlockID) abci.BlockID {
  60. return abci.BlockID{
  61. Hash: blockID.Hash,
  62. PartsHeader: TM2PB.PartSetHeader(blockID.PartsHeader),
  63. }
  64. }
  65. func (tm2pb) PartSetHeader(header PartSetHeader) abci.PartSetHeader {
  66. return abci.PartSetHeader{
  67. Total: int32(header.Total),
  68. Hash: header.Hash,
  69. }
  70. }
  71. // XXX: panics on unknown pubkey type
  72. func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate {
  73. return abci.ValidatorUpdate{
  74. PubKey: TM2PB.PubKey(val.PubKey),
  75. Power: val.VotingPower,
  76. }
  77. }
  78. // XXX: panics on nil or unknown pubkey type
  79. // TODO: add cases when new pubkey types are added to crypto
  80. func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
  81. switch pk := pubKey.(type) {
  82. case ed25519.PubKey:
  83. return abci.PubKey{
  84. Type: ABCIPubKeyTypeEd25519,
  85. Data: pk[:],
  86. }
  87. case sr25519.PubKey:
  88. return abci.PubKey{
  89. Type: ABCIPubKeyTypeSr25519,
  90. Data: pk[:],
  91. }
  92. case secp256k1.PubKey:
  93. return abci.PubKey{
  94. Type: ABCIPubKeyTypeSecp256k1,
  95. Data: pk[:],
  96. }
  97. default:
  98. panic(fmt.Sprintf("unknown pubkey type: %v %v", pubKey, reflect.TypeOf(pubKey)))
  99. }
  100. }
  101. // XXX: panics on nil or unknown pubkey type
  102. func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
  103. validators := make([]abci.ValidatorUpdate, vals.Size())
  104. for i, val := range vals.Validators {
  105. validators[i] = TM2PB.ValidatorUpdate(val)
  106. }
  107. return validators
  108. }
  109. func (tm2pb) ConsensusParams(params *tmproto.ConsensusParams) *abci.ConsensusParams {
  110. return &abci.ConsensusParams{
  111. Block: &abci.BlockParams{
  112. MaxBytes: params.Block.MaxBytes,
  113. MaxGas: params.Block.MaxGas,
  114. },
  115. Evidence: &params.Evidence,
  116. Validator: &params.Validator,
  117. }
  118. }
  119. // ABCI Evidence includes information from the past that's not included in the evidence itself
  120. // so Evidence types stays compact.
  121. // XXX: panics on nil or unknown pubkey type
  122. func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
  123. addr := ev.Address()
  124. _, val := valSet.GetByAddress(addr)
  125. if val == nil {
  126. // should already have checked this
  127. panic(val)
  128. }
  129. // set type
  130. var evType string
  131. switch ev.(type) {
  132. case *DuplicateVoteEvidence:
  133. evType = ABCIEvidenceTypeDuplicateVote
  134. case *PhantomValidatorEvidence:
  135. evType = "phantom"
  136. case *LunaticValidatorEvidence:
  137. evType = "lunatic"
  138. case *PotentialAmnesiaEvidence:
  139. evType = "potential_amnesia"
  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.PubKeySize {
  171. return nil, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d",
  172. len(pubKey.Data), ed25519.PubKeySize)
  173. }
  174. var pk = make(ed25519.PubKey, ed25519.PubKeySize)
  175. copy(pk, pubKey.Data)
  176. return pk, nil
  177. case ABCIPubKeyTypeSr25519:
  178. if len(pubKey.Data) != sr25519.PubKeySize {
  179. return nil, fmt.Errorf("invalid size for PubKeySr25519. Got %d, expected %d",
  180. len(pubKey.Data), sr25519.PubKeySize)
  181. }
  182. var pk = make(sr25519.PubKey, sr25519.PubKeySize)
  183. copy(pk, pubKey.Data)
  184. return pk, nil
  185. case ABCIPubKeyTypeSecp256k1:
  186. if len(pubKey.Data) != secp256k1.PubKeySize {
  187. return nil, fmt.Errorf("invalid size for PubKeySecp256k1. Got %d, expected %d",
  188. len(pubKey.Data), secp256k1.PubKeySize)
  189. }
  190. var pk = make(secp256k1.PubKey, secp256k1.PubKeySize)
  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. }