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.

185 lines
5.4 KiB

7 years ago
  1. package types
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. abci "github.com/tendermint/tendermint/abci/types"
  7. "github.com/tendermint/tendermint/crypto/tmhash"
  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. // DefaultConsensusParams returns a default ConsensusParams.
  19. func DefaultConsensusParams() *tmproto.ConsensusParams {
  20. return &tmproto.ConsensusParams{
  21. Block: DefaultBlockParams(),
  22. Evidence: DefaultEvidenceParams(),
  23. Validator: DefaultValidatorParams(),
  24. Version: DefaultVersionParams(),
  25. }
  26. }
  27. // DefaultBlockParams returns a default BlockParams.
  28. func DefaultBlockParams() tmproto.BlockParams {
  29. return tmproto.BlockParams{
  30. MaxBytes: 22020096, // 21MB
  31. MaxGas: -1,
  32. TimeIotaMs: 1000, // 1s
  33. }
  34. }
  35. // DefaultEvidenceParams returns a default EvidenceParams.
  36. func DefaultEvidenceParams() tmproto.EvidenceParams {
  37. return tmproto.EvidenceParams{
  38. MaxAgeNumBlocks: 100000, // 27.8 hrs at 1block/s
  39. MaxAgeDuration: 48 * time.Hour,
  40. MaxBytes: 1048576, // 1MB
  41. }
  42. }
  43. // DefaultValidatorParams returns a default ValidatorParams, which allows
  44. // only ed25519 pubkeys.
  45. func DefaultValidatorParams() tmproto.ValidatorParams {
  46. return tmproto.ValidatorParams{
  47. PubKeyTypes: []string{ABCIPubKeyTypeEd25519},
  48. }
  49. }
  50. func DefaultVersionParams() tmproto.VersionParams {
  51. return tmproto.VersionParams{
  52. AppVersion: 0,
  53. }
  54. }
  55. func IsValidPubkeyType(params tmproto.ValidatorParams, pubkeyType string) bool {
  56. for i := 0; i < len(params.PubKeyTypes); i++ {
  57. if params.PubKeyTypes[i] == pubkeyType {
  58. return true
  59. }
  60. }
  61. return false
  62. }
  63. // Validate validates the ConsensusParams to ensure all values are within their
  64. // allowed limits, and returns an error if they are not.
  65. func ValidateConsensusParams(params tmproto.ConsensusParams) error {
  66. if params.Block.MaxBytes <= 0 {
  67. return fmt.Errorf("block.MaxBytes must be greater than 0. Got %d",
  68. params.Block.MaxBytes)
  69. }
  70. if params.Block.MaxBytes > MaxBlockSizeBytes {
  71. return fmt.Errorf("block.MaxBytes is too big. %d > %d",
  72. params.Block.MaxBytes, MaxBlockSizeBytes)
  73. }
  74. if params.Block.MaxGas < -1 {
  75. return fmt.Errorf("block.MaxGas must be greater or equal to -1. Got %d",
  76. params.Block.MaxGas)
  77. }
  78. if params.Block.TimeIotaMs <= 0 {
  79. return fmt.Errorf("block.TimeIotaMs must be greater than 0. Got %v",
  80. params.Block.TimeIotaMs)
  81. }
  82. if params.Evidence.MaxAgeNumBlocks <= 0 {
  83. return fmt.Errorf("evidence.MaxAgeNumBlocks must be greater than 0. Got %d",
  84. params.Evidence.MaxAgeNumBlocks)
  85. }
  86. if params.Evidence.MaxAgeDuration <= 0 {
  87. return fmt.Errorf("evidence.MaxAgeDuration must be grater than 0 if provided, Got %v",
  88. params.Evidence.MaxAgeDuration)
  89. }
  90. if params.Evidence.MaxBytes > params.Block.MaxBytes {
  91. return fmt.Errorf("evidence.MaxBytesEvidence is greater than upper bound, %d > %d",
  92. params.Evidence.MaxBytes, params.Block.MaxBytes)
  93. }
  94. if params.Evidence.MaxBytes < 0 {
  95. return fmt.Errorf("evidence.MaxBytes must be non negative. Got: %d",
  96. params.Evidence.MaxBytes)
  97. }
  98. if len(params.Validator.PubKeyTypes) == 0 {
  99. return errors.New("len(Validator.PubKeyTypes) must be greater than 0")
  100. }
  101. // Check if keyType is a known ABCIPubKeyType
  102. for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
  103. keyType := params.Validator.PubKeyTypes[i]
  104. if _, ok := ABCIPubKeyTypesToNames[keyType]; !ok {
  105. return fmt.Errorf("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
  106. i, keyType)
  107. }
  108. }
  109. return nil
  110. }
  111. // Hash returns a hash of a subset of the parameters to store in the block header.
  112. // Only the Block.MaxBytes and Block.MaxGas are included in the hash.
  113. // This allows the ConsensusParams to evolve more without breaking the block
  114. // protocol. No need for a Merkle tree here, just a small struct to hash.
  115. func HashConsensusParams(params tmproto.ConsensusParams) []byte {
  116. hasher := tmhash.New()
  117. hp := tmproto.HashedParams{
  118. BlockMaxBytes: params.Block.MaxBytes,
  119. BlockMaxGas: params.Block.MaxGas,
  120. }
  121. bz, err := hp.Marshal()
  122. if err != nil {
  123. panic(err)
  124. }
  125. _, err = hasher.Write(bz)
  126. if err != nil {
  127. panic(err)
  128. }
  129. return hasher.Sum(nil)
  130. }
  131. // Update returns a copy of the params with updates from the non-zero fields of p2.
  132. // NOTE: note: must not modify the original
  133. func UpdateConsensusParams(params tmproto.ConsensusParams, params2 *abci.ConsensusParams) tmproto.ConsensusParams {
  134. res := params // explicit copy
  135. if params2 == nil {
  136. return res
  137. }
  138. // we must defensively consider any structs may be nil
  139. if params2.Block != nil {
  140. res.Block.MaxBytes = params2.Block.MaxBytes
  141. res.Block.MaxGas = params2.Block.MaxGas
  142. }
  143. if params2.Evidence != nil {
  144. res.Evidence.MaxAgeNumBlocks = params2.Evidence.MaxAgeNumBlocks
  145. res.Evidence.MaxAgeDuration = params2.Evidence.MaxAgeDuration
  146. res.Evidence.MaxBytes = params2.Evidence.MaxBytes
  147. }
  148. if params2.Validator != nil {
  149. // Copy params2.Validator.PubkeyTypes, and set result's value to the copy.
  150. // This avoids having to initialize the slice to 0 values, and then write to it again.
  151. res.Validator.PubKeyTypes = append([]string{}, params2.Validator.PubKeyTypes...)
  152. }
  153. if params2.Version != nil {
  154. res.Version.AppVersion = params2.Version.AppVersion
  155. }
  156. return res
  157. }