Skip to content

Sync lookup requests blocks from peers that may not have it #5707

@dapplion

Description

@dapplion

Sync lookup NoResponseReturned downscoring issue

Creating a child lookup with a peer from UnknownParentBlock is not okay since that peer may not know about the block. Consider the following sequence of events:

  • Peer receives blob of block before block
  • Peer fowards blob of block to us
  • We don't know the parent of block and trigger UnknownParentBlob(parent, block, peer)
  • Create a lookup for parent
  • Create a lookup for block
  • Lookup for block requests block to peer
  • Peer respons with empty
  • We penalize peer with NoResponseReturned

Instead we should:

  1. Wait for a gossip attestation and request that peer for the block, or an unknown parent event for its child block
  2. Don't create a current lookup. Cache child components somewhere else, or not at all
  3. Allow peers to return empty. This will cause "zombie" lookups where no peer has the block but we keep the lookup around somehow

Solution 1

Create a child lookup with 0 peers and cache the child components there. Scenarios:

  • Block has no blobs, so after the parent finishes processing the child block is imported immediately
  • Block has blobs, but lookup still has 0 peers. What to do? The lookup will fail and the cached block will be dropped

Example A:

  • UnknownParentBlock(parent, block)
  • Create lookup for block
  • Resolve parent
  • Lookup for block dropped because NoPeers

Example B:

  • UnknownParentBlock(parent, block)
  • Create lookup for block
  • UnknownBlockFromAttestation(block)
  • Resolve parent
  • Lookup for block continues with new peer

Solution 2

Don't create current block lookup on UnknownParentBlock events, instead cache child components somewhere else. They can be cached in the sync network context. Then when the lookup wants to request blocks, immediately reply with the cached blocks.

This is a bit ugly because it forces the network context into sending sync events. It introduces a cache of blocks that should be pruned with some timeout

We can also choose to not cache child components at all


Thoughts? Any better solution?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions