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.

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