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.

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