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