Amendment Lifecycle
← Back to Building an Amendments I: Lifecycle and Impact on Core Protocol
Introduction
The lifecycle of an amendment on XRPL is a carefully orchestrated process that ensures protocol changes are adopted in a coordinated and consensual manner across the decentralized network. This process involves several distinct phases, each with its own rules, timeouts, and transition mechanisms.
In this section, we will follow the complete journey of the Subscriptions amendment (XLS-0078) from its initial conception to its final activation on the ledger. This amendment introduces a subscription mechanism (recurring payments) on XRPL, allowing account owners to authorize automatic recurring payments with predefined parameters including amount, frequency, and destination - similar to bank direct debits.
Understanding this lifecycle is essential for anticipating when a protocol change will become effective, coordinating node updates, and managing risks associated with protocol transitions.
Lifecycle Overview
The lifecycle of an amendment can be represented by the following phases:
┌─────────────┐
│ Proposal │ Code developed, amendment added to registry
└──────┬──────┘
│
▼
┌─────────────┐
│ Vote │ Validators vote for/against the amendment
└──────┬──────┘
│
▼
┌─────────────┐
│ Majority │ More than 80% of validators vote for (2 weeks minimum)
└──────┬──────┘
│
▼
┌─────────────┐
│ Activation │ EnableAmendment pseudo-transaction injected
└──────┬──────┘
│
▼
┌─────────────┐
│ Enablement │ Amendment active, new rules applied
└─────────────┘Each phase has specific criteria that must be satisfied before moving to the next. Let's now explore each phase in detail following the Subscriptions example.
Phase 1: Proposal
Code Development
The first phase begins with the development of code that implements the new functionality. For Subscriptions (XLS-0078), this includes:
New data structures:
Ledger entry type
ltSUBSCRIPTION(0x0055) to store recurring payment authorizationsNew fields:
sfAccount: Subscription owner accountsfDestination: Subscription receiver accountsfDestinationTag(optional): Tag to categorize paymentssfAmount: Maximum amount that can be withdrawn per periodsfFrequency: Interval in seconds between periodssfNextPaymentTime: Timestamp of next possible claimsfExpiration(optional): Timestamp of last possible period
New transactions:
ttSUBSCRIPTION_SET: Create or modify a subscription (creation requires Destination, Amount, Frequency)ttSUBSCRIPTION_CLAIM: Claim a payment within available balance limitsttSUBSCRIPTION_CANCEL: Cancel an existing subscription (owner or destination can initiate)
Validation logic:
Checks in
preflight,preclaim, anddoApplyManagement of amounts per period (≤ Amount)
Support for XRP, IOUs (with trustlines and transfer rates), and MPTs (Multi-Purpose Tokens)
Arrears management: if a period passes without claim, the opportunity is lost and NextPaymentTime advances by one Frequency interval
Single claim per period to avoid spam
Respect freeze states (IOU) and lock (MPT)
Auto-creation of trustlines and MPToken holdings if authorizations and reserves are sufficient
Reference: XLS-0078 Subscriptions
Amendment Registration
Once the code is ready, the amendment is registered in the system via features.macro:
Parameters:
Subscriptions: Amendment nameSupported::yes: The code is included and supportedVoteBehavior::DefaultNo: By default, nodes do not vote for (requires explicit activation)
Hash Calculation
The amendment hash is calculated automatically:
This hash is the unique identifier that will be used in all network communications and data structures.
Code Distribution
The code containing the new amendment is distributed via:
A new version of rippled (e.g., 2.3.0)
Publication on GitHub with detailed release notes
Announcements on community communication channels
Documentation on XRPL.org and link to XLS-0078
At this stage, the amendment exists in the code but is not yet enabled. Nodes that update to this version recognize the amendment but do not apply it yet.
Phase 2: Vote
Vote Activation by Validators
Validators must explicitly activate their vote for the amendment. This is typically done via the RPC command feature:
Or by modifying the configuration file:
Inclusion in Validations
Once a validator has activated their vote, this vote is included in each validation they publish. The validation contains:
The amendments field contains the list of all amendments the validator wishes to see enabled, including Subscriptions.
Vote Collection
Each node on the network collects validations received from trusted validators and extracts their amendment votes. The system maintains:
TrustedVotes: Structure that aggregates votes over a time period
Freshness period: Votes have a limited lifetime (typically 5 minutes). A vote expires if it is not reaffirmed by a new validation within this time. This ensures that vote counts reflect the current state of the network.
Status Monitoring
During the voting phase, the status of Subscriptions can be queried via the RPC command feature:
Interpretation:
15 out of 25 validators vote for Subscriptions (60%)
The 80% threshold is not yet exceeded (need more than 20 votes, so minimum 21)
The amendment is supported but not enabled
Note on threshold: The threshold field displays floor(validations * 0.8) = 20, but the comparison in the code uses votes > threshold, so 21 votes minimum are needed to reach majority.
Phase 3: Majority
Exceeding the 80% Threshold
When enough validators activate their vote, the amendment exceeds the required threshold. Let's assume 6 additional validators activate their vote:
The majority field: This is the critical moment. This field contains the XRPL Time (seconds since 2000-01-01 00:00:00 UTC) when the 80% threshold was first exceeded (count > threshold). In our example: 805385181 corresponds approximately to a date in 2025.
Support calculation: 21/25 = 84% > 80% ✓
tfGotMajority Pseudo-transaction
When the threshold is reached, an EnableAmendment pseudo-transaction with the tfGotMajority flag is injected into the ledger:
Impact on ledger: This pseudo-transaction adds an entry to the sfMajorities field of the global ledger object:
Two-Week Stability Period
From this moment, the amendment enters a mandatory two-week stability period (more precisely, two flag ledgers). Flag ledgers are special ledgers that occur approximately every 15 minutes (256 ledgers).
Duration calculation:
1 flag ledger ≈ 15 minutes (256 ledgers × 3.5 seconds/ledger)
2 flag ledgers ≈ 30 minutes in terms of ledgers
But in practice, the minimum period is 2 weeks in real time
Reason for the period: This window allows:
Node operators to prepare and update their systems
The community to detect any potential problems
Exchanges and wallets to adapt their integrations to support subscriptions
A last opportunity for validators to withdraw their vote if necessary
Loss of Majority (Edge Case)
If during the stability period support falls below 80%, the amendment loses its majority. An EnableAmendment pseudo-transaction with the tfLostMajority flag is injected:
The majority field disappears from the amendment status, and the countdown restarts from zero if the threshold is reached again.
Phase 4: Activation
Expiration of Stability Period
After two weeks of uninterrupted majority, the amendment is ready to be activated. The network automatically calculates when this moment arrives based on the CloseTime recorded in sfMajorities.
EnableAmendment Pseudo-transaction
At the next flag ledger after the period expires, an EnableAmendment pseudo-transaction without flags is injected:
Processing by Change::applyAmendment: This pseudo-transaction is processed by the Change::applyAmendment() function in src/xrpld/app/tx/detail/Change.cpp:
Ledger Update
The amendment is added to the sfAmendments field of the global ledger object:
The corresponding entry is removed from the sfMajorities field since the amendment is no longer pending.
Phase 5: Enablement
Application of New Rules
As soon as the amendment is added to the sfAmendments field, all new transactions and all new ledgers must apply the Subscriptions rules.
For Subscriptions (XLS-0078), this means:
ttSUBSCRIPTION_SETtransactions are now valid and can be submitted to create/modify subscriptionsttSUBSCRIPTION_CLAIMtransactions can claim payments within available balance limitsttSUBSCRIPTION_CANCELtransactions can cancel existing subscriptionsThe ledger can contain
ltSUBSCRIPTIONobjects (type 0x0055)Logic for managing periods, balances, and arrears is activated
Support for XRP, IOUs with trustlines, and MPTs with their specific rules
Rules Object Construction
The state of amendments is encapsulated in the Rules object which is constructed for each ledger:
Transactors and ledger logic consult this object to know which rules to apply:
Final Status
The amendment status after activation simplifies:
The fields count, threshold, validations, majority disappear because they are no longer relevant once the amendment is enabled.
Complete Timeline: Concrete Example
Here is a realistic timeline for Subscriptions on mainnet:
2025-03-01: Release of rippled 2.3.0 including Subscriptions (XLS-0078)
Code distributed, nodes begin to update
Publication of detailed documentation on XRPL.org
2025-03-15: First validators activate their vote
5 out of 35 validators vote for (14%)
2025-04-01: Growing momentum
20 out of 35 validators vote for (57%)
Exchanges and wallets begin to prepare their integrations
2025-04-20 14:32:15 UTC: Threshold exceeded
29 out of 35 validators vote for (82.9% > 80%)
majorityfield appears with timestamp806021535tfGotMajoritypseudo-transaction injected at ledger 86245789
2025-04-20 → 2025-05-04: Stability period
2 weeks mandatory waiting
Support remains stable above 80%
Final tests on staging environments
2025-05-04 14:32:15 UTC: Activation
EnableAmendmentpseudo-transaction (without flag) injected at ledger 86652345Subscriptions added to
sfAmendmentsfield
2025-05-04 14:32:18 UTC: Enablement
First ledger with Subscriptions active
First
ttSUBSCRIPTION_SETtransactions processedUsers can now create subscriptions for recurring payments
State Transition Management
doValidatedLedger: Local Synchronization
After each validated ledger, the AmendmentTableImpl::doValidatedLedger() function synchronizes the local state of amendments with the ledger state:
This synchronization ensures that the node's internal state always reflects the validated ledger state.
Detection of Unsupported Amendments
If an amendment is enabled but the local node does not support it, the node enters "amendment blocked" mode:
This protects network integrity by preventing an outdated node from applying incorrect rules.
Special Cases and Edge Cases
Changes in UNL List
If the list of trusted validators (UNL) changes during the voting or majority phase, the threshold calculation adapts dynamically:
If validators are added to the UNL, the absolute threshold increases
If validators are removed, the threshold decreases
An amendment can lose its majority if enough validators supporting the amendment leave the UNL
Rollback and Contingency
There is no mechanism to disable an amendment once enabled. If a critical problem is discovered after activation:
A fix must be developed and deployed via a new amendment
Or a security patch must be distributed urgently
In extreme cases, out-of-band coordination may be necessary
This is why the two-week stability period is crucial: it offers a last opportunity to detect problems before irreversible activation.
Last updated

