UNL Management
← Back to Consensus II: UNLs and Ledger Amendments
Introduction
The Unique Node List (UNL) forms the foundation of XRPL's consensus mechanism by defining the set of trusted validators that participate in consensus. The Negative UNL (N-UNL) extends this system by providing a mechanism to temporarily disable unreliable validators without permanent removal, ensuring network reliability while maintaining decentralization.
What is the UNL?
Unique Node List (UNL):
Set of trusted validators that participate in consensus
Determines which nodes can propose and validate ledgers
Each node operator independently chooses their UNL
Typically published by trusted organizations
Negative UNL (N-UNL):
Mechanism to temporarily disable unreliable validators
Subset of UNL validators that are excluded from consensus participation
Provides automatic recovery without permanent removal
Managed through on-ledger consensus process
Core Purpose
Security Maintenance:
Only reliable validators participate in consensus
Prevents malicious or faulty nodes from disrupting network
Automatic Recovery:
Temporarily unreliable validators can be re-enabled
No permanent exclusion maintains validator diversity
Network Resilience:
Prevents disruption from validator failures
Maintains consensus even with poor-performing nodes
Decentralization Preservation:
Avoids permanent validator exclusion
Maintains distributed nature of the network
Negative UNL Architecture
System Components
The Negative UNL system consists of several key components:
Validator Scoring System:
Tracks reliability by counting validations over time
Measures participation rates during consensus rounds
Built using validation history from recent ledgers
Candidate Selection Process:
Identifies underperforming validators for disabling
Identifies recovered validators for re-enabling
Uses performance thresholds to determine eligibility
Deterministic Voting Mechanism:
Uses cryptographic randomness for fair selection
Prevents bias in validator management decisions
Ensures all nodes arrive at the same decision
Automatic Management:
Operates without human intervention
Self-regulating system maintains network health
Integrated into normal consensus process
Negative UNL Ledger Object
Structure
Location: Stored in the ledger state
The Negative UNL ledger object stores:
sfDisabledValidators: List of validator public keys currently disabledsfValidatorToDisable: Validator pending disable actionsfValidatorToReEnable: Validator pending re-enable action
Lifecycle
Initialization: The Negative UNL is empty or contains previously disabled validators from the last validated ledger
Voting: Each consensus round on a flag ledger, the
NegativeUNLVote::doVotingmethod evaluates validator performance and proposes modificationsModification: If a validator is to be disabled or re-enabled, a
ttUNL_MODIFYtransaction is created and added to the ledger's transaction setApplication: Once the transaction is included in a validated ledger, the Negative UNL is updated accordingly via
applyUNLModify
Accessors
Ledger Methods:
Ledger::negativeUNL()- Returns the set of currently disabled validatorsLedger::validatorToDisable()- Returns validator pending disableLedger::validatorToReEnable()- Returns validator pending re-enable
These methods allow the consensus engine and other components to query the current Negative UNL state.
NegativeUNLVote Class
Location:
rippled/src/xrpld/app/misc/NegativeUNLVote.cpprippled/src/xrpld/app/misc/NegativeUNLVote.h
The NegativeUNLVote class manages the entire voting process for the Negative UNL.
Key Responsibilities
Collect and Score Validator Performance: Build a score table of validator reliability over a configurable interval using validation history
Identify Candidates: Determine which validators should be disabled (added to Negative UNL) or re-enabled (removed from Negative UNL) based on reliability scores and protocol thresholds
Deterministic Selection: Use cryptographic randomness (previous ledger hash) to fairly select candidates for action
Transaction Construction: Create and add
ttUNL_MODIFYtransactions to the ledger to modify the Negative UNLTrack New Validators: Maintain a grace period for new validators to avoid disabling them prematurely
Logging and Auditability: Log all relevant actions and errors for debugging and monitoring
Performance Monitoring and Scoring
Validator Scoring: buildScoreTable()
Location: rippled/src/xrpld/app/misc/NegativeUNLVote.cpp
Purpose: Constructs a score table mapping each validator NodeID in the current UNL to the number of trusted validations they have issued over a recent interval of ledgers.
Process:
Determines the scoring interval (typically
FLAG_LEDGER_INTERVALledgers)Iterates through recent ledgers to collect validation data
Counts validations per validator
Returns a map of
NodeID -> validation_count
Edge Cases:
If there is insufficient ledger history, returns
std::nulloptand no voting occursIf the local node has too few or too many validations, returns
std::nulloptto ensure voting fairness
Why This Matters:
The score table provides an objective measurement of validator reliability. By tracking actual validation submissions over time, the system can identify validators that are consistently participating versus those that are unreliable or offline.
Continuous Monitoring
Performance Tracking:
System tracks validator participation over
FLAG_LEDGER_INTERVALperiodsRecords validation submissions for each consensus round
Builds comprehensive reliability metrics
Performance Assessment:
Compares actual vs. expected validation counts
Identifies patterns of reliability or unreliability
Calculates participation percentages
Candidate Selection and Voting
Finding Candidates: findAllCandidates()
Location: rippled/src/xrpld/app/misc/NegativeUNLVote.cpp
Purpose: Identifies which validators are candidates to be disabled (added to Negative UNL) or re-enabled (removed from Negative UNL).
Candidate Identification:
Disable Candidates:
Validators with validation count below the low water mark
Not already on the Negative UNL
Not pending disable
Not in the new validator grace period
Re-enable Candidates:
Validators currently on the Negative UNL
Validation count above the high water mark
Not pending re-enable
Edge Cases:
If the Negative UNL is full (25% of UNL), no disables are proposed
If no candidates are found, no modification is proposed
New validators have a grace period before they can be disabled
Key Thresholds and Parameters
The Negative UNL system uses several critical parameters defined in NegativeUNLVote.cpp:
Low Water Mark:
Threshold: 50% of
FLAG_LEDGER_INTERVALValidators below this may be disabled
Indicates consistently poor performance
High Water Mark:
Threshold: 80% of
FLAG_LEDGER_INTERVALDisabled validators above this may be re-enabled
Shows recovery and reliable participation
Minimum Local Validations to Vote:
Threshold: 90% of
FLAG_LEDGER_INTERVALLocal node must have this many validations to participate in voting
Ensures only well-synchronized nodes vote
New Validator Disable Skip:
Grace period: 2 ×
FLAG_LEDGER_INTERVALNew validators are protected from being disabled during this period
Allows time for validators to establish themselves
Safety Limits:
Maximum 25% of UNL can be on Negative UNL
Prevents excessive network disruption
Ensures sufficient validators remain active
Deterministic Selection: choose()
Location: rippled/src/xrpld/app/misc/NegativeUNLVote.cpp
Purpose: Deterministically selects a single NodeID from a list of candidates using a randomizing pad (typically the previous ledger hash).
Process:
Takes a list of candidate NodeIDs
Uses the previous ledger hash as a cryptographic random source
Combines each candidate's ID with the random pad
Selects the candidate with the highest resulting hash
Why Deterministic Selection?
Fairness: No node can bias the selection process
Consensus: All nodes make the same selection independently
Transparency: Selection is based on public ledger data
Security: Prevents gaming or manipulation of the process
Transaction Construction and Application
Creating UNL Modify Transactions: addTx()
Location: rippled/src/xrpld/app/misc/NegativeUNLVote.cpp
Purpose: Constructs and adds a Negative UNL modification transaction to the SHAMap of transactions for the next ledger.
Transaction Structure:
The ttUNL_MODIFY transaction contains:
Transaction type:
ttUNL_MODIFYValidator public key: The validator to disable or re-enable
Action: ToDisable or ToReEnable
Ledger sequence: The ledger sequence for which this modification is intended
Process:
Constructs a
STTxobject with the appropriate fieldsAdds the transaction to the SHAMap (transaction set)
Logs the action for auditability
Failure Mode:
If the transaction cannot be added to the SHAMap, a warning is logged and no change occurs
This can happen if the SHAMap is full or corrupted
Voting Process: doVoting()
Location: rippled/src/xrpld/app/misc/NegativeUNLVote.cpp
Purpose: Orchestrates the entire Negative UNL voting process for a consensus round.
Process:
Check if Voting is Needed:
Only vote on flag ledgers
Ensure
featureNegativeUNLamendment is enabled
Build Score Table:
Call
buildScoreTable()to get validator performance metricsIf score table cannot be built, exit without voting
Find Candidates:
Call
findAllCandidates()to identify disable/re-enable candidatesSeparate into disable and re-enable lists
Prioritize Re-enables:
If there are re-enable candidates, prefer those first
This helps restore network capacity
Select Candidate:
Use
choose()to deterministically select one candidateCreate appropriate transaction (disable or re-enable)
Add Transaction:
Call
addTx()to add the modification transaction to the ledger
Edge Cases:
If no score table can be built, no modification is proposed
If no candidates are found, no modification is proposed
Only one validator is modified per flag ledger to ensure gradual changes
Ledger Application: applyUNLModify()
Location: rippled/src/xrpld/app/tx/detail/Change.cpp
Purpose: Processes a UNL_MODIFY transaction to either disable or re-enable a validator in the Negative UNL.
Process:
Validation Checks:
Verify it's a flag ledger
Check transaction fields are present and valid
Ensure ledger sequence matches
Disable Action:
Verify validator is not already disabled
Verify validator is not pending disable
Add validator to Negative UNL
Clear any pending re-enable for this validator
Re-enable Action:
Verify validator is currently on Negative UNL
Verify validator is not pending re-enable
Remove validator from Negative UNL
Clear any pending disable for this validator
State Update:
Modify the Negative UNL ledger object
Update pending disable/re-enable fields
Failure Modes:
Transaction is not applied if:
Not a flag ledger
Transaction fields are missing or invalid
Disabling a validator already disabled or pending disable
Re-enabling a validator not in Negative UNL or already pending re-enable
Ledger sequence does not match
Quorum Dynamics
Adaptive Consensus Requirements
The presence of validators on the Negative UNL affects the quorum calculation for consensus.
Base Quorum Calculation:
Formula: max(80% of effective UNL, 60% of total UNL)
This ensures sufficient validator participation while accounting for disabled validators.
Effective UNL:
Total UNL minus validators on Negative UNL
Represents currently active validator set
Used for quorum calculations
Dynamic Adjustment:
Quorum automatically adjusts as validators are disabled/enabled
Maintains consensus viability under changing conditions
Prevents network halt from insufficient participation
Safety Mechanisms:
Minimum viable consensus requirements maintained
Maximum 25% can be disabled prevents excessive quorum reduction
Ensures network can always reach consensus
Consensus Integration
Integration with Consensus Process
The Negative UNL voting and transaction process is integrated into the consensus round:
Voting Trigger:
doVoting()is called during ledger closing on flag ledgersIntegrated into the consensus finalization process
Runs alongside fee and amendment voting
Consensus Engine Updates:
Validator list and Negative UNL are updated in application state
Consensus engine ensures only trusted, non-disabled validators are counted
Quorum calculations automatically adjust for disabled validators
RPC and API Exposure:
Negative UNL is exposed via RPC commands for monitoring
Internal APIs provide access to current N-UNL state
Diagnostics and debugging tools can query N-UNL status
Interaction with Fee and Amendment Voting
Parallel Voting:
Negative UNL voting is performed alongside fee and amendment voting
During a voting ledger, if
featureNegativeUNLis enabled, all voting types run concurrentlyEnsures all governance changes are considered in the same consensus round
Transaction Ordering:
Fee, amendment, and UNL modify transactions are all pseudo-transactions
Processed during ledger close, not from transaction queue
Applied in deterministic order
State Management and Recovery
Consensus State Transitions
Consensus in XRPL is tracked using the following states:
ConsensusState Enum:
No: Consensus has not been reached
Yes: Consensus has been reached
MovedOn: The network has moved on to a new ledger
Expired: The consensus process has expired
State Transitions and N-UNL Impact:
No State:
Triggered by: Insufficient agreement among validators
Action: Continue collecting validations, may attempt consensus in subsequent rounds
N-UNL Impact: Disabled validators not counted toward agreement
Yes State:
Triggered by: Sufficient agreement (meeting quorum) among validators
Action: Ledger is accepted, network moves forward
N-UNL Impact: Quorum calculated based on effective UNL (excluding disabled)
MovedOn State:
Triggered by: Network progresses despite lack of full consensus
Action: Validators accept new ledger
N-UNL Impact: May occur if too many validators disabled
Expired State:
Triggered by: Consensus process times out
Action: Process abandoned, network may recover or resync
N-UNL Impact: Could result from excessive disabled validators
Edge Cases and Recovery
Consensus Cannot Be Reached:
If consensus fails (No or Expired state):
Network continues attempting consensus in subsequent rounds
May move on to new ledger (MovedOn state)
Temporary divergence until consensus restored
Negative UNL is Full:
Maximum size: 25% of total UNL (
negativeUNLMaxListed = 0.25)If N-UNL is full:
No additional validators can be added
Re-enables are prioritized to free space
Network may struggle if more validators fail
No Eligible Candidates:
If no validators meet disable/re-enable criteria:
No modification transaction is proposed
System waits for next flag ledger
Status quo is maintained
Insufficient Ledger History:
If
buildScoreTable()cannot gather enough data:No voting occurs
Prevents premature or unfair disable decisions
Waits for more history to accumulate
Example Scenario
Disabling an Unreliable Validator
Scenario: The network detects that validator A is consistently missing validations.
Step 1: Monitoring
Validator
Asubmits only 45 out of 100 expected validations during the scoring periodThis is below the low water mark (50%)
Step 2: Scoring
During the next flag ledger,
NegativeUNLVote::doVotingis calledbuildScoreTable()constructs reliability metrics for all UNL validatorsValidator
Ahas a score of 45, belownegativeUNLLowWaterMark(50)
Step 3: Candidate Selection
findAllCandidates()identifiesAas a disable candidateChecks that
Ais not already disabled or pending disableChecks that N-UNL is not full (< 25% of UNL)
Step 4: Deterministic Selection
choose()deterministically selectsAfrom the candidate list using previous ledger hashAll nodes independently arrive at the same selection
Step 5: Transaction Construction
addTx()creates attUNL_MODIFYtransaction to disableA:Transaction is added to the ledger's transaction set
Step 6: Consensus
Ledger with the transaction is proposed and goes through normal consensus
Once validated, ledger becomes immutable
Step 7: Application
applyUNLModify()processes the transactionValidator
Ais added to the Negative UNLAis excluded from consensus calculations until re-enabled
Step 8: Recovery
If
Alater recovers and submits > 80% validationsOn a future flag ledger,
Abecomes a re-enable candidateProcess repeats to remove
Afrom Negative UNL
Benefits and Design Goals
System Advantages
Automatic Resilience:
Network self-heals from validator issues
No manual intervention required
Maintains network health automatically
Fairness and Transparency:
Deterministic selection prevents bias
All actions recorded on-ledger and auditable
Every node follows the same rules
Network Stability:
Gradual changes prevent sudden disruptions (one validator per flag ledger)
Maintains consensus continuity
Smooth adaptation to changing conditions
Decentralization Preservation:
No central authority controls participation
Maintains distributed validator ecosystem
Temporary, not permanent, exclusion
Performance Optimization:
Removes unreliable validators from quorum calculations
Improves consensus speed and reliability
Prevents network stalls from offline validators
Supporting Classes and Utilities
ValidatorList
Purpose: Manages the trusted validator set, Negative UNL, and quorum calculation
Key Methods:
Updates UNL based on published lists
Calculates effective UNL (total - disabled)
Provides quorum requirements
Tracks validator trust levels
Ledger
Purpose: Stores the Negative UNL state and provides accessors
Key Methods:
negativeUNL()- Returns current disabled validatorsvalidatorToDisable()- Returns pending disablevalidatorToReEnable()- Returns pending re-enableManages N-UNL ledger object
RCLConsensus
Purpose: Integrates Negative UNL voting into the consensus process
Key Responsibilities:
Calls
doVoting()during flag ledgersCoordinates with fee and amendment voting
Ensures voting occurs at appropriate times
SHAMap
Purpose: Holds the set of transactions for each ledger
N-UNL Usage:
Stores
ttUNL_MODIFYtransactionsEnsures transactions are included in ledger
Provides transaction set management
Summary
Key Takeaways
UNL defines the set of trusted validators for each node
Negative UNL provides automatic, temporary validator disabling
Deterministic voting ensures all nodes agree on changes
Gradual adaptation maintains network stability
Automatic recovery preserves decentralization
The Big Picture
The Unique Node List and Negative UNL system creates a robust, self-maintaining network that automatically manages validator reliability without sacrificing decentralization. By combining deterministic voting, performance monitoring, and automatic recovery, XRPL ensures both security and distributed operation. The system gracefully handles validator failures, recovers from network issues, and maintains consensus even under adverse conditions—all without central control or manual intervention.
References to Source Code
rippled/src/xrpld/app/misc/NegativeUNLVote.cpp- Negative UNL voting implementationrippled/src/xrpld/app/misc/NegativeUNLVote.h- NegativeUNLVote class definitionrippled/src/xrpld/app/tx/detail/Change.cpp- applyUNLModify implementationrippled/src/xrpld/app/misc/detail/ValidatorList.cpp- Validator list managementrippled/src/xrpld/app/ledger/Ledger.cpp- Ledger N-UNL accessorsrippled/src/xrpld/app/consensus/RCLConsensus.cpp- Consensus integrationrippled/src/xrpld/consensus/Consensus.h- Generic consensus templaterippled/src/xrpld/consensus/ConsensusTypes.h- Consensus state definitions
Last updated

