github.com/amazechain/amc@v0.1.3/params/config.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package params 18 19 import ( 20 "embed" 21 "encoding/binary" 22 "encoding/json" 23 "fmt" 24 "github.com/amazechain/amc/common/paths" 25 "github.com/amazechain/amc/common/types" 26 "github.com/amazechain/amc/internal/avm/common" 27 "github.com/amazechain/amc/params/networkname" 28 "golang.org/x/crypto/sha3" 29 "math/big" 30 "path" 31 "sort" 32 "strconv" 33 ) 34 35 //go:embed chainspecs 36 var chainspecs embed.FS 37 38 func readChainSpec(filename string) *ChainConfig { 39 f, err := chainspecs.Open(filename) 40 if err != nil { 41 panic(fmt.Sprintf("Could not open chainspec for %s: %v", filename, err)) 42 } 43 defer f.Close() 44 decoder := json.NewDecoder(f) 45 spec := &ChainConfig{} 46 err = decoder.Decode(&spec) 47 if err != nil { 48 panic(fmt.Sprintf("Could not parse chainspec for %s: %v", filename, err)) 49 } 50 return spec 51 } 52 53 type ConsensusType string 54 55 const ( 56 AuRaConsensus ConsensusType = "aura" 57 EtHashConsensus ConsensusType = "ethash" 58 CliqueConsensus ConsensusType = "clique" 59 ParliaConsensus ConsensusType = "parlia" 60 BorConsensus ConsensusType = "bor" 61 AposConsensu ConsensusType = "apos" 62 Faker ConsensusType = "faker" // faker consensus 63 ) 64 65 // Genesis hashes to enforce below configs on. 66 var ( 67 MainnetGenesisHash = types.HexToHash("0x138734b7044254e5ecbabf8056f5c2b73cd0847aaa5acac7345507cbeab387b8") 68 TestnetGenesisHash = types.HexToHash("0x5c0555d9ec963f58c63112862294e7e4836b12802304c23f2ec480a8f55cc5bb") 69 ) 70 71 var ( 72 // MainnetChainConfig is the chain parameters to run a node on the main network. 73 MainnetChainConfig = readChainSpec("chainspecs/mainnet.json") 74 75 // TestnetChainConfig contains the chain parameters to run a node on the Test network. 76 TestnetChainConfig = readChainSpec("chainspecs/testnet.json") 77 78 TestChainConfig = &ChainConfig{ 79 ChainID: big.NewInt(1), 80 Consensus: EtHashConsensus, 81 HomesteadBlock: big.NewInt(0), 82 DAOForkBlock: nil, 83 DAOForkSupport: false, 84 TangerineWhistleBlock: big.NewInt(0), 85 TangerineWhistleHash: types.Hash{}, 86 SpuriousDragonBlock: big.NewInt(0), 87 ByzantiumBlock: big.NewInt(0), 88 ConstantinopleBlock: big.NewInt(0), 89 PetersburgBlock: big.NewInt(0), 90 IstanbulBlock: big.NewInt(0), 91 MuirGlacierBlock: big.NewInt(0), 92 BerlinBlock: big.NewInt(0), 93 LondonBlock: nil, 94 ArrowGlacierBlock: nil, 95 Ethash: new(EthashConfig), 96 Clique: nil, 97 } 98 ) 99 100 // ChainConfig is the core config which determines the blockchain settings. 101 // 102 // ChainConfig is stored in the database on a per block basis. This means 103 // that any network, identified by its genesis block, can have its own 104 // set of configuration options. 105 type ChainConfig struct { 106 ChainName string 107 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 108 109 Consensus ConsensusType `json:"consensus,omitempty"` // aura, ethash or clique 110 111 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 112 113 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) 114 DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork 115 116 // Tangerine Whistle (EIP150) implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 117 TangerineWhistleBlock *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 118 TangerineWhistleHash types.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) 119 120 SpuriousDragonBlock *big.Int `json:"eip155Block,omitempty"` // Spurious Dragon HF block 121 122 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 123 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 124 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 125 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 126 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // EIP-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 127 BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) 128 LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) 129 ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // EIP-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) 130 GrayGlacierBlock *big.Int `json:"grayGlacierBlock,omitempty"` // EIP-5133 (bomb delay) switch block (nil = no fork, 0 = already activated) 131 132 // EIP-3675: Upgrade consensus to Proof-of-Stake 133 TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` // The merge happens when terminal total difficulty is reached 134 TerminalTotalDifficultyPassed bool `json:"terminalTotalDifficultyPassed,omitempty"` // Disable PoW sync for networks that have already passed through the Merge 135 MergeNetsplitBlock *big.Int `json:"mergeNetsplitBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter; see FORK_NEXT_VALUE in EIP-3675 136 137 ShanghaiBlock *big.Int `json:"shanghaiBlock,omitempty"` // Shanghai switch block (nil = no fork, 0 = already activated) 138 CancunBlock *big.Int `json:"cancunTime,omitempty"` 139 ShardingForkTime *big.Int `json:"shardingForkTime,omitempty"` 140 PragueTime *big.Int `json:"pragueTime,omitempty"` 141 142 // Parlia fork blocks 143 //RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated) 144 //NielsBlock *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated) 145 //MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated) 146 //BrunoBlock *big.Int `json:"brunoBlock,omitempty" toml:",omitempty"` // brunoBlock switch block (nil = no fork, 0 = already activated) 147 //EulerBlock *big.Int `json:"eulerBlock,omitempty" toml:",omitempty"` // eulerBlock switch block (nil = no fork, 0 = already activated) 148 //GibbsBlock *big.Int `json:"gibbsBlock,omitempty" toml:",omitempty"` // gibbsBlock switch block (nil = no fork, 0 = already activated) 149 NanoBlock *big.Int `json:"nanoBlock,omitempty" toml:",omitempty"` // nanoBlock switch block (nil = no fork, 0 = already activated) 150 MoranBlock *big.Int `json:"moranBlock,omitempty" toml:",omitempty"` // moranBlock switch block (nil = no fork, 0 = already activated) 151 BeijingBlock *big.Int `json:"beijingBlock,omitempty" toml:",omitempty"` // beijingBlock switch block (nil = no fork, 0 = already activated) 152 //Apos *AposConfig `json:"apos,omitempty"` 153 154 // Gnosis Chain fork blocks 155 //PosdaoBlock *big.Int `json:"posdaoBlock,omitempty"` 156 // 157 Eip1559FeeCollector *types.Address `json:"eip1559FeeCollector,omitempty"` // (Optional) Address where burnt EIP-1559 fees go to 158 Eip1559FeeCollectorTransition *big.Int `json:"eip1559FeeCollectorTransition,omitempty"` // (Optional) Block from which burnt EIP-1559 fees go to the Eip1559FeeCollector 159 160 // Various consensus engines 161 Ethash *EthashConfig `json:"ethash,omitempty"` 162 Clique *CliqueConfig `json:"clique,omitempty"` 163 Aura *AuRaConfig `json:"aura,omitempty"` 164 Parlia *ParliaConfig `json:"parlia,omitempty" toml:",omitempty"` 165 Bor *BorConfig `json:"bor,omitempty"` 166 Apos *APosConfig `json:"apos,omitempty"` 167 } 168 169 // EthashConfig is the consensus engine configs for proof-of-work based sealing. 170 type EthashConfig struct{} 171 172 // String implements the stringer interface, returning the consensus engine details. 173 func (c *EthashConfig) String() string { 174 return "ethash" 175 } 176 177 // CliqueConfig is the consensus engine configs for proof-of-authority based sealing. 178 type CliqueConfig struct { 179 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 180 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 181 } 182 183 // String implements the stringer interface, returning the consensus engine details. 184 func (c *CliqueConfig) String() string { 185 return "clique" 186 } 187 188 type APosConfig struct { 189 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 190 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 191 192 RewardEpoch uint64 `json:"rewardEpoch"` 193 RewardLimit *big.Int `json:"rewardLimit"` 194 195 DepositContract string `json:"depositContract"` // Deposit contract 196 DepositNFTContract string `json:"depositNFTContract"` // Deposit NFT contract 197 DepositFUJIContract string `json:"depositFUJIContract"` // Deposit NFT contract 198 } 199 200 // String implements the stringer interface, returning the consensus engine details. 201 func (b *APosConfig) String() string { 202 return fmt.Sprintf("{DepositContract: %v, NFTDepositContract:%v, Period: %v, Epoch: %v, RewardEpoch: %v, RewardLimit: %v}", 203 b.DepositContract, 204 b.DepositNFTContract, 205 b.Period, 206 b.Epoch, 207 b.RewardEpoch, 208 b.RewardLimit, 209 ) 210 } 211 212 // AuRaConfig is the consensus engine configs for proof-of-authority based sealing. 213 type AuRaConfig struct { 214 DBPath string 215 InMemory bool 216 Etherbase common.Address // same as miner etherbase 217 } 218 219 // String implements the stringer interface, returning the consensus engine details. 220 func (c *AuRaConfig) String() string { 221 return "aura" 222 } 223 224 type ParliaConfig struct { 225 DBPath string 226 InMemory bool 227 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 228 Epoch uint64 `json:"epoch"` // Epoch length to update validatorSet 229 } 230 231 // String implements the stringer interface, returning the consensus engine details. 232 func (b *ParliaConfig) String() string { 233 return "parlia" 234 } 235 236 //type AposConfig struct { 237 // DepositContract string `json:"depositContract"` // Deposit contract 238 // Period uint64 `json:"period"` // Number of seconds between blocks to enforce 239 // Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 240 // 241 // RewardEpoch uint64 `json:"rewardEpoch"` 242 // RewardLimit uint64 `json:"rewardLimit"` 243 //} 244 245 // BorConfig is the consensus engine configs for Matic bor based sealing. 246 type BorConfig struct { 247 Period map[string]uint64 `json:"period"` // Number of seconds between blocks to enforce 248 ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval 249 Sprint uint64 `json:"sprint"` // Epoch length to proposer 250 BackupMultiplier map[string]uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time 251 ValidatorContract string `json:"validatorContract"` // Validator set contract 252 StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract 253 254 OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count 255 BlockAlloc map[string]interface{} `json:"blockAlloc"` 256 JaipurBlock uint64 `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) 257 } 258 259 // String implements the stringer interface, returning the consensus engine details. 260 func (b *BorConfig) String() string { 261 return "bor" 262 } 263 264 func (c *BorConfig) CalculateBackupMultiplier(number uint64) uint64 { 265 return c.calculateBorConfigHelper(c.BackupMultiplier, number) 266 } 267 268 func (c *BorConfig) CalculatePeriod(number uint64) uint64 { 269 return c.calculateBorConfigHelper(c.Period, number) 270 } 271 272 func (c *BorConfig) IsJaipur(number uint64) bool { 273 return number >= c.JaipurBlock 274 } 275 276 func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 { 277 keys := make([]string, 0, len(field)) 278 for k := range field { 279 keys = append(keys, k) 280 } 281 sort.Strings(keys) 282 for i := 0; i < len(keys)-1; i++ { 283 valUint, _ := strconv.ParseUint(keys[i], 10, 64) 284 valUintNext, _ := strconv.ParseUint(keys[i+1], 10, 64) 285 if number > valUint && number < valUintNext { 286 return field[keys[i]] 287 } 288 } 289 return field[keys[len(keys)-1]] 290 } 291 292 // String implements the fmt.Stringer interface. 293 func (c *ChainConfig) String() string { 294 return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, DAO Support: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v}", 295 c.ChainID, 296 c.HomesteadBlock, 297 c.DAOForkBlock, 298 c.DAOForkSupport, 299 c.TangerineWhistleBlock, 300 c.SpuriousDragonBlock, 301 c.ByzantiumBlock, 302 c.ConstantinopleBlock, 303 c.PetersburgBlock, 304 c.IstanbulBlock, 305 c.MuirGlacierBlock, 306 c.BerlinBlock, 307 c.LondonBlock, 308 c.ArrowGlacierBlock, 309 c.GrayGlacierBlock, 310 c.TerminalTotalDifficulty, 311 c.MergeNetsplitBlock, 312 c.ShanghaiBlock, 313 c.CancunBlock, 314 ) 315 } 316 317 func (c *ChainConfig) IsHeaderWithSeal() bool { 318 return c.Consensus == AuRaConsensus 319 } 320 321 type ConsensusSnapshotConfig struct { 322 CheckpointInterval uint64 // Number of blocks after which to save the vote snapshot to the database 323 InmemorySnapshots int // Number of recent vote snapshots to keep in memory 324 InmemorySignatures int // Number of recent block signatures to keep in memory 325 DBPath string 326 InMemory bool 327 } 328 329 const cliquePath = "clique" 330 331 func NewSnapshotConfig(checkpointInterval uint64, inmemorySnapshots int, inmemorySignatures int, inmemory bool, dbPath string) *ConsensusSnapshotConfig { 332 if len(dbPath) == 0 { 333 dbPath = paths.DefaultDataDir() 334 } 335 336 return &ConsensusSnapshotConfig{ 337 checkpointInterval, 338 inmemorySnapshots, 339 inmemorySignatures, 340 path.Join(dbPath, cliquePath), 341 inmemory, 342 } 343 } 344 345 // NetworkNames are user friendly names to use in the chain spec banner. 346 var NetworkNames = map[string]string{ 347 "100100100": "testnet", 348 "94": "mainnet", 349 //"131": "testnet", 350 } 351 352 // Description returns a human-readable description of ChainConfig. 353 func (c *ChainConfig) Description() string { 354 var banner string 355 356 // Create some basinc network config output 357 network := NetworkNames[c.ChainID.String()] 358 if network == "" { 359 network = "unknown" 360 } 361 banner += fmt.Sprintf("Chain ID: %v (%s)\n", c.ChainID, network) 362 363 // Create a list of forks with a short description of them. Forks that only 364 // makes sense for mainnet should be optional at printing to avoid bloating 365 // the output for testnets and private networks. 366 //banner += fmt.Sprintf(" - Homestead: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock) 367 //if c.DAOForkBlock != nil { 368 // banner += fmt.Sprintf(" - DAO Fork: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock) 369 //} 370 //banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)\n", c.TangerineWhistleBlock) 371 //banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.SpuriousDragonBlock) 372 //banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.SpuriousDragonBlock) 373 //banner += fmt.Sprintf(" - Byzantium: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock) 374 //banner += fmt.Sprintf(" - Constantinople: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock) 375 //banner += fmt.Sprintf(" - Petersburg: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock) 376 //banner += fmt.Sprintf(" - Istanbul: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock) 377 //if c.MuirGlacierBlock != nil { 378 // banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) 379 //} 380 //banner += fmt.Sprintf(" - Berlin: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)\n", c.BerlinBlock) 381 //banner += fmt.Sprintf(" - London: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)\n", c.LondonBlock) 382 //if c.ArrowGlacierBlock != nil { 383 // banner += fmt.Sprintf(" - Arrow Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock) 384 //} 385 //if c.GrayGlacierBlock != nil { 386 // banner += fmt.Sprintf(" - Gray Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock) 387 //} 388 banner += "\n" 389 390 // Add a special section for the merge as it's non-obvious 391 //if c.TerminalTotalDifficulty == nil { 392 // banner += "The Merge is not yet available for this network!\n" 393 // banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n" 394 //} else { 395 // banner += "Merge configured:\n" 396 // banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n" 397 // banner += fmt.Sprintf(" - Network known to be merged: %v\n", c.TerminalTotalDifficultyPassed) 398 // banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty) 399 // if c.MergeNetsplitBlock != nil { 400 // banner += fmt.Sprintf(" - Merge netsplit block: #%-8v\n", c.MergeNetsplitBlock) 401 // } 402 //} 403 banner += "\n" 404 405 return banner 406 } 407 408 // IsHomestead returns whether num is either equal to the homestead block or greater. 409 func (c *ChainConfig) IsHomestead(num uint64) bool { 410 return isForked(c.HomesteadBlock, num) 411 } 412 413 // IsDAOFork returns whether num is either equal to the DAO fork block or greater. 414 func (c *ChainConfig) IsDAOFork(num uint64) bool { 415 return isForked(c.DAOForkBlock, num) 416 } 417 418 // IsTangerineWhistle returns whether num is either equal to the Tangerine Whistle (EIP150) fork block or greater. 419 func (c *ChainConfig) IsTangerineWhistle(num uint64) bool { 420 return isForked(c.TangerineWhistleBlock, num) 421 } 422 423 // IsSpuriousDragon returns whether num is either equal to the Spurious Dragon fork block or greater. 424 func (c *ChainConfig) IsSpuriousDragon(num uint64) bool { 425 return isForked(c.SpuriousDragonBlock, num) 426 } 427 428 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 429 func (c *ChainConfig) IsByzantium(num uint64) bool { 430 return isForked(c.ByzantiumBlock, num) 431 } 432 433 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 434 func (c *ChainConfig) IsConstantinople(num uint64) bool { 435 return isForked(c.ConstantinopleBlock, num) 436 } 437 438 func (c *ChainConfig) IsMoran(num uint64) bool { 439 return isForked(c.MoranBlock, num) 440 } 441 442 // func (c *ChainConfig) IsOnMoran(num *big.Int) bool { 443 // return configNumEqual(c.MoranBlock, num) 444 // } 445 // 446 // IsNano returns whether num is either equal to the euler fork block or greater. 447 func (c *ChainConfig) IsNano(num uint64) bool { 448 return isForked(c.NanoBlock, num) 449 } 450 451 // 452 //func (c *ChainConfig) IsOnNano(num *big.Int) bool { 453 // return configNumEqual(c.NanoBlock, num) 454 //} 455 456 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 457 func (c *ChainConfig) IsMuirGlacier(num uint64) bool { 458 return isForked(c.MuirGlacierBlock, num) 459 } 460 461 // IsPetersburg returns whether num is either 462 // - equal to or greater than the PetersburgBlock fork block, 463 // - OR is nil, and Constantinople is active 464 func (c *ChainConfig) IsPetersburg(num uint64) bool { 465 return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num) 466 } 467 468 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 469 func (c *ChainConfig) IsIstanbul(num uint64) bool { 470 return isForked(c.IstanbulBlock, num) 471 } 472 473 // IsBerlin returns whether num is either equal to the Berlin fork block or greater. 474 func (c *ChainConfig) IsBerlin(num uint64) bool { 475 return isForked(c.BerlinBlock, num) 476 } 477 478 // IsLondon returns whether num is either equal to the London fork block or greater. 479 func (c *ChainConfig) IsLondon(num uint64) bool { 480 return isForked(c.LondonBlock, num) 481 } 482 483 // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. 484 func (c *ChainConfig) IsArrowGlacier(num uint64) bool { 485 return isForked(c.ArrowGlacierBlock, num) 486 } 487 488 // IsGrayGlacier returns whether num is either equal to the Gray Glacier (EIP-5133) fork block or greater. 489 func (c *ChainConfig) IsGrayGlacier(num uint64) bool { 490 return isForked(c.GrayGlacierBlock, num) 491 } 492 493 // IsShanghai returns whether num is either equal to the Shanghai fork block or greater. 494 func (c *ChainConfig) IsShanghai(num uint64) bool { 495 return isForked(c.ShanghaiBlock, num) 496 } 497 498 // IsCancun returns whether num is either equal to the Cancun fork block or greater. 499 func (c *ChainConfig) IsCancun(num uint64) bool { 500 return isForked(c.CancunBlock, num) 501 } 502 503 // IsPrague returns whether time is either equal to the Prague fork time or greater. 504 func (c *ChainConfig) IsPrague(time uint64) bool { 505 return isForked(c.PragueTime, time) 506 } 507 508 // IsBeijing returns whether num is either equal to the IsBeijing fork block or greater. 509 func (c *ChainConfig) IsBeijing(num uint64) bool { 510 return isForked(c.BeijingBlock, num) 511 } 512 513 func (c *ChainConfig) IsEip1559FeeCollector(num uint64) bool { 514 return c.Eip1559FeeCollector != nil && isForked(c.Eip1559FeeCollectorTransition, num) 515 } 516 517 //func (c *ChainConfig) IsMoran(num uint64) bool { 518 // return isForked(c.MoranBlock, num) 519 //} 520 // 521 //func (c *ChainConfig) IsOnMoran(num *big.Int) bool { 522 // return numEqual(c.MoranBlock, num) 523 //} 524 // 525 //// IsNano returns whether num is either equal to the euler fork block or greater. 526 //func (c *ChainConfig) IsNano(num uint64) bool { 527 // return isForked(c.NanoBlock, num) 528 //} 529 530 // CheckCompatible checks whether scheduled fork transitions have been imported 531 // with a mismatching chain configuration. 532 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 533 bhead := height 534 535 // Iterate checkCompatible to find the lowest conflict. 536 var lasterr *ConfigCompatError 537 for { 538 err := c.checkCompatible(newcfg, bhead) 539 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 540 break 541 } 542 lasterr = err 543 bhead = err.RewindTo 544 } 545 return lasterr 546 } 547 548 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 549 // to guarantee that forks can be implemented in a different order than on official networks 550 func (c *ChainConfig) CheckConfigForkOrder() error { 551 if c != nil && c.ChainID != nil && c.ChainID.Uint64() == 77 { 552 return nil 553 } 554 type fork struct { 555 name string 556 block *big.Int 557 optional bool // if true, the fork may be nil and next fork is still allowed 558 } 559 var lastFork fork 560 for _, cur := range []fork{ 561 {name: "homesteadBlock", block: c.HomesteadBlock}, 562 {name: "daoForkBlock", block: c.DAOForkBlock, optional: true}, 563 {name: "eip150Block", block: c.TangerineWhistleBlock}, 564 {name: "eip155Block", block: c.SpuriousDragonBlock}, 565 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 566 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 567 {name: "petersburgBlock", block: c.PetersburgBlock}, 568 {name: "istanbulBlock", block: c.IstanbulBlock}, 569 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 570 //{name: "eulerBlock", block: c.EulerBlock, optional: true}, 571 //{name: "gibbsBlock", block: c.GibbsBlock, optional: true}, 572 {name: "berlinBlock", block: c.BerlinBlock}, 573 {name: "londonBlock", block: c.LondonBlock}, 574 {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, 575 {name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true}, 576 {name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true}, 577 {name: "shanghaiBlock", block: c.ShanghaiBlock}, 578 {name: "cancunBlock", block: c.CancunBlock}, 579 } { 580 if lastFork.name != "" { 581 // Next one must be higher number 582 if lastFork.block == nil && cur.block != nil { 583 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 584 lastFork.name, cur.name, cur.block) 585 } 586 if lastFork.block != nil && cur.block != nil { 587 if lastFork.block.Cmp(cur.block) > 0 { 588 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 589 lastFork.name, lastFork.block, cur.name, cur.block) 590 } 591 } 592 // If it was optional and not set, then ignore it 593 } 594 if !cur.optional || cur.block != nil { 595 lastFork = cur 596 } 597 } 598 return nil 599 } 600 601 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head uint64) *ConfigCompatError { 602 // Ethereum mainnet forks 603 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { 604 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 605 } 606 if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { 607 return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 608 } 609 if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { 610 return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 611 } 612 if isForkIncompatible(c.TangerineWhistleBlock, newcfg.TangerineWhistleBlock, head) { 613 return newCompatError("Tangerine Whistle fork block", c.TangerineWhistleBlock, newcfg.TangerineWhistleBlock) 614 } 615 if isForkIncompatible(c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock, head) { 616 return newCompatError("Spurious Dragon fork block", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock) 617 } 618 if c.IsSpuriousDragon(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { 619 return newCompatError("EIP155 chain ID", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock) 620 } 621 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { 622 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 623 } 624 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { 625 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 626 } 627 if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) { 628 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 629 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 630 if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) { 631 return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 632 } 633 } 634 if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) { 635 return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 636 } 637 if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) { 638 return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 639 } 640 if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) { 641 return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock) 642 } 643 if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) { 644 return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock) 645 } 646 if isForkIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, head) { 647 return newCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock) 648 } 649 if isForkIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, head) { 650 return newCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock) 651 } 652 if isForkIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, head) { 653 return newCompatError("Merge netsplit block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock) 654 } 655 if isForkIncompatible(c.ShanghaiBlock, newcfg.ShanghaiBlock, head) { 656 return newCompatError("Shanghai fork block", c.ShanghaiBlock, newcfg.ShanghaiBlock) 657 } 658 if isForkIncompatible(c.CancunBlock, newcfg.CancunBlock, head) { 659 return newCompatError("Cancun fork block", c.CancunBlock, newcfg.CancunBlock) 660 } 661 662 // Parlia forks 663 //if isForkIncompatible(c.RamanujanBlock, newcfg.RamanujanBlock, head) { 664 // return newCompatError("Ramanujan fork block", c.RamanujanBlock, newcfg.RamanujanBlock) 665 //} 666 //if isForkIncompatible(c.NielsBlock, newcfg.NielsBlock, head) { 667 // return newCompatError("Niels fork block", c.NielsBlock, newcfg.NielsBlock) 668 //} 669 //if isForkIncompatible(c.MirrorSyncBlock, newcfg.MirrorSyncBlock, head) { 670 // return newCompatError("MirrorSync fork block", c.MirrorSyncBlock, newcfg.MirrorSyncBlock) 671 //} 672 //if isForkIncompatible(c.BrunoBlock, newcfg.BrunoBlock, head) { 673 // return newCompatError("Bruno fork block", c.BrunoBlock, newcfg.BrunoBlock) 674 //} 675 //if isForkIncompatible(c.EulerBlock, newcfg.EulerBlock, head) { 676 // return newCompatError("Euler fork block", c.EulerBlock, newcfg.EulerBlock) 677 //} 678 //if isForkIncompatible(c.GibbsBlock, newcfg.GibbsBlock, head) { 679 // return newCompatError("Gibbs fork block", c.GibbsBlock, newcfg.GibbsBlock) 680 //} 681 //if isForkIncompatible(c.NanoBlock, newcfg.NanoBlock, head) { 682 // return newCompatError("Nano fork block", c.NanoBlock, newcfg.NanoBlock) 683 //} 684 //if isForkIncompatible(c.MoranBlock, newcfg.MoranBlock, head) { 685 // return newCompatError("moran fork block", c.MoranBlock, newcfg.MoranBlock) 686 //} 687 return nil 688 } 689 690 // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 691 // block s2 because head is already past the fork. 692 func isForkIncompatible(s1, s2 *big.Int, head uint64) bool { 693 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 694 } 695 696 // isForked returns whether a fork scheduled at block s is active at the given head block. 697 func isForked(s *big.Int, head uint64) bool { 698 if s == nil { 699 return false 700 } 701 return s.Uint64() <= head 702 } 703 704 func configNumEqual(x, y *big.Int) bool { 705 if x == nil { 706 return y == nil 707 } 708 if y == nil { 709 return x == nil 710 } 711 return x.Cmp(y) == 0 712 } 713 714 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 715 // ChainConfig that would alter the past. 716 type ConfigCompatError struct { 717 What string 718 // block numbers of the stored and new configurations 719 StoredConfig, NewConfig *big.Int 720 // the block number to which the local chain must be rewound to correct the error 721 RewindTo uint64 722 } 723 724 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 725 var rew *big.Int 726 switch { 727 case storedblock == nil: 728 rew = newblock 729 case newblock == nil || storedblock.Cmp(newblock) < 0: 730 rew = storedblock 731 default: 732 rew = newblock 733 } 734 err := &ConfigCompatError{what, storedblock, newblock, 0} 735 if rew != nil && rew.Sign() > 0 { 736 err.RewindTo = rew.Uint64() - 1 737 } 738 return err 739 } 740 741 func (err *ConfigCompatError) Error() string { 742 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 743 } 744 745 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 746 // that do not have or require information about the block. 747 // 748 // Rules is a one time interface meaning that it shouldn't be used in between transition 749 // phases. 750 type Rules struct { 751 ChainID *big.Int 752 IsHomestead, IsTangerineWhistle, IsSpuriousDragon bool 753 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 754 IsBerlin, IsLondon, IsShanghai, IsCancun, IsPrague bool 755 IsNano, IsMoran bool 756 IsEip1559FeeCollector bool 757 IsParlia, IsStarknet, IsAura, IsBeijing bool 758 } 759 760 // Rules ensures c's ChainID is not nil. 761 func (c *ChainConfig) Rules(num uint64) *Rules { 762 chainID := c.ChainID 763 if chainID == nil { 764 chainID = new(big.Int) 765 } 766 return &Rules{ 767 ChainID: new(big.Int).Set(chainID), 768 IsHomestead: c.IsHomestead(num), 769 IsTangerineWhistle: c.IsTangerineWhistle(num), 770 IsSpuriousDragon: c.IsSpuriousDragon(num), 771 IsByzantium: c.IsByzantium(num), 772 IsConstantinople: c.IsConstantinople(num), 773 IsPetersburg: c.IsPetersburg(num), 774 IsIstanbul: c.IsIstanbul(num), 775 IsBerlin: c.IsBerlin(num), 776 IsLondon: c.IsLondon(num), 777 IsShanghai: c.IsShanghai(num), 778 IsCancun: c.IsCancun(num), 779 IsPrague: c.IsPrague(num), 780 IsNano: c.IsNano(num), 781 IsMoran: c.IsMoran(num), 782 IsEip1559FeeCollector: c.IsEip1559FeeCollector(num), 783 IsParlia: c.Parlia != nil, 784 IsAura: c.Aura != nil, 785 IsBeijing: c.IsBeijing(num), 786 } 787 } 788 789 func ChainConfigByChainName(chain string) *ChainConfig { 790 switch chain { 791 case networkname.MainnetChainName: 792 return MainnetChainConfig 793 case networkname.TestnetChainName: 794 return TestnetChainConfig 795 default: 796 return nil 797 } 798 } 799 800 func GenesisHashByChainName(chain string) *types.Hash { 801 switch chain { 802 case networkname.MainnetChainName: 803 return &MainnetGenesisHash 804 case networkname.TestnetChainName: 805 return &TestnetGenesisHash 806 default: 807 return nil 808 } 809 } 810 811 func ChainConfigByGenesisHash(genesisHash types.Hash) *ChainConfig { 812 switch { 813 case genesisHash == MainnetGenesisHash: 814 return MainnetChainConfig 815 case genesisHash == TestnetGenesisHash: 816 return TestnetChainConfig 817 default: 818 return nil 819 } 820 } 821 822 func NetworkIDByChainName(chain string) uint64 { 823 switch chain { 824 case networkname.MainnetChainName: 825 return 97 826 case networkname.TestnetChainName: 827 return 100100100 828 default: 829 config := ChainConfigByChainName(chain) 830 if config == nil { 831 return 0 832 } 833 return config.ChainID.Uint64() 834 } 835 } 836 837 // TrustedCheckpoint represents a set of post-processed trie roots (CHT and 838 // BloomTrie) associated with the appropriate section index and head hash. It is 839 // used to start light syncing from this checkpoint and avoid downloading the 840 // entire header chain while still being able to securely access old headers/logs. 841 type TrustedCheckpoint struct { 842 SectionIndex uint64 `json:"sectionIndex"` 843 SectionHead types.Hash `json:"sectionHead"` 844 CHTRoot types.Hash `json:"chtRoot"` 845 BloomRoot types.Hash `json:"bloomRoot"` 846 } 847 848 // HashEqual returns an indicator comparing the itself hash with given one. 849 func (c *TrustedCheckpoint) HashEqual(hash types.Hash) bool { 850 if c.Empty() { 851 return hash == types.Hash{} 852 } 853 return c.Hash() == hash 854 } 855 856 // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot). 857 func (c *TrustedCheckpoint) Hash() types.Hash { 858 var sectionIndex [8]byte 859 binary.BigEndian.PutUint64(sectionIndex[:], c.SectionIndex) 860 861 w := sha3.NewLegacyKeccak256() 862 w.Write(sectionIndex[:]) 863 w.Write(c.SectionHead[:]) 864 w.Write(c.CHTRoot[:]) 865 w.Write(c.BloomRoot[:]) 866 867 var h types.Hash 868 w.Sum(h[:0]) 869 return h 870 } 871 872 // Empty returns an indicator whether the checkpoint is regarded as empty. 873 func (c *TrustedCheckpoint) Empty() bool { 874 return c.SectionHead == (types.Hash{}) || c.CHTRoot == (types.Hash{}) || c.BloomRoot == (types.Hash{}) 875 } 876 877 // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle) 878 // blockchain which used for light client checkpoint syncing. 879 type CheckpointOracleConfig struct { 880 Address types.Address `json:"address"` 881 Signers []types.Address `json:"signers"` 882 Threshold uint64 `json:"threshold"` 883 }