github.com/core-coin/go-core/v2@v2.1.9/params/config.go (about) 1 // Copyright 2016 by the Authors 2 // This file is part of the go-core library. 3 // 4 // The go-core 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-core 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-core library. If not, see <http://www.gnu.org/licenses/>. 16 17 package params 18 19 import ( 20 "encoding/binary" 21 "fmt" 22 "math/big" 23 24 "github.com/core-coin/go-core/v2/common" 25 "github.com/core-coin/go-core/v2/crypto" 26 ) 27 28 // Genesis hashes to enforce below configs on. 29 var ( 30 MainnetGenesisHash = common.HexToHash("0xacecc18e30188588d4932a29df096198bbbe01a955f05ecd32489a7740a9a13b") 31 DevinGenesisHash = common.HexToHash("0x2a92b248f5843827cbbd5045161cd6f294a154505ee1a14b607a2c26ffc6fddf") 32 ) 33 34 // TrustedCheckpoints associates each known checkpoint with the genesis hash of 35 // the chain it belongs to. 36 var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{ 37 MainnetGenesisHash: MainnetTrustedCheckpoint, 38 DevinGenesisHash: DevinTrustedCheckpoint, 39 } 40 41 // CheckpointOracles associates each known checkpoint oracles with the genesis hash of 42 // the chain it belongs to. 43 var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{ 44 MainnetGenesisHash: MainnetCheckpointOracle, 45 DevinGenesisHash: DevinCheckpointOracle, 46 } 47 48 var ( 49 // MainnetChainConfig is the chain parameters to run a node on the main network. 50 MainnetChainConfig = &ChainConfig{ 51 NetworkID: big.NewInt(1), 52 Cryptore: new(CryptoreConfig), 53 } 54 55 // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. 56 MainnetTrustedCheckpoint = &TrustedCheckpoint{ 57 SectionIndex: 137, 58 SectionHead: common.HexToHash("0x9c6c7bb3b600e9d27725101a965d33bd9f6f7260307b252866de7d793ece66ab"), 59 CHTRoot: common.HexToHash("0x5e861527c64be9813c3f1521f45c42c74345b68f5d8585d778695836dede3c48"), 60 BloomRoot: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), 61 } 62 // MainnetCheckpointOracle contains a set of configs for the main network oracle. 63 MainnetCheckpointOracle = &CheckpointOracleConfig{ 64 Address: common.Address{}, 65 Signers: []common.Address{}, 66 Threshold: 2, 67 } 68 69 // DevinChainConfig contains the chain parameters to run a node on the Devin test network. 70 DevinChainConfig = &ChainConfig{ 71 NetworkID: big.NewInt(3), 72 Cryptore: new(CryptoreConfig), 73 } 74 75 // DevinTrustedCheckpoint contains the light client trusted checkpoint for the Devin test network. 76 DevinTrustedCheckpoint = &TrustedCheckpoint{ 77 SectionIndex: 0, 78 SectionHead: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), 79 CHTRoot: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), 80 BloomRoot: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), 81 } 82 83 // DevinCheckpointOracle contains a set of configs for the Devin test network oracle. 84 DevinCheckpointOracle = &CheckpointOracleConfig{ 85 Address: common.Address{}, 86 Signers: []common.Address{}, 87 Threshold: 2, 88 } 89 90 // AllCliqueProtocolChanges contains every protocol change (CIPs) introduced 91 // and accepted by the Core core developers into the Clique consensus. 92 // 93 // This configuration is intentionally not using keyed fields to force anyone 94 // adding flags to the config to also have to set these fields. 95 AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} 96 97 TestChainConfig = &ChainConfig{big.NewInt(1337), nil, new(CryptoreConfig), nil} 98 ) 99 100 // TrustedCheckpoint represents a set of post-processed trie roots (CHT and 101 // BloomTrie) associated with the appropriate section index and head hash. It is 102 // used to start light syncing from this checkpoint and avoid downloading the 103 // entire header chain while still being able to securely access old headers/logs. 104 type TrustedCheckpoint struct { 105 SectionIndex uint64 `json:"sectionIndex"` 106 SectionHead common.Hash `json:"sectionHead"` 107 CHTRoot common.Hash `json:"chtRoot"` 108 BloomRoot common.Hash `json:"bloomRoot"` 109 } 110 111 // HashEqual returns an indicator comparing the itself hash with given one. 112 func (c *TrustedCheckpoint) HashEqual(hash common.Hash) bool { 113 if c.Empty() { 114 return hash == common.Hash{} 115 } 116 return c.Hash() == hash 117 } 118 119 // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot). 120 func (c *TrustedCheckpoint) Hash() common.Hash { 121 buf := make([]byte, 8+3*common.HashLength) 122 binary.BigEndian.PutUint64(buf, c.SectionIndex) 123 copy(buf[8:], c.SectionHead.Bytes()) 124 copy(buf[8+common.HashLength:], c.CHTRoot.Bytes()) 125 copy(buf[8+2*common.HashLength:], c.BloomRoot.Bytes()) 126 return crypto.SHA3Hash(buf) 127 } 128 129 // Empty returns an indicator whether the checkpoint is regarded as empty. 130 func (c *TrustedCheckpoint) Empty() bool { 131 return c.SectionHead == (common.Hash{}) || c.CHTRoot == (common.Hash{}) || c.BloomRoot == (common.Hash{}) 132 } 133 134 // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle) 135 // config which used for light client checkpoint syncing. 136 type CheckpointOracleConfig struct { 137 Address common.Address `json:"address"` 138 Signers []common.Address `json:"signers"` 139 Threshold uint64 `json:"threshold"` 140 } 141 142 // ChainConfig is the core config which determines the blockchain settings. 143 // 144 // ChainConfig is stored in the database on a per block basis. This means 145 // that any network, identified by its genesis block, can have its own 146 // set of configuration options. 147 type ChainConfig struct { 148 NetworkID *big.Int `json:"networkId"` // networkId identifies the current chain and is used for replay protection 149 150 EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) 151 152 // Various consensus engines 153 Cryptore *CryptoreConfig `json:"cryptore,omitempty"` 154 Clique *CliqueConfig `json:"clique,omitempty"` 155 } 156 157 // CryptoreConfig is the consensus engine configs for proof-of-work based sealing. 158 type CryptoreConfig struct{} 159 160 // String implements the stringer interface, returning the consensus engine details. 161 func (c *CryptoreConfig) String() string { 162 return "cryptore" 163 } 164 165 // CliqueConfig is the consensus engine configs for proof-of-authority based sealing. 166 type CliqueConfig struct { 167 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 168 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 169 } 170 171 // String implements the stringer interface, returning the consensus engine details. 172 func (c *CliqueConfig) String() string { 173 return "clique" 174 } 175 176 // String implements the fmt.Stringer interface. 177 func (c *ChainConfig) String() string { 178 var engine interface{} 179 switch { 180 case c.Cryptore != nil: 181 engine = c.Cryptore 182 case c.Clique != nil: 183 engine = c.Clique 184 default: 185 engine = "unknown" 186 } 187 return fmt.Sprintf("{NetworkID: %v, Engine: %v}", 188 c.NetworkID, 189 engine, 190 ) 191 } 192 193 // IsEWASM returns whether num represents a block number after the EWASM fork 194 func (c *ChainConfig) IsEWASM(num *big.Int) bool { 195 return isForked(c.EWASMBlock, num) 196 } 197 198 // CheckCompatible checks whether scheduled fork transitions have been imported 199 // with a mismatching chain configuration. 200 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 201 bhead := new(big.Int).SetUint64(height) 202 203 // Iterate checkCompatible to find the lowest conflict. 204 var lasterr *ConfigCompatError 205 for { 206 err := c.checkCompatible(newcfg, bhead) 207 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 208 break 209 } 210 lasterr = err 211 bhead.SetUint64(err.RewindTo) 212 } 213 return lasterr 214 } 215 216 // CheckConfigForkOrder checks that we don't "skip" any forks, gocore isn't pluggable enough 217 // to guarantee that forks can be implemented in a different order than on official networks 218 func (c *ChainConfig) CheckConfigForkOrder() error { 219 type fork struct { 220 name string 221 block *big.Int 222 optional bool // if true, the fork may be nil and next fork is still allowed 223 } 224 var lastFork fork 225 for _, cur := range []fork{} { 226 if lastFork.name != "" { 227 // Next one must be higher number 228 if lastFork.block == nil && cur.block != nil { 229 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 230 lastFork.name, cur.name, cur.block) 231 } 232 if lastFork.block != nil && cur.block != nil { 233 if lastFork.block.Cmp(cur.block) > 0 { 234 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 235 lastFork.name, lastFork.block, cur.name, cur.block) 236 } 237 } 238 } 239 // If it was optional and not set, then ignore it 240 if !cur.optional || cur.block != nil { 241 lastFork = cur 242 } 243 } 244 return nil 245 } 246 247 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { 248 if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { 249 return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) 250 } 251 return nil 252 } 253 254 // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 255 // block s2 because head is already past the fork. 256 func isForkIncompatible(s1, s2, head *big.Int) bool { 257 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 258 } 259 260 // isForked returns whether a fork scheduled at block s is active at the given head block. 261 func isForked(s, head *big.Int) bool { 262 if s == nil || head == nil { 263 return false 264 } 265 return s.Cmp(head) <= 0 266 } 267 268 func configNumEqual(x, y *big.Int) bool { 269 if x == nil { 270 return y == nil 271 } 272 if y == nil { 273 return x == nil 274 } 275 return x.Cmp(y) == 0 276 } 277 278 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 279 // ChainConfig that would alter the past. 280 type ConfigCompatError struct { 281 What string 282 // block numbers of the stored and new configurations 283 StoredConfig, NewConfig *big.Int 284 // the block number to which the local chain must be rewound to correct the error 285 RewindTo uint64 286 } 287 288 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 289 var rew *big.Int 290 switch { 291 case storedblock == nil: 292 rew = newblock 293 case newblock == nil || storedblock.Cmp(newblock) < 0: 294 rew = storedblock 295 default: 296 rew = newblock 297 } 298 err := &ConfigCompatError{what, storedblock, newblock, 0} 299 if rew != nil && rew.Sign() > 0 { 300 err.RewindTo = rew.Uint64() - 1 301 } 302 return err 303 } 304 305 func (err *ConfigCompatError) Error() string { 306 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 307 } 308 309 var ( 310 ZeroNetworkIDTxHash = common.HexToHash("0x4da048016efe74bce5fdee20897f55cdec66308bc2b6e326f2fbbaf18edcaa6f") 311 )