Skip to content

Commit ca3f71e

Browse files
authored
Implement dynamic adjustment of ForkedChain persistBatchSize (#3750)
1 parent ec973a3 commit ca3f71e

File tree

5 files changed

+46
-3
lines changed

5 files changed

+46
-3
lines changed

execution_chain/config.nim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ type
301301
defaultValue: 4'u64
302302
name: "debug-persist-batch-size" .}: uint64
303303

304+
dynamicBatchSize* {.
305+
hidden
306+
defaultValue: false
307+
name: "debug-dynamic-batch-size" .}: bool
308+
304309
rocksdbMaxOpenFiles {.
305310
hidden
306311
defaultValue: defaultMaxOpenFiles

execution_chain/core/chain/forked_chain.nim

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ proc updateBase(c: ForkedChainRef, base: BlockRef): uint =
314314
# No update, return
315315
return
316316

317+
let startTime = Moment.now()
318+
317319
# State root sanity check is performed to verify, before writing to disk,
318320
# that optimistically checked blocks indeed end up being stored with a
319321
# consistent state root.
@@ -338,8 +340,7 @@ with --debug-eager-state-root."""
338340

339341
# Cleanup in-memory blocks starting from base backward
340342
# e.g. B2 backward.
341-
var
342-
count = 0'u
343+
var count = 0'u
343344

344345
for it in ancestors(base.parent):
345346
c.removeBlockFromCache(it)
@@ -352,6 +353,33 @@ with --debug-eager-state-root."""
352353
# Base block always have finalized marker
353354
c.base.finalize()
354355

356+
if c.dynamicBatchSize:
357+
# Dynamicly adjust the persistBatchSize based on the recorded run time.
358+
# The goal here is use the maximum batch size possible without blocking the
359+
# event loop for too long which could negatively impact the p2p networking.
360+
# Increasing the batch size can improve performance because the stateroot
361+
# computation and persist calls are performed less frequently.
362+
const
363+
targetTime = 500.milliseconds
364+
targetTimeDelta = 200.milliseconds
365+
targetTimeLowerBound = (targetTime - targetTimeDelta).milliseconds
366+
targetTimeUpperBound = (targetTime + targetTimeDelta).milliseconds
367+
batchSizeLowerBound = 4
368+
batchSizeUpperBound = 512
369+
370+
let
371+
finishTime = Moment.now()
372+
runTime = (finishTime - startTime).milliseconds
373+
374+
if runTime < targetTimeLowerBound and c.persistBatchSize <= batchSizeUpperBound:
375+
c.persistBatchSize *= 2
376+
info "Increased persistBatchSize", runTime, targetTime,
377+
persistBatchSize = c.persistBatchSize
378+
elif runTime > targetTimeUpperBound and c.persistBatchSize >= batchSizeLowerBound:
379+
c.persistBatchSize = c.persistBatchSize div 2
380+
info "Decreased persistBatchSize", runTime, targetTime,
381+
persistBatchSize = c.persistBatchSize
382+
355383
count
356384

357385
proc processUpdateBase(c: ForkedChainRef): Future[Result[void, string]] {.async: (raises: [CancelledError]).} =
@@ -586,6 +614,7 @@ proc init*(
586614
com: CommonRef;
587615
baseDistance = BaseDistance;
588616
persistBatchSize = PersistBatchSize;
617+
dynamicBatchSize = false;
589618
eagerStateRoot = false;
590619
enableQueue = false;
591620
): T =
@@ -627,6 +656,7 @@ proc init*(
627656
baseTxFrame: baseTxFrame,
628657
baseDistance: baseDistance,
629658
persistBatchSize: persistBatchSize,
659+
dynamicBatchSize: dynamicBatchSize,
630660
quarantine: Quarantine.init(),
631661
fcuHead: fcuHead,
632662
fcuSafe: fcuSafe,

execution_chain/core/chain/forked_chain/chain_desc.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ type
8888
# to move the base. And the bulk writing can works
8989
# efficiently.
9090

91+
dynamicBatchSize*: bool
92+
# Enable adjusting the persistBatchSize dynamically based on the
93+
# time it takes to update base.
94+
9195
portal*: HistoryExpiryRef
9296
# History Expiry tracker and portal access entry point
9397

execution_chain/nimbus_execution_client.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ proc basicServices(nimbus: NimbusNode, conf: NimbusConf, com: CommonRef) =
6565
let fc = ForkedChainRef.init(com,
6666
eagerStateRoot = conf.eagerStateRootCheck,
6767
persistBatchSize = conf.persistBatchSize,
68+
dynamicBatchSize = conf.dynamicBatchSize,
6869
enableQueue = true)
6970
if conf.deserializeFcState:
7071
fc.deserialize().isOkOr:

tests/test_forked_chain.nim

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,10 @@ suite "ForkedChainRef tests":
711711
test "newBase move forward, auto mode, base finalized marker needed":
712712
const info = "newBase move forward, auto mode, base finalized marker needed"
713713
let com = env.newCom()
714-
var chain = ForkedChainRef.init(com, baseDistance = 2, persistBatchSize = 1)
714+
var chain = ForkedChainRef.init(com,
715+
baseDistance = 2,
716+
persistBatchSize = 1,
717+
dynamicBatchSize = false)
715718
check (waitFor chain.forkChoice(blk8.blockHash, blk8.blockHash)).isErr
716719
check chain.tryUpdatePendingFCU(blk8.blockHash, blk8.header.number)
717720
checkImportBlock(chain, blk1)

0 commit comments

Comments
 (0)