-
Couldn't load subscription status.
- Fork 127
Description
We initialize the time validity window here:
Line 300 in d296edd
| vm.chainTimeValidityWindow = validitywindow.NewTimeValidityWindow(vm.snowCtx.Log, vm.tracer, vm, func(timestamp int64) int64 { |
This relies on populating the seen emap to contain the transactions (or containers) of all blocks within the validity window's range ie.
If the last accepted block has timestamp 1000 and the validitywindow is 120, then it must contain all transactions included in blocks with a timestamp in the range [880, 1000].
The chain's time validity window is updated while accepting blocks during normal operation of consensus (after dynamic state sync) and from the state syncer.
The state syncer will backfill the validity window from blocks that are already on disk:
| seenValidityWindow := s.backfillFromExisting(ctx, target) |
However, this assumes that the VM decides to start dynamic state sync and executes this line:
Line 105 in d296edd
| return block.StateSyncDynamic, c.startDynamicStateSync(ctx, target) |
This is not guaranteed to execute if we start up and see that we are less than min blocks behind the proposed new tip. Additionally, there's an edge case where the ProposerVM will accept a dynamic state sync summary and skip calling accept on the inner VM if it has already accepted up to that height (assumes if the outer VM has accepted up to block 100, then there's no need for the inner VM to accept a state sync summary targeting block 100) (#1993).
If we don't initialize the the validity window correctly, then we can see non-deterministic results in e2e test runs due to nodes disagreeing about the validity of a block.
To fix this, we should:
- populate the
seenemap of the validity window in the constructor, so that it does not require a state sync summary to be accepted - force the ProposerVM to call
Accepton the inner state summary if invoking it on the outer summary (Make sure inner state summary accept is called avalanchego#3831) - document the current initialization paths with normal operation/bootstrapping/state sync from AvalancheGo (simplify if possible)