Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mainnet full archive state database in 167.47 GiB, pruned 25.03 GiB #971

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions nimbus/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ type
NimbusCmd* {.pure.} = enum
noCommand
`import`
blockExec

ProtocolFlag* {.pure.} = enum
## Protocol flags
Expand Down Expand Up @@ -245,6 +246,13 @@ type
defaultValue: 10
name: "log-metrics-interval" .}: int

dbCompare* {.
desc: "Specify path of an archive-mode state history file and check all executed transaction states against that archive. " &
"This option is experimental, currently read-only, and the format is likely to change often"
defaultValue: ""
name: "db-compare"
includeIfEvmc }: string

bootstrapNodes {.
separator: "\pNETWORKING OPTIONS:"
desc: "Specifies one or more bootstrap nodes(as enode URL) to use when connecting to the network"
Expand Down Expand Up @@ -418,6 +426,19 @@ type
defaultValue: ""
name: "blocks-file" }: InputFile

of blockExec:

blockNumberStart* {.
argument
desc: "Execute from local database starting with this block number",
defaultValueDesc: "0"
name: "start-block" }: Option[uint64]

blockNumberEnd* {.
argument
desc: "Execution stops at this block number",
defaultValueDesc: "no limit"
name: "end-block" }: Option[uint64]

proc parseCmdArg(T: type NetworkId, p: TaintedString): T =
parseInt(p.string).T
Expand Down
19 changes: 12 additions & 7 deletions nimbus/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,18 @@ const
# address zero by accident, unrecoverably, due to poor user interface issues.
ZERO_ADDRESS* = default(EthAddress)

# ZERO_HASH256 is the parent hash of genesis blocks.
ZERO_HASH256* = Hash256()
# Uses as parent block hash of genesis blocks and other places where "no hash"
# is represented. This is all zero digits.
ZERO_HASH256* = "0000000000000000000000000000000000000000000000000000000000000000".toDigest

# Used for root of empty hexary trie: keccak256(RLP("")) == keccak256(0x80).
BLANK_ROOT_HASH* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".toDigest

# Used as code hash for contracts with no code: keccak256("").
EMPTY_SHA3* = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".toDigest

# Used for empty `ommersHash` in block headers: keccak256(RLP([])) == keccak256(0xc0).
EMPTY_UNCLE_HASH* = "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347".toDigest

GAS_LIMIT_ADJUSTMENT_FACTOR* = 1_024

Expand All @@ -28,8 +38,6 @@ const
MAX_UNCLE_DEPTH* = 6.u256
MAX_UNCLES* = 2

EMPTY_UNCLE_HASH* = "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347".toDigest

GENESIS_BLOCK_NUMBER* = 0.toBlockNumber
GENESIS_DIFFICULTY* = 131_072.u256
GENESIS_GAS_LIMIT* = 3_141_592
Expand All @@ -42,9 +50,6 @@ const
GAS_LIMIT_MAXIMUM* = high(GasInt)
DEFAULT_GAS_LIMIT* = 8_000_000

BLANK_ROOT_HASH* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".toDigest
EMPTY_SHA3* = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".toDigest

GAS_MOD_EXP_QUADRATIC_DENOMINATOR* = 20.u256

MAX_PREV_HEADER_DEPTH* = 256.toBlockNumber
Expand Down
11 changes: 9 additions & 2 deletions nimbus/nimbus.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import
config, genesis, rpc/[common, p2p, debug], p2p/chain,
eth/trie/db, metrics, metrics/[chronos_httpserver, chronicles_support],
graphql/ethapi, context,
"."/[conf_utils, sealer, constants]
"."/[conf_utils, sealer, constants],
./transaction/[db_compare, db_exec_range]

when defined(evmc_enabled):
import transaction/evmc_dynamic_loader
Expand Down Expand Up @@ -203,6 +204,8 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =

when defined(evmc_enabled):
evmcSetLibraryPath(conf.evm)
if conf.dbCompare.len > 0:
dbCompareOpen(conf.dbCompare)

createDir(string conf.dataDir)
let trieDB = trieDB newChainDb(string conf.dataDir)
Expand All @@ -222,6 +225,8 @@ proc start(nimbus: NimbusNode, conf: NimbusConf) =
case conf.cmd
of NimbusCmd.`import`:
importBlocks(conf, chainDB)
of NimbusCmd.blockExec:
dbCompareExecBlocks(chainDB, conf.blockNumberStart, conf.blockNumberEnd)
else:
manageAccounts(nimbus, conf)
setupP2P(nimbus, conf, chainDB, protocols)
Expand Down Expand Up @@ -279,4 +284,6 @@ when isMainModule:
let conf = makeConfig()

nimbus.start(conf)
nimbus.process(conf)

if conf.cmd == noCommand:
nimbus.process(conf)
14 changes: 12 additions & 2 deletions nimbus/p2p/dao.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import eth/common, stew/byteutils, ../db/accounts_cache

when defined(evmc_enabled):
import ../transaction/db_compare

const
# DAOForkBlockExtra is the block header extra-data field to set for the DAO fork
# point and a number of consecutive blocks to allow fast/light syncers to correctly
Expand Down Expand Up @@ -135,9 +138,16 @@ const
# ApplyDAOHardFork modifies the state database according to the DAO hard-fork
# rules, transferring all balances of a set of DAO accounts to a single refund
# contract.
proc applyDAOHardFork*(statedb: var AccountsCache) =
proc applyDAOHardFork*(statedb: var AccountsCache, blockNumber: BlockNumber) =
const zero = 0.u256

# Move every DAO account and extra-balance account funds into the refund contract
for address in DAODrainList:
statedb.addBalance(DAORefundContract, statedb.getBalance(address))
# NOTE: We read the balances, so must include them in `dbCompare` read-set.
let balance = statedb.getBalance(address)
when defined(evmc_enabled):
if dbCompareEnabled:
blockNumber.dbCompareBalance(address, balance)

statedb.addBalance(DAORefundContract, balance)
statedb.setBalance(address, zero)
2 changes: 2 additions & 0 deletions nimbus/p2p/executor/calculate_reward.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import
./executor_helpers,
eth/common

when defined(evmc_enabled):
import ../../transaction/db_compare

func eth(n: int): Uint256 {.compileTime.} =
n.u256 * pow(10.u256, 18)
Expand Down
8 changes: 7 additions & 1 deletion nimbus/p2p/executor/process_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import
eth/[common, trie/db],
nimcrypto

when defined(evmc_enabled):
import ../../transaction/db_compare

{.push raises: [Defect].}

# ------------------------------------------------------------------------------
Expand All @@ -33,10 +36,13 @@ import
proc procBlkPreamble(vmState: BaseVMState; dbTx: DbTransaction;
header: BlockHeader, body: BlockBody): bool
{.gcsafe, raises: [Defect,CatchableError].} =
when defined(evmc_enabled):
dbCompareResetSeen()

if vmState.chainDB.config.daoForkSupport and
vmState.chainDB.config.daoForkBlock == header.blockNumber:
vmState.mutateStateDB:
db.applyDAOHardFork()
db.applyDAOHardFork(header.blockNumber)

if body.transactions.calcTxRoot != header.txRoot:
debug "Mismatched txRoot",
Expand Down
4 changes: 3 additions & 1 deletion nimbus/p2p/executor/process_transaction.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import
chronicles,
eth/common

when defined(evmc_enabled):
import ../../transaction/db_compare

{.push raises: [Defect].}

# ------------------------------------------------------------------------------
Expand All @@ -32,7 +35,6 @@ proc eip1559TxNormalization(tx: Transaction): Transaction =
result.maxPriorityFee = tx.gasPrice
result.maxFee = tx.gasPrice


proc processTransactionImpl(tx: Transaction, sender: EthAddress,
vmState: BaseVMState, fork: Fork): GasInt
# wildcard exception, wrapped below
Expand Down
11 changes: 11 additions & 0 deletions nimbus/p2p/validate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import
options,
stew/[results, endians2]

when defined(evmc_enabled):
import ../transaction/db_compare

from stew/byteutils
import nil

Expand Down Expand Up @@ -217,6 +220,14 @@ proc validateTransaction*(vmState: BaseVMState, tx: Transaction,
sender: EthAddress, fork: Fork): bool =
let balance = vmState.readOnlyStateDB.getBalance(sender)
let nonce = vmState.readOnlyStateDB.getNonce(sender)
# NOTE: We read balance and nonce so must add them to `dbCompare`.
when defined(evmc_enabled):
if dbCompareEnabled:
vmState.blockHeader.blockNumber.dbCompareBalance(sender, balance)
vmState.blockHeader.blockNumber.dbCompareNonce(sender, nonce)

# NOTE: Not comparing balance and nonce here against the compact db.
# They will be read again when executing the transaction.

if tx.txType == TxEip2930 and fork < FkBerlin:
debug "invalid tx: Eip2930 Tx type detected before Berlin"
Expand Down
1 change: 1 addition & 0 deletions nimbus/tracer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ proc toJson*(receipts: seq[Receipt]): JsonNode =
result.add receipt.toJson

proc captureAccount(n: JsonNode, db: AccountsCache, address: EthAddress, name: string) =
# TODO: It might be useful to add dbCompare here.
var jaccount = newJObject()
jaccount["name"] = %name
jaccount["address"] = %("0x" & $address)
Expand Down
20 changes: 17 additions & 3 deletions nimbus/transaction/call_common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import
".."/[vm_types, vm_state, vm_computation, vm_state_transactions],
".."/[vm_internals, vm_precompiles, vm_gas_costs],
".."/[db/accounts_cache, forks],
./host_types
./host_types, ./db_compare

when defined(evmc_enabled):
import ".."/[utils]
Expand Down Expand Up @@ -133,15 +133,22 @@ proc setupHost(call: CallParams): TransactionHost =
# All other defaults in `TransactionHost` are fine.
)

when defined(evmc_enabled):
if dbCompareEnabled:
host.dbCompare = true

# Generate new contract address, prepare code, and update message `destination`
# with the contract address. This differs from the previous Nimbus EVM API.
# Guarded under `evmc_enabled` for now so it doesn't break vm2.
when defined(evmc_enabled):
var code: seq[byte]
if call.isCreate:
let sender = call.sender
let contractAddress =
generateAddress(sender, call.vmState.readOnlyStateDB.getNonce(sender))
let nonce = call.vmState.readOnlyStateDB.getNonce(sender)
# NOTE: Because we read nonce we must add it to the `dbCompare` read-set.
if host.dbCompare:
host.dbCompareNonce(sender, nonce)
let contractAddress = generateAddress(sender, nonce)
host.msg.destination = contractAddress.toEvmc
host.msg.input_size = 0
host.msg.input_data = nil
Expand All @@ -150,6 +157,9 @@ proc setupHost(call: CallParams): TransactionHost =
# TODO: Share the underlying data, but only after checking this does not
# cause problems with the database.
code = host.vmState.readOnlyStateDB.getCode(host.msg.destination.fromEvmc)
if host.dbCompare:
let codeHash = host.vmState.readOnlyStateDB.getCodeHash(host.msg.destination.fromEvmc)
host.dbCompareCodeHash(host.msg.destination.fromEvmc, codeHash)
if call.input.len > 0:
host.msg.input_size = call.input.len.csize_t
# Must copy the data so the `host.msg.input_data` pointer
Expand Down Expand Up @@ -206,6 +216,10 @@ proc runComputation*(call: CallParams): CallResult =

# Charge for gas.
if not call.noGasCharge:
when defined(evmc_enabled):
if dbCompareEnabled:
let balance = host.vmState.readOnlyStateDB.getBalance(call.sender)
host.dbCompareBalance(call.sender, balance)
host.vmState.mutateStateDB:
db.subBalance(call.sender, call.gasLimit.u256 * call.gasPrice.u256)

Expand Down