Skip to content

Commit f05da96

Browse files
authored
NOD-525: Optimize baker finalization awake updates (#1322)
* NOD-525: Optimize baker finalization awake updates Prevent redundant writes in bsoMarkFinalizationAwakeBakers by only updating BakerPoolRewardDetails when a baker's finalization state actually changes. This avoids unnecessary tree rehashing on each block. Technical details: - Added check before updating BakerPoolRewardDetails - Added tests for bsoMarkFinalizationAwakeBakers
1 parent 28ac72d commit f05da96

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState.hs

+12-4
Original file line numberDiff line numberDiff line change
@@ -3823,13 +3823,21 @@ doMarkFinalizationAwakeBakers pbs bids = do
38233823
case binarySearchI bcBakerId bpc bid of
38243824
Nothing -> return bprs
38253825
Just (i, _) -> do
3826-
mBPRs <- LFMBT.update setAwake (fromIntegral i) bprs
3826+
mBPRs <- MTL.runExceptT $ LFMBT.update setAwake (fromIntegral i) bprs
38273827
case mBPRs of
3828-
Nothing ->
3828+
-- error is used to signal that there is no change
3829+
Left () -> return bprs
3830+
Right Nothing ->
38293831
error "Invariant violation: unable to find baker in baker pool reward details tree"
3830-
Just ((), newBPRs) ->
3832+
Right (Just ((), newBPRs)) ->
38313833
return newBPRs
3832-
setAwake bpr =
3834+
setAwake bpr = do
3835+
-- If there's nothing to do, use throwError to skip the update.
3836+
when
3837+
( finalizationAwake bpr
3838+
&& all (== emptySuspensionInfo) (suspensionInfo bpr)
3839+
)
3840+
$ MTL.throwError ()
38333841
return
38343842
( (),
38353843
bpr

concordium-consensus/tests/scheduler/SchedulerTests/KonsensusV1/EpochTransition.hs

+25
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,29 @@ testSuspendPrimedSnapshotPaydayCombo accountConfigs = runTestBlockState @P8 $ do
953953
startEpoch = 10
954954
startTriggerTime = 1000
955955

956+
testMarkFinalizationAwakeBakers :: [AccountConfig 'AccountV3] -> Assertion
957+
testMarkFinalizationAwakeBakers accountConfigs = runTestBlockState @P7 $ do
958+
bs0 <- makeInitialState accountConfigs (transitionalSeedState startEpoch startTriggerTime) 1
959+
bprd0 <- bsoGetBakerPoolRewardDetails bs0
960+
let activeBakerIds0 = Map.keys bprd0
961+
-- `bsoMarkFinalizationAwakeBakers` should update reward details only on change
962+
-- of their finalizationAwake / suspensionInfo field. Hence, the operation
963+
-- should be idempotent. This also checks, that the early return in the
964+
-- implementation of `markFinalizerAwake` works.
965+
bs1 <- bsoMarkFinalizationAwakeBakers bs0 activeBakerIds0
966+
bs2 <- bsoMarkFinalizationAwakeBakers bs1 activeBakerIds0
967+
bprd1 <- bsoGetBakerPoolRewardDetails bs1
968+
bprd2 <- bsoGetBakerPoolRewardDetails bs2
969+
liftIO $
970+
assertBool
971+
"bsoMarkFinalizationAwakeBakers updates reward details"
972+
(bprd0 /= bprd1)
973+
liftIO $
974+
assertEqual "bsoMarkFinalizationAwakeBakers is idempotent" bprd1 bprd2
975+
where
976+
startEpoch = 10
977+
startTriggerTime = 1000
978+
956979
tests :: Spec
957980
tests = parallel $ describe "EpochTransition" $ do
958981
it "testEpochTransitionNoPaydayNoSnapshot" $
@@ -977,3 +1000,5 @@ tests = parallel $ describe "EpochTransition" $ do
9771000
forAll (genAccountConfigs False) testSuspendPrimedSnapshotOnly
9781001
it "testSuspendPrimedSnapshotPaydayCombo" $
9791002
forAll (genAccountConfigs False) testSuspendPrimedSnapshotPaydayCombo
1003+
it "testMarkFinalizationAwakeBakers" $
1004+
forAll (genAccountConfigs False) testMarkFinalizationAwakeBakers

0 commit comments

Comments
 (0)