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.

250 lines
6.5 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. "github.com/tendermint/tendermint/crypto/secp256k1"
  10. )
  11. //-------------------------------------------------------
  12. // Use strings to distinguish types in ABCI messages
  13. const (
  14. ABCIEvidenceTypeDuplicateVote = "duplicate/vote"
  15. ABCIEvidenceTypeMockGood = "mock/good"
  16. )
  17. const (
  18. ABCIPubKeyTypeEd25519 = "ed25519"
  19. ABCIPubKeyTypeSecp256k1 = "secp256k1"
  20. )
  21. // TODO: Make non-global by allowing for registration of more pubkey types
  22. var ABCIPubKeyTypesToAminoNames = map[string]string{
  23. ABCIPubKeyTypeEd25519: ed25519.PubKeyAminoName,
  24. ABCIPubKeyTypeSecp256k1: secp256k1.PubKeyAminoName,
  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) abci.Header {
  32. return abci.Header{
  33. Version: abci.Version{
  34. Block: header.Version.Block.Uint64(),
  35. App: header.Version.App.Uint64(),
  36. },
  37. ChainID: header.ChainID,
  38. Height: header.Height,
  39. Time: header.Time,
  40. NumTxs: header.NumTxs,
  41. TotalTxs: header.TotalTxs,
  42. LastBlockId: TM2PB.BlockID(header.LastBlockID),
  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. return abci.ValidatorUpdate{
  75. PubKey: TM2PB.PubKey(val.PubKey),
  76. Power: val.VotingPower,
  77. }
  78. }
  79. // XXX: panics on nil or unknown pubkey type
  80. // TODO: add cases when new pubkey types are added to crypto
  81. func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
  82. switch pk := pubKey.(type) {
  83. case ed25519.PubKeyEd25519:
  84. return abci.PubKey{
  85. Type: ABCIPubKeyTypeEd25519,
  86. Data: pk[:],
  87. }
  88. case secp256k1.PubKeySecp256k1:
  89. return abci.PubKey{
  90. Type: ABCIPubKeyTypeSecp256k1,
  91. Data: pk[:],
  92. }
  93. default:
  94. panic(fmt.Sprintf("unknown pubkey type: %v %v", pubKey, reflect.TypeOf(pubKey)))
  95. }
  96. }
  97. // XXX: panics on nil or unknown pubkey type
  98. func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
  99. validators := make([]abci.ValidatorUpdate, vals.Size())
  100. for i, val := range vals.Validators {
  101. validators[i] = TM2PB.ValidatorUpdate(val)
  102. }
  103. return validators
  104. }
  105. func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams {
  106. return &abci.ConsensusParams{
  107. Block: &abci.BlockParams{
  108. MaxBytes: params.Block.MaxBytes,
  109. MaxGas: params.Block.MaxGas,
  110. TimeIotaMs: params.Block.TimeIotaMs,
  111. },
  112. Evidence: &abci.EvidenceParams{
  113. MaxAge: params.Evidence.MaxAge,
  114. },
  115. Validator: &abci.ValidatorParams{
  116. PubKeyTypes: params.Validator.PubKeyTypes,
  117. },
  118. }
  119. }
  120. // ABCI Evidence includes information from the past that's not included in the evidence itself
  121. // so Evidence types stays compact.
  122. // XXX: panics on nil or unknown pubkey type
  123. func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
  124. _, val := valSet.GetByAddress(ev.Address())
  125. if val == nil {
  126. // should already have checked this
  127. panic(val)
  128. }
  129. // set type
  130. var evType string
  131. switch ev.(type) {
  132. case *DuplicateVoteEvidence:
  133. evType = ABCIEvidenceTypeDuplicateVote
  134. case MockGoodEvidence:
  135. // XXX: not great to have test types in production paths ...
  136. evType = ABCIEvidenceTypeMockGood
  137. default:
  138. panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
  139. }
  140. return abci.Evidence{
  141. Type: evType,
  142. Validator: TM2PB.Validator(val),
  143. Height: ev.Height(),
  144. Time: evTime,
  145. TotalVotingPower: valSet.TotalVotingPower(),
  146. }
  147. }
  148. // XXX: panics on nil or unknown pubkey type
  149. func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate {
  150. pubkeyABCI := TM2PB.PubKey(pubkey)
  151. return abci.ValidatorUpdate{
  152. PubKey: pubkeyABCI,
  153. Power: power,
  154. }
  155. }
  156. //----------------------------------------------------------------------------
  157. // PB2TM is used for converting protobuf ABCI to Tendermint ABCI.
  158. // UNSTABLE
  159. var PB2TM = pb2tm{}
  160. type pb2tm struct{}
  161. func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) {
  162. switch pubKey.Type {
  163. case ABCIPubKeyTypeEd25519:
  164. if len(pubKey.Data) != ed25519.PubKeyEd25519Size {
  165. return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d",
  166. len(pubKey.Data), ed25519.PubKeyEd25519Size)
  167. }
  168. var pk ed25519.PubKeyEd25519
  169. copy(pk[:], pubKey.Data)
  170. return pk, nil
  171. case ABCIPubKeyTypeSecp256k1:
  172. if len(pubKey.Data) != secp256k1.PubKeySecp256k1Size {
  173. return nil, fmt.Errorf("Invalid size for PubKeySecp256k1. Got %d, expected %d",
  174. len(pubKey.Data), secp256k1.PubKeySecp256k1Size)
  175. }
  176. var pk secp256k1.PubKeySecp256k1
  177. copy(pk[:], pubKey.Data)
  178. return pk, nil
  179. default:
  180. return nil, fmt.Errorf("Unknown pubkey type %v", pubKey.Type)
  181. }
  182. }
  183. func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) {
  184. tmVals := make([]*Validator, len(vals))
  185. for i, v := range vals {
  186. pub, err := PB2TM.PubKey(v.PubKey)
  187. if err != nil {
  188. return nil, err
  189. }
  190. tmVals[i] = NewValidator(pub, v.Power)
  191. }
  192. return tmVals, nil
  193. }
  194. func (pb2tm) ConsensusParams(csp *abci.ConsensusParams) ConsensusParams {
  195. params := ConsensusParams{}
  196. // we must defensively consider any structs may be nil
  197. if csp.Block != nil {
  198. params.Block = BlockParams{
  199. MaxBytes: csp.Block.MaxBytes,
  200. MaxGas: csp.Block.MaxGas,
  201. TimeIotaMs: csp.Block.TimeIotaMs,
  202. }
  203. }
  204. if csp.Evidence != nil {
  205. params.Evidence = EvidenceParams{
  206. MaxAge: csp.Evidence.MaxAge,
  207. }
  208. }
  209. if csp.Validator != nil {
  210. params.Validator = ValidatorParams{
  211. PubKeyTypes: csp.Validator.PubKeyTypes,
  212. }
  213. }
  214. return params
  215. }