2024-05-31 07:13:56 +00:00
|
|
|
# Nimbus
|
|
|
|
# Copyright (c) 2024 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
|
|
# at your option.
|
|
|
|
# This file may not be copied, modified, or distributed except according to
|
|
|
|
# those terms.
|
|
|
|
|
2024-06-02 11:00:05 +00:00
|
|
|
{.push raises: [].}
|
|
|
|
|
2024-05-31 07:13:56 +00:00
|
|
|
import
|
|
|
|
chronicles,
|
2024-06-20 17:06:58 +00:00
|
|
|
metrics,
|
2024-06-02 11:00:05 +00:00
|
|
|
chronos/timer,
|
2024-10-03 11:42:24 +00:00
|
|
|
std/[strformat, strutils],
|
2024-05-31 07:13:56 +00:00
|
|
|
stew/io2,
|
2024-07-12 03:15:14 +00:00
|
|
|
beacon_chain/era_db,
|
|
|
|
beacon_chain/networking/network_metadata,
|
2024-05-31 07:13:56 +00:00
|
|
|
./config,
|
|
|
|
./common/common,
|
|
|
|
./core/[block_import, chain],
|
|
|
|
./db/era1_db,
|
2024-07-12 03:15:14 +00:00
|
|
|
./utils/era_helpers
|
2024-05-31 07:13:56 +00:00
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
declareGauge nec_import_block_number, "Latest imported block number"
|
2024-06-24 05:56:41 +00:00
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
declareCounter nec_imported_blocks, "Blocks processed during import"
|
2024-06-20 17:06:58 +00:00
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
declareCounter nec_imported_transactions, "Transactions processed during import"
|
2024-06-20 17:06:58 +00:00
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
declareCounter nec_imported_gas, "Gas processed during import"
|
2024-06-20 17:06:58 +00:00
|
|
|
|
2024-05-31 07:13:56 +00:00
|
|
|
var running {.volatile.} = true
|
|
|
|
|
|
|
|
proc importBlocks*(conf: NimbusConf, com: CommonRef) =
|
|
|
|
proc controlCHandler() {.noconv.} =
|
|
|
|
when defined(windows):
|
|
|
|
# workaround for https://github.com/nim-lang/Nim/issues/4057
|
|
|
|
setupForeignThreadGc()
|
|
|
|
running = false
|
|
|
|
|
|
|
|
setControlCHook(controlCHandler)
|
|
|
|
|
|
|
|
let
|
2024-06-14 07:31:08 +00:00
|
|
|
start = com.db.getSavedStateBlockNumber() + 1
|
2024-05-31 07:13:56 +00:00
|
|
|
chain = com.newChain()
|
|
|
|
|
2024-06-15 09:22:37 +00:00
|
|
|
template boolFlag(flags, b): PersistBlockFlags =
|
|
|
|
if b:
|
|
|
|
flags
|
|
|
|
else:
|
|
|
|
{}
|
|
|
|
|
2024-05-31 07:13:56 +00:00
|
|
|
var
|
|
|
|
imported = 0'u64
|
2024-07-09 13:28:01 +00:00
|
|
|
importedSlot = 1'u64
|
2024-06-14 05:10:00 +00:00
|
|
|
gas = GasInt(0)
|
2024-05-31 07:13:56 +00:00
|
|
|
txs = 0
|
2024-06-02 11:00:05 +00:00
|
|
|
time0 = Moment.now()
|
2024-06-06 05:03:11 +00:00
|
|
|
csv =
|
|
|
|
if conf.csvStats.isSome:
|
|
|
|
try:
|
|
|
|
let f = open(conf.csvStats.get(), fmAppend)
|
2024-07-09 13:28:01 +00:00
|
|
|
let pos = f.getFileSize()
|
|
|
|
if pos == 0:
|
|
|
|
f.writeLine("block_number,blocks,slot,txs,gas,time")
|
2024-06-06 05:03:11 +00:00
|
|
|
f
|
|
|
|
except IOError as exc:
|
|
|
|
error "Could not open statistics output file",
|
|
|
|
file = conf.csvStats, err = exc.msg
|
|
|
|
quit(QuitFailure)
|
|
|
|
else:
|
|
|
|
File(nil)
|
2024-06-15 09:22:37 +00:00
|
|
|
flags =
|
2024-07-04 14:51:50 +00:00
|
|
|
boolFlag({PersistBlockFlag.NoValidation}, conf.noValidation) +
|
2024-06-15 09:22:37 +00:00
|
|
|
boolFlag({PersistBlockFlag.NoFullValidation}, not conf.fullValidation) +
|
|
|
|
boolFlag(NoPersistBodies, not conf.storeBodies) +
|
2024-08-16 06:22:51 +00:00
|
|
|
boolFlag({PersistBlockFlag.NoPersistReceipts}, not conf.storeReceipts) +
|
|
|
|
boolFlag({PersistBlockFlag.NoPersistSlotHashes}, not conf.storeSlotHashes)
|
2024-07-09 13:28:01 +00:00
|
|
|
blocks: seq[EthBlock]
|
|
|
|
clConfig: Eth2NetworkMetadata
|
|
|
|
genesis_validators_root: Eth2Digest
|
|
|
|
lastEra1Block: uint64
|
|
|
|
firstSlotAfterMerge: uint64
|
2024-06-15 09:22:37 +00:00
|
|
|
|
2024-06-06 05:03:11 +00:00
|
|
|
defer:
|
|
|
|
if csv != nil:
|
|
|
|
close(csv)
|
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
# Network Specific Configurations
|
|
|
|
# TODO: the merge block number could be fetched from the era1 file instead,
|
|
|
|
# specially if the accumulator is added to the chain metadata
|
|
|
|
if conf.networkId == MainNet:
|
|
|
|
doAssert isDir(conf.era1Dir.string), "Era1 directory not found"
|
|
|
|
clConfig = getMetadataForNetwork("mainnet")
|
|
|
|
genesis_validators_root = Eth2Digest.fromHex(
|
|
|
|
"0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"
|
|
|
|
) # Mainnet Validators Root
|
|
|
|
lastEra1Block = 15537393'u64 # Mainnet
|
|
|
|
firstSlotAfterMerge =
|
|
|
|
if isDir(conf.eraDir.string):
|
|
|
|
4700013'u64 # Mainnet
|
|
|
|
else:
|
2024-09-21 06:38:38 +00:00
|
|
|
warn "No eraDir found for Mainnet, block loading will stop after era1"
|
2024-07-09 13:28:01 +00:00
|
|
|
0'u64 # No eraDir for Mainnet
|
|
|
|
elif conf.networkId == SepoliaNet:
|
|
|
|
doAssert isDir(conf.era1Dir.string), "Era1 directory not found"
|
|
|
|
clConfig = getMetadataForNetwork("sepolia")
|
|
|
|
genesis_validators_root = Eth2Digest.fromHex(
|
|
|
|
"0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"
|
|
|
|
) # Sepolia Validators Root
|
2024-07-12 03:15:14 +00:00
|
|
|
lastEra1Block = 1450408'u64 # Sepolia
|
2024-07-09 13:28:01 +00:00
|
|
|
firstSlotAfterMerge =
|
|
|
|
if isDir(conf.eraDir.string):
|
|
|
|
115193'u64 # Sepolia
|
|
|
|
else:
|
2024-09-21 06:38:38 +00:00
|
|
|
warn "No eraDir found for Sepolia, block loading will stop after era1"
|
2024-07-09 13:28:01 +00:00
|
|
|
0'u64 # No eraDir for Sepolia
|
|
|
|
elif conf.networkId == HoleskyNet:
|
|
|
|
doAssert isDir(conf.eraDir.string), "Era directory not found"
|
|
|
|
clConfig = getMetadataForNetwork("holesky")
|
|
|
|
genesis_validators_root = Eth2Digest.fromHex(
|
|
|
|
"0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"
|
|
|
|
) # Holesky Validators Root
|
|
|
|
lastEra1Block = 0'u64
|
|
|
|
firstSlotAfterMerge = 0'u64
|
|
|
|
else:
|
|
|
|
error "Unsupported network", network = conf.networkId
|
|
|
|
quit(QuitFailure)
|
|
|
|
|
2024-06-24 05:56:41 +00:00
|
|
|
nec_import_block_number.set(start.int64)
|
|
|
|
|
2024-05-31 07:13:56 +00:00
|
|
|
template blockNumber(): uint64 =
|
|
|
|
start + imported
|
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
func f(value: float): string =
|
2024-08-20 13:23:14 +00:00
|
|
|
&"{value:4.3f}"
|
2024-07-09 13:28:01 +00:00
|
|
|
|
2024-08-22 08:06:45 +00:00
|
|
|
proc process() =
|
2024-07-09 13:28:01 +00:00
|
|
|
let
|
|
|
|
time1 = Moment.now()
|
|
|
|
statsRes = chain.persistBlocks(blocks, flags)
|
|
|
|
if statsRes.isErr():
|
|
|
|
error "Failed to persist blocks", error = statsRes.error
|
|
|
|
quit(QuitFailure)
|
|
|
|
|
|
|
|
txs += statsRes[].txs
|
|
|
|
gas += statsRes[].gas
|
|
|
|
let
|
|
|
|
time2 = Moment.now()
|
|
|
|
diff1 = (time2 - time1).nanoseconds().float / 1000000000
|
|
|
|
diff0 = (time2 - time0).nanoseconds().float / 1000000000
|
|
|
|
|
|
|
|
info "Imported blocks",
|
|
|
|
blockNumber,
|
|
|
|
blocks = imported,
|
|
|
|
importedSlot,
|
|
|
|
txs,
|
|
|
|
mgas = f(gas.float / 1000000),
|
|
|
|
bps = f(blocks.len.float / diff1),
|
|
|
|
tps = f(statsRes[].txs.float / diff1),
|
|
|
|
mgps = f(statsRes[].gas.float / 1000000 / diff1),
|
|
|
|
avgBps = f(imported.float / diff0),
|
|
|
|
avgTps = f(txs.float / diff0),
|
|
|
|
avgMGps = f(gas.float / 1000000 / diff0),
|
2024-10-03 11:42:24 +00:00
|
|
|
elapsed = toString(time2 - time0, 3)
|
2024-07-09 13:28:01 +00:00
|
|
|
|
|
|
|
metrics.set(nec_import_block_number, int64(blockNumber))
|
|
|
|
nec_imported_blocks.inc(blocks.len)
|
|
|
|
nec_imported_transactions.inc(statsRes[].txs)
|
|
|
|
nec_imported_gas.inc(int64 statsRes[].gas)
|
2024-05-31 07:13:56 +00:00
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
if csv != nil:
|
|
|
|
# In the CSV, we store a line for every chunk of blocks processed so
|
|
|
|
# that the file can meaningfully be appended to when restarting the
|
|
|
|
# process - this way, each sample is independent
|
|
|
|
try:
|
|
|
|
csv.writeLine(
|
|
|
|
[
|
|
|
|
$blockNumber,
|
|
|
|
$blocks.len,
|
|
|
|
$importedSlot,
|
|
|
|
$statsRes[].txs,
|
|
|
|
$statsRes[].gas,
|
|
|
|
$(time2 - time1).nanoseconds(),
|
|
|
|
].join(",")
|
|
|
|
)
|
|
|
|
csv.flushFile()
|
|
|
|
except IOError as exc:
|
|
|
|
warn "Could not write csv", err = exc.msg
|
|
|
|
blocks.setLen(0)
|
|
|
|
|
2024-07-22 21:17:07 +00:00
|
|
|
# Finds the slot number to resume the import process
|
|
|
|
# First it sets the initial lower bound to `firstSlotAfterMerge` + number of blocks after Era1
|
|
|
|
# Then it iterates over the slots to find the current slot number, along with reducing the
|
|
|
|
# search space by calculating the difference between the `blockNumber` and the `block_number` from the executionPayload
|
2024-07-26 05:32:01 +00:00
|
|
|
# of the slot, then adding the difference to the importedSlot. This pushes the lower bound more,
|
2024-07-22 21:17:07 +00:00
|
|
|
# making the search way smaller
|
2024-08-22 08:06:45 +00:00
|
|
|
proc updateLastImportedSlot(
|
2024-07-09 13:28:01 +00:00
|
|
|
era: EraDB,
|
|
|
|
historical_roots: openArray[Eth2Digest],
|
|
|
|
historical_summaries: openArray[HistoricalSummary],
|
2024-09-21 06:38:38 +00:00
|
|
|
endSlot: Slot,
|
|
|
|
): bool =
|
|
|
|
# Checks if the Nimbus block number is ahead the era block number
|
2024-10-03 11:42:24 +00:00
|
|
|
# First we load the last era number, and get the fist slot number
|
2024-09-21 06:38:38 +00:00
|
|
|
# Since the slot emptiness cannot be predicted, we iterate over to find the block and check
|
|
|
|
# if the block number is greater than the current block number
|
|
|
|
var
|
|
|
|
lastEra = era(endSlot - 1)
|
|
|
|
startSlot = start_slot(lastEra) - 8192
|
|
|
|
debug "Finding slot number to resume import", startSlot, endSlot
|
|
|
|
|
|
|
|
while startSlot < endSlot:
|
|
|
|
let blk = getEthBlockFromEra(
|
|
|
|
era, historical_roots, historical_summaries, startSlot, clConfig.cfg
|
|
|
|
).valueOr:
|
|
|
|
startSlot += 1
|
|
|
|
if startSlot == endSlot - 1:
|
|
|
|
error "No blocks found in the last era file"
|
|
|
|
return false
|
|
|
|
else:
|
|
|
|
continue
|
|
|
|
|
|
|
|
startSlot += 1
|
|
|
|
if blk.header.number < blockNumber:
|
|
|
|
notice "Available Era Files are already imported",
|
|
|
|
stateBlockNumber = blockNumber, eraBlockNumber = blk.header.number
|
|
|
|
quit QuitSuccess
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
if blockNumber > 1:
|
2024-07-26 05:32:01 +00:00
|
|
|
# Setting the initial lower bound
|
2024-07-22 21:17:07 +00:00
|
|
|
importedSlot = (blockNumber - lastEra1Block) + firstSlotAfterMerge
|
2024-09-21 06:38:38 +00:00
|
|
|
debug "Finding slot number after resuming import", importedSlot
|
2024-07-22 21:17:07 +00:00
|
|
|
|
|
|
|
# BlockNumber based slot finding
|
|
|
|
var clNum = 0'u64
|
|
|
|
|
|
|
|
while clNum < blockNumber:
|
2024-07-26 05:32:01 +00:00
|
|
|
let blk = getEthBlockFromEra(
|
2024-07-09 13:28:01 +00:00
|
|
|
era, historical_roots, historical_summaries, Slot(importedSlot), clConfig.cfg
|
2024-07-22 21:17:07 +00:00
|
|
|
).valueOr:
|
|
|
|
importedSlot += 1
|
|
|
|
continue
|
|
|
|
|
2024-07-26 05:32:01 +00:00
|
|
|
clNum = blk.header.number
|
2024-07-22 21:17:07 +00:00
|
|
|
# decreasing the lower bound with each iteration
|
|
|
|
importedSlot += blockNumber - clNum
|
2024-07-09 13:28:01 +00:00
|
|
|
|
2024-09-21 06:38:38 +00:00
|
|
|
notice "Resuming import from", importedSlot
|
|
|
|
return true
|
2024-07-09 13:28:01 +00:00
|
|
|
|
|
|
|
if isDir(conf.era1Dir.string) or isDir(conf.eraDir.string):
|
2024-05-31 07:13:56 +00:00
|
|
|
if start <= lastEra1Block:
|
|
|
|
notice "Importing era1 archive",
|
|
|
|
start, dataDir = conf.dataDir.string, era1Dir = conf.era1Dir.string
|
|
|
|
|
|
|
|
let db =
|
2024-07-09 13:28:01 +00:00
|
|
|
if conf.networkId == MainNet:
|
|
|
|
Era1DbRef.init(conf.era1Dir.string, "mainnet").expect("Era files present")
|
|
|
|
# Mainnet
|
|
|
|
else:
|
|
|
|
Era1DbRef.init(conf.era1Dir.string, "sepolia").expect("Era files present")
|
|
|
|
# Sepolia
|
2024-05-31 07:13:56 +00:00
|
|
|
defer:
|
|
|
|
db.dispose()
|
|
|
|
|
2024-08-22 08:06:45 +00:00
|
|
|
proc loadEraBlock(blockNumber: uint64): bool =
|
|
|
|
# Separate proc to reduce stack usage of blk
|
|
|
|
let blk = db.getEthBlock(blockNumber).valueOr:
|
2024-10-04 01:37:50 +00:00
|
|
|
error "Could not load block from era1", blockNumber, error=error
|
2024-08-22 08:06:45 +00:00
|
|
|
return false
|
|
|
|
|
|
|
|
blocks.add blk
|
|
|
|
true
|
|
|
|
|
|
|
|
while running and imported < conf.maxBlocks and blockNumber <= lastEra1Block:
|
|
|
|
if not loadEraBlock(blockNumber):
|
2024-10-04 01:37:50 +00:00
|
|
|
notice "No more era1 blocks to import", blockNumber
|
2024-05-31 07:13:56 +00:00
|
|
|
break
|
|
|
|
|
|
|
|
imported += 1
|
|
|
|
|
Consolidate block type for block processing (#2325)
This PR consolidates the split header-body sequences into a single EthBlock
sequence and cleans up the fallout from that which significantly reduces
block processing overhead during import thanks to less garbage collection
and fewer copies of things all around.
Notably, since the number of headers must always match the number of bodies,
we also get rid of a pointless degree of freedom that in the future could
introduce unnecessary bugs.
* only read header and body from era file
* avoid several unnecessary copies along the block processing way
* simplify signatures, cleaning up unused arguemnts and returns
* use `stew/assign2` in a few strategic places where the generated
nim assignent is slow and add a few `move` to work around poor
analysis in nim 1.6 (will need to be revisited for 2.0)
```
stats-20240607_2223-a814aa0b.csv vs stats-20240608_0714-21c1d0a9.csv
bps_x bps_y tps_x tps_y bpsd tpsd timed
block_number
(498305, 713245] 1,540.52 1,809.73 2,361.58 2775.340189 17.63% 17.63% -14.92%
(713245, 928185] 730.36 865.26 1,715.90 2028.973852 18.01% 18.01% -15.21%
(928185, 1143126] 663.03 789.10 2,529.26 3032.490771 19.79% 19.79% -16.28%
(1143126, 1358066] 393.46 508.05 2,152.50 2777.578119 29.13% 29.13% -22.50%
(1358066, 1573007] 370.88 440.72 2,351.31 2791.896052 18.81% 18.81% -15.80%
(1573007, 1787947] 283.65 335.11 2,068.93 2441.373402 17.60% 17.60% -14.91%
(1787947, 2002888] 287.29 342.11 2,078.39 2474.179448 18.99% 18.99% -15.91%
(2002888, 2217828] 293.38 343.16 2,208.83 2584.77457 17.16% 17.16% -14.61%
(2217828, 2432769] 140.09 167.86 1,081.87 1296.336926 18.82% 18.82% -15.80%
blocks: 1934464, baseline: 3h13m1s, contender: 2h43m47s
bpsd (mean): 19.55%
tpsd (mean): 19.55%
Time (total): -29m13s, -15.14%
```
2024-06-09 14:32:20 +00:00
|
|
|
if blocks.lenu64 mod conf.chunkSize == 0:
|
2024-05-31 07:13:56 +00:00
|
|
|
process()
|
|
|
|
|
Consolidate block type for block processing (#2325)
This PR consolidates the split header-body sequences into a single EthBlock
sequence and cleans up the fallout from that which significantly reduces
block processing overhead during import thanks to less garbage collection
and fewer copies of things all around.
Notably, since the number of headers must always match the number of bodies,
we also get rid of a pointless degree of freedom that in the future could
introduce unnecessary bugs.
* only read header and body from era file
* avoid several unnecessary copies along the block processing way
* simplify signatures, cleaning up unused arguemnts and returns
* use `stew/assign2` in a few strategic places where the generated
nim assignent is slow and add a few `move` to work around poor
analysis in nim 1.6 (will need to be revisited for 2.0)
```
stats-20240607_2223-a814aa0b.csv vs stats-20240608_0714-21c1d0a9.csv
bps_x bps_y tps_x tps_y bpsd tpsd timed
block_number
(498305, 713245] 1,540.52 1,809.73 2,361.58 2775.340189 17.63% 17.63% -14.92%
(713245, 928185] 730.36 865.26 1,715.90 2028.973852 18.01% 18.01% -15.21%
(928185, 1143126] 663.03 789.10 2,529.26 3032.490771 19.79% 19.79% -16.28%
(1143126, 1358066] 393.46 508.05 2,152.50 2777.578119 29.13% 29.13% -22.50%
(1358066, 1573007] 370.88 440.72 2,351.31 2791.896052 18.81% 18.81% -15.80%
(1573007, 1787947] 283.65 335.11 2,068.93 2441.373402 17.60% 17.60% -14.91%
(1787947, 2002888] 287.29 342.11 2,078.39 2474.179448 18.99% 18.99% -15.91%
(2002888, 2217828] 293.38 343.16 2,208.83 2584.77457 17.16% 17.16% -14.61%
(2217828, 2432769] 140.09 167.86 1,081.87 1296.336926 18.82% 18.82% -15.80%
blocks: 1934464, baseline: 3h13m1s, contender: 2h43m47s
bpsd (mean): 19.55%
tpsd (mean): 19.55%
Time (total): -29m13s, -15.14%
```
2024-06-09 14:32:20 +00:00
|
|
|
if blocks.len > 0:
|
2024-05-31 07:13:56 +00:00
|
|
|
process() # last chunk, if any
|
|
|
|
|
2024-07-12 03:15:14 +00:00
|
|
|
if blockNumber > lastEra1Block:
|
2024-07-09 13:28:01 +00:00
|
|
|
notice "Importing era archive",
|
2024-10-04 01:37:50 +00:00
|
|
|
blockNumber, dataDir = conf.dataDir.string, eraDir = conf.eraDir.string
|
2024-07-09 13:28:01 +00:00
|
|
|
|
|
|
|
let
|
|
|
|
eraDB = EraDB.new(clConfig.cfg, conf.eraDir.string, genesis_validators_root)
|
|
|
|
(historical_roots, historical_summaries, endSlot) = loadHistoricalRootsFromEra(
|
|
|
|
conf.eraDir.string, clConfig.cfg
|
|
|
|
).valueOr:
|
|
|
|
error "Error loading historical summaries", error
|
|
|
|
quit QuitFailure
|
|
|
|
|
|
|
|
# Load the last slot number
|
2024-09-21 06:38:38 +00:00
|
|
|
var moreEraAvailable = true
|
2024-07-12 03:15:14 +00:00
|
|
|
if blockNumber > lastEra1Block + 1:
|
2024-09-21 06:38:38 +00:00
|
|
|
moreEraAvailable = updateLastImportedSlot(
|
|
|
|
eraDB, historical_roots.asSeq(), historical_summaries.asSeq(), endSlot
|
2024-07-12 03:15:14 +00:00
|
|
|
)
|
2024-07-09 13:28:01 +00:00
|
|
|
|
|
|
|
if importedSlot < firstSlotAfterMerge and firstSlotAfterMerge != 0:
|
|
|
|
# if resuming import we do not update the slot
|
|
|
|
importedSlot = firstSlotAfterMerge
|
|
|
|
|
2024-08-22 08:06:45 +00:00
|
|
|
proc loadEra1Block(importedSlot: Slot): bool =
|
|
|
|
# Separate proc to reduce stack usage of blk
|
2024-07-26 05:32:01 +00:00
|
|
|
var blk = getEthBlockFromEra(
|
2024-07-09 13:28:01 +00:00
|
|
|
eraDB,
|
|
|
|
historical_roots.asSeq(),
|
|
|
|
historical_summaries.asSeq(),
|
2024-08-22 08:06:45 +00:00
|
|
|
importedSlot,
|
2024-07-09 13:28:01 +00:00
|
|
|
clConfig.cfg,
|
|
|
|
).valueOr:
|
2024-08-22 08:06:45 +00:00
|
|
|
return false
|
|
|
|
|
|
|
|
blocks.add blk
|
|
|
|
true
|
|
|
|
|
2024-09-21 06:38:38 +00:00
|
|
|
while running and moreEraAvailable and imported < conf.maxBlocks and
|
|
|
|
importedSlot < endSlot:
|
2024-08-22 08:06:45 +00:00
|
|
|
if not loadEra1Block(Slot(importedSlot)):
|
2024-07-09 13:28:01 +00:00
|
|
|
importedSlot += 1
|
|
|
|
continue
|
|
|
|
|
|
|
|
imported += 1
|
|
|
|
importedSlot += 1
|
2024-08-22 08:06:45 +00:00
|
|
|
|
2024-07-09 13:28:01 +00:00
|
|
|
if blocks.lenu64 mod conf.chunkSize == 0:
|
|
|
|
process()
|
|
|
|
|
|
|
|
if blocks.len > 0:
|
|
|
|
process()
|
|
|
|
|
2024-09-04 09:54:54 +00:00
|
|
|
importRlpBlocks(conf, com)
|