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.

276 lines
8.1 KiB

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