github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/neat_genesis.go (about) 1 package core 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "io/ioutil" 8 9 "github.com/neatlab/neatio/chain/core/rawdb" 10 "github.com/neatlab/neatio/chain/core/types" 11 "github.com/neatlab/neatio/chain/log" 12 "github.com/neatlab/neatio/neatdb" 13 "github.com/neatlab/neatio/params" 14 "github.com/neatlab/neatio/utilities/common" 15 ) 16 17 func WriteGenesisBlock(chainDb neatdb.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 ( 24 genesis Genesis 25 genesisW GenesisWrite 26 ) 27 28 genesis.Alloc = GenesisAlloc{} 29 30 if err := json.Unmarshal(contents, &genesisW); err != nil { 31 return nil, err 32 } 33 34 genesis = Genesis{ 35 Config: genesisW.Config, 36 Nonce: genesisW.Nonce, 37 Timestamp: genesisW.Timestamp, 38 ParentHash: genesisW.ParentHash, 39 ExtraData: genesisW.ExtraData, 40 GasLimit: genesisW.GasLimit, 41 Difficulty: genesisW.Difficulty, 42 Mixhash: genesisW.Mixhash, 43 Coinbase: common.HexToAddress(genesisW.Coinbase), 44 Alloc: GenesisAlloc{}, 45 } 46 47 for k, v := range genesisW.Alloc { 48 genesis.Alloc[common.HexToAddress(k)] = v 49 } 50 51 return SetupGenesisBlockEx(chainDb, &genesis) 52 } 53 54 func SetupGenesisBlockEx(db neatdb.Database, genesis *Genesis) (*types.Block, error) { 55 56 if genesis != nil && genesis.Config == nil { 57 return nil, errGenesisNoConfig 58 } 59 60 var block *types.Block = nil 61 var err error = nil 62 63 stored := rawdb.ReadCanonicalHash(db, 0) 64 if (stored == common.Hash{}) { 65 if genesis == nil { 66 log.Info("Writing default main-net genesis block") 67 genesis = DefaultGenesisBlock() 68 } else { 69 log.Info("Writing custom genesis block") 70 } 71 block, err = genesis.Commit(db) 72 return block, err 73 } 74 75 if genesis != nil { 76 block = genesis.ToBlock(nil) 77 hash := block.Hash() 78 if hash != stored { 79 return nil, &GenesisMismatchError{stored, hash} 80 } 81 } 82 83 newcfg := genesis.configOrDefault(stored) 84 storedcfg := rawdb.ReadChainConfig(db, stored) 85 if storedcfg == nil { 86 log.Warn("Found genesis block without chain config") 87 rawdb.WriteChainConfig(db, stored, newcfg) 88 return block, err 89 } 90 91 if genesis == nil && stored != params.MainnetGenesisHash { 92 return block, nil 93 } 94 95 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 96 if height == nil { 97 return nil, fmt.Errorf("missing block number for head header hash") 98 } 99 compatErr := storedcfg.CheckCompatible(newcfg, *height) 100 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 101 return nil, compatErr 102 } 103 return block, err 104 } 105 106 func SetupGenesisBlockWithDefault(db neatdb.Database, genesis *Genesis, isMainChain, isTestnet bool) (*params.ChainConfig, common.Hash, error) { 107 if genesis != nil && genesis.Config == nil { 108 109 return nil, common.Hash{}, errGenesisNoConfig 110 } 111 112 stored := rawdb.ReadCanonicalHash(db, 0) 113 if (stored == common.Hash{} && isMainChain) { 114 if genesis == nil { 115 log.Info("Writing default main-net genesis block") 116 if isTestnet { 117 genesis = DefaultGenesisBlockFromJson(DefaultTestnetGenesisJSON) 118 } else { 119 genesis = DefaultGenesisBlockFromJson(DefaultMainnetGenesisJSON) 120 } 121 } else { 122 log.Info("Writing custom genesis block") 123 } 124 block, err := genesis.Commit(db) 125 126 return genesis.Config, block.Hash(), err 127 } 128 129 if genesis != nil { 130 hash := genesis.ToBlock(nil).Hash() 131 if hash != stored { 132 133 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 134 } 135 } 136 137 newcfg := genesis.configOrDefault(stored) 138 storedcfg := rawdb.ReadChainConfig(db, stored) 139 if storedcfg == nil { 140 log.Warn("Found genesis block without chain config") 141 rawdb.WriteChainConfig(db, stored, newcfg) 142 143 return newcfg, stored, nil 144 } 145 146 if genesis == nil && stored != params.MainnetGenesisHash { 147 148 return storedcfg, stored, nil 149 } 150 151 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 152 if height == nil { 153 154 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 155 } 156 compatErr := storedcfg.CheckCompatible(newcfg, *height) 157 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 158 159 return newcfg, stored, compatErr 160 } 161 rawdb.WriteChainConfig(db, stored, newcfg) 162 163 return newcfg, stored, nil 164 } 165 166 func DefaultGenesisBlockFromJson(genesisJson string) *Genesis { 167 168 var ( 169 genesis Genesis 170 genesisW GenesisWrite 171 ) 172 173 genesis.Alloc = GenesisAlloc{} 174 if err := json.Unmarshal([]byte(genesisJson), &genesisW); err != nil { 175 return nil 176 } 177 178 genesis = Genesis{ 179 Config: genesisW.Config, 180 Nonce: genesisW.Nonce, 181 Timestamp: genesisW.Timestamp, 182 ParentHash: genesisW.ParentHash, 183 ExtraData: genesisW.ExtraData, 184 GasLimit: genesisW.GasLimit, 185 Difficulty: genesisW.Difficulty, 186 Mixhash: genesisW.Mixhash, 187 Coinbase: common.HexToAddress(genesisW.Coinbase), 188 Alloc: GenesisAlloc{}, 189 } 190 191 for i, v := range genesisW.Alloc { 192 genesis.Alloc[common.HexToAddress(i)] = v 193 } 194 195 return &genesis 196 } 197 198 var DefaultMainnetGenesisJSON = `{ 199 "config": { 200 "neatChainId": "neatio", 201 "chainId": 515, 202 "homesteadBlock": 0, 203 "eip150Block": 0, 204 "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 205 "eip155Block": 0, 206 "eip158Block": 0, 207 "byzantiumBlock": 0, 208 "petersburgBlock": 0, 209 "istanbulBlock": 0, 210 "neatcon": { 211 "epoch": 30000, 212 "policy": 0 213 } 214 }, 215 "nonce": "0x0", 216 "timestamp": "0x6264ddcb", 217 "extraData": "0x", 218 "gasLimit": "0xe0000000", 219 "difficulty": "0x1", 220 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 221 "coinbase": "0x0000000000000000000000000000000000000000", 222 "alloc": { 223 "03ba7541d4484155c7d08b398d6ade9f34bd8363": { 224 "balance": "0x492bb173ae3d8b5300000", 225 "amount": "0xa968163f0a57b400000" 226 } 227 }, 228 "number": "0x0", 229 "gasUsed": "0x0", 230 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 231 }` 232 233 var DefaultTestnetGenesisJSON = `{ 234 "config": { 235 "neatChainId": "neatio", 236 "chainId": 515, 237 "homesteadBlock": 0, 238 "eip150Block": 0, 239 "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 240 "eip155Block": 0, 241 "eip158Block": 0, 242 "byzantiumBlock": 0, 243 "petersburgBlock": 0, 244 "istanbulBlock": 0, 245 "neatcon": { 246 "epoch": 30000, 247 "policy": 0 248 } 249 }, 250 "nonce": "0x0", 251 "timestamp": "0x62579611", 252 "extraData": "0x", 253 "gasLimit": "0xe0000000", 254 "difficulty": "0x1", 255 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 256 "coinbase": "0x0000000000000000000000000000000000000000", 257 "alloc": { 258 "a67175cdaf47b91f2aa332d8ec44409a4890f0c4": { 259 "balance": "0x31729a3b22ff18d800000", 260 "amount": "0xa968163f0a57b400000" 261 } 262 }, 263 "number": "0x0", 264 "gasUsed": "0x0", 265 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 266 }`