Amendments
← Back to Consensus II: UNLs and Ledger Amendments
Introduction
Amendments are XRPL's democratic governance system for protocol evolution. They enable the network to evolve and improve while maintaining consensus and decentralization—allowing protocol changes to be coordinated across thousands of nodes without a central authority.
What Are Amendments?
Definition: An amendment is a proposed change to the XRPL's core rules that affects transaction processing logic, consensus mechanisms, ledger structure, or network behavior.
Key Characteristics:
Backward Compatibility:
Must not break existing functionality
Graceful activation without network disruption
Code exists dormant until activated
Network-Wide Impact:
Affects all participants equally
All nodes must comply simultaneously
Synchronized activation across network
Irreversible:
Once activated, cannot be undone
Permanent change to protocol
Requires careful consideration before activation
Democratic:
Requires supermajority approval (80%+)
Sustained support over 2+ weeks
Any significant minority can veto (21%+)
Why Amendments Matter
The Challenge:
Blockchain networks must evolve to remain competitive
All participants must agree on the same rules
Changes must be coordinated across thousands of nodes
No central authority can force updates
The Solution:
Democratic voting system for protocol changes
Ensures network-wide consensus before activation
Maintains decentralization while enabling evolution
Transparent and auditable process
Amendment Lifecycle
The journey of an amendment from idea to activation involves six distinct phases:
Phase 1: Community Proposal
The Democratic Process:
Anyone Can Propose:
Developers, businesses, community members
Open submission process
No gatekeepers or central approval
Public Discussion:
Ideas debated openly in forums and GitHub
Technical analysis and impact assessment
Community feedback and refinement
Consensus Building:
Gathering community support
Building coalition for approval
Addressing concerns and objections
Refinement:
Proposals improved through feedback
Technical specifications refined
Edge cases identified and addressed
Key Considerations:
Need Identification: What problem does this solve?
Impact Assessment: Who benefits? Who might be affected?
Technical Feasibility: Can this be implemented safely?
Community Support: Is there genuine demand?
Phase 2: Development & Testing
Development Process:
Technical Specification:
Detailed requirements written
Formal specification document
Clear success criteria
Code Implementation:
Developers write the actual changes
Pull request submitted to rippled repository
Code review by maintainers and community
Rigorous Testing:
Unit tests for individual components
Integration tests for system-wide behavior
Security audits for potential vulnerabilities
Performance analysis for network impact
Quality Assurance:
Multiple rounds of testing
Peer review by other developers
Community testing on test networks
Stress testing under various conditions
Phase 3: Network Deployment
Code Distribution:
Pull Request Merge:
Code approved and merged to main repository
Included in next rippled release
Version number assigned
Build Integration:
Amendment code included in rippled software
Compilation and packaging
Distribution via official channels
Node Updates:
Validators update their software
Amendment code present but inactive
Dormant state—no immediate effect
The Waiting Period:
Network behavior remains unchanged
Nodes confirm they have the update
System prepares for voting
Validators configure their preferences
Phase 4: Voting Period
Voting Participants:
Validators Only:
Only nodes that participate in consensus can vote
Weighted equally—each validator has one vote
Public positions—all votes transparent and verifiable
Voting Expression:
Continuous Signaling:
Validators constantly express preferences in validations
Amendment flags indicate support
Flexible timing—can change vote anytime
Configuration:
Vote Collection:
Votes collected from trusted validations
Aggregated each consensus round
Threshold calculated based on trusted validator count
Phase 5: Threshold Achievement & Activation
The 80% Threshold:
Why 80%?
Strong Consensus: Ensures broad community support
Minority Protection: Prevents tyranny of simple majority (51%)
Network Stability: Reduces risk of contentious splits
Coordination Assurance: High confidence in network-wide adoption
Comparison with Other Systems:
Simple majority (51%): Too risky for irreversible changes
Unanimity (100%): Would prevent any progress
80%: Sweet spot between progress and stability
Two-Week Requirement:
Purpose of Sustained Support:
Prevents Hasty Decisions: Allows time for reflection
Confirms Stability: Ensures support isn't temporary
Enables Coordination: Gives network time to prepare
Allows Opposition: Provides opportunity for concerns to emerge
Dynamic Nature:
Continuous monitoring of support levels
Vote changes tracked in real-time
Reset mechanism if support drops below 80%
Clock restarts when threshold lost
Activation Trigger:
Automatic Process:
No human intervention required
80%+ support for 2+ weeks triggers activation
Network-wide effect—all nodes comply simultaneously
Irreversible change—no going back
Coordination:
Synchronized activation at specific ledger
All nodes switch at same moment
Consensus ensures smooth transition
Service continues uninterrupted
Phase 6: Network Integration
For Node Operators:
Mandatory Compliance:
Must use new rules or be excluded from consensus
Nodes with old rules cannot participate
Amendment-blocked nodes stop processing
Software Updates:
May need to upgrade rippled versions
Download and install latest release
Restart node with new code
Monitoring Requirements:
Track amendment status via RPC
Monitor for upcoming activations
Prepare for changes proactively
Operational Changes:
May need to adjust configurations
Update monitoring and alerting
Review documentation for changes
For Network Users:
New Capabilities:
Access to enhanced features
Improved transaction types
Better performance or security
Behavior Changes:
Some operations may work differently
New validation rules
Updated fee structures
Compatibility:
Applications may need updates
APIs might have new fields
Client libraries require updates
Improved Experience:
Generally benefits from enhancements
Bug fixes and security improvements
Better network performance
Amendment Architecture
AmendmentTable Interface
Location: rippled/src/xrpld/app/misc/AmendmentTable.h
Purpose: Provides methods for managing, voting on, and querying amendment status
Key Methods:
Amendment Management:
find(amendmentID)- Look up amendment by hashveto(amendmentID)- Veto a specific amendmentunVeto(amendmentID)- Remove vetoenable(amendmentID)- Enable an amendment
Status Queries:
isEnabled(amendmentID)- Check if amendment is activeisSupported(amendmentID)- Check if this node supports ithasUnsupportedEnabled()- Are there unsupported active amendments?firstUnsupportedExpected()- When will unsupported amendment activate?
Voting and Validation:
doVoting(parentCloseTime, amendments, majorityAmendments)- Determine voting actionsdoValidation(ledger, enabled)- Get amendments to include in validationgetDesired()- Get all amendments this node wants enabled
Reporting:
getJson(majority)- Get JSON representation of amendment state
AmendmentTableImpl Implementation
Location: rippled/src/xrpld/app/misc/detail/AmendmentTable.cpp
Internal State:
Amendment Map:
Tracks state of all known amendments
Voting Tracking:
Maintains validator votes and aggregation
Database:
Persists voting preferences
Thread Safety:
Protects all internal state
AmendmentState Structure
Each amendment tracked with:
AmendmentVote Enum:
up- Vote to enable this amendmentdown- Veto this amendmentobsolete- Amendment is obsolete, don't vote
Amendment Registration
Supported, Obsolete, and Retired Amendments
Location: rippled/include/xrpl/protocol/detail/features.macro
Amendments registered at compile time using macros:
Active Amendments:
Fixes (Bug Fixes):
Retired Amendments:
Amendment Types:
Supported Amendments:
Currently relevant features
Code exists and is maintained
Can be voted on and activated
Obsolete Amendments:
Marked with
VoteBehavior::ObsoleteNo longer relevant but must remain supported
In case they were ever enabled historically
Don't actively vote on them
Retired Amendments:
Active for 2+ years
Pre-amendment code removed
Identifiers deprecated but preserved
Always considered enabled
Process for Registering New Amendments
Steps:
Add to features.macro:
Use
XRPL_FEATUREfor new featuresUse
XRPL_FIXfor bug fixesProvide unique identifier and name
Increment Feature Count:
Update
numFeaturesinFeature.hEnsures proper array sizing
Implement Feature Logic:
Add conditional code checking
rules.enabled(featureName)Implement new behavior when enabled
Maintain old behavior when disabled
Add Tests:
Unit tests for both enabled/disabled states
Integration tests for activation
Edge case coverage
Documentation:
Update release notes
Document behavior changes
Provide migration guidance
Voting Process
Vote Collection and Aggregation
TrustedVotes Class:
Purpose: Tracks votes from trusted validators and manages timeouts
Functionality:
Collects amendment votes from validations
Filters for trusted validators only
Handles vote expiration
Aggregates votes per amendment
Location: rippled/src/xrpld/app/misc/detail/AmendmentTable.cpp
Vote Caching and 24-Hour Timeout:
Why Cache Votes?
Prevents "flapping" during temporary validator disconnections
If a validator loses synchronization near a flag ledger, their votes might be missed
Without caching, amendments could repeatedly gain/lose support during network issues
How It Works:
When a validator sends a validation with amendment votes:
Their votes are recorded in the cache
A timeout is set:
currentTime + 24 hoursThese cached votes are used for subsequent vote counting
When 24 hours pass without hearing from a validator:
Their cached votes expire
Votes are cleared (set to empty)
The validator is effectively counted as voting "No" on all amendments
This prevents stale votes from influencing decisions indefinitely
Code Reference (AmendmentTable.cpp:153):
Why 24 Hours?
Balances responsiveness with stability
Allows for brief outages without changing vote record
Long enough to avoid flapping from short disconnections
Short enough to reflect actual validator intent
After 24h of silence, reasonable to assume position may have changed
Practical Impact:
Validators must actively maintain their votes by sending regular validations
Offline validators don't indefinitely count toward amendment support
Encourages validator uptime and participation
Default state is effectively "No" - validators must continuously signal "Yes"
AmendmentSet Class
Purpose: Aggregates votes and determines which amendments pass
Structure:
Threshold Calculation:
computeThreshold() Method:
Pre-Fix Threshold:
Typically 80% of trusted validators
At least 1 vote required
(trustedValidations * 8) / 10
Post-Fix Threshold:
More precise calculation
Handles rounding better
Prevents edge cases
passes() Method:
Determines if an amendment has enough votes:
Ledger Integration: Flag Ledgers
Every 256 Ledgers (~15 minutes):
Regular voting opportunities called "flag ledgers"
Predictable schedule: ledgers 256, 512, 768, 1024, etc.
FLAG_LEDGER_INTERVAL = 256Votes are counted and decisions are made only at these checkpoints
Why Flag Ledgers?
Reduces computational overhead (not counting every ledger)
Provides predictable voting schedule
Allows time for vote dissemination across network
Synchronized decision-making across all nodes
Relationship with 24-Hour Timeout:
Flag ledgers determine when votes are counted (every ~15 minutes)
24-hour timeout determines which votes are valid (recent validators only)
Both mechanisms work together:
At each flag ledger: count votes from validators heard from in last 24h
Expired votes (>24h old) are not included in the count
This ensures only active, participating validators influence decisions
Embedded in Consensus:
Voting part of normal ledger creation
No disruption to transaction processing
Automated counting—no human intervention
Transparent Record:
All votes permanently recorded on-ledger
Audit trail for all changes
Anyone can verify voting process
Parallel Processing:
Amendments and transactions coexist
Voting doesn't interfere with operations
Consistent timing across network
Consensus Integration
doVoting: Amendment Voting Logic
Location: rippled/src/xrpld/app/misc/detail/AmendmentTable.cpp
Called: Each consensus round on voting ledgers
Process:
Update Trusted Votes:
Collect votes from current validations
Filter for trusted validators
Update vote tracking
Build AmendmentSet:
Aggregate votes per amendment
Calculate threshold
Determine which amendments pass
For Each Amendment:
If Already Enabled: Skip
Determine Status:
Validator Majority: Does it pass vote threshold?
Ledger Majority: Is it recorded in ledger as having majority?
Time Held: How long has it had majority?
Decide Actions:
Just Achieved Majority: Signal
tfGotMajorityLost Majority: Signal
tfLostMajorityHeld 2+ Weeks: Signal enablement (no flag)
Otherwise: Log status, no action
Return Actions:
Map of amendment hash to action code
tfGotMajority(0x00010000)tfLostMajority(0x00020000)0 for enablement
doValidation: Advertising Support
Location: rippled/src/xrpld/app/misc/detail/AmendmentTable.cpp
Purpose: Determines which amendments to advertise in validation messages
Process:
Gather all supported amendments
Filter for upvoted (not vetoed)
Exclude already enabled
Sort for deterministic ordering
Return vector of amendment hashes
Included in Validations:
Validators broadcast their amendment support
Other nodes collect these votes
Aggregated to determine network support
getDesired() Method:
Calls
doValidationwith empty setReturns all amendments node wants enabled
Used for status queries
Ledger Application and Activation
doValidatedLedger: Synchronizing State
Location: rippled/src/xrpld/app/misc/detail/AmendmentTable.cpp
Called: After each ledger is validated
Process:
Enable Ledger Amendments:
Get enabled amendments from ledger
Call
enable()for eachUpdate internal state
Track Majority Amendments:
Get amendments with majority from ledger
Update internal tracking
Calculate expected activation times
Check for Unsupported:
Identify amendments this node doesn't support
Track when they're expected to activate
Set
firstUnsupportedExpected_if needed
Update Last Processed:
Record ledger sequence
Prevents duplicate processing
Change::applyAmendment: Transaction Application
Location: rippled/src/xrpld/app/tx/detail/Change.cpp
Purpose: Applies amendment pseudo-transactions to ledger
Process:
Extract Amendment Hash:
Get amendment ID from transaction
Validate format
Check if Already Enabled:
If already enabled, return
tefALREADYPrevent duplicate activation
Handle tfGotMajority Flag:
Add amendment to
sfMajoritiesarrayRecord close time when majority achieved
Update amendment object in ledger
Handle tfLostMajority Flag:
Remove amendment from
sfMajoritiesarrayClear majority status
Update amendment object
Enable Amendment (No Flags):
Add to
sfAmendmentsarrayCall special activation handlers if needed
Call
app.getAmendmentTable().enable(amendment)If unsupported: Log error and block server
Return Success:
Update ledger state
Return
tesSUCCESS
Special Handling:
fixTrustLinesToSelf:
Some amendments require special activation logic for data migration or state updates.
Persistence and Database
Storing Vote Preferences
persistVote() Method:
Location: rippled/src/xrpld/app/misc/detail/AmendmentTable.cpp
Purpose: Records vote preference in database
Process:
Assert vote is not obsolete
Get database session
Call
voteAmendment()with detailsPersist to FeatureVotes table
voteAmendment() Function:
Location: rippled/src/xrpld/app/rdb/detail/Wallet.cpp
SQL Operation:
Transaction Management:
Begin transaction
Execute insert
Commit transaction
Ensures atomicity
Reading Stored Preferences
readAmendments() Function:
Location: rippled/src/xrpld/app/rdb/detail/Wallet.cpp
Purpose: Reads vote preferences from database at startup
SQL Query:
Process:
Use window function to get latest vote per amendment
Invoke callback for each row
Caller validates and updates internal state
Restores preferences across restarts
RPC and Admin Interface
feature RPC Command
Location: rippled/src/xrpld/rpc/handlers/Feature1.cpp
Purpose: Query and manage amendment status
Query All Amendments:
Query Specific Amendment:
Response Format:
Admin Operations
Veto Amendment:
Remove Veto:
Admin Only:
Requires admin credentials
Modifies node's voting preferences
Persisted to database
Takes effect immediately
Operational Consequences
Unsupported Enabled Amendments
Detection:
Node checks each enabled amendment
Compares against supported list
Identifies unsupported active amendments
Response:
setAmendmentBlocked():
Server logs critical error
Sets amendment blocked flag
Stops processing ledgers
Prevents incorrect behavior
Error Message:
Recovery Options:
Upgrade Software:
Install rippled version supporting amendment
Restart node
Resume normal operation
Wait for Code:
If amendment very new, wait for release
Monitor rippled repository
Plan upgrade window
Network Fallback:
Node excluded from consensus
Can still query data
Cannot validate or propose
Veto Power and Minority Protection
How Veto Works:
Withholding Support:
Simply not voting "yes" is a veto
No explicit "no" vote needed
Absence of support blocks activation
Minority Protection:
Just 21% opposition blocks amendments
Significant minority has power
Prevents controversial changes
Continuous Power:
Can veto at any time during voting
Even after gaining majority
Until 2-week period completes
Strategic Implications:
Conservative Bias:
System favors stability over change
Higher bar for activation
Protects against hasty decisions
Coalition Building:
Proponents must build broad support
Need 80%+ validator backing
Encourages compromise
Compromise Incentive:
Amendments designed inclusively
Address concerns proactively
Build consensus before proposing
Edge Cases and Special Scenarios
Low Validator Count
Challenge:
Few validators make 80% easier to achieve
Less geographic/organizational diversity
Higher risk of coordination
Threshold Minimum:
Always at least 1 vote required
Even with 1 validator, needs support
Prevents accidental activation
Network Growth:
As validators increase, threshold rises
More voices required for consensus
Increases legitimacy
Network Partitioning
Scenario:
Network splits into separate groups
Each group may vote differently
Could activate different amendments
Resolution:
When partition heals, use longest chain
Network converges on majority view
Minority partition abandoned
Prevention:
Well-connected overlay network
Geographic diversity
Multiple communication paths
Critical Bug Fixes
Emergency Amendments:
Accelerated Process:
Validators may vote quickly
Community coordination on urgency
Faster than normal 2-week period
Same Mechanism:
Uses normal amendment process
No special bypass
Just expedited timeline
Risk Assessment:
Balance speed vs. safety
Critical security issues justify haste
Community consensus on urgency
Process Adaptation:
Informal agreement to expedite
Higher risk tolerance
Accept some risk for urgent fixes
Amendment Voting in Standalone Mode
Behavior:
Standalone nodes don't participate in consensus
No validator voting
Can enable amendments manually
Configuration:
Use Cases:
Testing amendment behavior
Development and debugging
Isolated testing environments
Interactions with Other Systems
Negative UNL Integration
Parallel Voting:
Amendment voting runs alongside Negative UNL voting
Both occur on flag ledgers
Fee voting also concurrent
Shared Infrastructure:
Same voting ledger mechanism
Same trusted validator tracking
Coordinated pseudo-transactions
Independence:
Each votes independently
Different thresholds and timings
No interference between systems
Fee Voting
Different from Amendments:
Continuous Adjustment:
Fees can change regularly
Every 256 ledgers opportunity
Quantitative Decision:
Not just yes/no
Specific fee values
Multiple options
Operational Parameter:
Affects network economics
Not protocol rules
Faster process
Consensus Challenge:
Must agree on specific values
Median or majority vote
Economic impact considerations
Summary
Key Takeaways
Democratic governance enables protocol evolution without central authority
80% supermajority requirement balances progress with stability
Two-week sustained support prevents hasty or temporary decisions
Transparent voting recorded permanently on-ledger
Veto power protects significant minorities from unwanted changes
Amendment blocking protects network from unsupported activations
Coordinated activation ensures network-wide consensus
Critical Timeframes
Understanding the different time periods is essential:
Every 256 ledgers (~15 min)
Flag ledgers
Votes are counted and amendment status is evaluated
24 hours
Vote cache timeout
If validator doesn't send validations for 24h, their cached votes expire → counted as "No"
2 weeks (configurable)
Majority hold period
Amendment must maintain ≥80% support for this duration before activation
Why votes "reset to No":
NOT because of monthly cycles
NOT because of flag ledgers
BECAUSE validators must actively signal support every 24 hours
If a validator is offline/silent for 24h, their vote cache expires
Expired cache = no votes = effectively voting "No" on all amendments
This ensures only active, participating validators influence decisions
The Big Picture
The amendment system demonstrates how distributed networks can evolve and improve while maintaining consensus and avoiding the pitfalls that have affected other blockchain projects. By combining democratic voting with strong consensus requirements, sustained support periods, and transparent on-ledger tracking, XRPL achieves:
Continuous innovation without compromising decentralization
Network stability through careful change management
Minority protection via veto power
Transparency with public voting records
Coordination ensuring synchronized network upgrades
Flexibility allowing protocol to adapt to new requirements
This sophisticated governance mechanism is fundamental to XRPL's ability to remain competitive and relevant while maintaining its core principles of decentralization, reliability, and security.
References to Source Code
rippled/src/xrpld/app/misc/AmendmentTable.h- Amendment table interfacerippled/src/xrpld/app/misc/detail/AmendmentTable.cpp- Amendment table implementationrippled/src/xrpld/app/tx/detail/Change.cpp- Amendment transaction applicationrippled/src/xrpld/app/rdb/detail/Wallet.cpp- Database persistencerippled/src/xrpld/rpc/handlers/Feature1.cpp- RPC interfacerippled/include/xrpl/protocol/Feature.h- Feature definitionsrippled/include/xrpl/protocol/detail/features.macro- Amendment registrationrippled/src/libxrpl/protocol/Feature.cpp- Feature implementationrippled/src/xrpld/consensus/ConsensusParms.h- Consensus parametersrippled/src/xrpld/app/misc/README.md- Amendment system documentation
Last updated

