Skip to content

[FEATURE]: Chain Sync Block History Synchronization for New Nodes #83

@0u-Y

Description

@0u-Y

Feature and its Use Cases

Problem

When a new node joins the MiniChain network, it only receives account state via the current sync message. Past blocks are never transmitted, so the new node starts with only the genesis block.

I verified this by running 3 nodes locally:

  • Node A (port 9000): mined Block #1 after sending coins to Node B
  • Node B (port 9001): received Block #1 via broadcast
  • Node C (port 9002): connected to Node A after Block #1 was mined

Result:

Node A — Chain length: 2 blocks (Block #0, Block #1)
Node C — Chain length: 1 block  (Block #0 only)

Node C never received Block #1 because the current on_peer_connected() only sends account state, not block history.

Why This Matters

Without block history synchronization, MiniChain cannot function as a truly distributed blockchain. New nodes have no way to verify the chain's integrity or participate in consensus correctly. This is necessary for MiniChain to be "fully functional" as stated in the project goals, and lays the groundwork for Fork Choice, where nodes need accurate chain history to resolve competing chains.

Proposed Solution

Add a minimal 3-message handshake protocol, inspired by Bitcoin's Blocks-First IBD but simplified for MiniChain's minimal philosophy.

Bitcoin IBD uses getblocks → inv → getdata → block (4 messages) because it needs hash-based fork detection and inventory filtering for bandwidth optimization. MiniChain's current linear chain makes height-based range requests sufficient, and block sizes are small enough that inventory filtering adds no benefit. This reduces the protocol to 3 messages:

  • status — share current chain height on peer connection
  • get_blocks — request a range of blocks by height
  • blocks — respond with the requested serialized blocks

Flow:

Node A (height=5)            Node B (height=0, new node)
      |                            |
      |── status(height=5) ──────→ |
      |←── status(height=0) ────── |
      |                            |
      |←── get_blocks(1~5) ─────── |
      |── blocks([B1..B5]) ──────→ |
      |                            |
      |   Node B validates block   |
      |   linkage and adds them    |
      |   to chain: height=5       |

On connection, both nodes exchange status messages. If one node is behind, it requests the missing blocks. Each received block is validated for chain linkage (validate_block_link_and_hash()) and appended to the chain. Account state relies on the existing sync message — this avoids double-applying transactions that are already reflected in the synced state.

Design rationale:

  • Reference: Marabu Blockchain Foundations §5.6 (block validation), §6.3 (honest convergence)
  • Follows MiniChain's "as few lines of code as possible" principle
  • No changes to existing message types or Block class

Scope

  • minichain/chain.py — add height property, get_blocks_range(), add_blocks_bulk()
  • minichain/p2p.py — add status, get_blocks, blocks to supported message types with validators
  • main.py — add status exchange in on_peer_connected(), add message handling in handler()

I'd like to work on this as part of my GSoC 2026 proposal.

Additional Context

No response

Code of Conduct

  • I have joined the Discord server and will post updates there
  • I have searched existing issues to avoid duplicates

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions