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.

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