Skip to content

Initialize Validity Window outside of State Sync #2003

@aaronbuchwald

Description

@aaronbuchwald

We initialize the time validity window here:

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)
, add blocks as they are accepted during dynamic state sync consensus, and proactively backfill them by fetching from the network.

However, this assumes that the VM decides to start dynamic state sync and executes this line:

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 seen emap 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 Accept on 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions