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.

180 lines
4.6 KiB

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