Skip to content

Conversation

@liamzebedee
Copy link
Collaborator

@liamzebedee liamzebedee commented Aug 6, 2024

Right now, in testnet1, the network behaves in a single-producer many-follower consensus mode. While the block DAG correctly determines the heaviest chain from a history of blocks, the sync algorithm does not yet search divergent branch histories (ie forks) from nodes.

Sync is implemented as a greedy search, which starts from a base tip and requests windows of 2048 blocks. The tip we start at is our local headers tip:

https://github.com/tinychainorg/tinychain/blob/main/core/nakamoto/sync.go#L301

As such, the node when it hears of a block on an alternative branch does not download it. And so testnet1 can support proper nakamoto POW branching, once it starts downloading alternative branches too.

The improvement proposed in this PR is to search on divergent branches and download history.

The way this will work:

  1. Interactive binary search to find common ancestor when we hear of a new block we don't know.
    a. First check this remote tip has more accumulated work than the current local tip.
  2. Perform the search algorithm from this common ancestor.
  3. Download blocks.

@liamzebedee
Copy link
Collaborator Author

liamzebedee commented Jan 19, 2025

One of the issues presented here is that the search may have multiple concurrent instances, which is undesirable.

Another potential issue is that in a network with two miners (such as the testnet), each node will be downloading the history of each other's chain simultaneously while producing blocks. This incurs some high bandwidth cost/overhead.

Alternate solution concepts:

Download headers (light sync) from highest common ancestor to the peer tip. This is much cheaper (80 B headers vs. 1 MB full blocks) and faster.

Implement the light sync mode, which we want anyways (related to above).

New block gossip sends the block header, not the full block. We can then request the full block if it's needed.

Each peer optimistically tracks the state of other peer's in the network. PeerState includes - headersTip, fullTip, hashrate, connectivity, client version/type, ip/port/tag. This is useful from a pure network observability standpoint (can be displayed on the block explorer). This is useful for optimizing new block gossip and sync efficiency.

The miner only mines on the full tip. This is the current functionality

current_tip, err := miner.dag.GetLatestFullTip()

The problem with sync is that it doesn't search divergent branches, it always begins from the headerstip, which is only updated by sync searching from this tip as a base in getPeerTips.

currentTip, err := n.Dag.GetLatestHeadersTip()

tip, err := n.Peer.SyncGetTipAtDepth(peer, baseBlock, depth, dir)

The issue with searching all divergent branches and downloading full blocks based on the heaviest light tip is a long range attack. A malicious node could generate a long history of headers with zero data availability, and our node could be blocked/stuck on trying to download these full block bodies for the heaviest light tip. There are various ways in which Bitcoin mitigates these attacks I'm sure. The category is something like "first sync".

  • accept block histories from anyone and do a very inefficient O(NB) (N - number of nodes, B - number of blocks) esque sync.
  • try to download the longest chain based on multiple heuristics:
    • greatest number of peers on the same [tip minus 1 block] - susceptible to eclipse attack.
    • heaviest full tip we've seen - requires downloading full blocks, slow.
    • heaviest headers tip we've seen - susceptible to long range attacks / data availability attacks.
    • searching on the "freshest" branches - ones with the most recent timestamps, recent new blocks being mined on them.

@liamzebedee
Copy link
Collaborator Author

liamzebedee commented Jan 19, 2025

Idea: when we receive a new block and don't know parent, do "fast path" and ask for most recent 10 headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants