Skip to content

Pruned Full-Node Mode#


NiPoPoWS make it possible to boot a full node using a verified UTXO set snapshot This provides full node security on an ordinary laptop in ~30-60 mins, without having to check ~95% of the blockchain.

Hopefully, in Q1 2023, we will see a release with UTXO set snapshots + NiPoPoWs bootstrapping; you can follow along on GitHub here, Bootstrapping with UTXO set

This mode is similar to fast-sync in Geth or Grothendieck, or warp-mode in Parity (all are Ethereum protocol clients), but makes more aggressive optimisations.

Specifically, a pruned-full node does not download and store full blocks that do not reside in a target blockchain suffix while also removing full blocks from the suffix.

Technical Workflow (WIP)#

In detail, a pruned client downloads all the headers, then, by using them, it checks proofs-of-work and linking structure(or parent id only?). Then it downloads a UTXO snapshot for some height from its peers. Finally, full blocks after the snapshot will be downloaded and applied to get a current UTXO set. A pruned full node also skips the AD-transformation block part, like a full node. Additional setting: \"suffix\" - how many full blocks to store(w. some minimum set?). Its regular modifiers processing is the same as for the full node regime, while its bootstrap process is different:

  1. Send an ErgoSyncInfo message to connected peers.
  2. Get a response with an INV message containing the ids of blocks, better than our best block.
  3. Request headers for all ids from 2.
  4. On receiving Header:
if(History.apply(header).isSuccess) {
    if(!(localScore == networkScore)) GOTO 1
    else GOTO 5
    } else {
    blacklist peer
  1. Request historical UTXOManifest for at least BlocksToKeep back.

  2. On receiving UTXOSnapshotManifest:

UTXOSnapshotManifest.chunks.foreach { chunk =>
    request chunk from sender() //Or from random full node
  1. On receiving UTXOSnapshotChunk:

    State.applyChunk(UTXOSnapshotChunk) match {
         case Success(Some(newMinimalState)) => GOTO 8
         case Success(None) => stay at 7
         /*we need more chunks to construct the state.
         TODO periodically request missed chunks*/
         case Failure(e) => ???
         //UTXOSnapshotChunk or constructed state root hash is invalid
  2. Request BlockTransactions starting from State we have

    History.headersStartingFromId(State.headerId).foreach { header =>
        send message(GetBlockTransactionsForHeader(header)) to Random full node
  3. On receiving BlockTransactions: same as in Fullnode.7.

  4. Operate as Fullnode.