github.com/theQRL/go-zond@v0.2.1/params/config.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package params 18 19 import ( 20 "fmt" 21 "math/big" 22 23 "github.com/theQRL/go-zond/common" 24 ) 25 26 // TODO(now.youtrack.cloud/issue/TGZ-16) 27 // Genesis hashes to enforce below configs on. 28 var ( 29 MainnetGenesisHash = common.HexToHash("0xb3de630542cf9acf842e24f428c7c21b7824b38a7718a632e424b58ba0f562c6") 30 BetaNetGenesisHash = common.HexToHash("0xab0c2cf4bd9bc1d3bad049a5ae94725177bf2b95f45115415e9941f218c661b1") 31 TestnetGenesisHash = common.HexToHash("0x05db5e4aaf4ca0c301ed6912280e20e0f20de36ba3ccc893dc777050216494ea") 32 ) 33 34 // NOTE(rgeraldes24): unused atm 35 // func newUint64(val uint64) *uint64 { return &val } 36 37 var ( 38 // MainnetChainConfig is the chain parameters to run a node on the main network. 39 MainnetChainConfig = &ChainConfig{ 40 ChainID: big.NewInt(1), 41 } 42 // TestnetChainConfig contains the chain parameters to run a node on the BetaNet test network. 43 TestnetChainConfig = &ChainConfig{ 44 ChainID: big.NewInt(32382), 45 } 46 // BetaNetChainConfig contains the chain parameters to run a node on the BetaNet test network. 47 BetaNetChainConfig = &ChainConfig{ 48 ChainID: big.NewInt(32382), 49 } 50 51 // AllBeaconProtocolChanges contains every protocol change (EIPs) introduced 52 // and accepted by the Zond core developers into the Beacon consensus. 53 AllBeaconProtocolChanges = &ChainConfig{ 54 ChainID: big.NewInt(1337), 55 } 56 57 AllDevChainProtocolChanges = &ChainConfig{ 58 ChainID: big.NewInt(1337), 59 IsDevMode: true, 60 } 61 62 // TestChainConfig contains every protocol change (EIPs) introduced 63 // and accepted by the Zond core developers for testing proposes. 64 TestChainConfig = &ChainConfig{ 65 ChainID: big.NewInt(1), 66 } 67 68 // NonActivatedConfig defines the chain configuration without activating 69 // any protocol change (EIPs). 70 NonActivatedConfig = &ChainConfig{ 71 ChainID: big.NewInt(1), 72 } 73 TestRules = TestChainConfig.Rules(new(big.Int), 0) 74 ) 75 76 // NetworkNames are user friendly names to use in the chain spec banner. 77 var NetworkNames = map[string]string{ 78 MainnetChainConfig.ChainID.String(): "mainnet", 79 } 80 81 // ChainConfig is the core config which determines the blockchain settings. 82 // 83 // ChainConfig is stored in the database on a per block basis. This means 84 // that any network, identified by its genesis block, can have its own 85 // set of configuration options. 86 type ChainConfig struct { 87 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 88 89 IsDevMode bool `json:"isDev,omitempty"` 90 } 91 92 // Description returns a human-readable description of ChainConfig. 93 func (c *ChainConfig) Description() string { 94 var banner string 95 96 // Create some basic network config output 97 network := NetworkNames[c.ChainID.String()] 98 if network == "" { 99 network = "unknown" 100 } 101 banner += fmt.Sprintf("Chain ID: %v (%s)\n", c.ChainID, network) 102 banner += "Consensus: Beacon (proof-of-stake)\n" 103 banner += "\n" 104 105 return banner 106 } 107 108 // CheckCompatible checks whether scheduled fork transitions have been imported 109 // with a mismatching chain configuration. 110 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { 111 var ( 112 bhead = new(big.Int).SetUint64(height) 113 // btime = time 114 ) 115 // Iterate checkCompatible to find the lowest conflict. 116 var lasterr *ConfigCompatError 117 for { 118 err := c.checkCompatible(newcfg /*, bhead, btime*/) 119 if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) { 120 break 121 } 122 lasterr = err 123 124 if err.RewindToTime > 0 { 125 // btime = err.RewindToTime 126 } else { 127 bhead.SetUint64(err.RewindToBlock) 128 } 129 } 130 return lasterr 131 } 132 133 // CheckConfigForkOrder checks that we don't "skip" any forks, gzond isn't pluggable enough 134 // to guarantee that forks can be implemented in a different order than on official networks 135 func (c *ChainConfig) CheckConfigForkOrder() error { 136 type fork struct { 137 name string 138 block *big.Int // forks up to - and including the merge - were defined with block numbers 139 timestamp *uint64 // forks after the merge are scheduled using timestamps 140 optional bool // if true, the fork may be nil and next fork is still allowed 141 } 142 var lastFork fork 143 for _, cur := range []fork{} { 144 if lastFork.name != "" { 145 switch { 146 // Non-optional forks must all be present in the chain config up to the last defined fork 147 case lastFork.block == nil && lastFork.timestamp == nil && (cur.block != nil || cur.timestamp != nil): 148 if cur.block != nil { 149 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at block %v", 150 lastFork.name, cur.name, cur.block) 151 } else { 152 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at timestamp %v", 153 lastFork.name, cur.name, cur.timestamp) 154 } 155 156 // Fork (whether defined by block or timestamp) must follow the fork definition sequence 157 case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil): 158 if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 { 159 return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v", 160 lastFork.name, lastFork.block, cur.name, cur.block) 161 } else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp { 162 return fmt.Errorf("unsupported fork ordering: %v enabled at timestamp %v, but %v enabled at timestamp %v", 163 lastFork.name, lastFork.timestamp, cur.name, cur.timestamp) 164 } 165 166 // Timestamp based forks can follow block based ones, but not the other way around 167 if lastFork.timestamp != nil && cur.block != nil { 168 return fmt.Errorf("unsupported fork ordering: %v used timestamp ordering, but %v reverted to block ordering", 169 lastFork.name, cur.name) 170 } 171 } 172 } 173 // If it was optional and not set, then ignore it 174 if !cur.optional || (cur.block != nil || cur.timestamp != nil) { 175 lastFork = cur 176 } 177 } 178 return nil 179 } 180 181 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig /*, headNumber *big.Int, headTimestamp uint64*/) *ConfigCompatError { 182 if !configBlockEqual(c.ChainID, newcfg.ChainID) { 183 return newBlockCompatError("chain ID", c.ChainID, newcfg.ChainID) 184 } 185 186 return nil 187 } 188 189 // BaseFeeChangeDenominator bounds the amount the base fee can change between blocks. 190 func (c *ChainConfig) BaseFeeChangeDenominator() uint64 { 191 return DefaultBaseFeeChangeDenominator 192 } 193 194 // ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have. 195 func (c *ChainConfig) ElasticityMultiplier() uint64 { 196 return DefaultElasticityMultiplier 197 } 198 199 // isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be 200 // rescheduled to block s2 because head is already past the fork. 201 func isForkBlockIncompatible(s1, s2, head *big.Int) bool { 202 return (isBlockForked(s1, head) || isBlockForked(s2, head)) && !configBlockEqual(s1, s2) 203 } 204 205 // isBlockForked returns whether a fork scheduled at block s is active at the 206 // given head block. Whilst this method is the same as isTimestampForked, they 207 // are explicitly separate for clearer reading. 208 func isBlockForked(s, head *big.Int) bool { 209 if s == nil || head == nil { 210 return false 211 } 212 return s.Cmp(head) <= 0 213 } 214 215 func configBlockEqual(x, y *big.Int) bool { 216 if x == nil { 217 return y == nil 218 } 219 if y == nil { 220 return x == nil 221 } 222 return x.Cmp(y) == 0 223 } 224 225 // isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 226 // cannot be rescheduled to timestamp s2 because head is already past the fork. 227 func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { 228 return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) 229 } 230 231 // isTimestampForked returns whether a fork scheduled at timestamp s is active 232 // at the given head timestamp. Whilst this method is the same as isBlockForked, 233 // they are explicitly separate for clearer reading. 234 func isTimestampForked(s *uint64, head uint64) bool { 235 if s == nil { 236 return false 237 } 238 return *s <= head 239 } 240 241 func configTimestampEqual(x, y *uint64) bool { 242 if x == nil { 243 return y == nil 244 } 245 if y == nil { 246 return x == nil 247 } 248 return *x == *y 249 } 250 251 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 252 // ChainConfig that would alter the past. 253 type ConfigCompatError struct { 254 What string 255 256 // block numbers of the stored and new configurations if block based forking 257 StoredBlock, NewBlock *big.Int 258 259 // timestamps of the stored and new configurations if time based forking 260 StoredTime, NewTime *uint64 261 262 // the block number to which the local chain must be rewound to correct the error 263 RewindToBlock uint64 264 265 // the timestamp to which the local chain must be rewound to correct the error 266 RewindToTime uint64 267 } 268 269 func newBlockCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 270 var rew *big.Int 271 switch { 272 case storedblock == nil: 273 rew = newblock 274 case newblock == nil || storedblock.Cmp(newblock) < 0: 275 rew = storedblock 276 default: 277 rew = newblock 278 } 279 err := &ConfigCompatError{ 280 What: what, 281 StoredBlock: storedblock, 282 NewBlock: newblock, 283 RewindToBlock: 0, 284 } 285 if rew != nil && rew.Sign() > 0 { 286 err.RewindToBlock = rew.Uint64() - 1 287 } 288 return err 289 } 290 291 func newTimestampCompatError(what string, storedtime, newtime *uint64) *ConfigCompatError { 292 var rew *uint64 293 switch { 294 case storedtime == nil: 295 rew = newtime 296 case newtime == nil || *storedtime < *newtime: 297 rew = storedtime 298 default: 299 rew = newtime 300 } 301 err := &ConfigCompatError{ 302 What: what, 303 StoredTime: storedtime, 304 NewTime: newtime, 305 RewindToTime: 0, 306 } 307 if rew != nil { 308 err.RewindToTime = *rew - 1 309 } 310 return err 311 } 312 313 func (err *ConfigCompatError) Error() string { 314 if err.StoredBlock != nil { 315 return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) 316 } 317 return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp %d, rewindto timestamp %d)", err.What, err.StoredTime, err.NewTime, err.RewindToTime) 318 } 319 320 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 321 // that do not have or require information about the block. 322 // 323 // Rules is a one time interface meaning that it shouldn't be used in between transition 324 // phases. 325 type Rules struct { 326 ChainID *big.Int 327 } 328 329 // Rules ensures c's ChainID is not nil. 330 func (c *ChainConfig) Rules(num *big.Int, timestamp uint64) Rules { 331 chainID := c.ChainID 332 if chainID == nil { 333 chainID = new(big.Int) 334 } 335 return Rules{ 336 ChainID: new(big.Int).Set(chainID), 337 } 338 }