github.com/aquanetwork/aquachain@v1.7.8/core/genesis.go (about) 1 // Copyright 2014 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 core 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "encoding/json" 23 "errors" 24 "fmt" 25 "math/big" 26 "strings" 27 28 "gitlab.com/aquachain/aquachain/aquadb" 29 "gitlab.com/aquachain/aquachain/common" 30 "gitlab.com/aquachain/aquachain/common/hexutil" 31 "gitlab.com/aquachain/aquachain/common/log" 32 "gitlab.com/aquachain/aquachain/common/math" 33 "gitlab.com/aquachain/aquachain/core/state" 34 "gitlab.com/aquachain/aquachain/core/types" 35 "gitlab.com/aquachain/aquachain/params" 36 "gitlab.com/aquachain/aquachain/rlp" 37 ) 38 39 //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go 40 //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go 41 42 var errGenesisNoConfig = errors.New("genesis has no chain configuration") 43 44 // Genesis specifies the header fields, state of a genesis block. It also defines hard 45 // fork switch-over blocks through the chain configuration. 46 type Genesis struct { 47 Config *params.ChainConfig `json:"config"` 48 Nonce uint64 `json:"nonce"` 49 Timestamp uint64 `json:"timestamp"` 50 ExtraData []byte `json:"extraData"` 51 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 52 Difficulty *big.Int `json:"difficulty" gencodec:"required"` 53 Mixhash common.Hash `json:"mixHash"` 54 Coinbase common.Address `json:"coinbase"` 55 Alloc GenesisAlloc `json:"alloc" gencodec:"required"` 56 57 // These fields are used for consensus tests. Please don't use them 58 // in actual genesis blocks. 59 Number uint64 `json:"number"` 60 GasUsed uint64 `json:"gasUsed"` 61 ParentHash common.Hash `json:"parentHash"` 62 } 63 64 // GenesisAlloc specifies the initial state that is part of the genesis block. 65 type GenesisAlloc map[common.Address]GenesisAccount 66 67 func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { 68 m := make(map[common.UnprefixedAddress]GenesisAccount) 69 if err := json.Unmarshal(data, &m); err != nil { 70 return err 71 } 72 *ga = make(GenesisAlloc) 73 for addr, a := range m { 74 (*ga)[common.Address(addr)] = a 75 } 76 return nil 77 } 78 79 // GenesisAccount is an account in the state of the genesis block. 80 type GenesisAccount struct { 81 Code []byte `json:"code,omitempty"` 82 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 83 Balance *big.Int `json:"balance" gencodec:"required"` 84 Nonce uint64 `json:"nonce,omitempty"` 85 PrivateKey []byte `json:"secretKey,omitempty"` // for tests 86 } 87 88 // field type overrides for gencodec 89 type genesisSpecMarshaling struct { 90 Nonce math.HexOrDecimal64 91 Timestamp math.HexOrDecimal64 92 ExtraData hexutil.Bytes 93 GasLimit math.HexOrDecimal64 94 GasUsed math.HexOrDecimal64 95 Number math.HexOrDecimal64 96 Difficulty *math.HexOrDecimal256 97 Alloc map[common.UnprefixedAddress]GenesisAccount 98 } 99 100 type genesisAccountMarshaling struct { 101 Code hexutil.Bytes 102 Balance *math.HexOrDecimal256 103 Nonce math.HexOrDecimal64 104 Storage map[storageJSON]storageJSON 105 PrivateKey hexutil.Bytes 106 } 107 108 // storageJSON represents a 256 bit byte array, but allows less than 256 bits when 109 // unmarshaling from hex. 110 type storageJSON common.Hash 111 112 func (h *storageJSON) UnmarshalText(text []byte) error { 113 text = bytes.TrimPrefix(text, []byte("0x")) 114 if len(text) > 64 { 115 return fmt.Errorf("too many hex characters in storage key/value %q", text) 116 } 117 offset := len(h) - len(text)/2 // pad on the left 118 if _, err := hex.Decode(h[offset:], text); err != nil { 119 fmt.Println(err) 120 return fmt.Errorf("invalid hex storage key/value %q", text) 121 } 122 return nil 123 } 124 125 func (h storageJSON) MarshalText() ([]byte, error) { 126 return hexutil.Bytes(h[:]).MarshalText() 127 } 128 129 // GenesisMismatchError is raised when trying to overwrite an existing 130 // genesis block with an incompatible one. 131 type GenesisMismatchError struct { 132 Stored, New common.Hash 133 } 134 135 func (e *GenesisMismatchError) Error() string { 136 return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8]) 137 } 138 139 // SetupGenesisBlock writes or updates the genesis block in db. 140 // The block that will be used is: 141 // 142 // genesis == nil genesis != nil 143 // +------------------------------------------ 144 // db has no genesis | main-net default | genesis 145 // db has genesis | from DB | genesis (if compatible) 146 // 147 // The stored chain configuration will be updated if it is compatible (i.e. does not 148 // specify a fork block below the local head block). In case of a conflict, the 149 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 150 // 151 // The returned chain configuration is never nil. 152 func SetupGenesisBlock(db aquadb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 153 if genesis != nil && genesis.Config == nil { 154 log.Warn("No genesis config found, using default (all)") 155 return params.AllAquahashProtocolChanges, common.Hash{}, errGenesisNoConfig 156 } 157 158 // Just commit the new block if there is no stored genesis block. 159 stored := GetCanonicalHash(db, 0) 160 if (stored == common.Hash{}) { 161 if genesis == nil { 162 log.Info("Writing default main-net genesis block") 163 genesis = DefaultGenesisBlock() 164 } else { 165 log.Info("Writing custom genesis block") 166 } 167 block, err := genesis.Commit(db) 168 return genesis.Config, block.Hash(), err 169 } 170 171 // Check whether the genesis block is already written. 172 if genesis != nil { 173 hash := genesis.ToBlock(nil).Hash() 174 if hash != stored { 175 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 176 } 177 } 178 179 // Get the existing chain configuration. 180 newcfg := genesis.configOrDefault(stored) 181 storedcfg, err := GetChainConfig(db, stored) 182 if err != nil { 183 if err == ErrChainConfigNotFound { 184 // This case happens if a genesis write was interrupted. 185 log.Warn("Found genesis block without chain config") 186 err = WriteChainConfig(db, stored, newcfg) 187 } 188 return newcfg, stored, err 189 } 190 // Special case: don't change the existing config of a non-mainnet chain if no new 191 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 192 // if we just continued here. 193 if genesis == nil && stored != params.MainnetGenesisHash { 194 return storedcfg, stored, nil 195 } 196 197 // Check config compatibility and write the config. Compatibility errors 198 // are returned to the caller unless we're already at block zero. 199 height := GetBlockNumber(db, GetHeadHeaderHash(db)) 200 if height == missingNumber { 201 return newcfg, stored, fmt.Errorf("missing block number for head header hash, this happens when using test versions on existing incompatible databases, if you are sure you are running the correct version, try removedb") 202 } 203 compatErr := storedcfg.CheckCompatible(newcfg, height) 204 if compatErr != nil && height != 0 && compatErr.RewindTo != 0 { 205 return newcfg, stored, compatErr 206 } 207 return newcfg, stored, WriteChainConfig(db, stored, newcfg) 208 } 209 210 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 211 switch { 212 case g != nil: 213 return g.Config 214 case ghash == params.MainnetGenesisHash: 215 return params.MainnetChainConfig 216 case ghash == params.TestnetGenesisHash: 217 return params.TestnetChainConfig 218 case ghash == params.Testnet2GenesisHash: 219 return params.Testnet2ChainConfig 220 default: 221 return params.AllAquahashProtocolChanges 222 } 223 } 224 225 // ToBlock creates the genesis block and writes state of a genesis specification 226 // to the given database (or discards it if nil). 227 func (g *Genesis) ToBlock(db aquadb.Database) *types.Block { 228 if db == nil { 229 db = aquadb.NewMemDatabase() 230 } 231 if g.Config == nil { 232 g.Config = params.TestChainConfig 233 } 234 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 235 for addr, account := range g.Alloc { 236 statedb.AddBalance(addr, account.Balance) 237 statedb.SetCode(addr, account.Code) 238 statedb.SetNonce(addr, account.Nonce) 239 for key, value := range account.Storage { 240 statedb.SetState(addr, key, value) 241 } 242 } 243 root := statedb.IntermediateRoot(false) 244 head := &types.Header{ 245 Number: new(big.Int).SetUint64(g.Number), 246 Nonce: types.EncodeNonce(g.Nonce), 247 Time: new(big.Int).SetUint64(g.Timestamp), 248 ParentHash: g.ParentHash, 249 Extra: g.ExtraData, 250 GasLimit: g.GasLimit, 251 GasUsed: g.GasUsed, 252 Difficulty: g.Difficulty, 253 MixDigest: g.Mixhash, 254 Coinbase: g.Coinbase, 255 Root: root, 256 Version: g.Config.GetBlockVersion(new(big.Int).SetUint64(g.Number)), 257 } 258 if g.GasLimit == 0 { 259 head.GasLimit = params.GenesisGasLimit 260 } 261 if g.Difficulty == nil { 262 head.Difficulty = params.GenesisDifficulty 263 } 264 statedb.Commit(false) 265 statedb.Database().TrieDB().Commit(root, true) 266 267 return types.NewBlock(head, nil, nil, nil) 268 } 269 270 // Commit writes the block and state of a genesis specification to the database. 271 // The block is committed as the canonical head block. 272 func (g *Genesis) Commit(db aquadb.Database) (*types.Block, error) { 273 block := g.ToBlock(db) 274 if block.Version() == 0 { 275 return nil, fmt.Errorf("can't commit genesis block with no version") 276 } 277 if block.Number().Sign() != 0 { 278 return nil, fmt.Errorf("can't commit genesis block with number > 0") 279 } 280 if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil { 281 return nil, err 282 } 283 if err := WriteBlock(db, block); err != nil { 284 return nil, err 285 } 286 if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil { 287 return nil, err 288 } 289 if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil { 290 return nil, err 291 } 292 if err := WriteHeadBlockHash(db, block.Hash()); err != nil { 293 return nil, err 294 } 295 if err := WriteHeadHeaderHash(db, block.Hash()); err != nil { 296 return nil, err 297 } 298 config := g.Config 299 if config == nil { 300 config = params.AllAquahashProtocolChanges 301 } 302 return block, WriteChainConfig(db, block.Hash(), config) 303 } 304 305 // MustCommit writes the genesis block and state to db, panicking on error. 306 // The block is committed as the canonical head block. 307 func (g *Genesis) MustCommit(db aquadb.Database) *types.Block { 308 block, err := g.Commit(db) 309 if err != nil { 310 panic(err) 311 } 312 return block 313 } 314 315 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. 316 func GenesisBlockForTesting(db aquadb.Database, addr common.Address, balance *big.Int) *types.Block { 317 g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}, Config: params.TestChainConfig} 318 return g.MustCommit(db) 319 } 320 321 // DefaultGenesisBlock returns the AquaChain main net genesis block. 322 func DefaultGenesisBlock() *Genesis { 323 return &Genesis{ 324 Config: params.MainnetChainConfig, 325 Nonce: 42, 326 GasLimit: 4200000, 327 Difficulty: big.NewInt(99999999), 328 Alloc: decodePrealloc(mainnetAllocData), // all of ethereum presale, "fixed" in HF4 329 } 330 } 331 332 // DefaultTestnetGenesisBlock returns the Ropsten network genesis block. 333 func DefaultTestnetGenesisBlock() *Genesis { 334 return &Genesis{ 335 Config: params.TestnetChainConfig, 336 Nonce: 66, 337 GasLimit: 16777216, 338 Difficulty: big.NewInt(1048576), 339 } 340 } 341 342 // DefaultTestnet2GenesisBlock returns the Testnet2 network genesis block. 343 func DefaultTestnet2GenesisBlock() *Genesis { 344 return &Genesis{ 345 Config: params.Testnet2ChainConfig, 346 Timestamp: 1492009146, 347 GasLimit: 4700000, 348 Difficulty: big.NewInt(1), 349 } 350 } 351 352 // DeveloperGenesisBlock returns the 'aquachain --dev' genesis block. Note, this must 353 // be seeded with the 354 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { 355 // Override the default period to the user requested one 356 config := *params.AllAquahashProtocolChanges 357 358 // Assemble and return the genesis with the precompiles and faucet pre-funded 359 return &Genesis{ 360 Config: &config, 361 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...), 362 GasLimit: 6283185, 363 Difficulty: big.NewInt(1), 364 Alloc: map[common.Address]GenesisAccount{ 365 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover 366 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 367 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD 368 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 369 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 370 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 371 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 372 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 373 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 374 }, 375 } 376 } 377 378 func decodePrealloc(data string) GenesisAlloc { 379 var p []struct{ Addr, Balance *big.Int } 380 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 381 panic(err) 382 } 383 ga := make(GenesisAlloc, len(p)) 384 for _, account := range p { 385 ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} 386 } 387 return ga 388 } 389 390 //func listPrealloc(g GenesisAlloc) []common.Address { 391 // list := []common.Address{} 392 // for k := range g { 393 // list = append(list, k) 394 // 395 // } 396 // return list 397 //}