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.

266 lines
7.7 KiB

7 years ago
  1. package types
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. "github.com/tendermint/tendermint/crypto/tmhash"
  7. tmstrings "github.com/tendermint/tendermint/libs/strings"
  8. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  9. )
  10. const (
  11. // MaxBlockSizeBytes is the maximum permitted size of the blocks.
  12. MaxBlockSizeBytes = 104857600 // 100MB
  13. // BlockPartSizeBytes is the size of one block part.
  14. BlockPartSizeBytes uint32 = 65536 // 64kB
  15. // MaxBlockPartsCount is the maximum number of block parts.
  16. MaxBlockPartsCount = (MaxBlockSizeBytes / BlockPartSizeBytes) + 1
  17. )
  18. // ConsensusParams contains consensus critical parameters that determine the
  19. // validity of blocks.
  20. type ConsensusParams struct {
  21. Block BlockParams `json:"block"`
  22. Evidence EvidenceParams `json:"evidence"`
  23. Validator ValidatorParams `json:"validator"`
  24. Version VersionParams `json:"version"`
  25. }
  26. // HashedParams is a subset of ConsensusParams.
  27. // It is amino encoded and hashed into
  28. // the Header.ConsensusHash.
  29. type HashedParams struct {
  30. BlockMaxBytes int64
  31. BlockMaxGas int64
  32. }
  33. // BlockParams define limits on the block size and gas plus minimum time
  34. // between blocks.
  35. type BlockParams struct {
  36. MaxBytes int64 `json:"max_bytes"`
  37. MaxGas int64 `json:"max_gas"`
  38. }
  39. // EvidenceParams determine how we handle evidence of malfeasance.
  40. type EvidenceParams struct {
  41. MaxAgeNumBlocks int64 `json:"max_age_num_blocks"` // only accept new evidence more recent than this
  42. MaxAgeDuration time.Duration `json:"max_age_duration"`
  43. MaxBytes int64 `json:"max_bytes"`
  44. }
  45. // ValidatorParams restrict the public key types validators can use.
  46. // NOTE: uses ABCI pubkey naming, not Amino names.
  47. type ValidatorParams struct {
  48. PubKeyTypes []string `json:"pub_key_types"`
  49. }
  50. type VersionParams struct {
  51. AppVersion uint64 `json:"app_version"`
  52. }
  53. // DefaultConsensusParams returns a default ConsensusParams.
  54. func DefaultConsensusParams() *ConsensusParams {
  55. return &ConsensusParams{
  56. Block: DefaultBlockParams(),
  57. Evidence: DefaultEvidenceParams(),
  58. Validator: DefaultValidatorParams(),
  59. Version: DefaultVersionParams(),
  60. }
  61. }
  62. // DefaultBlockParams returns a default BlockParams.
  63. func DefaultBlockParams() BlockParams {
  64. return BlockParams{
  65. MaxBytes: 22020096, // 21MB
  66. MaxGas: -1,
  67. }
  68. }
  69. // DefaultEvidenceParams returns a default EvidenceParams.
  70. func DefaultEvidenceParams() EvidenceParams {
  71. return EvidenceParams{
  72. MaxAgeNumBlocks: 100000, // 27.8 hrs at 1block/s
  73. MaxAgeDuration: 48 * time.Hour,
  74. MaxBytes: 1048576, // 1MB
  75. }
  76. }
  77. // DefaultValidatorParams returns a default ValidatorParams, which allows
  78. // only ed25519 pubkeys.
  79. func DefaultValidatorParams() ValidatorParams {
  80. return ValidatorParams{
  81. PubKeyTypes: []string{ABCIPubKeyTypeEd25519},
  82. }
  83. }
  84. func DefaultVersionParams() VersionParams {
  85. return VersionParams{
  86. AppVersion: 0,
  87. }
  88. }
  89. func (val *ValidatorParams) IsValidPubkeyType(pubkeyType string) bool {
  90. for i := 0; i < len(val.PubKeyTypes); i++ {
  91. if val.PubKeyTypes[i] == pubkeyType {
  92. return true
  93. }
  94. }
  95. return false
  96. }
  97. // Validate validates the ConsensusParams to ensure all values are within their
  98. // allowed limits, and returns an error if they are not.
  99. func (params ConsensusParams) ValidateConsensusParams() error {
  100. if params.Block.MaxBytes <= 0 {
  101. return fmt.Errorf("block.MaxBytes must be greater than 0. Got %d",
  102. params.Block.MaxBytes)
  103. }
  104. if params.Block.MaxBytes > MaxBlockSizeBytes {
  105. return fmt.Errorf("block.MaxBytes is too big. %d > %d",
  106. params.Block.MaxBytes, MaxBlockSizeBytes)
  107. }
  108. if params.Block.MaxGas < -1 {
  109. return fmt.Errorf("block.MaxGas must be greater or equal to -1. Got %d",
  110. params.Block.MaxGas)
  111. }
  112. if params.Evidence.MaxAgeNumBlocks <= 0 {
  113. return fmt.Errorf("evidence.MaxAgeNumBlocks must be greater than 0. Got %d",
  114. params.Evidence.MaxAgeNumBlocks)
  115. }
  116. if params.Evidence.MaxAgeDuration <= 0 {
  117. return fmt.Errorf("evidence.MaxAgeDuration must be grater than 0 if provided, Got %v",
  118. params.Evidence.MaxAgeDuration)
  119. }
  120. if params.Evidence.MaxBytes > params.Block.MaxBytes {
  121. return fmt.Errorf("evidence.MaxBytesEvidence is greater than upper bound, %d > %d",
  122. params.Evidence.MaxBytes, params.Block.MaxBytes)
  123. }
  124. if params.Evidence.MaxBytes < 0 {
  125. return fmt.Errorf("evidence.MaxBytes must be non negative. Got: %d",
  126. params.Evidence.MaxBytes)
  127. }
  128. if len(params.Validator.PubKeyTypes) == 0 {
  129. return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
  130. }
  131. // Check if keyType is a known ABCIPubKeyType
  132. for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
  133. keyType := params.Validator.PubKeyTypes[i]
  134. if _, ok := ABCIPubKeyTypesToNames[keyType]; !ok {
  135. return fmt.Errorf("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
  136. i, keyType)
  137. }
  138. }
  139. return nil
  140. }
  141. // Hash returns a hash of a subset of the parameters to store in the block header.
  142. // Only the Block.MaxBytes and Block.MaxGas are included in the hash.
  143. // This allows the ConsensusParams to evolve more without breaking the block
  144. // protocol. No need for a Merkle tree here, just a small struct to hash.
  145. func (params ConsensusParams) HashConsensusParams() []byte {
  146. hasher := tmhash.New()
  147. hp := tmproto.HashedParams{
  148. BlockMaxBytes: params.Block.MaxBytes,
  149. BlockMaxGas: params.Block.MaxGas,
  150. }
  151. bz, err := hp.Marshal()
  152. if err != nil {
  153. panic(err)
  154. }
  155. _, err = hasher.Write(bz)
  156. if err != nil {
  157. panic(err)
  158. }
  159. return hasher.Sum(nil)
  160. }
  161. func (params *ConsensusParams) Equals(params2 *ConsensusParams) bool {
  162. return params.Block == params2.Block &&
  163. params.Evidence == params2.Evidence &&
  164. tmstrings.StringSliceEqual(params.Validator.PubKeyTypes, params2.Validator.PubKeyTypes)
  165. }
  166. // Update returns a copy of the params with updates from the non-zero fields of p2.
  167. // NOTE: note: must not modify the original
  168. func (params ConsensusParams) UpdateConsensusParams(params2 *tmproto.ConsensusParams) ConsensusParams {
  169. res := params // explicit copy
  170. if params2 == nil {
  171. return res
  172. }
  173. // we must defensively consider any structs may be nil
  174. if params2.Block != nil {
  175. res.Block.MaxBytes = params2.Block.MaxBytes
  176. res.Block.MaxGas = params2.Block.MaxGas
  177. }
  178. if params2.Evidence != nil {
  179. res.Evidence.MaxAgeNumBlocks = params2.Evidence.MaxAgeNumBlocks
  180. res.Evidence.MaxAgeDuration = params2.Evidence.MaxAgeDuration
  181. res.Evidence.MaxBytes = params2.Evidence.MaxBytes
  182. }
  183. if params2.Validator != nil {
  184. // Copy params2.Validator.PubkeyTypes, and set result's value to the copy.
  185. // This avoids having to initialize the slice to 0 values, and then write to it again.
  186. res.Validator.PubKeyTypes = append([]string{}, params2.Validator.PubKeyTypes...)
  187. }
  188. if params2.Version != nil {
  189. res.Version.AppVersion = params2.Version.AppVersion
  190. }
  191. return res
  192. }
  193. func (params *ConsensusParams) ToProto() tmproto.ConsensusParams {
  194. return tmproto.ConsensusParams{
  195. Block: &tmproto.BlockParams{
  196. MaxBytes: params.Block.MaxBytes,
  197. MaxGas: params.Block.MaxGas,
  198. },
  199. Evidence: &tmproto.EvidenceParams{
  200. MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks,
  201. MaxAgeDuration: params.Evidence.MaxAgeDuration,
  202. MaxBytes: params.Evidence.MaxBytes,
  203. },
  204. Validator: &tmproto.ValidatorParams{
  205. PubKeyTypes: params.Validator.PubKeyTypes,
  206. },
  207. Version: &tmproto.VersionParams{
  208. AppVersion: params.Version.AppVersion,
  209. },
  210. }
  211. }
  212. func ConsensusParamsFromProto(pbParams tmproto.ConsensusParams) ConsensusParams {
  213. return ConsensusParams{
  214. Block: BlockParams{
  215. MaxBytes: pbParams.Block.MaxBytes,
  216. MaxGas: pbParams.Block.MaxGas,
  217. },
  218. Evidence: EvidenceParams{
  219. MaxAgeNumBlocks: pbParams.Evidence.MaxAgeNumBlocks,
  220. MaxAgeDuration: pbParams.Evidence.MaxAgeDuration,
  221. MaxBytes: pbParams.Evidence.MaxBytes,
  222. },
  223. Validator: ValidatorParams{
  224. PubKeyTypes: pbParams.Validator.PubKeyTypes,
  225. },
  226. Version: VersionParams{
  227. AppVersion: pbParams.Version.AppVersion,
  228. },
  229. }
  230. }