PIP-0015.md 4.4 KB

  PIP: PIP-0015
  Title: Fast Block Propagation
  Type: Protocol
  Impact: Soft-Fork
  Author: Herman Schoenfeld <[email protected]>
  Comments-URI: https://discord.gg/sJqcgtD  (channel #pip-0015)
  Status: Proposed
  Created: 2018-01-04

Summary

A method to rapidly propagate blocks is proposed in order to minimize orphan rates. It involves propagating a block skeleton rather than the full block, reducing network traffic by 95%. Nodes can rebuild the full block by plugging operations from the Pending Pool into the skeleton.

Motivation

Due to slow block propagation and expensive SafeBox rollbacks, PascalCoin tends to experience high orphan rates when mining community becomes highly decentralized. Due to the current centralization, this has not been noticable. However, once decentralization is resolved as has been proposed, this issue will re-emerge. As a result, a solution is required in combination with centralization resolution.

Specification

Block Propagation Change

Currently, when a peer is notified of a new block the entire block is sent. In this proposal only a Block Skeleton is sent, structured as follows:

Block Skeleton

[BLOCK HEADER]  (~200 bytes)
[NUM OPERATIONS] (4 bytes)
[OP_REF_1] (8 bytes)
....
[OP_REF_N] (8 bytes)

The skeleton does not contain full operation data, only a reference to the operation. The reference is a 64bit value composed of the AccountNumber and the N_OPERATION of the account authoring the operation.

function GetOpRef(operation : Operation) : QWord
begin
  let accountNumber = operation.Account
  let n_operation = operation.n_operation
  Result = (QWord(accountNumber) SHL 31) BIT-OR QWord(n_operation))
end

The concept of OP_REF is already in PascalCon as part of Albert Molina's OPHASH algorithm:

OPHASH = OP_BLOCK_ID ++ OP_REF ++ RIPEMD160(OP_RAW_DATA)

Block Construction From Skeleton

The receiving node is required to rebuild the full block from the skeleton it has received as follows:

Function ReconstructBlock(skeleton : BlockSkeleton) : Block
begin
    let missing = List<QWord>.Create
    let block = Block.Create
    block.Header = skeleton.Header
    for i = 0 to skeleton.NumOperations - 1 do
        let opRef = skeleton.Operations[i]
        if PendingPool.Contains(opRef) then
            block.Operations[i] = PendingPool.GetByOpRef(opRef)
        else
            missing.Add(opRef)

        if missing.Length > 0 then
            PendingPool.AddMany( NET_OP_PULL_ACCOUNT_OPS(missing) )
            Result := ReconstructBlock(skeleton)
        else
            Result := block
end

NOTE Care must be taken to ensure endianess correctness in OP_REF as done now in PascalCoin OPHASH calculations.

New Network Operation: NET_OP_PULL_ACCOUNT_OPS

This network operation allows a node to fetch specific operations from other nodes that it does not have. It is used when rebuilding the block from the block skeleton. If the node does not have the operations referenced in the skeleton, it uses this network operation to fetch them from other peers. This operation will be used sparingly since most nodes will already have most of the operations most of the time.

Arguments

  • N: DWord - the number of operations being requested
  • OP_REF_1: QWord - the first operation being requested

    . . .

  • OP_REF_N: QWord - the N'th operation being requested

Output

  • M: DWord - the number of operations being returned
  • OP_SIZE_1 : DWord - the size of first operation being returned
  • OP_1 : ByteArray[OP_SIZE_1] -- the raw data of first operation being returned

    . . .

  • OP_SIZE_M : DWord - the size of the M'th operation being returned

  • OP_M - the raw data of M'th operation being returned

Rationale

This provides a 95% reduction in the block data being transmitted increasing propagation efficiency. As a result, orphan rates are expected to proportionally reduce resulting a dramatically less number of orphans. In combination with other PIPs that improve SafeBox rollback efficiency, PascalCoin will be able to seamlessly support CPU-mining such as proposed in PIP-0009.

Backwards Compatibility

This change is backwards compatible and can be introduced as a soft-fork.

## Links

  1. PIP-009: RandomHash: GPU & ASIC Resistant Hash Algorithm