github.com/Gessiux/neatchain@v1.3.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/Gessiux/neatchain/chain/log" 24 25 "github.com/Gessiux/neatchain/utilities/common" 26 "github.com/Gessiux/neatchain/utilities/crypto" 27 ) 28 29 var ( 30 MainnetGenesisHash = common.HexToHash("0xb8ec7179904a79bd642b43355ec5e3180fdf76724870f23b1adfda6a993cb5c8") // Mainnet genesis hash to enforce below configs on 31 TestnetGenesisHash = common.HexToHash("0x1cbef527b5e69640b795df3b76437741e7fd4c98be557c6ead9be5f38ae7febc") // Testnet genesis hash to enforce below configs on 32 ) 33 34 var ( 35 // MainnetChainConfig is the chain parameters to run a node on the main network. 36 MainnetChainConfig = &ChainConfig{ 37 NeatChainId: "neatchain", 38 ChainId: big.NewInt(1), 39 HomesteadBlock: big.NewInt(0), 40 EIP150Block: big.NewInt(0), 41 EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), 42 EIP155Block: big.NewInt(0), 43 EIP158Block: big.NewInt(0), 44 ByzantiumBlock: big.NewInt(0), //let's start from 1 block 45 ConstantinopleBlock: nil, 46 NeatCon: &NeatConConfig{ 47 Epoch: 30000, 48 ProposerPolicy: 0, 49 }, 50 } 51 52 // TestnetChainConfig contains the chain parameters to run a node on the test network. 53 TestnetChainConfig = &ChainConfig{ 54 NeatChainId: "testnet", 55 ChainId: big.NewInt(2), 56 HomesteadBlock: big.NewInt(0), 57 EIP150Block: big.NewInt(0), 58 EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), 59 EIP155Block: big.NewInt(0), 60 EIP158Block: big.NewInt(0), 61 ByzantiumBlock: big.NewInt(0), 62 ConstantinopleBlock: nil, 63 NeatCon: &NeatConConfig{ 64 Epoch: 30000, 65 ProposerPolicy: 0, 66 }, 67 } 68 69 TestChainConfig = &ChainConfig{"", big.NewInt(1), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil} 70 TestRules = TestChainConfig.Rules(new(big.Int)) 71 ) 72 73 func init() { 74 //digest := crypto.Keccak256([]byte(MainnetChainConfig.NeatChainId)) 75 //MainnetChainConfig.ChainId = new(big.Int).SetBytes(digest[:]) 76 //MainnetChainConfig.ChainId = new(big.Int).SetUint64(1) 77 } 78 79 // ChainConfig is the core config which determines the blockchain settings. 80 // 81 // ChainConfig is stored in the database on a per block basis. This means 82 // that any network, identified by its genesis block, can have its own 83 // set of configuration options. 84 type ChainConfig struct { 85 NeatChainId string `json:"NeatChainId"` //NeatChain id identifies the current chain 86 ChainId *big.Int `json:"chainId"` // Chain id identifies the current chain and is used for replay protection 87 88 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 89 90 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 91 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 92 EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) 93 94 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 95 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 96 97 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 98 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 99 100 // Various consensus engines 101 NeatCon *NeatConConfig `json:"neatcon,omitempty"` 102 103 ChainLogger log.Logger `json:"-"` 104 } 105 106 // NeatConConfig is the consensus engine configs for Istanbul based sealing. 107 type NeatConConfig struct { 108 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 109 ProposerPolicy uint64 `json:"policy"` // The policy for proposer selection 110 } 111 112 // String implements the stringer interface, returning the consensus engine details. 113 func (c *NeatConConfig) String() string { 114 return "neatcon" 115 } 116 117 // Create a new Chain Config based on the Chain ID, for side chain creation purpose 118 func NewSideChainConfig(sideChainID string) *ChainConfig { 119 config := &ChainConfig{ 120 NeatChainId: sideChainID, 121 HomesteadBlock: big.NewInt(0), 122 EIP150Block: big.NewInt(0), 123 EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), 124 EIP155Block: big.NewInt(0), 125 EIP158Block: big.NewInt(0), 126 //ByzantiumBlock: big.NewInt(4370000), 127 ByzantiumBlock: big.NewInt(0), //let's start from 1 block 128 ConstantinopleBlock: nil, 129 NeatCon: &NeatConConfig{ 130 Epoch: 30000, 131 ProposerPolicy: 0, 132 }, 133 } 134 135 digest := crypto.Keccak256([]byte(config.NeatChainId)) 136 config.ChainId = new(big.Int).SetBytes(digest[:]) 137 138 return config 139 } 140 141 // String implements the fmt.Stringer interface. 142 func (c *ChainConfig) String() string { 143 var engine interface{} 144 switch { 145 case c.NeatCon != nil: 146 engine = c.NeatCon 147 default: 148 engine = "unknown" 149 } 150 return fmt.Sprintf("{NeatChainId: %s ChainID: %v Homestead: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Engine: %v}", 151 c.NeatChainId, 152 c.ChainId, 153 c.HomesteadBlock, 154 c.EIP150Block, 155 c.EIP155Block, 156 c.EIP158Block, 157 c.ByzantiumBlock, 158 c.ConstantinopleBlock, 159 engine, 160 ) 161 } 162 163 // IsHomestead returns whether num is either equal to the homestead block or greater. 164 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 165 return isForked(c.HomesteadBlock, num) 166 } 167 168 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 169 return isForked(c.EIP150Block, num) 170 } 171 172 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 173 return isForked(c.EIP155Block, num) 174 } 175 176 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 177 return isForked(c.EIP158Block, num) 178 } 179 180 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 181 return isForked(c.ByzantiumBlock, num) 182 } 183 184 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 185 return isForked(c.ConstantinopleBlock, num) 186 } 187 188 func (c *ChainConfig) IsEWASM(num *big.Int) bool { 189 return false 190 } 191 192 // Check whether is on main chain or not 193 func (c *ChainConfig) IsMainChain() bool { 194 return c.NeatChainId == MainnetChainConfig.NeatChainId || c.NeatChainId == TestnetChainConfig.NeatChainId 195 } 196 197 // Check provided chain id is on main chain or not 198 func IsMainChain(chainId string) bool { 199 return chainId == MainnetChainConfig.NeatChainId || chainId == TestnetChainConfig.NeatChainId 200 } 201 202 // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice). 203 // 204 // The returned GasTable's fields shouldn't, under any circumstances, be changed. 205 func (c *ChainConfig) GasTable(num *big.Int) GasTable { 206 if num == nil { 207 return GasTableHomestead 208 } 209 switch { 210 case c.IsEIP158(num): 211 return GasTableEIP158 212 case c.IsEIP150(num): 213 return GasTableEIP150 214 default: 215 return GasTableHomestead 216 } 217 } 218 219 // CheckCompatible checks whether scheduled fork transitions have been imported 220 // with a mismatching chain configuration. 221 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 222 bhead := new(big.Int).SetUint64(height) 223 224 // Iterate checkCompatible to find the lowest conflict. 225 var lasterr *ConfigCompatError 226 for { 227 err := c.checkCompatible(newcfg, bhead) 228 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 229 break 230 } 231 lasterr = err 232 bhead.SetUint64(err.RewindTo) 233 } 234 return lasterr 235 } 236 237 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { 238 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { 239 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 240 } 241 if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { 242 return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 243 } 244 if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { 245 return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 246 } 247 if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { 248 return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 249 } 250 if c.IsEIP158(head) && !configNumEqual(c.ChainId, newcfg.ChainId) { 251 return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 252 } 253 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { 254 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 255 } 256 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { 257 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 258 } 259 return nil 260 } 261 262 // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 263 // block s2 because head is already past the fork. 264 func isForkIncompatible(s1, s2, head *big.Int) bool { 265 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 266 } 267 268 // isForked returns whether a fork scheduled at block s is active at the given head block. 269 func isForked(s, head *big.Int) bool { 270 if s == nil || head == nil { 271 return false 272 } 273 return s.Cmp(head) <= 0 274 } 275 276 func configNumEqual(x, y *big.Int) bool { 277 if x == nil { 278 return y == nil 279 } 280 if y == nil { 281 return x == nil 282 } 283 return x.Cmp(y) == 0 284 } 285 286 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 287 // ChainConfig that would alter the past. 288 type ConfigCompatError struct { 289 What string 290 // block numbers of the stored and new configurations 291 StoredConfig, NewConfig *big.Int 292 // the block number to which the local chain must be rewound to correct the error 293 RewindTo uint64 294 } 295 296 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 297 var rew *big.Int 298 switch { 299 case storedblock == nil: 300 rew = newblock 301 case newblock == nil || storedblock.Cmp(newblock) < 0: 302 rew = storedblock 303 default: 304 rew = newblock 305 } 306 err := &ConfigCompatError{what, storedblock, newblock, 0} 307 if rew != nil && rew.Sign() > 0 { 308 err.RewindTo = rew.Uint64() - 1 309 } 310 return err 311 } 312 313 func (err *ConfigCompatError) Error() string { 314 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 315 } 316 317 // Rules wraps ChainConfig and is merely syntatic sugar or can be used for functions 318 // that do not have or require information about the block. 319 // 320 // Rules is a one time interface meaning that it shouldn't be used in between transition 321 // phases. 322 type Rules struct { 323 ChainId *big.Int 324 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 325 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 326 } 327 328 func (c *ChainConfig) Rules(num *big.Int) Rules { 329 chainId := c.ChainId 330 if chainId == nil { 331 chainId = new(big.Int) 332 } 333 return Rules{ 334 ChainId: new(big.Int).Set(chainId), 335 IsHomestead: c.IsHomestead(num), 336 IsEIP150: c.IsEIP150(num), 337 IsEIP155: c.IsEIP155(num), 338 IsEIP158: c.IsEIP158(num), 339 IsByzantium: c.IsByzantium(num), 340 IsConstantinople: false, 341 IsPetersburg: false, 342 IsIstanbul: false, 343 } 344 }