nimbus-eth1/nimbus/common/genesis.nim

133 lines
4.1 KiB
Nim
Raw Normal View History

import
std/tables,
2022-12-02 04:39:12 +00:00
eth/[common, rlp, eip1559],
eth/trie/[db, trie_defs],
2022-12-02 04:39:12 +00:00
../db/state_db,
../constants,
./chain_config
2020-01-13 18:35:40 +00:00
{.push raises: [].}
# ------------------------------------------------------------------------------
2022-02-15 03:22:05 +00:00
# Public functions
# ------------------------------------------------------------------------------
proc newStateDB*(
db: TrieDatabaseRef;
pruneTrie: bool;
): AccountStateDB
{.gcsafe, raises: [].}=
2022-02-15 03:22:05 +00:00
newAccountStateDB(db, emptyRlpHash, pruneTrie)
proc toGenesisHeader*(
g: Genesis;
sdb: AccountStateDB;
fork: HardFork;
): BlockHeader
{.gcsafe, raises: [RlpError].} =
## Initialise block chain DB accounts derived from the `genesis.alloc` table
## of the `db` descriptor argument.
##
## The function returns the `Genesis` block header.
##
# For `eth/trie/db.newMemoryDB()`, the following initialisation is part of
# the constructor function which is missing for the permanent constructor
# function `eth/trie/db.trieDB()`.
2022-12-02 04:39:12 +00:00
sdb.db.put(emptyRlpHash.data, emptyRlp)
2018-08-01 12:50:44 +00:00
for address, account in g.alloc:
2018-08-09 09:25:37 +00:00
sdb.setAccount(address, newAccount(account.nonce, account.balance))
sdb.setCode(address, account.code)
# Kludge:
#
# With the pruning persistent version, the initial/trivial key-value
# pair `(emptyRlpHash.data,emptyRlp)` will have been deleted after
# adding a non-trivial key-value pair in one of the above functions.
# This happens in the function/template
#
# eth/trie/db.del() called by
# eth/trie/hexary.prune() invoked by
# eth/trie/hexary.origWithNewValue() invoked by
# eth/trie/hexary.mergeAt() called by
# eth/trie/hexary.put()
#
# if the database contains the trivial key-value pair, only.
# Unfortunately, the *trie* is now empty but the previous root hash
# is re-used. This leads to an assert exception in any subsequent
# invocation of `eth/trie/hexary.put()`.
#
# See also https://github.com/status-im/nim-eth/issues/9 where other,
# probably related debilities are discussed.
#
# This kludge also fixes the initial crash described in
# https://github.com/status-im/nimbus-eth1/issues/932.
2022-12-02 04:39:12 +00:00
if sdb.pruneTrie and 0 < account.storage.len:
sdb.db.put(emptyRlpHash.data, emptyRlp) # <-- kludge
2018-08-09 09:25:37 +00:00
for k, v in account.storage:
sdb.setStorage(address, k, v)
2018-08-01 12:50:44 +00:00
result = BlockHeader(
nonce: g.nonce,
timestamp: g.timestamp,
extraData: g.extraData,
gasLimit: g.gasLimit,
difficulty: g.difficulty,
2022-04-08 04:54:11 +00:00
mixDigest: g.mixHash,
2018-08-01 12:50:44 +00:00
coinbase: g.coinbase,
stateRoot: sdb.rootHash,
2018-08-01 12:50:44 +00:00
parentHash: GENESIS_PARENT_HASH,
txRoot: EMPTY_ROOT_HASH,
receiptRoot: EMPTY_ROOT_HASH,
2018-08-01 12:50:44 +00:00
ommersHash: EMPTY_UNCLE_HASH
)
if g.baseFeePerGas.isSome:
result.baseFee = g.baseFeePerGas.get()
2022-12-02 04:39:12 +00:00
elif fork >= London:
result.baseFee = EIP1559_INITIAL_BASE_FEE.u256
if g.gasLimit.isZero:
2018-08-01 12:50:44 +00:00
result.gasLimit = GENESIS_GAS_LIMIT
2022-12-02 04:39:12 +00:00
if g.difficulty.isZero and fork <= London:
2018-08-01 12:50:44 +00:00
result.difficulty = GENESIS_DIFFICULTY
if fork >= Shanghai:
result.withdrawalsRoot = some(EMPTY_ROOT_HASH)
if fork >= Cancun:
result.dataGasUsed = g.dataGasUsed
result.excessDataGas = g.excessDataGas
proc toGenesisHeader*(
genesis: Genesis;
fork: HardFork;
db = TrieDatabaseRef(nil);
): BlockHeader
{.gcsafe, raises: [RlpError].} =
2022-12-02 04:39:12 +00:00
## Generate the genesis block header from the `genesis` and `config` argument value.
let
db = if db.isNil: newMemoryDB() else: db
sdb = newStateDB(db, pruneTrie = true)
toGenesisHeader(genesis, sdb, fork)
proc toGenesisHeader*(
params: NetworkParams;
db = TrieDatabaseRef(nil);
): BlockHeader
{.raises: [RlpError].} =
2022-12-02 04:39:12 +00:00
## Generate the genesis block header from the `genesis` and `config` argument value.
let map = toForkTransitionTable(params.config)
let fork = map.toHardFork(forkDeterminationInfo(0.toBlockNumber, params.genesis.timestamp))
2022-12-02 04:39:12 +00:00
toGenesisHeader(params.genesis, fork, db)
# End
2022-12-02 04:39:12 +00:00
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------