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.

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