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.

235 lines
6.1 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. //-------------------------------------------------------
  22. // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
  23. // UNSTABLE
  24. var TM2PB = tm2pb{}
  25. type tm2pb struct{}
  26. func (tm2pb) Header(header *Header) abci.Header {
  27. return abci.Header{
  28. ChainID: header.ChainID,
  29. Height: header.Height,
  30. Time: header.Time,
  31. NumTxs: header.NumTxs,
  32. TotalTxs: header.TotalTxs,
  33. LastBlockId: TM2PB.BlockID(header.LastBlockID),
  34. LastCommitHash: header.LastCommitHash,
  35. DataHash: header.DataHash,
  36. ValidatorsHash: header.ValidatorsHash,
  37. ConsensusHash: header.ConsensusHash,
  38. AppHash: header.AppHash,
  39. LastResultsHash: header.LastResultsHash,
  40. EvidenceHash: header.EvidenceHash,
  41. ProposerAddress: header.ProposerAddress,
  42. }
  43. }
  44. func (tm2pb) Validator(val *Validator) abci.Validator {
  45. return abci.Validator{
  46. Address: val.PubKey.Address(),
  47. Power: val.VotingPower,
  48. }
  49. }
  50. func (tm2pb) BlockID(blockID BlockID) abci.BlockID {
  51. return abci.BlockID{
  52. Hash: blockID.Hash,
  53. PartsHeader: TM2PB.PartSetHeader(blockID.PartsHeader),
  54. }
  55. }
  56. func (tm2pb) PartSetHeader(header PartSetHeader) abci.PartSetHeader {
  57. return abci.PartSetHeader{
  58. Total: int32(header.Total),
  59. Hash: header.Hash,
  60. }
  61. }
  62. // XXX: panics on unknown pubkey type
  63. func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate {
  64. return abci.ValidatorUpdate{
  65. PubKey: TM2PB.PubKey(val.PubKey),
  66. Power: val.VotingPower,
  67. }
  68. }
  69. // XXX: panics on nil or unknown pubkey type
  70. // TODO: add cases when new pubkey types are added to crypto
  71. func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
  72. switch pk := pubKey.(type) {
  73. case ed25519.PubKeyEd25519:
  74. return abci.PubKey{
  75. Type: ABCIPubKeyTypeEd25519,
  76. Data: pk[:],
  77. }
  78. case secp256k1.PubKeySecp256k1:
  79. return abci.PubKey{
  80. Type: ABCIPubKeyTypeSecp256k1,
  81. Data: pk[:],
  82. }
  83. default:
  84. panic(fmt.Sprintf("unknown pubkey type: %v %v", pubKey, reflect.TypeOf(pubKey)))
  85. }
  86. }
  87. // XXX: panics on nil or unknown pubkey type
  88. func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
  89. validators := make([]abci.ValidatorUpdate, vals.Size())
  90. for i, val := range vals.Validators {
  91. validators[i] = TM2PB.ValidatorUpdate(val)
  92. }
  93. return validators
  94. }
  95. func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams {
  96. return &abci.ConsensusParams{
  97. BlockSize: &abci.BlockSize{
  98. MaxBytes: int32(params.BlockSize.MaxBytes),
  99. MaxTxs: int32(params.BlockSize.MaxTxs),
  100. MaxGas: params.BlockSize.MaxGas,
  101. },
  102. TxSize: &abci.TxSize{
  103. MaxBytes: int32(params.TxSize.MaxBytes),
  104. MaxGas: params.TxSize.MaxGas,
  105. },
  106. BlockGossip: &abci.BlockGossip{
  107. BlockPartSizeBytes: int32(params.BlockGossip.BlockPartSizeBytes),
  108. },
  109. }
  110. }
  111. // ABCI Evidence includes information from the past that's not included in the evidence itself
  112. // so Evidence types stays compact.
  113. // XXX: panics on nil or unknown pubkey type
  114. func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
  115. _, val := valSet.GetByAddress(ev.Address())
  116. if val == nil {
  117. // should already have checked this
  118. panic(val)
  119. }
  120. // set type
  121. var evType string
  122. switch ev.(type) {
  123. case *DuplicateVoteEvidence:
  124. evType = ABCIEvidenceTypeDuplicateVote
  125. case MockGoodEvidence:
  126. // XXX: not great to have test types in production paths ...
  127. evType = ABCIEvidenceTypeMockGood
  128. default:
  129. panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
  130. }
  131. return abci.Evidence{
  132. Type: evType,
  133. Validator: TM2PB.Validator(val),
  134. Height: ev.Height(),
  135. Time: evTime,
  136. TotalVotingPower: valSet.TotalVotingPower(),
  137. }
  138. }
  139. // XXX: panics on nil or unknown pubkey type
  140. func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate {
  141. pubkeyABCI := TM2PB.PubKey(pubkey)
  142. return abci.ValidatorUpdate{
  143. PubKey: pubkeyABCI,
  144. Power: power,
  145. }
  146. }
  147. //----------------------------------------------------------------------------
  148. // PB2TM is used for converting protobuf ABCI to Tendermint ABCI.
  149. // UNSTABLE
  150. var PB2TM = pb2tm{}
  151. type pb2tm struct{}
  152. func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) {
  153. // TODO: define these in crypto and use them
  154. sizeEd := 32
  155. sizeSecp := 33
  156. switch pubKey.Type {
  157. case ABCIPubKeyTypeEd25519:
  158. if len(pubKey.Data) != sizeEd {
  159. return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d", len(pubKey.Data), sizeEd)
  160. }
  161. var pk ed25519.PubKeyEd25519
  162. copy(pk[:], pubKey.Data)
  163. return pk, nil
  164. case ABCIPubKeyTypeSecp256k1:
  165. if len(pubKey.Data) != sizeSecp {
  166. return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d", len(pubKey.Data), sizeSecp)
  167. }
  168. var pk secp256k1.PubKeySecp256k1
  169. copy(pk[:], pubKey.Data)
  170. return pk, nil
  171. default:
  172. return nil, fmt.Errorf("Unknown pubkey type %v", pubKey.Type)
  173. }
  174. }
  175. func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) {
  176. tmVals := make([]*Validator, len(vals))
  177. for i, v := range vals {
  178. pub, err := PB2TM.PubKey(v.PubKey)
  179. if err != nil {
  180. return nil, err
  181. }
  182. tmVals[i] = NewValidator(pub, v.Power)
  183. }
  184. return tmVals, nil
  185. }
  186. func (pb2tm) ConsensusParams(csp *abci.ConsensusParams) ConsensusParams {
  187. return ConsensusParams{
  188. BlockSize: BlockSize{
  189. MaxBytes: int(csp.BlockSize.MaxBytes), // XXX
  190. MaxTxs: int(csp.BlockSize.MaxTxs), // XXX
  191. MaxGas: csp.BlockSize.MaxGas,
  192. },
  193. TxSize: TxSize{
  194. MaxBytes: int(csp.TxSize.MaxBytes), // XXX
  195. MaxGas: csp.TxSize.MaxGas,
  196. },
  197. BlockGossip: BlockGossip{
  198. BlockPartSizeBytes: int(csp.BlockGossip.BlockPartSizeBytes), // XXX
  199. },
  200. // TODO: EvidenceParams: EvidenceParams{
  201. // MaxAge: int(csp.Evidence.MaxAge), // XXX
  202. // },
  203. }
  204. }