Skip to main content

Proof-of-Unity (PoU) Consensus

Proof-of-Unity is Savitri Network's consensus mechanism. It combines reputation-based scoring with BFT-style voting to achieve fast finality without the energy waste of Proof-of-Work or the capital lockup of Proof-of-Stake.

Score Formula

Each node maintains a PoU score updated every epoch:

S_i(t) = alpha * S_i(t-1) + (1 - alpha) * (weighted components)

Where alpha = 0.3-0.5 (smoothing factor for temporal stability).

Score Components

ComponentWeightDescription
Availability0.25-0.30Uptime and responsiveness
Latency0.10-0.20Network response time
Integrity0.20-0.25Correct behavior, no byzantine faults
Reputation0.20Historical participation and reliability
Participation0.15Active block production and validation

Final Score

PoU_i = round(S_i(t) * 1000)

Produces a score on a 0-1000 integer scale. The node with the highest PoU score becomes the block proposer.

Election Process

  1. PoU score sharing: Nodes periodically share their PoU scores via gossipsub
  2. Candidate collection: Each node collects scores from group members
  3. Proposer determination: Node with highest pou_score wins (peer_id tiebreaker)
  4. Minimum quorum: Requires (total+1)/2 candidates to start election
  5. Progressive relaxation: After 3+ consecutive failures, minimum candidates drops to 2

Election Recovery

  • Watchdog timer: Re-triggers election if no block progress for 60 seconds
  • Proposer rotation: After 50 blocks, proposer voluntarily steps down
  • Immediate re-election: After group re-initialization, spawns PoU + election task immediately

Group Formation

Masternodes organize lightnodes into groups for parallel block production:

Masternode (coordinator)
├── Group A: [LN1, LN2, LN3, LN4, LN5]
├── Group B: [LN6, LN7, LN8, LN9, LN10]
└── ...
  • Group size: 3-7 lightnodes (configurable)
  • Group ID: Deterministic based on epoch (all masternodes produce the same ID)
  • Announcements: Masternodes publish group assignments every ~30 seconds
  • Re-initialization: When group membership changes, scores are retained for continuing members

BFT Voting

Block finality requires a 2f+1 quorum (67% of validators):

  1. Proposer produces a block
  2. Block is broadcast via gossipsub (/savitri/block/1)
  3. Validators verify and vote
  4. Block Acceptance Certificate (BAC) is produced with 2f+1 signatures
  5. Masternodes verify the BAC and finalize the block

Consensus Modes

ModeFeature FlagUse Case
group-awaregroup-awareFull group-based consensus
pou-basedpou-basedPoU scoring without groups
bftbftBFT voting only
lightweightlightweightMinimal consensus for mobile/embedded
fullfullAll consensus features

PoU Tiers and Rewards

TierMin ScoreReward Multiplier
Bronze3001.0x
Silver5001.5x
Gold7002.0x
Platinum9003.0x

Nodes below score 300 do not receive rewards.

Querying PoU State

Via RPC

# Local PoU state
curl -X POST http://localhost:8545/rpc \
-d '{"jsonrpc":"2.0","method":"savitri_pouLocal","params":[],"id":1}'

# Peer scores
curl -X POST http://localhost:8545/rpc \
-d '{"jsonrpc":"2.0","method":"savitri_pouPeers","params":[],"id":1}'

Via SDK

let client = RpcClient::from_url("http://localhost:8545")?;

let pou = client.pou_local().await?;
println!("Score: {:?}, Leader: {:?}", pou.local_score, pou.leader);

let peers = client.pou_peers().await?;
for (peer, score) in &peers.peers {
println!("{}: {}", peer, score);
}

Network Topology

P2P Topics:
/savitri/tx/1 -- Transaction broadcast
/savitri/block/1 -- Block broadcast
/savitri/consensus/cert/1 -- Block acceptance certificates
/savitri/peer_registry/1 -- Peer keepalive
/savitri/lightnode/group/announce/1 -- Group assignments
/savitri/group/{id}/election -- Per-group elections

Configuration

Key consensus parameters (from config/production.toml):

ParameterDevProduction
Block time2s5s
Max TPS1001000
Group size37
Node timeout300s600s
Election interval300s300s
PoU sharing interval60s60s
Latency probe interval30s30s