-
Notifications
You must be signed in to change notification settings - Fork 459
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
Update pivot basing on message from CL #5256
Conversation
Why disabled by default? |
It is "smart" I think. We can hardcode |
So this basically works by delaying starting normal sync by 180 seconds at which time the CL can send us the pivot. If someone re syncs CL it will probably miss this time window. (am I right?) What I would call This way we would support situations when we get pivot like 1h into sync or something. |
@marcindsobczak |
@marcindsobczak |
@LukaszRozmej generally you are right, but
In practice, after running Nethermind + CL with checkpoint sync, it takes not more than 1-2min to update pivot and then <1min to start SnapSync. I expect it to behave like that in majority of use-cases and then state sync would start way faster (with 3-4 weeks old pivots even 30-60min). In minority of cases when update would not be successful, state sync will just start 3min later than without this feature. What I can potentially improve is to not postpone downloading of blocks after hardcoded pivot by the time of waiting for CL message and then sync time would not be affected in any scenario. I need to check how much additional complexity this will bring
I'm not sure. Open to discuss. Advantage of having it disabled by default (even in default config files) is that it is a new feature and we might release it as beta version which must be manually triggered when running nethermind. We did it when introducing SnapSync. After few weeks and many users experimenting with that it was enabled by default in the config. But SnapSync was way more complex than this small feature so maybe we don't need that approach? Again, open to discuss
Catching the head after updating pivot take just <1min. But right, it is still possible to turn the node off during this period. Once updated pivot would not be updated again - it will keep using data from first update. So in this scenario we would just continue downloading newest blocks from the time when node was disabled, so similar as in current implementation. |
@marcindsobczak But on PoS it does not have sense especially when Pivot is already post-merge - it will not start syncing at all. Can we make that on PoS that it will always wait for Fcu no matter for how long? If we are not getting that, then connection can be treated as invalid. Ofc - correct me if I'm wrong :) |
@kamilchodola you are right |
public const int UpdatedPivotHash = 9; | ||
public const int UpdatedPivotNumber = 10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dislike that there are 2 keys, we should pack this into 1 value, having first 8bytes being number and later 32 bytes being a hash.
Or just using RLP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will be really small advantage in number of writes/reads - we are writing it only once per node life and reading it only when there was a restart during sync. So performance is definitely not an issue here. And after this change there will be a lack of consistency - we will have:
public const int TerminalPoWHash = 1;
public const int TerminalPoWNumber = 2;
(...)
public const int BeaconSyncPivotHash = 5;
public const int BeaconSyncPivotNumber = 6;
(...)
public const int UpdatedPivotData = 9;
so hashes, numbers and one combined value of number+hash.
In other values we are using separated numbers and hashes. I can change it if you want, but IMO it is better in current form.
src/Nethermind/Nethermind.Merge.Plugin/Synchronization/PivotUpdator.cs
Outdated
Show resolved
Hide resolved
return updateRequestedAndNotFinished && | ||
FastSyncEnabled && | ||
isPostMerge && | ||
stateSyncNotFinished; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if we even start state sync, there is no point of updating Pivot as we already FastSynced to Head?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add logger.Trace like for other methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need it to have correct pivot when downloading headers/bodies/receipts to avoid gaps. After restart pivot is set back to value from config. We are going to PivotUpdator
, it is checking db for updated values, founding it, setting pivot back to updated value and that's all. We just have logic of reading already updated pivot from db in class PivotUpdator
.
Actually I think it can be problematic if restart would be during old bodies. Then we will not read it from db and sync of old receipts would start from old pivot. I think it is a bug and I need to change stateSyncNotFinished
to oldReceiptsNotFinished
, as we stop carrying about pivot only when we are fully synced (not only state). Or maybe even change it to always go to PivotUpdator
and read updated pivot from db? Need to think about it a bit more
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and logger added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if we even start state sync, there is no point of updating Pivot as we already FastSynced to Head?
Right. We are trying to read already updated pivot from DB during initialization (in InitializeNetwork
step). If it is successful, updateRequestedAndNotFinished = _syncConfig.MaxAttemptsToUpdatePivot > 0
check will return false
and mode would not change to UpdatingPivot
. If not, we want to update pivot always if we are post-merge and fast sync in enabled. No need to check state here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually we need this state check - it is for already synced nodes which will be updated to version with PivotUpdator
. We don't want to update pivot in that case.
Looks like it was implemented right way from the very beginning, I just forgot why was that during long period from writing it 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to sum up - right about
I think if we even start state sync, there is no point of updating Pivot as we already FastSynced to Head?
but this check is needed for backward compatibility with nodes synced before updating to Nethermind version with PivotUpdator
.
In general, pivot can be updated only once in node lifetime. Then is saved to DB and loaded during initialization.
|
||
_syncConfig.PivotNumber = updatedPivotBlockNumber.ToString(); | ||
_syncConfig.PivotHash = updatedPivotBlockHash.ToString(); | ||
_syncConfig.MaxAttemptsToUpdatePivot = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not modify the config value?
|
||
private bool ShouldBeInUpdatingPivot() | ||
{ | ||
bool updateRequestedAndNotFinished = _syncConfig.MaxAttemptsToUpdatePivot > 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not modify the config value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add logger.Trace like for other methods
src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs
Show resolved
Hide resolved
|
||
public Keccak GetFinalizedHash() | ||
{ | ||
return _blockCacheService.FinalizedHash; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot go from BlockTree right? As before we sync it won't give us correct answer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FinalizedHash
is needed in MultiSyncModeSelector
. We could potentially pass it through SyncProgressResolver
, but BeaconSync
fits perfect for both, MultiSyncModeSelector
and PivotUpdator
(BeaconSync
is needed in PivotUpdator
anyway because of GetTargetBlockHeight()
).
Have you double check other place that uses the config? |
# Conflicts: # src/Nethermind/Nethermind.Blockchain/Synchronization/SyncConfig.cs # src/Nethermind/Nethermind.Synchronization/ParallelSync/MultiSyncModeSelector.cs
@asdacap If pivot was already updated, it is read from DB in
|
@luk About modifying config values, I agree it is not the best practice. But looking at the usages, if we don't want to overwrite
I'm not sure what is worse here - overwriting config data or creating a lot of code and additional complexity which can be easily avoided. |
Closes #4895
Changes
MaxAttemptsToUpdatePivot = 900
by default. It will try to update pivots 900 times (so for about 15min). It will be activated only on post-merge chains.Types of changes
Testing
Requires testing
If yes, did you write tests?