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.

188 lines
4.9 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. cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
  10. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  11. )
  12. //-------------------------------------------------------
  13. // Use strings to distinguish types in ABCI messages
  14. const (
  15. ABCIEvidenceTypeDuplicateVote = "duplicate/vote"
  16. ABCIEvidenceTypePhantom = "phantom"
  17. ABCIEvidenceTypeLunatic = "lunatic"
  18. ABCIEvidenceTypePotentialAmnesia = "potential_amnesia"
  19. ABCIEvidenceTypeMock = "mock/evidence"
  20. )
  21. const (
  22. ABCIPubKeyTypeEd25519 = "ed25519"
  23. )
  24. // TODO: Make non-global by allowing for registration of more pubkey types
  25. var ABCIPubKeyTypesToNames = map[string]string{
  26. ABCIPubKeyTypeEd25519: ed25519.PubKeyName,
  27. }
  28. //-------------------------------------------------------
  29. // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
  30. // UNSTABLE
  31. var TM2PB = tm2pb{}
  32. type tm2pb struct{}
  33. func (tm2pb) Header(header *Header) tmproto.Header {
  34. return tmproto.Header{
  35. Version: header.Version,
  36. ChainID: header.ChainID,
  37. Height: header.Height,
  38. Time: header.Time,
  39. LastBlockId: header.LastBlockID.ToProto(),
  40. LastCommitHash: header.LastCommitHash,
  41. DataHash: header.DataHash,
  42. ValidatorsHash: header.ValidatorsHash,
  43. NextValidatorsHash: header.NextValidatorsHash,
  44. ConsensusHash: header.ConsensusHash,
  45. AppHash: header.AppHash,
  46. LastResultsHash: header.LastResultsHash,
  47. EvidenceHash: header.EvidenceHash,
  48. ProposerAddress: header.ProposerAddress,
  49. }
  50. }
  51. func (tm2pb) Validator(val *Validator) abci.Validator {
  52. return abci.Validator{
  53. Address: val.PubKey.Address(),
  54. Power: val.VotingPower,
  55. }
  56. }
  57. func (tm2pb) BlockID(blockID BlockID) tmproto.BlockID {
  58. return tmproto.BlockID{
  59. Hash: blockID.Hash,
  60. PartSetHeader: TM2PB.PartSetHeader(blockID.PartSetHeader),
  61. }
  62. }
  63. func (tm2pb) PartSetHeader(header PartSetHeader) tmproto.PartSetHeader {
  64. return tmproto.PartSetHeader{
  65. Total: header.Total,
  66. Hash: header.Hash,
  67. }
  68. }
  69. // XXX: panics on unknown pubkey type
  70. func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate {
  71. pk, err := cryptoenc.PubKeyToProto(val.PubKey)
  72. if err != nil {
  73. panic(err)
  74. }
  75. return abci.ValidatorUpdate{
  76. PubKey: pk,
  77. Power: val.VotingPower,
  78. }
  79. }
  80. // XXX: panics on nil or unknown pubkey type
  81. func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
  82. validators := make([]abci.ValidatorUpdate, vals.Size())
  83. for i, val := range vals.Validators {
  84. validators[i] = TM2PB.ValidatorUpdate(val)
  85. }
  86. return validators
  87. }
  88. func (tm2pb) ConsensusParams(params *tmproto.ConsensusParams) *abci.ConsensusParams {
  89. return &abci.ConsensusParams{
  90. Block: &abci.BlockParams{
  91. MaxBytes: params.Block.MaxBytes,
  92. MaxGas: params.Block.MaxGas,
  93. },
  94. Evidence: &params.Evidence,
  95. Validator: &params.Validator,
  96. }
  97. }
  98. // ABCI Evidence includes information from the past that's not included in the evidence itself
  99. // so Evidence types stays compact.
  100. // XXX: panics on nil or unknown pubkey type
  101. func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
  102. addr := ev.Address()
  103. _, val := valSet.GetByAddress(addr)
  104. if val == nil {
  105. // should already have checked this
  106. panic(val)
  107. }
  108. // set type
  109. var evType string
  110. switch ev.(type) {
  111. case *DuplicateVoteEvidence:
  112. evType = ABCIEvidenceTypeDuplicateVote
  113. case *PhantomValidatorEvidence:
  114. evType = ABCIEvidenceTypePhantom
  115. case *LunaticValidatorEvidence:
  116. evType = ABCIEvidenceTypeLunatic
  117. case *PotentialAmnesiaEvidence:
  118. evType = ABCIEvidenceTypePotentialAmnesia
  119. case MockEvidence:
  120. // XXX: not great to have test types in production paths ...
  121. evType = ABCIEvidenceTypeMock
  122. default:
  123. panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
  124. }
  125. return abci.Evidence{
  126. Type: evType,
  127. Validator: TM2PB.Validator(val),
  128. Height: ev.Height(),
  129. Time: evTime,
  130. TotalVotingPower: valSet.TotalVotingPower(),
  131. }
  132. }
  133. // XXX: panics on nil or unknown pubkey type
  134. func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate {
  135. pubkeyABCI, err := cryptoenc.PubKeyToProto(pubkey)
  136. if err != nil {
  137. panic(err)
  138. }
  139. return abci.ValidatorUpdate{
  140. PubKey: pubkeyABCI,
  141. Power: power,
  142. }
  143. }
  144. //----------------------------------------------------------------------------
  145. // PB2TM is used for converting protobuf ABCI to Tendermint ABCI.
  146. // UNSTABLE
  147. var PB2TM = pb2tm{}
  148. type pb2tm struct{}
  149. func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) {
  150. tmVals := make([]*Validator, len(vals))
  151. for i, v := range vals {
  152. pub, err := cryptoenc.PubKeyFromProto(v.PubKey)
  153. if err != nil {
  154. return nil, err
  155. }
  156. tmVals[i] = NewValidator(pub, v.Power)
  157. }
  158. return tmVals, nil
  159. }