github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/genesis1.go (about) 1 package core 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "github.com/intfoundation/intchain/common" 7 "github.com/intfoundation/intchain/core/rawdb" 8 "github.com/intfoundation/intchain/core/types" 9 "github.com/intfoundation/intchain/intdb" 10 "github.com/intfoundation/intchain/log" 11 "github.com/intfoundation/intchain/params" 12 "io" 13 "io/ioutil" 14 ) 15 16 // WriteGenesisBlock writes the genesis block to the database as block number 0 17 func WriteGenesisBlock(chainDb intdb.Database, reader io.Reader) (*types.Block, error) { 18 contents, err := ioutil.ReadAll(reader) 19 if err != nil { 20 return nil, err 21 } 22 23 var genesis = Genesis{} 24 25 if err := json.Unmarshal(contents, &genesis); err != nil { 26 return nil, err 27 } 28 29 return SetupGenesisBlockEx(chainDb, &genesis) 30 } 31 32 func SetupGenesisBlockEx(db intdb.Database, genesis *Genesis) (*types.Block, error) { 33 34 if genesis != nil && genesis.Config == nil { 35 return nil, errGenesisNoConfig 36 } 37 38 var block *types.Block = nil 39 var err error = nil 40 41 // Just commit the new block if there is no stored genesis block. 42 stored := rawdb.ReadCanonicalHash(db, 0) 43 if (stored == common.Hash{}) { 44 if genesis == nil { 45 log.Info("Writing default main-net genesis block") 46 genesis = DefaultGenesisBlock() 47 } else { 48 log.Info("Writing custom genesis block") 49 } 50 block, err = genesis.Commit(db) 51 return block, err 52 } 53 54 // Check whether the genesis block is already written. 55 if genesis != nil { 56 block = genesis.ToBlock(nil) 57 hash := block.Hash() 58 if hash != stored { 59 return nil, &GenesisMismatchError{stored, hash} 60 } 61 } 62 63 // Get the existing chain configuration. 64 newcfg := genesis.configOrDefault(stored) 65 storedcfg := rawdb.ReadChainConfig(db, stored) 66 if storedcfg == nil { 67 log.Warn("Found genesis block without chain config") 68 rawdb.WriteChainConfig(db, stored, newcfg) 69 return block, err 70 } 71 // Special case: don't change the existing config of a non-mainnet chain if no new 72 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 73 // if we just continued here. 74 if genesis == nil && stored != params.MainnetGenesisHash { 75 return block, nil 76 } 77 78 // Check config compatibility and write the config. Compatibility errors 79 // are returned to the caller unless we're already at block zero. 80 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 81 if height == nil { 82 return nil, fmt.Errorf("missing block number for head header hash") 83 } 84 compatErr := storedcfg.CheckCompatible(newcfg, *height) 85 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 86 return nil, compatErr 87 } 88 return block, err 89 } 90 91 // SetupGenesisBlock writes or updates the genesis block in db. 92 // The block that will be used is: 93 // 94 // genesis == nil genesis != nil 95 // +------------------------------------------ 96 // db has no genesis | main-net default | genesis 97 // db has genesis | from DB | genesis (if compatible) 98 // 99 // The stored chain configuration will be updated if it is compatible (i.e. does not 100 // specify a fork block below the local head block). In case of a conflict, the 101 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 102 // 103 // The returned chain configuration is never nil. 104 func SetupGenesisBlockWithDefault(db intdb.Database, genesis *Genesis, isMainChain, isTestnet bool) (*params.ChainConfig, common.Hash, error) { 105 if genesis != nil && genesis.Config == nil { 106 return nil, common.Hash{}, errGenesisNoConfig 107 } 108 109 // Just commit the new block if there is no stored genesis block. 110 stored := rawdb.ReadCanonicalHash(db, 0) 111 if (stored == common.Hash{} && isMainChain) { 112 if genesis == nil { 113 log.Info("Writing default main-net genesis block") 114 if isTestnet { 115 genesis = DefaultGenesisBlockFromJson(DefaultTestnetGenesisJSON) 116 } else { 117 genesis = DefaultGenesisBlockFromJson(DefaultMainnetGenesisJSON) 118 } 119 } else { 120 log.Info("Writing custom genesis block") 121 } 122 block, err := genesis.Commit(db) 123 return genesis.Config, block.Hash(), err 124 } 125 126 // Check whether the genesis block is already written. 127 if genesis != nil { 128 hash := genesis.ToBlock(nil).Hash() 129 if hash != stored { 130 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 131 } 132 } 133 134 // Get the existing chain configuration. 135 newcfg := genesis.configOrDefault(stored) 136 storedcfg := rawdb.ReadChainConfig(db, stored) 137 if storedcfg == nil { 138 log.Warn("Found genesis block without chain config") 139 rawdb.WriteChainConfig(db, stored, newcfg) 140 return newcfg, stored, nil 141 } 142 // Special case: don't change the existing config of a non-mainnet chain if no new 143 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 144 // if we just continued here. 145 if genesis == nil && stored != params.MainnetGenesisHash { 146 return storedcfg, stored, nil 147 } 148 149 // Check config compatibility and write the config. Compatibility errors 150 // are returned to the caller unless we're already at block zero. 151 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 152 if height == nil { 153 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 154 } 155 compatErr := storedcfg.CheckCompatible(newcfg, *height) 156 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 157 return newcfg, stored, compatErr 158 } 159 rawdb.WriteChainConfig(db, stored, newcfg) 160 return newcfg, stored, nil 161 } 162 163 // DefaultGenesisBlock returns the INT Chain main net genesis block. 164 func DefaultGenesisBlockFromJson(genesisJson string) *Genesis { 165 166 var genesis = Genesis{} 167 168 if err := json.Unmarshal([]byte(genesisJson), &genesis); err != nil { 169 return nil 170 } 171 172 return &genesis 173 } 174 175 var DefaultMainnetGenesisJSON = `{ 176 "config": { 177 "intChainId": "intchain", 178 "chainId": 2047, 179 "homesteadBlock": 0, 180 "eip150Block": 0, 181 "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 182 "eip155Block": 0, 183 "eip158Block": 0, 184 "byzantiumBlock": 0, 185 "constantinopleBlock": 0, 186 "petersburgBlock": 0, 187 "istanbulBlock": 0, 188 "ipbft": { 189 "epoch": 30000, 190 "policy": 0 191 } 192 }, 193 "nonce": "0x0", 194 "timestamp": "0x611cde5c", 195 "extraData": "0x", 196 "gasLimit": "0x5f5e100", 197 "difficulty": "0x1", 198 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 199 "coinbase": "0x0000000000000000000000000000000000000000", 200 "alloc": { 201 "e00026f798c36ed24cc946474f92494de800c6c9": { 202 "balance": "0x2e7a2a7a739a67c63000000", 203 "amount": "0xd3c21bcecceda1000000" 204 } 205 }, 206 "number": "0x0", 207 "gasUsed": "0x0", 208 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 209 }` 210 211 var DefaultTestnetGenesisJSON = `{ 212 "config": { 213 "intChainId": "testnet", 214 "chainId": 2048, 215 "homesteadBlock": 0, 216 "eip150Block": 0, 217 "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 218 "eip155Block": 0, 219 "eip158Block": 0, 220 "byzantiumBlock": 0, 221 "constantinopleBlock": 0, 222 "petersburgBlock": 0, 223 "istanbulBlock": 0, 224 "ipbft": { 225 "epoch": 30000, 226 "policy": 0 227 } 228 }, 229 "nonce": "0x0", 230 "timestamp": "0x6119cecb", 231 "extraData": "0x", 232 "gasLimit": "0x5f5e100", 233 "difficulty": "0x1", 234 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 235 "coinbase": "0x0000000000000000000000000000000000000000", 236 "alloc": { 237 "0d3a15f869e4c50d59154ad1bc1b11702673b394": { 238 "balance": "0x2e7a2a7a739a67c63000000", 239 "amount": "0xd3c21bcecceda1000000" 240 } 241 }, 242 "number": "0x0", 243 "gasUsed": "0x0", 244 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 245 } 246 `