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.

188 lines
5.6 KiB

6 years ago
  1. package types
  2. import (
  3. "github.com/pkg/errors"
  4. abci "github.com/tendermint/tendermint/abci/types"
  5. "github.com/tendermint/tendermint/crypto/tmhash"
  6. cmn "github.com/tendermint/tendermint/libs/common"
  7. )
  8. const (
  9. // MaxBlockSizeBytes is the maximum permitted size of the blocks.
  10. MaxBlockSizeBytes = 104857600 // 100MB
  11. // BlockPartSizeBytes is the size of one block part.
  12. BlockPartSizeBytes = 65536 // 64kB
  13. // MaxBlockPartsCount is the maximum count of block parts.
  14. MaxBlockPartsCount = (MaxBlockSizeBytes / BlockPartSizeBytes) + 1
  15. )
  16. // ConsensusParams contains consensus critical parameters that determine the
  17. // validity of blocks.
  18. type ConsensusParams struct {
  19. Block BlockParams `json:"block"`
  20. Evidence EvidenceParams `json:"evidence"`
  21. Validator ValidatorParams `json:"validator"`
  22. }
  23. // HashedParams is a subset of ConsensusParams.
  24. // It is amino encoded and hashed into
  25. // the Header.ConsensusHash.
  26. type HashedParams struct {
  27. BlockMaxBytes int64
  28. BlockMaxGas int64
  29. }
  30. // BlockParams define limits on the block size and gas plus minimum time
  31. // between blocks.
  32. type BlockParams struct {
  33. MaxBytes int64 `json:"max_bytes"`
  34. MaxGas int64 `json:"max_gas"`
  35. // Minimum time increment between consecutive blocks (in milliseconds)
  36. // Not exposed to the application.
  37. TimeIotaMs int64 `json:"time_iota_ms"`
  38. }
  39. // EvidenceParams determine how we handle evidence of malfeasance.
  40. type EvidenceParams struct {
  41. MaxAge int64 `json:"max_age"` // only accept new evidence more recent than this
  42. }
  43. // ValidatorParams restrict the public key types validators can use.
  44. // NOTE: uses ABCI pubkey naming, not Amino names.
  45. type ValidatorParams struct {
  46. PubKeyTypes []string `json:"pub_key_types"`
  47. }
  48. // DefaultConsensusParams returns a default ConsensusParams.
  49. func DefaultConsensusParams() *ConsensusParams {
  50. return &ConsensusParams{
  51. DefaultBlockParams(),
  52. DefaultEvidenceParams(),
  53. DefaultValidatorParams(),
  54. }
  55. }
  56. // DefaultBlockParams returns a default BlockParams.
  57. func DefaultBlockParams() BlockParams {
  58. return BlockParams{
  59. MaxBytes: 22020096, // 21MB
  60. MaxGas: -1,
  61. TimeIotaMs: 1000, // 1s
  62. }
  63. }
  64. // DefaultEvidenceParams Params returns a default EvidenceParams.
  65. func DefaultEvidenceParams() EvidenceParams {
  66. return EvidenceParams{
  67. MaxAge: 100000, // 27.8 hrs at 1block/s
  68. }
  69. }
  70. // DefaultValidatorParams returns a default ValidatorParams, which allows
  71. // only ed25519 pubkeys.
  72. func DefaultValidatorParams() ValidatorParams {
  73. return ValidatorParams{[]string{ABCIPubKeyTypeEd25519}}
  74. }
  75. func (params *ValidatorParams) IsValidPubkeyType(pubkeyType string) bool {
  76. for i := 0; i < len(params.PubKeyTypes); i++ {
  77. if params.PubKeyTypes[i] == pubkeyType {
  78. return true
  79. }
  80. }
  81. return false
  82. }
  83. // Validate validates the ConsensusParams to ensure all values are within their
  84. // allowed limits, and returns an error if they are not.
  85. func (params *ConsensusParams) Validate() error {
  86. if params.Block.MaxBytes <= 0 {
  87. return errors.Errorf("Block.MaxBytes must be greater than 0. Got %d",
  88. params.Block.MaxBytes)
  89. }
  90. if params.Block.MaxBytes > MaxBlockSizeBytes {
  91. return errors.Errorf("Block.MaxBytes is too big. %d > %d",
  92. params.Block.MaxBytes, MaxBlockSizeBytes)
  93. }
  94. if params.Block.MaxGas < -1 {
  95. return errors.Errorf("Block.MaxGas must be greater or equal to -1. Got %d",
  96. params.Block.MaxGas)
  97. }
  98. if params.Block.TimeIotaMs <= 0 {
  99. return errors.Errorf("Block.TimeIotaMs must be greater than 0. Got %v",
  100. params.Block.TimeIotaMs)
  101. }
  102. if params.Evidence.MaxAge <= 0 {
  103. return errors.Errorf("EvidenceParams.MaxAge must be greater than 0. Got %d",
  104. params.Evidence.MaxAge)
  105. }
  106. if len(params.Validator.PubKeyTypes) == 0 {
  107. return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
  108. }
  109. // Check if keyType is a known ABCIPubKeyType
  110. for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
  111. keyType := params.Validator.PubKeyTypes[i]
  112. if _, ok := ABCIPubKeyTypesToAminoNames[keyType]; !ok {
  113. return errors.Errorf("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
  114. i, keyType)
  115. }
  116. }
  117. return nil
  118. }
  119. // Hash returns a hash of a subset of the parameters to store in the block header.
  120. // Only the Block.MaxBytes and Block.MaxGas are included in the hash.
  121. // This allows the ConsensusParams to evolve more without breaking the block
  122. // protocol. No need for a Merkle tree here, just a small struct to hash.
  123. func (params *ConsensusParams) Hash() []byte {
  124. hasher := tmhash.New()
  125. bz := cdcEncode(HashedParams{
  126. params.Block.MaxBytes,
  127. params.Block.MaxGas,
  128. })
  129. if bz == nil {
  130. panic("cannot fail to encode ConsensusParams")
  131. }
  132. hasher.Write(bz)
  133. return hasher.Sum(nil)
  134. }
  135. func (params *ConsensusParams) Equals(params2 *ConsensusParams) bool {
  136. return params.Block == params2.Block &&
  137. params.Evidence == params2.Evidence &&
  138. cmn.StringSliceEqual(params.Validator.PubKeyTypes, params2.Validator.PubKeyTypes)
  139. }
  140. // Update returns a copy of the params with updates from the non-zero fields of p2.
  141. // NOTE: note: must not modify the original
  142. func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusParams {
  143. res := params // explicit copy
  144. if params2 == nil {
  145. return res
  146. }
  147. // we must defensively consider any structs may be nil
  148. if params2.Block != nil {
  149. res.Block.MaxBytes = params2.Block.MaxBytes
  150. res.Block.MaxGas = params2.Block.MaxGas
  151. }
  152. if params2.Evidence != nil {
  153. res.Evidence.MaxAge = params2.Evidence.MaxAge
  154. }
  155. if params2.Validator != nil {
  156. // Copy params2.Validator.PubkeyTypes, and set result's value to the copy.
  157. // This avoids having to initialize the slice to 0 values, and then write to it again.
  158. res.Validator.PubKeyTypes = append([]string{}, params2.Validator.PubKeyTypes...)
  159. }
  160. return res
  161. }