github.com/aquanetwork/aquachain@v1.7.8/params/config.go (about) 1 // Copyright 2016 The aquachain Authors 2 // This file is part of the aquachain library. 3 // 4 // The aquachain 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 aquachain 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 aquachain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package params 18 19 import ( 20 "fmt" 21 "math/big" 22 23 "gitlab.com/aquachain/aquachain/common" 24 ) 25 26 var ( 27 MainnetGenesisHash = common.HexToHash("0x381c8d2c3e3bc702533ee504d7621d510339cafd830028337a4b532ff27cd505") // Mainnet genesis hash to enforce below configs on 28 TestnetGenesisHash = common.HexToHash("0xa8773cb7d32b8f7e1b32b0c2c8b735c293b8936dd3760c15afc291a23eb0cf88") // Testnet genesis hash to enforce below configs on 29 Testnet2GenesisHash = common.HexToHash("0xde434983d3ada19cd43c44d8ad5511bad01ed12b3cc9a99b1717449a245120df") // Testnet2 genesis hash to enforce below configs on 30 ) 31 32 const KnownHF = 9 33 34 var ( 35 AquachainHF = ForkMap{ 36 0: big.NewInt(3000), // HF0 37 1: big.NewInt(3600), // increase min difficulty to the next multiple of 2048 38 2: big.NewInt(7200), // use simple difficulty algo (240 seconds) 39 3: big.NewInt(13026), // increase min difficulty for anticipation of gpu mining 40 4: big.NewInt(21800), // HF4 41 5: big.NewInt(22800), // HF5 argonated (argon2id) 42 6: big.NewInt(36000), // HF6 divisor increase 43 7: big.NewInt(36050), // eip 155, 158 44 } 45 46 // TestnetHF ... 47 TestnetHF = ForkMap{ 48 0: big.NewInt(0), // hf0 had no changes 49 1: big.NewInt(1), // increase min difficulty to the next multiple of 2048 50 2: big.NewInt(2), // use simple difficulty algo (240 seconds) 51 3: big.NewInt(3), // increase min difficulty for anticipation of gpu mining 52 4: big.NewInt(4), // HF4 53 5: big.NewInt(5), // HF5 54 6: big.NewInt(6), // noop in testnet 55 7: big.NewInt(25), // eip 155, 158 56 8: big.NewInt(650), // HF8 57 } 58 59 // Testnet2HF for -testnet2 private network 60 Testnet2HF = ForkMap{ 61 5: big.NewInt(0), 62 6: big.NewInt(0), 63 7: big.NewInt(0), 64 8: big.NewInt(8), 65 9: big.NewInt(19), 66 } 67 68 // TestHF for test suite 69 TestHF = ForkMap{ 70 0: big.NewInt(0), // hf0 had no changes 71 //1: big.NewInt(0), // increase min difficulty to the next multiple of 2048 72 //2: big.NewInt(10), 73 //3: big.NewInt(11), 74 4: big.NewInt(12), 75 5: big.NewInt(13), 76 //6: big.NewInt(14), 77 7: big.NewInt(30), 78 } 79 ) 80 var ( 81 // MainnetChainConfig is the chain parameters to run a node on the main network. 82 MainnetChainConfig = &ChainConfig{ 83 ChainId: big.NewInt(61717561), 84 HomesteadBlock: big.NewInt(0), 85 EIP150Block: big.NewInt(0), 86 EIP155Block: AquachainHF[7], 87 EIP158Block: AquachainHF[7], 88 ByzantiumBlock: AquachainHF[7], 89 Aquahash: new(AquahashConfig), 90 HF: AquachainHF, 91 } 92 93 // TestnetChainConfig contains the chain parameters to run a node on the Aquachain test network. 94 TestnetChainConfig = &ChainConfig{ 95 ChainId: big.NewInt(3), 96 HomesteadBlock: big.NewInt(0), 97 EIP150Block: big.NewInt(0), 98 EIP155Block: TestnetHF[7], 99 EIP158Block: TestnetHF[7], 100 ByzantiumBlock: TestnetHF[7], 101 Aquahash: new(AquahashConfig), 102 HF: TestnetHF, 103 } 104 105 // Testnet2ChainConfig contains the chain parameters to run a node on the Testnet2 test network. 106 Testnet2ChainConfig = &ChainConfig{ 107 ChainId: big.NewInt(4096), 108 HomesteadBlock: big.NewInt(0), 109 EIP150Block: big.NewInt(0), 110 EIP155Block: Testnet2HF[7], 111 EIP158Block: Testnet2HF[7], 112 ByzantiumBlock: Testnet2HF[7], 113 Aquahash: new(AquahashConfig), 114 HF: Testnet2HF, 115 } 116 117 // AllAquahashProtocolChanges contains every protocol change (EIPs) introduced 118 // and accepted by the AquaChain core developers into the Aquahash consensus. 119 // 120 // This configuration is intentionally not using keyed fields to force anyone 121 // adding flags to the config to also have to set these fields. 122 AllAquahashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(AquahashConfig), TestHF} 123 124 TestChainConfig = &ChainConfig{big.NewInt(3), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(AquahashConfig), TestHF} 125 TestRules = TestChainConfig.Rules(new(big.Int)) 126 ) 127 128 // ChainConfig is the core config which determines the blockchain settings. 129 // 130 // ChainConfig is stored in the database on a per block basis. This means 131 // that any network, identified by its genesis block, can have its own 132 // set of configuration options. 133 type ChainConfig struct { 134 ChainId *big.Int `json:"chainId"` // Chain id identifies the current chain and is used for replay protection 135 136 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 137 138 // et junk to remove 139 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) 140 DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork 141 142 // EIP150 implements the Gas price changes (https://github.com/aquanetwork/EIPs/issues/150) 143 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 144 EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) 145 146 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 147 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 148 149 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 150 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 151 152 // Various consensus engines 153 Aquahash *AquahashConfig `json:"aquahash,omitempty"` 154 155 // HF Scheduled Maintenance Hardforks 156 HF ForkMap `json:"hf,omitempty"` 157 } 158 159 // AquahashConfig is the consensus engine configs for proof-of-work based sealing. 160 type AquahashConfig struct{} 161 162 // String implements the stringer interface, returning the consensus engine details. 163 func (c *AquahashConfig) String() string { 164 return "aquahash" 165 } 166 167 // String implements the fmt.Stringer interface. 168 func (c *ChainConfig) String() string { 169 var engine interface{} 170 switch { 171 case c.Aquahash != nil: 172 engine = c.Aquahash 173 default: 174 engine = "unknown" 175 } 176 return fmt.Sprintf("{ChainID: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Engine: %v}", 177 c.ChainId, 178 c.EIP150Block, 179 c.EIP155Block, 180 c.EIP158Block, 181 c.ByzantiumBlock, 182 engine, 183 ) 184 } 185 186 // IsHomestead returns whether num is either equal to the homestead block or greater. 187 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 188 return isForked(c.HomesteadBlock, num) 189 } 190 191 // IsDAO returns whether num is either equal to the DAO fork block or greater. 192 func (c *ChainConfig) IsDAOFork(num *big.Int) bool { 193 return isForked(c.DAOForkBlock, num) 194 } 195 196 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 197 return isForked(c.EIP150Block, num) 198 } 199 200 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 201 return isForked(c.EIP155Block, num) 202 } 203 204 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 205 return isForked(c.EIP158Block, num) 206 } 207 208 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 209 return isForked(c.ByzantiumBlock, num) 210 } 211 212 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 213 return isForked(c.ConstantinopleBlock, num) 214 } 215 216 // GasTable returns the gas table corresponding to the current phase. 217 // 218 // The returned GasTable's fields shouldn't, under any circumstances, be changed. 219 func (c *ChainConfig) GasTable(num *big.Int) GasTable { 220 if num == nil { 221 return GasTableHomestead 222 } 223 switch { 224 case c.IsHF(1, num): 225 return GasTableHF1 226 default: 227 return GasTableHomestead 228 } 229 } 230 231 // CheckCompatible checks whether scheduled fork transitions have been imported 232 // with a mismatching chain configuration. 233 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 234 bhead := new(big.Int).SetUint64(height) 235 236 // Iterate checkCompatible to find the lowest conflict. 237 var lasterr *ConfigCompatError 238 for { 239 err := c.checkCompatible(newcfg, bhead) 240 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 241 break 242 } 243 lasterr = err 244 bhead.SetUint64(err.RewindTo) 245 } 246 return lasterr 247 } 248 249 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { 250 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { 251 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 252 } 253 if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { 254 return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 255 } 256 if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { 257 return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 258 } 259 if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { 260 return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 261 } 262 if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { 263 return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 264 } 265 if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { 266 return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 267 } 268 if c.IsEIP158(head) && !configNumEqual(c.ChainId, newcfg.ChainId) { 269 return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 270 } 271 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { 272 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 273 } 274 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { 275 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 276 } 277 return nil 278 } 279 280 // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 281 // block s2 because head is already past the fork. 282 func isForkIncompatible(s1, s2, head *big.Int) bool { 283 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 284 } 285 286 // isForked returns whether a fork scheduled at block s is active at the given head block. 287 func isForked(s, head *big.Int) bool { 288 if s == nil || head == nil { 289 return false 290 } 291 return s.Cmp(head) <= 0 292 } 293 294 func configNumEqual(x, y *big.Int) bool { 295 if x == nil { 296 return y == nil 297 } 298 if y == nil { 299 return x == nil 300 } 301 return x.Cmp(y) == 0 302 } 303 304 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 305 // ChainConfig that would alter the past. 306 type ConfigCompatError struct { 307 What string 308 // block numbers of the stored and new configurations 309 StoredConfig, NewConfig *big.Int 310 // the block number to which the local chain must be rewound to correct the error 311 RewindTo uint64 312 } 313 314 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 315 var rew *big.Int 316 switch { 317 case storedblock == nil: 318 rew = newblock 319 case newblock == nil || storedblock.Cmp(newblock) < 0: 320 rew = storedblock 321 default: 322 rew = newblock 323 } 324 err := &ConfigCompatError{what, storedblock, newblock, 0} 325 if rew != nil && rew.Sign() > 0 { 326 err.RewindTo = rew.Uint64() - 1 327 } 328 return err 329 } 330 331 func (err *ConfigCompatError) Error() string { 332 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 333 } 334 335 // Rules wraps ChainConfig and is merely syntatic sugar or can be used for functions 336 // that do not have or require information about the block. 337 // 338 // Rules is a one time interface meaning that it shouldn't be used in between transition 339 // phases. 340 type Rules struct { 341 ChainId *big.Int 342 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 343 IsByzantium bool 344 } 345 346 func (c *ChainConfig) Rules(num *big.Int) Rules { 347 chainId := c.ChainId 348 if chainId == nil { 349 chainId = new(big.Int) 350 } 351 return Rules{ChainId: new(big.Int).Set(chainId), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsByzantium: c.IsByzantium(num)} 352 }