Validators can vote for changes to basic transaction cost as well as reserve requirements. If the preferences in a validator's configuration are different than the network's current settings, the validator expresses its preferences to the network periodically. If a quorum of validators agrees on a change, they can apply a change that takes effect thereafter. Validators may do this for various reasons, especially to reflect long-term changes in the value of XRP.
-
Operators of rippled validators can set their preferences for the transaction cost and reserve requirements in the [voting] stanza of the rippled.cfg file. Caution: insufficient requirements could expose the Ripple peer-to-peer network to denial-of-service attacks. The parameters you can set are as follows:
+
Validators can vote for changes to basic transaction cost as well as reserve requirements. If the preferences in a validator's configuration are different than the network's current settings, the validator expresses its preferences to the network periodically. If a quorum of validators agrees on a change, they can apply a change that takes effect thereafter. Validators may do this for various reasons, especially to reflect long-term changes in the value of XRP.
+
Operators of rippled validators can set their preferences for the transaction cost and reserve requirements in the [voting] stanza of the rippled.cfg file. Caution: insufficient requirements could expose the Ripple peer-to-peer network to denial-of-service attacks. The parameters you can set are as follows:
@@ -157,7 +158,7 @@
Voting Process
Every 256th ledger is called a "flag" ledger. (A flag ledger is defined such that the ledger_indexmodulo256 is equal to 0.) In the ledger immediately before the flag ledger, each validator whose account reserve or transaction cost preferences are different than the current network setting distributes a "vote" message alongside its ledger validation, indicating the values that validator prefers.
In the flag ledger itself, nothing happens, but validators receive and take note of the votes from other validators they trust.
-
After counting the votes of other validators, each validator attempts to compromise between its own preferences and the preferences of a majority of validators it trusts. (For example, if one validator wants to raise the minimum transaction cost from 10 to 100, but most validators only want to raise it from 10 to 20, the one validator settles on the change to raise the cost to 20. However, the one validator never settles on a value lower than 10 or higher than 100.) If a compromise is possible, the validator inserts a SetFee pseudo-transaction into its proposal for the ledger following the flag ledger. Other validators who want the same change insert an identical SetFee pseudo-transaction into their proposals for the same ledger. (Validators whose preferences match the existing network settings do nothing.) If a SetFee psuedo-transaction survives the consensus process to be included in a validated ledger, then the new transaction cost and reserve settings denoted by the SetFee pseudo-transaction take effect starting with the following ledger.
+
After counting the votes of other validators, each validator attempts to compromise between its own preferences and the preferences of a majority of validators it trusts. (For example, if one validator wants to raise the minimum transaction cost from 10 to 100, but most validators only want to raise it from 10 to 20, the one validator settles on the change to raise the cost to 20. However, the one validator never settles on a value lower than 10 or higher than 100.) If a compromise is possible, the validator inserts a SetFee pseudo-transaction into its proposal for the ledger following the flag ledger. Other validators who want the same change insert an identical SetFee pseudo-transaction into their proposals for the same ledger. (Validators whose preferences match the existing network settings do nothing.) If a SetFee psuedo-transaction survives the consensus process to be included in a validated ledger, then the new transaction cost and reserve settings denoted by the SetFee pseudo-transaction take effect starting with the following ledger.
The Ripple Consensus Ledger is a decentralized ledger, secured by cryptography, and operated by a distributed peer-to-peer network of servers. This means that no one party, not even the Ripple, Inc., can charge a fee for access to the network.
-
However, the rules of the Ripple Consensus Ledger include several types of fees, including the transaction cost and reserve requirement, which protect the ledger against abuse. (These neutral fees are not paid to anyone.) There are also several optional ways that users of the Consensus Ledger can collect fees from each other, both inside and outside the Ripple Consensus Ledger.
+
However, the rules of the Ripple Consensus Ledger include several types of fees, including the transaction cost and reserve requirement, which protect the ledger against abuse. (These neutral fees are not paid to anyone.) There are also several optional ways that users of the Consensus Ledger can collect fees from each other, both inside and outside the Ripple Consensus Ledger.
In the Ledger
-
The transaction cost (sometimes called the transaction fee) is a miniscule amount of XRP destroyed in order to send a transaction. This cost scales with the load of the network, which protects the peer-to-peer network from spam. See Transaction Cost for more information.
-
The account reserve is a minimum amount of XRP that an account must possess. It scales with the number of objects the account owns in the ledger. This disincentivizes users from increasing the size of the ledger needlessly. See Reserves for more information.
-
Transfer fees are optional percentage fees that gateways can charge to transfer the currencies they issue to other accounts within the Ripple Consensus Ledger. See Transfer Fees for more information.
+
The transaction cost (sometimes called the transaction fee) is a miniscule amount of XRP destroyed in order to send a transaction. This cost scales with the load of the network, which protects the peer-to-peer network from spam. See Transaction Cost for more information.
+
The account reserve is a minimum amount of XRP that an account must possess. It scales with the number of objects the account owns in the ledger. This disincentivizes users from increasing the size of the ledger needlessly. See Reserves for more information.
+
Transfer fees are optional percentage fees that gateways can charge to transfer the currencies they issue to other accounts within the Ripple Consensus Ledger. See Transfer Fees for more information.
Trust line quality is a setting that allows an account to value balances on a trust line at higher or lower than face value. This can lead to situations that are similar to charging a fee. Trust line quality does not apply to XRP, which is not tied to a trust line.
Outside the Ledger
While the above values are the only fees built into the Ripple Consensus Ledger, people can still invent ways to charge fees associated with the ledger. A common example is withdrawal or deposit fees charged by gateways, which are assessed when you use the gateway to get money into or out of the Ripple Consensus Ledger. This may cover the costs of transferring balances on traditional payment rails, or it may be in addition to those costs.
Payments can still occur directly between the two parties of the frozen trust line.
The counterparty of that trust line can no longer decrease its balance on the frozen trust line, except in direct payments to the issuer. The counterparty can only send the frozen issuances directly to the issuer.
The counterparty can still receive payments from others on the frozen trust line.
-
The counterparty's offers to sell the currency issued on the frozen trust line are considered unfunded.
+
The counterparty's offers to sell the currency issued on the frozen trust line are considered unfunded.
A gateway can freeze the trust line linking it to a counterparty if that counterparty shows suspicious activity or violates the gateway's terms of use. The gateway should also freeze the counterparty in any other systems the gateway operates that are connected to the Ripple Consensus Ledger. (Otherwise, an account might still be able to engage in undesired activity by sending payments through the gateway.)
-
An individual account can freeze its trust line to a gateway. This has no effect on transactions between the gateway and other users. It does, however, prevent other accounts, including operational accounts, from sending that gateway's issued currency to the individual account. This type of individual freeze has no effect on offers.
+
An individual account can freeze its trust line to a gateway. This has no effect on transactions between the gateway and other users. It does, however, prevent other accounts, including operational accounts, from sending that gateway's issued currency to the individual account. This type of individual freeze has no effect on offers.
The Individual Freeze applies to a single currency only. In order to freeze multiple currencies with a particular counterparty, the account must enable Individual Freeze on the trust lines for each currency individually.
An account cannot enable the Individual Freeze setting if it has previously enabled the No Freeze setting.
Global Freeze
The Global Freeze feature is a setting on an account. When an issuing account enables the Global Freeze feature, the following rules apply:
-
All counterparties of the frozen issuing account can no longer decrease the balances in their trust lines to the frozen account, except in direct payments to the issuer. (This also affects any operational accounts.)
+
All counterparties of the frozen issuing account can no longer decrease the balances in their trust lines to the frozen account, except in direct payments to the issuer. (This also affects any operational accounts.)
Counterparties of the frozen issuing account can still send and receive payments directly to and from the issuing account.
-
All offers to sell currencies issued by the frozen account are considered unfunded.
+
All offers to sell currencies issued by the frozen account are considered unfunded.
-
It can be useful to enable Global Freeze on a gateway's issuing account if an operational account is compromised, or immediately after regaining control of a compromised issuing account. This stops the flow of funds, preventing attackers from getting away with any more money or at least making it easier to track what happened. In addition to enacting a Global Freeze in the Ripple Consensus Ledger, a financial institution should also suspend activities in its connectors to outside systems.
-
It can also be useful to enable Global Freeze if a gateway intends to migrate to a new issuing account, or if the gateway intends to cease doing business. This locks the funds at a specific point in time, so users cannot trade them away for other currencies.
+
It can be useful to enable Global Freeze on a gateway's issuing account if an operational account is compromised, or immediately after regaining control of a compromised issuing account. This stops the flow of funds, preventing attackers from getting away with any more money or at least making it easier to track what happened. In addition to enacting a Global Freeze in the Ripple Consensus Ledger, a financial institution should also suspend activities in its connectors to outside systems.
+
It can also be useful to enable Global Freeze if a gateway intends to migrate to a new issuing account, or if the gateway intends to cease doing business. This locks the funds at a specific point in time, so users cannot trade them away for other currencies.
Global Freeze applies to all currencies issued and held by the account. You cannot enable Global Freeze for only one currency. If you want to have the ability to freeze some currencies and not others, you should use different accounts for each currency.
An account can always enable the Global Freeze setting. However, if the account has previously enabled the No Freeze setting, it can never disable Global Freeze.
No Freeze
@@ -165,11 +166,11 @@
The Ripple Consensus Ledger cannot force a gateway to honor the obligations that its issued funds represent, so giving up the ability to enable a Global Freeze cannot protect customers. However, giving up the ability to disable a Global Freeze ensures that the Global Freeze feature is not used unfairly against some customers.
The No Freeze setting applies to all currencies issued to and from an account. If you want to be able to freeze some currencies but not others, you should use different accounts for each currency.
-
You can only enable the No Freeze setting with a transaction signed by your account's master key. You cannot use a Regular Key or a multi-signed transaction to enable No Freeze.
+
You can only enable the No Freeze setting with a transaction signed by your account's master key. You cannot use a Regular Key or a multi-signed transaction to enable No Freeze.
Technical Details
Enabling or Disabling Individual Freeze
Using rippled
-
To enable or disable Individual Freeze on a specific trust line, send a TrustSet transaction. Use the tfSetFreeze flag to enable a freeze, and the tfClearFreeze flag to disable it. The fields of the transaction should be as follows:
+
To enable or disable Individual Freeze on a specific trust line, send a TrustSet transaction. Use the tfSetFreeze flag to enable a freeze, and the tfClearFreeze flag to disable it. The fields of the transaction should be as follows:
@@ -216,8 +217,8 @@
-
Set the Fee, Sequence, and LastLedgerSequence parameters in the typical way.
-
Example of submitting a TrustSet transaction to enable an individual freeze using the WebSocket API:
+
Set the Fee, Sequence, and LastLedgerSequence parameters in the typical way.
+
Example of submitting a TrustSet transaction to enable an individual freeze using the WebSocket API:
(Reminder: Never transmit your account secret to an untrusted server or over an insecure channel.)
Using RippleAPI
-
To enable or disable Individual Freeze on a specific trust line, prepare a Trustline transaction using the prepareTrustline method. The fields of the trustline parameter should be set as follows:
+
To enable or disable Individual Freeze on a specific trust line, prepare a Trustline transaction using the prepareTrustline method. The fields of the trustline parameter should be set as follows:
To enable Global Freeze on an account, send an AccountSet transaction with the asfGlobalFreeze flag value in the SetFlag field. To disable Global Freeze, put the asfGlobalFreeze flag value in the ClearFlag field instead.
-
Example of submitting an AccountSet transaction to enable Global Freeze using the WebSocket API:
+
To enable Global Freeze on an account, send an AccountSet transaction with the asfGlobalFreeze flag value in the SetFlag field. To disable Global Freeze, put the asfGlobalFreeze flag value in the ClearFlag field instead.
+
Example of submitting an AccountSet transaction to enable Global Freeze using the WebSocket API:
(Reminder: Never transmit your account secret to an untrusted server or over an insecure channel.)
Using RippleAPI
-
To enable or disable Global Freeze on an account, prepare a Settings transaction using the prepareSettings method. The settings parameter should be an object set as follows:
+
To enable or disable Global Freeze on an account, prepare a Settings transaction using the prepareSettings method. The settings parameter should be an object set as follows:
@@ -373,7 +374,7 @@ api.connect().then(() => {
-
The rest of the transaction flow is the same as any other transaction.
+
The rest of the transaction flow is the same as any other transaction.
Example JavaScript (ECMAScript 6) code to enable Global Freeze on an account:
To enable No Freeze on an account, send an AccountSet transaction with the asfNoFreeze flag value in the SetFlag field. You must sign this transaction using the master key. Once enabled, you cannot disable No Freeze.
-
Example of submitting an AccountSet transaction to enable No Freeze using the WebSocket API:
+
To enable No Freeze on an account, send an AccountSet transaction with the asfNoFreeze flag value in the SetFlag field. You must sign this transaction using the master key. Once enabled, you cannot disable No Freeze.
+
Example of submitting an AccountSet transaction to enable No Freeze using the WebSocket API:
(Reminder: Never transmit your account secret to an untrusted server or over an insecure channel.)
Using RippleAPI
-
To enable No Freeze on an account, prepare a Settings transaction using the prepareSettings method. Once enabled, you cannot disable No Freeze. The settings parameter should be an object set as follows:
+
To enable No Freeze on an account, prepare a Settings transaction using the prepareSettings method. Once enabled, you cannot disable No Freeze. The settings parameter should be an object set as follows:
@@ -454,7 +455,7 @@ api.connect().then(() => {
-
You must sign this transaction using the master key. The rest of the transaction flow is the same as any other transaction.
+
You must sign this transaction using the master key. The rest of the transaction flow is the same as any other transaction.
Example JavaScript (ECMAScript 6) code to enable No Freeze on an account:
To see if a trust line has an Individual Freeze enabled, use the account_lines method with the following parameters:
+
To see if a trust line has an Individual Freeze enabled, use the account_lines method with the following parameters:
@@ -578,7 +579,7 @@ api.connect().then(() => {
The field "freeze": true indicates that rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn has enabled Individual Freeze on the USD trust line to rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW. The lack of a field "freeze_peer": true indicates that the counterparty has not frozen the trust line.
Using RippleAPI
-
To see if a trust line has an Individual Freeze enabled, use the getTrustlines method with the following parameters:
+
To see if a trust line has an Individual Freeze enabled, use the getTrustlines method with the following parameters:
@@ -663,7 +664,7 @@ api.connect().then(() => {
Checking for Global Freeze and No Freeze
Using rippled
-
To see if an account has Global Freeze and/or No Freeze enabled, use the account_info method with the following parameters:
+
To see if an account has Global Freeze and/or No Freeze enabled, use the account_info method with the following parameters:
@@ -687,8 +688,8 @@ api.connect().then(() => {
Check the value of the account_data.Flags field of the response using the bitwise-AND operator:
-
If Flags AND 0x00400000 (lsfGlobalFreeze) is nonzero: Global Freeze is enabled.
-
If Flags AND 0x00200000 (lsfNoFreeze) is nonzero: No Freeze is enabled.
+
If Flags AND 0x00400000 (lsfGlobalFreeze) is nonzero: Global Freeze is enabled.
+
If Flags AND 0x00200000 (lsfNoFreeze) is nonzero: No Freeze is enabled.
Example WebSocket request:
{
@@ -740,7 +741,7 @@ console.log(currentFlags & lsfNoFreeze); //0
//therefore, No Freeze is not enabled
Using RippleAPI
-
To see if an account has Global Freeze and/or No Freeze enabled, use the getSettings method with the following parameters:
+
To see if an account has Global Freeze and/or No Freeze enabled, use the getSettings method with the following parameters:
The rippled API has two methods that can be used for pathfinding. The ripple_path_find command does a one-time lookup of possible path sets. The path_find command (WebSocket only) expands on the initial search with follow-up responses whenever a ledger closes or the server finds a better path.
-
You can have rippled automatically fill in paths when you sign it, by including the build_path field in a request to the sign command or submit command (sign-and-submit mode). However, we recommend pathfinding separately and confirming the results prior to signing, in order to avoid surprises. There are no guarantees on how expensive the paths the server finds will be at the time of submission. (Although rippled is designed to search for the cheapest paths possible, it may not always find them. Untrustworthy rippled instances could also be modified to change this behavior for profit.)
+
The rippled API has two methods that can be used for pathfinding. The ripple_path_find command does a one-time lookup of possible path sets. The path_find command (WebSocket only) expands on the initial search with follow-up responses whenever a ledger closes or the server finds a better path.
+
You can have rippled automatically fill in paths when you sign it, by including the build_path field in a request to the sign command or submit command (sign-and-submit mode). However, we recommend pathfinding separately and confirming the results prior to signing, in order to avoid surprises. There are no guarantees on how expensive the paths the server finds will be at the time of submission. (Although rippled is designed to search for the cheapest paths possible, it may not always find them. Untrustworthy rippled instances could also be modified to change this behavior for profit.)
Finding paths is a very challenging problem that changes slightly every few seconds as new ledgers are validated, so rippled is not designed to find the absolute best path. Still, you can find several possible paths and estimate the cost of delivering a particular amount.
Implied Steps
-
By convention, several steps of a path are implied by the fields of the Payment transaction: specifically, the Account (sender), Destination (receiver), Amount (currency and amount to be delivered) and SendMax (currency and amount to be sent, if specified). The implied steps are as follows:
+
By convention, several steps of a path are implied by the fields of the Payment transaction: specifically, the Account (sender), Destination (receiver), Amount (currency and amount to be delivered) and SendMax (currency and amount to be sent, if specified). The implied steps are as follows:
The first step of a path is always implied to be the sender of the transaction, as defined by the transaction's Account field.
If the transaction includes a SendMax field with an issuer that is not the sender of the transaction, that issuer is implied to be the second step of the path.
-
If issuer of the SendMaxis the sending account, then the path starts at the sending account, and may use any of that account's trust lines in the given currency. See special values for SendMax and Amount for details.
+
If issuer of the SendMaxis the sending account, then the path starts at the sending account, and may use any of that account's trust lines in the given currency. See special values for SendMax and Amount for details.
If the Amount field of the transaction includes an issuer that is not the same as the Destination of the transaction, that issuer is implied to be the second-to-last step of the path.
@@ -168,7 +169,7 @@
The following diagram enumerates all possible default paths:
-
You can use the tfNoDirectRipple flag to disable the default path. In this case, the transaction can only execute using the paths explicitly included in the transaction. Traders can use this option to take arbitrage opportunities.
+
You can use the tfNoDirectRipple flag to disable the default path. In this case, the transaction can only execute using the paths explicitly included in the transaction. Traders can use this option to take arbitrage opportunities.
Path Specifications
A path set is an array. Each member of the path set is another array that represents an individual path. Each member of a path is an object that specifies the step. A step has the following fields:
Many objects in the ledger are owned by a particular account, and therefore count toward the reserve requirement of that account. When objects are removed from the ledger, they no longer count against their owner's reserve requirement.
-
Offers are owned by the account that placed them. An Offer can be automatically removed from the ledger if it is fully consumed or if it is found unfunded during transaction processing. Alternatively, the owner can cancel an offer by sending an OfferCancel transaction, or by sending an OfferCreate transaction that contains an OfferSequence parameter.
-
Trust lines are shared between two accounts. The owner reserve can apply to one or both of the accounts, depending on whether the fields that account controls are in their default state. See Contributing to the Owner Reserve for details.
-
Owner directories list all the ledger nodes that contribute to an account's owner reserve. However, the owner directory itself does not count towards the reserve.
+
Offers are owned by the account that placed them. An Offer can be automatically removed from the ledger if it is fully consumed or if it is found unfunded during transaction processing. Alternatively, the owner can cancel an offer by sending an OfferCancel transaction, or by sending an OfferCreate transaction that contains an OfferSequence parameter.
+
Trust lines are shared between two accounts. The owner reserve can apply to one or both of the accounts, depending on whether the fields that account controls are in their default state. See Contributing to the Owner Reserve for details.
+
Owner directories list all the ledger nodes that contribute to an account's owner reserve. However, the owner directory itself does not count towards the reserve.
Owner Reserve Edge Cases
-
The Ripple Consensus Ledger considers an OfferCreate transaction to be an explicit statement of willingness to hold an asset. Consuming the offer automatically creates a trust line (with limit 0, and a balance above that limit) for the taker_pays currency if such a trust line does not exist. However, if the offer's owner does not possess enough XRP to meet the additional reserve requirement of the new trust line, the offer is considered unfunded. See also: Lifecycle of an Offer.
+
The Ripple Consensus Ledger considers an OfferCreate transaction to be an explicit statement of willingness to hold an asset. Consuming the offer automatically creates a trust line (with limit 0, and a balance above that limit) for the taker_pays currency if such a trust line does not exist. However, if the offer's owner does not possess enough XRP to meet the additional reserve requirement of the new trust line, the offer is considered unfunded. See also: Lifecycle of an Offer.
Going Below the Reserve Requirement
-
During transaction processing, a transaction can only be successful if the sending account possesses at least the reserve requirement in XRP. In the process, the transaction cost destroys some of the sending account's XRP balance. This can cause an account to go below the reserve requirement.
+
During transaction processing, a transaction can only be successful if the sending account possesses at least the reserve requirement in XRP. In the process, the transaction cost destroys some of the sending account's XRP balance. This can cause an account to go below the reserve requirement.
When an account has less XRP than its current reserve requirement, it cannot send new transactions. Even so, it continues to exist in the ledger, as all accounts do. Unless the reserve requirements decrease, the only way for the account to become able to send transactions again is for it to receive enough XRP that it meets the reserve requirement.
-
Exception: When an account is below the reserve requirement, it can send new OfferCreate transactions to acquire more XRP, or other currencies on its existing trust lines. These transactions cannot create new trust lines, or Offer nodes in the ledger, so they can only execute trades that consume Offers that are already in the order books.
+
Exception: When an account is below the reserve requirement, it can send new OfferCreate transactions to acquire more XRP, or other currencies on its existing trust lines. These transactions cannot create new trust lines, or Offer nodes in the ledger, so they can only execute trades that consume Offers that are already in the order books.
Changing the Reserve Requirements
-
The Ripple Consensus Ledger has a mechanism for changing the reserve requirements in order to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See Fee Voting for more information.
+
The Ripple Consensus Ledger has a mechanism for changing the reserve requirements in order to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See Fee Voting for more information.
The transaction cost is not paid to any party: the XRP is irrevocably destroyed. Since no new XRP can ever be created, this makes XRP more scarce, and consequently benefits all holders of XRP by making XRP more valuable.
Load Scaling
-
Each rippled server independently scales the transaction cost based on its current load. If you submit a transaction with a Fee value that is lower than current load-based transaction cost of the rippled server, that server neither applies nor relays the transaction. (Note: If you submit a transaction through an admin connection, the server applies and relays the transaction as long as the transaction cost meets the overall minimum.) A transaction is very unlikely to survive the consensus process unless its Fee value meets the requirements of a majority of servers.
+
Each rippled server independently scales the transaction cost based on its current load. If you submit a transaction with a Fee value that is lower than current load-based transaction cost of the rippled server, that server neither applies nor relays the transaction. (Note: If you submit a transaction through an admin connection, the server applies and relays the transaction as long as the transaction cost meets the overall minimum.) A transaction is very unlikely to survive the consensus process unless its Fee value meets the requirements of a majority of servers.
Querying the Transaction Cost
The rippled APIs have two ways to query the transaction cost: the server_info command (intended for humans) and the server_state command (intended for machines).
server_info
-
The server_info command reports the unscaled minimum XRP cost, as of the previous ledger, as validated_ledger.base_fee_xrp, in the form of decimal XRP. The actual cost necessary to relay a transaction is scaled by multiplying that base_fee_xrp value by the load_factor parameter in the same response, which represents the server's current load level. In other words:
+
The server_info command reports the unscaled minimum XRP cost, as of the previous ledger, as validated_ledger.base_fee_xrp, in the form of decimal XRP. The actual cost necessary to relay a transaction is scaled by multiplying that base_fee_xrp value by the load_factor parameter in the same response, which represents the server's current load level. In other words:
Current Transaction Cost in XRP = base_fee_xrp × load_factor
server_state
-
The server_state command returns a direct representation of rippled's internal load calculations. In this case, the effective load rate is the ratio of the current load_factor to the load_base. The validated_ledger.base_fee parameter reports the minimum transaction cost in drops of XRP. This design enables rippled to calculate the transaction cost using only integer math, while still allowing a reasonable amount of fine-tuning for server load. The actual calculation of the transaction cost is as follows:
+
The server_state command returns a direct representation of rippled's internal load calculations. In this case, the effective load rate is the ratio of the current load_factor to the load_base. The validated_ledger.base_fee parameter reports the minimum transaction cost in drops of XRP. This design enables rippled to calculate the transaction cost using only integer math, while still allowing a reasonable amount of fine-tuning for server load. The actual calculation of the transaction cost is as follows:
Current Transaction Cost in Drops = (base_fee × load_factor) ÷ load_base
Specifying the Transaction Cost
-
Every signed transaction must include the transaction cost in the Fee field. Like all fields of a signed transaction, this field cannot be changed without invalidating the signature.
+
Every signed transaction must include the transaction cost in the Fee field. Like all fields of a signed transaction, this field cannot be changed without invalidating the signature.
As a rule, the Ripple Consensus Ledger executes transactions exactly as they are signed. (To do anything else would be difficult to coordinate across a decentralized consensus network, at the least.) As a consequence of this, every transaction destroys the exact amount of XRP specified by the Fee field, even if it is much more than the current minimum transaction cost for any part of the network. The transaction cost can even destroy XRP that would otherwise be set aside for an account's reserve requirement.
Before signing a transaction, we recommend looking up the current load-based transaction cost. If the transaction cost is currently high due to load scaling, you may want to wait for it to decrease. If you do not plan on submitting the transaction immediately, we recommend specifying a slightly higher transaction cost to account for future load-based fluctuations in the transaction cost.
Automatically Specifying the Transaction Cost
When you sign a transaction online, you can omit the Fee field. In this case, rippled or ripple-lib looks up an appropriate value based on the state of the peer-to-peer network, and includes it before signing the transaction. However, there are several drawbacks and limitations to automatically filling in the transaction cost in this manner:
If the network's transaction cost goes up between signing and distributing the transaction, the transaction may not be confirmed.
-
In the worst case, the transaction may be stuck in a state of being neither definitively confirmed or rejected, unless it included a LastLedgerSequence parameter or until you cancel it with a new transaction that uses the same Sequence number. See reliable transaction submission for best practices.
+
In the worst case, the transaction may be stuck in a state of being neither definitively confirmed or rejected, unless it included a LastLedgerSequence parameter or until you cancel it with a new transaction that uses the same Sequence number. See reliable transaction submission for best practices.
You do not know in advance exactly what value you are signing for the Fee field.
-
If you are using rippled, you can also use the fee_mult_max parameter of the sign command to set a limit to the load scaling you are willing to sign.
+
If you are using rippled, you can also use the fee_mult_max parameter of the sign command to set a limit to the load scaling you are willing to sign.
You cannot look up the current transaction cost from an offline machine.
Transaction Costs and Failed Transactions
-
Since the purpose of the transaction cost is to protect the peer-to-peer Ripple network from excessive load, it should apply to any transaction that gets distributed to the network, regardless of whether or not that transaction succeeds. However, in order to affect the shared global ledger, a transaction must be included in a validated ledger. Thus, rippled servers attempt to include failed transactions in ledgers, with tec status codes ("tec" stands for "Transaction Engine - Claimed fee only").
+
Since the purpose of the transaction cost is to protect the peer-to-peer Ripple network from excessive load, it should apply to any transaction that gets distributed to the network, regardless of whether or not that transaction succeeds. However, in order to affect the shared global ledger, a transaction must be included in a validated ledger. Thus, rippled servers attempt to include failed transactions in ledgers, with tec status codes ("tec" stands for "Transaction Engine - Claimed fee only").
The transaction cost is only debited from the sender's XRP balance when the transaction actually becomes included in a validated ledger. This is true whether the transaction is considered successful or fails with a tec code.
-
If a transaction's failure is final, the rippled server does not relay it to the network. Consequently, that transaction does not get included in a validated ledger, and it cannot have any effect on anyone's XRP balance.
+
If a transaction's failure is final, the rippled server does not relay it to the network. Consequently, that transaction does not get included in a validated ledger, and it cannot have any effect on anyone's XRP balance.
Insufficient XRP
-
When a rippled server initially evaluates a transaction, it rejects the transaction with the error code terINSUF_FEE_B if the sending account does not have a high enough XRP balance to pay the XRP transaction cost. Since this is a ter (Retry) code, the rippled server retries the transaction without relaying it to the network, until the transaction's outcome is final.
+
When a rippled server initially evaluates a transaction, it rejects the transaction with the error code terINSUF_FEE_B if the sending account does not have a high enough XRP balance to pay the XRP transaction cost. Since this is a ter (Retry) code, the rippled server retries the transaction without relaying it to the network, until the transaction's outcome is final.
When a transaction has already been distributed to the network, but the account does not have sufficient XRP to pay the transaction cost, the result code tecINSUFF_FEE occurs instead. In this case, the account pays all the XRP it can, ending with 0 XRP. This can occur because rippled decides whether to relay the transaction to the network based on its in-progress ledger, but transactions may be dropped or reordered when building the consensus ledger.
Key Reset Transaction
-
As a special case, an account can send a SetRegularKey transaction with a transaction cost of 0, as long as the account's lsfPasswordSpent flag is disabled. This transaction must be signed by the account's master key. Sending this transaction enables the lsfPasswordSpent flag.
+
As a special case, an account can send a SetRegularKey transaction with a transaction cost of 0, as long as the account's lsfPasswordSpent flag is disabled. This transaction must be signed by the account's master key. Sending this transaction enables the lsfPasswordSpent flag.
This feature is designed to allow you to recover an account if the regular key is compromised, without worrying about whether the compromised account has any XRP available. This way, you can regain control of the account before you send additional XRP to it.
-
The lsfPasswordSpent flag starts out disabled. If enabled, it gets disabled again when the account receives a Payment of XRP.
+
The lsfPasswordSpent flag starts out disabled. If enabled, it gets disabled again when the account receives a Payment of XRP.
Changing the Transaction Cost
-
In addition to short-term scaling to account for load, the Ripple Consensus Ledger has a mechanism for changing the minimum transaction cost in order to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See Fee Voting for more information.
+
In addition to short-term scaling to account for load, the Ripple Consensus Ledger has a mechanism for changing the minimum transaction cost in order to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See Fee Voting for more information.
The transfer fee is represented by a setting on the issuing (cold wallet) account. The transfer fee has a maximum precision of 9 digits, and cannot be less than 0% or greater than 100%. The TransferRate setting applies to all currencies issued by the same account. If you want to have different transfer fee percentages for different currencies, use different cold wallets to issue each currency.
RippleAPI
In RippleAPI, the transfer fee is specified in the transferRate field, as an integer which represents the amount you must send in order for the recipient to get 1 billion units of the same currency. A transferRate of 1005000000 is equivalent to a transfer fee of 0.5%. By default, the transferRate is set to no fee. The value of transferRate cannot be less than 1000000000 or more than 2000000000. The value null is special: it is equivalent to 1000000000, meaning no fee.
-
A gateway can send a Settings transaction with its cold wallet to change the transferRate for its issuances.
In rippled's JSON-RPC and WebSocket APIs, the transfer fee is specified in the TransferRate field, as an integer which represents the amount you must send in order for the recipient to get 1 billion units of the same currency. A TransferRate of 1005000000 is equivalent to a transfer fee of 0.5%. By default, the TransferRate is set at 1000000000, indicating no fee. The value of TransferRate cannot be less than 1000000000 or more than 2000000000. However, value 0 is special: it is equivalent to 1000000000, meaning no fee.
-
A gateway can submit an AccountSet transaction from its cold wallet to change the TransferRate for its issuances.
-
You can check an account's TransferRate with the account_info command. If the TransferRate is omitted, then that indicates no fee.
+
A gateway can submit an AccountSet transaction from its cold wallet to change the TransferRate for its issuances.
+
You can check an account's TransferRate with the account_info command. If the TransferRate is omitted, then that indicates no fee.