From 30fc1c3e8d9ae4b4357a4437342fcd35f31520af Mon Sep 17 00:00:00 2001 From: Rome Reginelli Date: Tue, 31 May 2016 13:16:21 -0700 Subject: [PATCH] Style revisions (#189) * Dactyl style checker - tune word list, handle rule overrides * massive revisions for style guide compliance (DOC-381) * Data API - make fieldnames code (so they're exempt from style rules) * Dactyl style checker - properly check only content elements --- concept-amendments.html | 26 +- concept-fee-voting.html | 6 +- concept-fees.html | 12 +- concept-freeze.html | 94 +- ...ept-issuing-and-operational-addresses.html | 14 +- concept-noripple.html | 14 +- concept-paths.html | 27 +- concept-reserves.html | 26 +- concept-stand-alone-mode.html | 2 +- concept-transaction-cost.html | 28 +- concept-transfer-fees.html | 24 +- content/concept-amendments.md | 26 +- content/concept-fee-voting.md | 6 +- content/concept-fees.md | 12 +- content/concept-freeze.md | 94 +- ...ncept-issuing-and-operational-addresses.md | 6 +- content/concept-noripple.md | 14 +- content/concept-paths.md | 28 +- content/concept-reserves.md | 26 +- content/concept-stand-alone-mode.md | 2 +- content/concept-transaction-cost.md | 28 +- content/concept-transfer-fees.md | 27 +- content/data_types/account_sequence.md | 2 +- content/data_types/address.md | 3 +- content/data_types/hash.md | 3 +- content/data_types/ledger_index.md | 6 +- content/reference-data-api.md | 1001 ++++++++-------- content/reference-ledger-format.md | 36 +- content/reference-rippled.md | 187 +-- content/reference-transaction-format.md | 167 +-- content/snippets/gateways-intro.md | 5 + ...issuing-and-operational-addresses-intro.md | 6 +- content/tutorial-gateway-guide.md | 108 +- content/tutorial-multisign.md | 8 +- ...utorial-reliable-transaction-submission.md | 50 +- content/tutorial-rippleapi-beginners-guide.md | 25 +- content/tutorial-rippled-setup.md | 46 +- reference-data-api.html | 1047 +++++++++-------- reference-ledger-format.html | 42 +- reference-rippled.html | 200 ++-- reference-transaction-format.html | 168 +-- tool/dactyl_style_checker.py | 61 +- tool/phrase_substitutions.yaml | 23 +- tool/word_substitutions.yaml | 55 +- tutorial-gateway-guide.html | 116 +- tutorial-multisign.html | 8 +- tutorial-reliable-transaction-submission.html | 50 +- tutorial-rippleapi-beginners-guide.html | 24 +- tutorial-rippled-setup.html | 47 +- 49 files changed, 2054 insertions(+), 1982 deletions(-) create mode 100644 content/snippets/gateways-intro.md diff --git a/concept-amendments.html b/concept-amendments.html index 45fda1f7e8..ca866bbee5 100644 --- a/concept-amendments.html +++ b/concept-amendments.html @@ -164,16 +164,16 @@

The Amendments system provides a means of introducing new features to the decentralized Ripple consensus network without causing disruptions. The amendments system works by utilizing the core consensus process of the network to approve any changes by showing continuous support before those changes go into effect. An amendment normally requires 80% support for two weeks before it can apply.

When an Amendment has been enabled, it applies permanently to all ledger versions after the one that included it. You cannot disable an Amendment, unless you introduce a new Amendment to do so.

Background

-

Any changes to transaction processing could cause servers to build a different ledger with the same set of transactions. If only a portion of validators (rippled servers participating in consensus) have upgraded to a new version of the software, this could cause anything from minor inconveniences to full outages. In the minor case, a minority of servers spend more time and bandwidth fetching the actual consensus ledger because they cannot build it using the transaction processing rules they already know. In the worst case, the consensus process might be unable to validate new ledger versions because servers with different rules could not reach a consensus on the exact ledger to build.

-

Amendments provide a solution to this problem, so that new features can be enabled only when enough validators support those features.

-

Users and businesses who rely on the Ripple Consensus Ledger can also use Amendments to provide advance notice of changes in transaction processing that might affect their business. However, API changes that do not impact transaction processing or the consensus process do not require Amendments.

+

Any changes to transaction processing could cause servers to build a different ledger with the same set of transactions. If some validators (rippled servers participating in consensus) have upgraded to a new version of the software while other validators use the old version, this could cause anything from minor inconveniences to full outages. In the minor case, a minority of servers spend more time and bandwidth fetching the actual consensus ledger because they cannot build it using the transaction processing rules they already know. In the worst case, the consensus process might be unable to validate new ledger versions because servers with different rules could not reach a consensus on the exact ledger to build.

+

Amendments solve this problem, so that new features can be enabled only when enough validators support those features.

+

Users and businesses who rely on the Ripple Consensus Ledger can also use Amendments to provide advance notice of changes in transaction processing that might affect their business. However, API changes that do not impact transaction processing or the consensus process do not need Amendments.

About Amendments

-

An amendment is a fully-functional feature or change, waiting to be enabled by the peer-to-peer network as a part of the consensus process. A rippled server that wants to use an amendment has code for two modes: without the amendment (previous behavior) and with the amendment (new behavior).

+

An amendment is a fully-functional feature or change, waiting to be enabled by the peer-to-peer network as a part of the consensus process. A rippled server that wants to use an amendment has code for two modes: without the amendment (old behavior) and with the amendment (new behavior).

Every amendment has a unique identifying hex value and a short name. The short name is for human use, and is not used in the amendment process. Two servers can support the same amendment ID while using different names to describe it. An amendment's name is not guaranteed to be unique.

See also: Known Amendments

Amendment Process

Every 256th ledger is called a "flag" ledger. The process of approving an amendment starts in the ledger version immediately before the flag ledger. When rippled validator servers send validation messages for that ledger, those servers also submit votes in favor of specific amendments. (Fee Voting also occurs around flag ledgers.)

-

The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an EnableAmendment pseudo-transaction into the following ledger. The flags of an EnableAmendment pseudo-transaction indicate what the server thinks happened:

+

The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an EnableAmendment pseudo-transaction into the following ledger. The flags of an EnableAmendment pseudo-transaction show what the server thinks happened:

-

It is theoretically possible (but extremely unlikely) that a tfLostMajority EnableAmendment pseudo-transaction could be included in the same ledger as the pseudo-transaction to enable an amendment. In this case, the pseudo-transaction with the tfLostMajority pseudo-transaction has no effect.

+

Theoretically, a tfLostMajority EnableAmendment pseudo-transaction could be included in the same ledger as the pseudo-transaction to enable an amendment. In this case, the pseudo-transaction with the tfLostMajority pseudo-transaction has no effect.

Amendment Voting

Operators of rippled validators can choose which amendments to support or reject using the feature command. This decides which amendments the validator votes for in the amendment process. By default, rippled votes in favor of every amendment it knows about.

The operator of a rippled validator can "veto" an amendment. In this case, that validator never sends a vote in favor of the amendment. If enough servers veto an amendment, that prevents it from reaching consistent 80% support, so the amendment does not apply.

-

As with all aspects of the consensus process, amendment votes are only taken into account by servers that trust the validators sending those votes. Currently, Ripple (the company) recommends only trusting the 5 default validators that Ripple (the company) operates. For now, trusting only those validators is sufficient to coordinate with Ripple (the company) on releasing new features.

+

As with all aspects of the consensus process, amendment votes are only taken into account by servers that trust the validators sending those votes. Ripple (the company) recommends only trusting the 5 default validators that Ripple (the company) operates. For now, trusting only those validators is enough to coordinate with Ripple (the company) on releasing new features.

Configuring Amendment Voting

-

You can temporarily configure an amendment using the feature command. To make a persistent change to your server's support for an amendment, modify your server's rippled.cfg file.

+

You can temporarily configure an amendment using the feature command. To make a persistent change to your server's support for an amendment, change your server's rippled.cfg file.

Use the [veto_amendments] stanza to list amendments you do not want the server to vote for. Each line should contain one amendment's unique ID, optionally followed by the short name for the amendment. For example:

[veto_amendments]
 C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 Tickets
@@ -264,7 +264,7 @@ TrustSetAuth
 
 
 
-

Changes the way the transaction cost applies to proposed transactions. Modifies the consensus process to prioritize transactions that pay a higher transaction cost.

+

Changes the way the transaction cost applies to proposed transactions. Modifies the consensus process to prioritize transactions that pay a higher transaction cost.

This amendment introduces a fixed-size transaction queue for transactions that were not able to be included in the previous consensus round. If the rippled servers in the consensus network are under heavy load, they queue the transactions with the lowest transaction cost for later ledgers. Each consensus round prioritizes transactions from the queue with the largest transaction cost (Fee value), and includes as many transactions as the consensus network can process. If the transaction queue is full, transactions drop from the queue entirely, starting with the ones that have the lowest transaction cost.

While the consensus network is under heavy load, legitimate users can pay a higher transaction cost to make sure their transactions get processed. The situation persists until the entire backlog of cheap transactions is processed or discarded.

A transaction remains in the queue until one of the following happens:

@@ -286,10 +286,10 @@ TrustSetAuth -

Introduces simple multi-signing as a way to authorize transactions. Creates the SignerList ledger node type and the SignerListSet transaction type. Adds the optional Signers field to all transaction types. Modifies some transaction result codes.

+

Introduces multi-signing as a way to authorize transactions. Creates the SignerList ledger node type and the SignerListSet transaction type. Adds the optional Signers field to all transaction types. Modifies some transaction result codes.

This amendment allows addresses to have a list of signers who can authorize transactions from that address in a multi-signature. The list has a quorum and 1 to 8 weighted signers. This allows various configurations, such as "any 3-of-5" or "signature from A plus any other two signatures."

Signers can be funded or unfunded addresses. Funded addresses in a signer list can sign using a regular key (if defined) or master key (unless disabled). Unfunded addresses can sign with a master key. Multi-signed transactions have the same permissions as transactions signed with a regular key.

-

An address with a SignerList can disable the master key even if a regular key is not defined. An address with a SignerList can also remove a regular key even if the master key is disabled. Therefore, the tecMASTER_DISABLED transaction result code is renamed tecNO_ALTERNATIVE_KEY. The tecNO_REGULAR_KEY transaction result is retired and replaced with tecNO_ALTERNATIVE_KEY. Additionally, this amendment adds the following new transaction result codes:

+

An address with a SignerList can disable the master key even if a regular key is not defined. An address with a SignerList can also remove a regular key even if the master key is disabled. The tecMASTER_DISABLED transaction result code is renamed tecNO_ALTERNATIVE_KEY. The tecNO_REGULAR_KEY transaction result is retired and replaced with tecNO_ALTERNATIVE_KEY. Additionally, this amendment adds the following new transaction result codes:

  • temBAD_SIGNER
  • temBAD_QUORUM
  • @@ -312,7 +312,7 @@ TrustSetAuth -

    Provides "Suspended Payments" for XRP as a means of escrow within the Ripple Consensus Ledger. Creates the SuspendedPayment ledger node type and the new transaction types SuspendedPaymentCreate, SuspendedPaymentFinish, and SuspendedPaymentCancel.

    +

    Provides "Suspended Payments" for XRP for escrow within the Ripple Consensus Ledger. Creates the SuspendedPayment ledger node type and the new transaction types SuspendedPaymentCreate, SuspendedPaymentFinish, and SuspendedPaymentCancel.

    This amendment is still in development. The current version is enabled on the Ripple Test Net.

    TrustSetAuth

    @@ -328,7 +328,7 @@ TrustSetAuth

    Allows pre-authorization of accounting relationships (zero-balance trust lines) when using Authorized Accounts.

    -

    With this amendment enabled, a TrustSet transaction with tfSetfAuth enabled can create a new RippleState ledger node even if it keeps all the other values of the RippleState node in their default state. The new RippleState node has the lsfLowAuth or lsfHighAuth flag enabled accordingly. The sender of the transaction must have lsfRequireAuth enabled.

    +

    With this amendment enabled, a TrustSet transaction with tfSetfAuth enabled can create a new RippleState ledger node even if it keeps all the other values of the RippleState node in their default state. The new RippleState node has the lsfLowAuth or lsfHighAuth flag enabled appropriately. The sender of the transaction must have lsfRequireAuth enabled.

    Tickets

    diff --git a/concept-fee-voting.html b/concept-fee-voting.html index a617dbe4b1..711ae27cfc 100644 --- a/concept-fee-voting.html +++ b/concept-fee-voting.html @@ -149,7 +149,7 @@

    Fee Voting

    -

    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.

    +

    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 adjust to 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:

    @@ -172,7 +172,7 @@ - + @@ -180,7 +180,7 @@

    Voting Process

    Every 256th ledger is called a "flag" ledger. (A flag ledger is defined such that the ledger_index modulo 256 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 the same 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.

    In short:

    • Flag ledger -1: Validators submit votes.
    • diff --git a/concept-fees.html b/concept-fees.html index d0cb18b0d3..961457ec7a 100644 --- a/concept-fees.html +++ b/concept-fees.html @@ -156,14 +156,14 @@

      However, the rules of the Ripple Consensus Ledger include several types of fees, including neutral fees which protect the ledger against abuse. These neutral fees are not paid to anyone. There are also several optional ways that users can collect fees from each other, both inside and outside the Ripple Consensus Ledger.

      In the Ledger

      Neutral Fees

      -

      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 carelessly or maliciously. See Reserves for more information.

      +

      The transaction cost (sometimes called the transaction fee) is a miniscule amount of XRP destroyed 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 reserve requirement is a minimum amount of XRP that an account must hold. It increases with the number of objects the account owns in the ledger. This disincentivizes users from increasing the size of the ledger carelessly or maliciously. See Reserves for more information.

      Optional Fees

      -

      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.

      +

      Transfer fees are optional percentage fees that issuers can charge to transfer the currencies they issue to other addresses 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 are like charging a fee. Trust line quality does not apply to XRP, which is not tied to a trust line.

      Outside the Ledger

      -

      Although the fees described above are the only fees built into the Ripple Consensus Ledger, people can still invent ways to charge fees associated with the ledger. For example, gateways commonly charge their customers to send money into and out of the Ripple Consensus Ledger.

      -

      Many other fees are also possible. Businesses might charge for access to a client application, maintenance of non-Ripple accounts, exchange services (especially when buying XRP on a private market instead of directly within the Ripple Consensus Ledger) and any number of other services. Always be aware of the fee schedule before doing business with any gateway or other financial institution.

      +

      Although the fees described above are the only fees built into the Ripple Consensus Ledger, people can still invent ways to charge fees associated with the ledger. For example, financial institutions commonly charge their customers to send money into and out of the Ripple Consensus Ledger.

      +

      Many other fees are also possible. Businesses might charge for access to a client application, maintenance of non-Ripple accounts, exchange services (especially when buying XRP on a private market instead of directly within the Ripple Consensus Ledger) and any number of other services. Always be aware of the fee schedule before doing business with any financial institution.

      diff --git a/concept-freeze.html b/concept-freeze.html index 3a5122b8b9..e1f1782e04 100644 --- a/concept-freeze.html +++ b/concept-freeze.html @@ -168,7 +168,7 @@

      Freeze Features

      -

      The Ripple Consensus Ledger gives accounts the ability to freeze non-XRP balances, which can be useful to comply with regulatory requirements, or while investigating suspicious activity. There are three settings related to freezes:

      +

      The Ripple Consensus Ledger gives addresses the ability to freeze non-XRP balances, which can be useful to meet regulatory requirements, or while investigating suspicious activity. There are three settings related to freezes:

      • Individual Freeze - Freeze one counterparty.
      • Global Freeze - Freeze all counterparties.
      • @@ -177,37 +177,37 @@

        Because no party has a privileged place in the Ripple Consensus Ledger, the freeze feature cannot prevent a counterparty from conducting transactions in XRP or funds issued by other counterparties. No one can freeze XRP.

        All freeze settings can be enacted regardless of whether the balance(s) to be frozen are positive or negative. Either the currency issuer or the currency holder can freeze a trust line; however, the effect of a currency holder freezing an issuer is minimal.

        Individual Freeze

        -

        The Individual Freeze feature is a setting on a trust line. When an issuing account enables the Individual Freeze setting, the following rules apply:

        +

        The Individual Freeze feature is a setting on a trust line. When an issuing address enables the Individual Freeze setting, the following rules apply:

        • 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.
        -

        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 addresses, 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.

        +

        A financial institution can freeze the trust line linking it to a counterparty if that counterparty shows suspicious activity or violates the financial institution's terms of use. The financial institution should also freeze the counterparty in any other systems the financial institution operates that are connected to the Ripple Consensus Ledger. (Otherwise, an address might still be able to engage in undesired activity by sending payments through the financial institution.)

        +

        An individual address can freeze its trust line to a financial institution. This has no effect on transactions between the institution and other users. It does, however, prevent other addresses, including operational addresses, from sending that financial institution's issuances to the individual address. This type of individual freeze has no effect on offers.

        +

        The Individual Freeze applies to a single currency only. To freeze multiple currencies with a particular counterparty, the address must enable Individual Freeze on the trust lines for each currency individually.

        +

        An address cannot enable the Individual Freeze setting if it has 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:

        +

        The Global Freeze feature is a setting on an address. When an issuing address 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 addresses.)
        • -
        • 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 counterparties of the frozen issuing address can no longer decrease the balances in their trust lines to the frozen address, except in direct payments to the issuer. (This also affects any operational addresses.)
        • +
        • Counterparties of the frozen issuing address can still send and receive payments directly to and from the issuing address.
        • +
        • All offers to sell currencies issued by the frozen address are considered unfunded.
        -

        It can be useful to enable Global Freeze on a gateway's issuing account if the secret key to an operational address is compromised, or immediately after regaining control of a such an address. 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.

        +

        It can be useful to enable Global Freeze on a financial institution's issuing address if the secret key to an operational address is compromised, even after regaining control of a such an address. 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. Besides 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 financial institution intends to migrate to a new issuing address, or if the financial institution 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 address. 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 addresses for each currency.

        +

        An address can always enable the Global Freeze setting. However, if the address has enabled the No Freeze setting, it can never disable Global Freeze.

        No Freeze

        -

        The No Freeze feature is a setting on an account that permanently gives up the ability to freeze counterparties. A business can use this feature to treat its issued funds as "more like physical money" in the sense that the business cannot interfere with customers trading it among themselves. The NoFreeze setting has two effects:

        +

        The No Freeze feature is a setting on an address that permanently gives up the ability to freeze counterparties. A business can use this feature to treat its issued funds as "more like physical money" in the sense that the business cannot interfere with customers trading it among themselves. The NoFreeze setting has two effects:

          -
        • The issuing account can no longer enable Individual Freeze on trust lines to any counterparty.
        • -
        • The issuing account can still enable Global Freeze to enact a global freeze, but the account cannot disable Global Freeze.
        • +
        • The issuing address can no longer enable Individual Freeze on trust lines to any counterparty.
        • +
        • The issuing address can still enable Global Freeze to enact a global freeze, but the address cannot disable Global Freeze.
        -

        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.

        +

        The Ripple Consensus Ledger cannot force a financial institution 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 address. If you want to be able to freeze some currencies but not others, you should use different addresses for each currency.

        +

        You can only enable the No Freeze setting with a transaction signed by your address's master key secret. You cannot use a Regular Key or a multi-signed transaction to enable No Freeze.

        Technical Details

        Enabling or Disabling Individual Freeze

        Using rippled

        @@ -224,7 +224,7 @@
    - + @@ -249,7 +249,7 @@ - + @@ -281,7 +281,7 @@ "fee_mult_max": 1000 } -

    (Reminder: Never transmit your account secret to an untrusted server or over an insecure channel.)

    +

    Caution: Never send your secret key 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:

    owner_reserveAdditional amount of XRP, in drops, that an account must have on reserve for each object it owns in the ledger.How much more XRP, in drops, that an address must hold for each object it owns in the ledger. 5000000 (5 XRP)
    Account StringThe address of your Ripple account.The Ripple address to enable or disable the freeze.
    TransactionType
    LimitAmount.value StringThe amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a gateway, this is typically "0".The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a financial institution, this is typically "0".
    Flags
    @@ -306,7 +306,7 @@ - + @@ -377,7 +377,7 @@ api.connect().then(() => {

    Enabling or Disabling Global Freeze

    Using rippled

    -

    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.

    +

    To enable Global Freeze on an address, 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:

    {
       "id": 12,
    @@ -396,9 +396,9 @@ api.connect().then(() => {
       "fee_mult_max": 1000
     }
     
    -

    (Reminder: Never transmit your account secret to an untrusted server or over an insecure channel.)

    +

    Caution: Never send your secret key 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 address, prepare a Settings transaction using the prepareSettings method. The settings parameter should be an object set as follows:

    limit StringThe amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a gateway, this is typically "0".The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a financial institution, this is typically "0".
    frozen
    @@ -411,12 +411,12 @@ api.connect().then(() => { - +
    globalFreeze Booleantrue to enable a Global Freeze on this account. false to disable Global Freeze.true to enable a Global Freeze on this address. false to disable Global Freeze.

    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:

    +

    Example JavaScript (ECMAScript 6) code to enable Global Freeze on an address:

    const {RippleAPI} = require('ripple-lib');
     
     const api = new RippleAPI({
    @@ -457,7 +457,7 @@ api.connect().then(() => {
     

    Enabling No Freeze

    Using rippled

    -

    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.

    +

    To enable No Freeze on an address, 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:

    WebSocket request:

    {
    @@ -477,9 +477,9 @@ api.connect().then(() => {
       "fee_mult_max": 1000
     }
     
    -

    (Reminder: Never transmit your account secret to an untrusted server or over an insecure channel.)

    +

    Caution: Never send your secret key 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 address, 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:

    @@ -497,7 +497,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.

    -

    Example JavaScript (ECMAScript 6) code to enable No Freeze on an account:

    +

    Example JavaScript (ECMAScript 6) code to enable No Freeze on an address:

    const {RippleAPI} = require('ripple-lib');
     
     const api = new RippleAPI({
    @@ -550,12 +550,12 @@ api.connect().then(() => {
     
     account
     String
    -The Ripple address of the issuing account
    +The Ripple address of the issuer
     
     
     peer
     String
    -The Ripple address of the counterparty account
    +The Ripple address of the counterparty
     
     
     ledger_index
    @@ -564,7 +564,7 @@ api.connect().then(() => {
     
     
     
    -

    The response contains an array of trust lines, for each currency in which the issuing account and the counterparty are linked. Look for the following fields in each trust line object:

    +

    The response contains an array of trust lines, for each currency in which the issuing address and the counterparty are linked. Look for the following fields in each trust line object:

    @@ -577,7 +577,7 @@ api.connect().then(() => { - + @@ -633,16 +633,16 @@ api.connect().then(() => { - + - +
    freeze Boolean(May be omitted) true if the issuing account has frozen this trust line. If omitted, that is the same as false.(May be omitted) true if the issuing address has frozen this trust line. If omitted, that is the same as false.
    freeze_peer
    address StringThe Ripple address of the issuing accountThe Ripple address of the issuer
    options.counterparty StringThe Ripple address of the counterparty accountThe Ripple address of the counterparty
    -

    The response contains an array of trust lines, for each currency in which the issuing account and the counterparty are linked. Look for the following fields in each trust line object:

    +

    The response contains an array of trust lines, for each currency in which the issuing address and the counterparty are linked. Look for the following fields in each trust line object:

    @@ -655,7 +655,7 @@ api.connect().then(() => { - + @@ -705,7 +705,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 address has enabled Global Freeze, No Freeze, or both, use the account_info method with the following parameters:

    specification.frozen Boolean(May be omitted) true if the issuing account has frozen the trust line.(May be omitted) true if the issuing address has frozen the trust line.
    counterparty.frozen
    @@ -718,7 +718,7 @@ api.connect().then(() => { - + @@ -782,7 +782,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 address has enabled Global Freeze, No Freeze, or both, use the getSettings method with the following parameters:

    account StringThe Ripple address of the issuing accountThe Ripple address of the issuing address
    ledger_index
    @@ -795,7 +795,7 @@ console.log(currentFlags & lsfNoFreeze); //0 - +
    address StringThe Ripple address of the issuing accountThe Ripple address of the issuing address
    @@ -821,7 +821,7 @@ console.log(currentFlags & lsfNoFreeze); //0 -

    Example JavaScript (ECMAScript 6) code to check whether an account has Global Freeze or No Freeze enabled:

    +

    Example JavaScript (ECMAScript 6) code to check whether an address has Global Freeze or No Freeze enabled:

    const {RippleAPI} = require('ripple-lib');
     
     const api = new RippleAPI({
    @@ -848,7 +848,7 @@ api.connect().then(() => {
     

    See Also

    diff --git a/concept-issuing-and-operational-addresses.html b/concept-issuing-and-operational-addresses.html index 7a88288492..6ba4a0b8d9 100644 --- a/concept-issuing-and-operational-addresses.html +++ b/concept-issuing-and-operational-addresses.html @@ -154,24 +154,24 @@

    Issuing and Operational Addresses

    In the Ripple Consensus Ledger, financial institutions typically use multiple Ripple addresses to minimize the risk associated with a compromised secret key. Ripple strongly recommends the following separation of roles:

      -
    • One issuing address, also known as a "cold wallet." This address is the hub of the financial institution's accounting relationships in the ledger, but sends as few transactions as possible.
    • -
    • One or more operational addresses, also known as "hot wallets." Automated, internet-connected systems use the secret keys to these addresses to conduct day-to-day business like transfers to customers and partners.
    • -
    • Optional standby addresses, also known as "warm wallets." Trusted human operators use these addresses to transfer money to the operational addresses.
    • +
    • One issuing address, also known as a "cold wallet." This address is the hub of the financial institution's accounting relationships in the ledger, but sends as few transactions as possible.
    • +
    • One or more operational addresses, also known as "hot wallets." Automated, internet-connected systems use the secret keys to these addresses to conduct day-to-day business like transfers to customers and partners.
    • +
    • Optional standby addresses, also known as "warm wallets." Trusted human operators use these addresses to transfer money to the operational addresses.

    Funds Lifecycle

    All non-XRP currency balances (issuances) in the Ripple Consensus Ledger (RCL) are tied to accounting relationships between two Ripple addresses. When a financial institution uses Ripple's recommended separation of roles, funds relating to that institution tend to flow in a cycle.

    Diagram: Funds flow from the issuing address to standby addresses, to operational addresses, to customer and partner addresses, and finally back to the issuing address.

    -

    When the issuing address sends payments, it creates balances in the accounting relationships in the Ripple Consensus Ledger. Within the RCL, users can exchange balances across different accounting relationships, so we use the term issuances to describe any non-XRP balance. Issuances have positive value from the perspective of the counterparties. The same issuances are negative balances from the perspective of the issuing address, since they represent obligations. When the issuing address receives a payment, this reduces its obligations, erasing the issuances that were sent.

    +

    When the issuing address sends payments, it creates balances in the accounting relationships in the Ripple Consensus Ledger. Within the RCL, users can exchange balances across different accounting relationships, so we use the term issuances to describe any non-XRP balance. Issuances have negative value from the perspective of the issuing address, since they represent obligations. The same issuances have positive value from the perspective of the issuing address's counterparties. When the issuing address receives a payment, this reduces its obligations, erasing the issuances that were sent.

    The issuing address sends issuances to a standby address, or directly to an operational address. The standby addresses send those issuances to operational addresses. Operational addresses send payments to other counterparties, such as liquidity providers, partners, and other customers. Because all issuances are tied to accounting relationships with the issuing address, payments and exchanges of issuances "ripple through" the issuing address. The payment debits the sender's balance in its accounting relationship with the issuing address and credits the recipient's balance in the recipient's accounting relationship with the issuing address. The Ripple Consensus Ledger also supports more complicated paths that connect multiple issuers through order books and liquidity providers who allow their funds to ripple.

    Issuing Address

    -

    The issuing address is like a vault. Partners, customers, and operational addresses create accounting relationships (trust lines) to the issuing address, but this address sends as few transactions as possible. Periodically, a human operator creates and signs a transaction from the issuing address in order to refill the balances of a standby or operational address. Ideally, the secret key used to sign these transactions should never be accessible from any internet-connected computer.

    +

    The issuing address is like a vault. Partners, customers, and operational addresses create accounting relationships (trust lines) to the issuing address, but this address sends as few transactions as possible. Periodically, a human operator creates and signs a transaction from the issuing address to refill the balances of a standby or operational address. Ideally, the secret key used to sign these transactions should never be accessible from any internet-connected computer.

    Unlike a vault, the issuing address can receive payments directly from customers and partners. Since all transactions in the Ripple Consensus Ledger are public, automated systems can monitor for payments to the issuing address without needing a secret key.

    Issuing Address Compromise

    If a malicious actor learns the secret key behind a institution's issuing address, that actor can create new issuances without limit and trade them in the decentralized exchange. This would make it difficult for the financial institution to distinguish legitimately-obtained issuances and redeem them fairly. If a financial institution loses control of its issuing address, the institution must create a new issuing address, and all users who have accounting relationships with the old issuing address must create new accounting relationships with the new address.

    Multiple Issuing Addresses

    A financial institution can issue more than one currency in the Ripple Consensus Ledger from a single issuing address. However, there are some settings that apply equally to all currencies issued from an address, including the percentage for transfer fees and the global freeze status. If the financial institution wants the flexibility to manage settings differently for each currency, the institution must use a different issuing address for each currency.

    Operational Addresses

    -

    An operational address is like a cash register. It makes payments on behalf of the institution by transferring issuances to customers and partners. In order to sign transactions automatically, the secret key for an operational address must be stored on a server that is connected to the internet. (The secret key can be stored encrypted, but the server must decrypt it in order to sign transactions.) Customers and partners do not, and should not, create accounting relationships with an operational address.

    +

    An operational address is like a cash register. It makes payments on behalf of the institution by transferring issuances to customers and partners. To sign transactions automatically, the secret key for an operational address must be stored on a server that is connected to the internet. (The secret key can be stored encrypted, but the server must decrypt it to sign transactions.) Customers and partners do not, and should not, create accounting relationships with an operational address.

    Each operational address has a limited balance of issuances. When the balance of an operational address gets low, the financial institution refills it by sending a payment from the issuing address or a standby address.

    Operational Address Compromise

    If a malicious actor learns the secret key behind an operational address, the financial institution can only lose as much currency as that operational address holds. The institution can switch to a new operational address with no action from customers and partners.

    @@ -180,7 +180,7 @@

    When an operational address is running low on funds, a trusted user can use a standby address to refill the operational address's balance. When a standby addresses run low on funds, the institution can use the issuing address to send more currency to a standby address in a single transaction, and the standby addresses can distribute that currency among themselves if necessary. This improves security of the issuing address, allowing it to make fewer total transactions, without leaving too much money in the control of a single automated system.

    As with operational addresses, a standby address must have an accounting relationship with the issuing address, and not with customers or partners. All precautions that apply to operational addresses also apply to standby addresses.

    Standby Address Compromise

    -

    If a standby address is compromised, the results are similar to an operational address being compromised. A malicious actor can steal any balances possessed by the standby address, and the financial institution can change to a new standby address with no action from customers and partners.

    +

    If a standby address is compromised, the consequences are like an operational address being compromised. A malicious actor can steal any balances possessed by the standby address, and the financial institution can change to a new standby address with no action from customers and partners.

    diff --git a/concept-noripple.html b/concept-noripple.html index e8b9980ba8..93e4335663 100644 --- a/concept-noripple.html +++ b/concept-noripple.html @@ -156,19 +156,19 @@

    Understanding the NoRipple Flag

    In the Ripple Consensus Ledger (RCL), the "NoRipple" flag is a setting on a trust line. When an address enables the NoRipple flag on two trust lines, payments from third parties cannot "ripple" through that address on those trust lines. This protects liquidity providers from having balances shift unexpectedly between different issuers of the same currency.

    Background

    -

    "Rippling" occurs when more than one trust line is adjusted in order to make a payment. For example, if Alice owes Charlie money, and Alice also owes Bob money, then you could represent that in Ripple with trust lines like so:

    +

    "Rippling" occurs when more than one trust line is adjusted to make a payment. For example, if Alice owes Charlie money, and Alice also owes Bob money, then you could represent that in Ripple with trust lines like so:

    Charlie --($10)-- Alice -- ($20) -- Bob

    -

    If Bob wants to pay $3 to Charlie, then he could say, "Alice, take $3 of the money you owe me, and pay it to Charlie." Alice simply transfers some of the debt from Bob to Charlie. In the end, the Ripple trust lines work out like so:

    +

    If Bob wants to pay $3 to Charlie, then he could say, "Alice, take $3 of the money you owe me, and pay it to Charlie." Alice transfers some of the debt from Bob to Charlie. In the end, the Ripple trust lines work out like so:

    Charlie --($13)-- Alice --($17)-- Bob

    We call this process, where two addresses pay each other by adjusting the balances of trust lines in between them, "rippling". This is a useful and important feature of the Ripple Consensus Ledger. Rippling occurs when are linked by trust lines that use the same currency code. The issuer does not need to be the same: in fact, larger chains always involve changing issuers.

    Justification

    -

    Sometimes you do not want your balances to ripple. For example, imagine Emily has money at two different Gateways, like so

    -

    Charlie --($10)-- Gateway A --($1)-- Emily --($100)-- Gateway B --($2)-- Daniel

    +

    Sometimes you do not want your balances to ripple. For example, imagine Emily has money issued by two different financial institutions, like so

    +

    Charlie --($10)-- Institution A --($1)-- Emily --($100)-- Institution B --($2)-- Daniel

    Now Charlie can pay Daniel by rippling through Emily's address. For example, if Charlie pays Daniel $10:

    -

    Charlie --($0)-- Gateway A --($11)-- Emily --($90)-- Gateway B --($12)-- Daniel

    -

    This may surprise Emily, who does not know Charlie or Daniel. Even worse, if Gateway A charges her higher fees to withdraw her money than Gateway B, this could cost Emily money. The NoRipple flag exists to avoid this scenario. If Emily sets it on both trust lines, then payments cannot ripple through her address using those two trust lines.

    +

    Charlie --($0)-- Institution A --($11)-- Emily --($90)-- Institution B --($12)-- Daniel

    +

    This may surprise Emily, who does not know Charlie or Daniel. Even worse, if Institution A charges her higher fees to withdraw her money than Institution B, this could cost Emily money. The NoRipple flag exists to avoid this scenario. If Emily sets it on both trust lines, then payments cannot ripple through her address using those two trust lines.

    For example:

    -

    Charlie --($10)-- Gateway A --($1, NoRipple)-- Emily --($100,NoRipple)-- Gateway B --($2)-- Daniel

    +

    Charlie --($10)-- Institution A --($1, NoRipple)-- Emily --($100,NoRipple)-- Institution B --($2)-- Daniel

    Now the above scenario, where Charlie pays Daniel while rippling through Emily's address, is no longer possible.

    Specifics

    The NoRipple flag makes certain paths invalid, so that they cannot be used to make payments. A path is considered invalid if and only if it enters and exits an address node through trust lines where NoRipple has been enabled for that address.

    diff --git a/concept-paths.html b/concept-paths.html index 48515fdc09..44530258a3 100644 --- a/concept-paths.html +++ b/concept-paths.html @@ -154,41 +154,42 @@

    Paths

    -

    In the Ripple Consensus Ledger, paths define a way for payments to flow through intermediary steps on their way from sender to receiver. Paths enable cross-currency payments by connecting sender and receiver via market makers. Paths also enable complex settlement of offsetting debts.

    +

    In the Ripple Consensus Ledger, paths define a way for payments to flow through intermediary steps on their way from sender to receiver. Paths enable cross-currency payments by connecting sender and receiver through order books. Paths also enable complex settlement of offsetting debts.

    A single Payment transaction in the Ripple Consensus Ledger can use multiple paths, combining liquidity from different sources to deliver the desired amount. Thus, a transaction includes a path set, which is a collection of possible paths to take. The paths in a path set must start and end with the same currency.

    Since XRP can be sent directly to any address, an XRP-to-XRP transaction does not use any paths.

    Path Steps

    A path is made of steps that connect the sender to the receiver of the payment. Every step is either:

      -
    • Rippling through another account in the same currency
    • +
    • Rippling through another address with the same currency
    • Exchanging currency at an order book
    -

    Rippling through another account is the process of moving debt around. In the typical case, this involves reducing a gateway's obligation to one party and increasing the gateway's obligation to another party. Rippling can occur between any accounts that are connected by trust lines. See Understanding the NoRipple Flag for more examples of rippling.

    -

    In the case of a currency exchange step, the path step specifies which currency to change to, but does not record the state of the orders in the order book. Since the order of transactions is not finalized until a ledger is validated, it is impossible to determine for certain which offers a transaction will execute, until after the transaction has been validated. Consequently, you cannot know in advance which offers a transaction will take: only which order books the transaction will use. (You can make an educated guess, since each transaction takes the best available offers at the time it executes in the final ledger.)

    -

    In both types of steps, each intermediate account gains and loses approximately equal value: either a balance ripples from a trust line to another trust line in the same currency, or they exchange currencies according to a previously-placed order. In some cases, the amounts gained and lost may not be exactly equivalent, due to transfer fees, trust line quality, or rounding.

    +

    Rippling through another address is the process of moving debt around. In the typical case, this involves reducing an issuer's obligation to one party and increasing the obligation to another party. Rippling can occur between any addresses that are connected by trust lines. See Understanding the NoRipple Flag for more examples of rippling.

    +

    In the case of a currency exchange step, the path step specifies which currency to change to, but does not record the state of the Offers in the order book. The canonical order of transactions is not final until a ledger is validated, so you cannot know for certain which Offers a transaction will take, until after the transaction has been validated. (You can make an educated guess, since each transaction takes the best available Offers at the time it executes in the final ledger.)

    +

    In both types of steps, each intermediate address gains and loses approximately equal value: either a balance ripples from a trust line to another trust line in the same currency, or they exchange currencies according to a previously-placed order. In some cases, the amounts gained and lost may not be exactly equivalent, due to transfer fees, trust line quality, or rounding.

    Diagram of three example paths

    Technical Details

    Pathfinding

    -

    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 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 before signing, to avoid surprises.

    +

    Caution: 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 actual cost to execute a payment along a path can change between submission and transaction execution.

    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:

    • 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 SendMax is 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 SendMax is the sending address, then the path starts at the sending address, and may use any of that address'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.
    • Finally, last step of a path is always implied to be the receiver of a transaction, as defined by the transaction's Destination field.

    Default Paths

    -

    In addition to any paths that are specified in the transaction, a transaction can also execute along the default path. The default path is the simplest possible way to connect the implied steps of the transaction.

    +

    In addition to explicitly specified paths, a transaction can execute along the default path. The default path is the simplest possible way to connect the implied steps of the transaction.

    The default path could be any of the following:

      -
    • If the transaction is uses only one currency (regardless of issuer), then the default path assumes the payment will ripple through the accounts involved. This path will only work if there are trust lines connecting those accounts.
        -
      • If SendMax is omitted, or the issuer of the SendMax is the sender, the default path needs a trust line from the sending Account to the issuer of the destination Amount in order to work.
      • +
      • If the transaction is uses only one currency (regardless of issuer), then the default path assumes the payment should ripple through the addresses involved. This path only works if those addresses are connected by trust lines.
          +
        • If SendMax is omitted, or the issuer of the SendMax is the sender, the default path needs a trust line from the sending Account to the issuer of the destination Amount to work.
        • If the SendMax and Amount have different issuer values, and neither are the sender or receiver, the default path is probably not useful because it would need to ripple across a trust line between the two issuers. Ripple (the company) typically discourages issuers from trusting one another directly.
      • @@ -211,7 +212,7 @@ account String - Address -(Optional) If present, this path step represents rippling through the specified account. +(Optional) If present, this path step represents rippling through the specified address. currency @@ -248,7 +249,7 @@ 0x01 1 -A change of account (rippling): the account field is present. +A change of address (rippling): the account field is present. 0x10 diff --git a/concept-reserves.html b/concept-reserves.html index 57df6634de..79b87729eb 100644 --- a/concept-reserves.html +++ b/concept-reserves.html @@ -153,30 +153,30 @@

        Reserves

        The Ripple Consensus Ledger applies reserve requirements, in XRP, to protect the shared global ledger from growing excessively large as the result of spam or malicious usage. The goal is to constrain the growth of the ledger to match Moore's Law so that a current commodity-level machine can always fit the current ledger in RAM and the full ledger history on disk.

        -

        Each account in the shared global ledger must hold a minimum of XRP in order to submit transactions, and it cannot send this XRP to other accounts. You cannot create a new account unless you send enough XRP to meet the minimum reserve requirement.

        -

        The current minimum reserve requirement is 20 XRP. (This is the cost of an account that owns no additional objects in the ledger.)

        +

        To submit transactions, an address must hold a minimum amount of XRP in the shared global ledger. You cannot send this XRP to other addresses. To fund a new address, you must send enough XRP to meet the reserve requirement.

        +

        The current minimum reserve requirement is 20 XRP. (This is the cost of an address that owns no other objects in the ledger.)

        Base Reserve and Owner Reserve

        The reserve requirement is divided into two parts:

          -
        • The Base Reserve is a minimum amount of XRP that is required for every account in the ledger. Currently, this is 20 XRP (20000000 drops).
        • -
        • The Owner Reserve is an additional requirement that scales with the number of objects that the account owns in the ledger. Currently, this is 5 XRP (5000000 drops) per item.
        • +
        • The Base Reserve is a minimum amount of XRP that is required for every address in the ledger. Currently, this is 20 XRP (20000000 drops).
        • +
        • The Owner Reserve is an increase to the reserve requirement for each object that the address owns in the ledger. Currently, this is 5 XRP (5000000 drops) per item.

        Owner Reserves

        -

        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.

        +

        Many objects in the ledger are owned by a particular address, and count toward the reserve requirement of that address. 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.
        • +
        • Offers are owned by the address that placed them. Transaction automatically removes Offers that are fully consumed or found to be unfunded. 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 addresses. The owner reserve can apply to one or both of the addresses, depending on whether the fields that address controls are in their default state. See Contributing to the Owner Reserve for details.
        • A single SignerList counts as 3 to 10 objects for purposes of the owner reserve, depending on how many members it has. See also: SignerLists and Reserves.
        • -
        • 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 directories list all the ledger nodes that contribute to an address'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 hold enough XRP to also meet the owner 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.

        -

        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.

        +

        During transaction processing, a transaction can only be successful if the sending address holds at least the reserve requirement in XRP. In the process, the transaction cost destroys some of the sending address's XRP balance. This can cause an address's XRP to go below the reserve requirement.

        +

        When an address holds less XRP than its current reserve requirement, it cannot send new transactions. Even so, the address continues to exist in the ledger, as all addresses do. Unless the reserve requirements decrease, the only way for the address to become able to send transactions again is for it to receive enough XRP that it meets the reserve requirement.

        +

        Exception: When an address 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 to adjust the reserve requirements 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.

    diff --git a/concept-stand-alone-mode.html b/concept-stand-alone-mode.html index 0b022ba3c9..26a5b8b601 100644 --- a/concept-stand-alone-mode.html +++ b/concept-stand-alone-mode.html @@ -192,7 +192,7 @@

    3. (Optional) Retrieve specific ledger versions.

    If you only want the most recent ledger, you can skip this step.

    If you want to load a specific historical ledger version, use the ledger_request command to make rippled fetch it. If rippled does not already have the ledger version, you may have to run the ledger_request command multiple times until it has finished retrieving the ledger.

    -

    If you want to replay a specific historical ledger version, you must fetch both the ledger version to replay and the ledger version immediately before it. (The previous ledger version sets up the initial state upon which you apply the changes described by the ledger version you replay.)

    +

    If you want to replay a specific historical ledger version, you must fetch both the ledger version to replay and the ledger version before it. (The previous ledger version sets up the initial state upon which you apply the changes described by the ledger version you replay.)

    4. Shut down rippled.

    Use the stop command:

    rippled stop --conf=/path/to/rippled.cfg
    diff --git a/concept-transaction-cost.html b/concept-transaction-cost.html
    index e807ead847..78103abf9f 100644
    --- a/concept-transaction-cost.html
    +++ b/concept-transaction-cost.html
    @@ -166,8 +166,8 @@
           

    Transaction Cost

    -

    In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This transaction cost is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.

    -

    Every transaction must specify how much XRP it will destroy in order to pay the transaction cost.

    +

    to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This transaction cost is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.

    +

    Every transaction must specify how much XRP to destroy to pay the transaction cost.

    Current Transaction Cost

    The current transaction cost required by the network for a standard transaction is typically 0.01 XRP (10,000 drops), after load scaling. It sometimes increases due to higher than usual load.

    You can also query rippled for the current transaction cost.

    @@ -196,7 +196,7 @@

    Beneficiaries of the Transaction Cost

    -

    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.

    +

    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 benefits all holders of XRP by making XRP more valuable.

    Load Cost and Open Ledger Cost

    When the FeeEscalation amendment is enabled, there are two thresholds for the transaction cost:

      @@ -213,13 +213,13 @@

      Each rippled server maintains a cost threshold 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 meets the un-scaled minimum transaction cost.) A transaction is very unlikely to survive the consensus process unless its Fee value meets the requirements of a majority of servers.

      Open Ledger Cost

      A rippled server with the FeeEscalation amendment enabled has a second mechanism for enforcing the transaction cost, called the open ledger cost. A transaction can only be included in the open ledger if it meets the open ledger cost requirement in XRP. Transactions that do not meet the open ledger cost are queued for a following ledger instead.

      -

      For each new ledger version, the server picks a soft limit on the number of transactions to be included in the open ledger, based on the number of transactions in the previous ledger. The open ledger cost is equal to the minimum un-scaled transaction cost until the number of transactions in the open ledger is equal to the soft limit. After that, the open ledger cost increases exponentially for each additional transaction included in the open ledger. For the next ledger, the server increases the soft limit if the current ledger contained more transactions than the soft limit, and decreases the soft limit if the consensus process takes more than 5 seconds.

      +

      For each new ledger version, the server picks a soft limit on the number of transactions to be included in the open ledger, based on the number of transactions in the previous ledger. The open ledger cost is equal to the minimum un-scaled transaction cost until the number of transactions in the open ledger is equal to the soft limit. After that, the open ledger cost increases exponentially for each transaction included in the open ledger. For the next ledger, the server increases the soft limit if the current ledger contained more transactions than the soft limit, and decreases the soft limit if the consensus process takes more than 5 seconds.

      The open ledger cost requirement is proportional to the normal cost of the transaction, not the absolute transaction cost. Transaction types that have a higher-than-normal requirement, such as multi-signed transactions must pay more to meet the open ledger cost than transactions which have minimum transaction cost requirements.

      See also: Fee Escalation explanation in rippled repository.

      Queued Transactions

      (Requires the FeeEscalation amendment)

      -

      When rippled receives a transaction that meet the server's local load cost but not the open ledger cost, the server checks the transaction to see if it is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries minimize the amount of network load caused by transactions that would not pay a transaction cost, since the transaction cost only applies when a transaction is included in a validated ledger.

      -

      The rippled server uses a variety of heuristics to determine which transactions are "likely to be included in a ledger." Most importantly, those transactions must be properly-formed and authorized with valid signatures.

      +

      When rippled receives a transaction that meet the server's local load cost but not the open ledger cost, the server estimates whether the transaction is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries minimize the amount of network load caused by transactions that would not pay a transaction cost, since the transaction cost only applies when a transaction is included in a validated ledger.

      +

      The rippled server uses a variety of heuristics to estimate which transactions are "likely to be included in a ledger." Most importantly, those transactions must be properly-formed and authorized with valid signatures.

      When the current open ledger closes and the server starts a new open ledger, the server starts taking transactions from the queue to include in the new open ledger. The transaction queue is sorted with the transactions that would pay the highest transaction cost first, proportional to the un-scaled cost of those transactions. Transactions that pay the same transaction cost are queued in the order the server receives them.

      Note: As of rippled version 0.31.0, the transaction queue supports at most 1 transaction per sending address. This is expected to change in later versions.

      Caution: The current implementation does not allow transactions with an AccountTxnID field in the transaction queue.

      @@ -272,10 +272,10 @@

      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.

      -

      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.

      +

      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 the specified amount 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 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:

      +

      When you sign a transaction online, you can omit the Fee field. In this case, rippled or RippleAPI checks the state of the peer-to-peer network for the current requirement and adds a Fee value 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.
        • @@ -289,19 +289,19 @@
        • You cannot automatically specify the transaction cost when multi-signing.

        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 Ripple peer-to-peer 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, to affect the shared global ledger, a transaction must be included in a validated ledger. Thus, rippled servers try 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. The transaction does not get included in a validated ledger, so 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 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.

        +

        When a transaction has already been distributed to the network, but the account does not have enough 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.

        -

        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.

        +

        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 more XRP to it.

        The lsfPasswordSpent flag starts out disabled. If enabled, it gets disabled again when the account receives a Payment of XRP.

        When the FeeEscalation amendment is enabled, rippled prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero.

        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.

        +

        The Ripple Consensus Ledger has a mechanism for changing the minimum transaction cost 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.

    diff --git a/concept-transfer-fees.html b/concept-transfer-fees.html index b3c4147eae..e1e55463bc 100644 --- a/concept-transfer-fees.html +++ b/concept-transfer-fees.html @@ -152,29 +152,29 @@

    Transfer Fees

    -

    The TransferRate setting in the Ripple Consensus Ledger allows issuing gateways to charge users a transfer fee for sending that gateway's issuances to other users. When a gateway sets a transfer fee, it costs extra to send a transfer of that gateway's issuances. The sender of the transfer is debited an extra percentage based on the transfer fee, while the recipient of the transfer is credited the intended amount. The difference is the transfer fee, which becomes the property of the issuing gateway, and is no longer tracked in the Ripple Consensus Ledger. The transfer fee does not apply when sending or receiving directly to and from the issuing account, but it does apply when transferring from a hot wallet to another user.

    +

    The TransferRate setting in the Ripple Consensus Ledger (RCL) allows financial institutions that issue currency in the RCL to charge users a transfer fee for sending the currencies issued by that financial institution. The sender of the transfer is debited an extra percentage based on the transfer fee, while the recipient of the transfer is credited the intended amount. The difference is the transfer fee, which becomes the property of the issuing address, and is no longer tracked in the Ripple Consensus Ledger. The transfer fee does not apply when sending or receiving directly to and from the issuing account, but it does apply when transferring from an operational address to another user.

    XRP never has a transfer fee, because it never has an issuer.

    -

    For example, ACME Gateway might set the transfer fee to 0.5% for ACME issuances. In order for the recipient of a payment to get 2 EUR.ACME, the sender must send 2.01 EUR.ACME. After the transaction, ACME's outstanding obligations in Ripple have decreased by 0.01€, which means that it is no longer obliged to hold that amount in the account backing its Ripple issuances.

    +

    For example, ACME Bank might set the transfer fee to 0.5% for ACME issuances. For the recipient of a payment to get 2 EUR.ACME, the sender must send 2.01 EUR.ACME. After the transaction, ACME's outstanding obligations in Ripple have decreased by 0.01€, which means that ACME no longer needs to hold that amount in the account backing its Ripple issuances.

    The following diagram shows a Ripple payment of 2 EUR.ACME from Alice to Charlie with a transfer fee of 1%:

    Alice sends 2,02€, Charlie receives 2,00€, and ACME owes 0,02€ less in Ripple

    Transfer Fees in Payment Paths

    -

    A transfer fee applies whenever an individual transfer would shift issuances from one party to another through the issuing account. In more complex transactions, this can occur multiple times. Transfer fees apply starting from the end and working backwards, so that ultimately the initial sender of a payment must send enough to account for all fees. For example:

    +

    A transfer fee applies whenever an individual transfer would shift issuances from one party to another through the issuing account. In more complex transactions, this can occur multiple times. Transfer fees apply starting from the end and working backwards, so that ultimately the sender of a payment must send enough to account for all fees. For example:

    Diagram of cross-currency payment with transfer fees

    -

    In this scenario, Salazar (the sender) holds EUR issued by ACME, and wants to deliver 100 USD issued by WayGate to Rosa (the recipient). FXMaker is a market maker with the best offer in the order book, at a rate of 1 USD.WayGate for every 0.9 EUR.ACME. If there were no transfer fees, Salazar could deliver 100 USD to Rosa by sending 90 EUR. However, ACME has a transfer fee of 1% and WayGate has a transfer fee of 0.2%. This means:

    +

    In this scenario, Salazar (the sender) holds EUR issued by ACME, and wants to deliver 100 USD issued by WayGate to Rosa (the recipient). FXMaker is a currency trader with the best offer in the order book, at a rate of 1 USD.WayGate for every 0.9 EUR.ACME. If there were no transfer fees, Salazar could deliver 100 USD to Rosa by sending 90 EUR. However, ACME has a transfer fee of 1% and WayGate has a transfer fee of 0.2%. This means:

      -
    • FXMaker must send 100.20 USD.WayGate in order for Rosa to receive 100 USD.WayGate.
    • -
    • FXMaker's current ask is 90.18 EUR.ACME in order to send 100.20 USD.WayGate.
    • -
    • In order for FXMaker to receive 90.18 EUR.ACME, Salazar must send 91.0818 EUR.ACME.
    • +
    • FXMaker must send 100.20 USD.WayGate for Rosa to receive 100 USD.WayGate.
    • +
    • FXMaker's current ask is 90.18 EUR.ACME to send 100.20 USD.WayGate.
    • +
    • For FXMaker to receive 90.18 EUR.ACME, Salazar must send 91.0818 EUR.ACME.

    Technical Details

    -

    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.

    +

    The transfer fee is represented by a setting on the issuing address. 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 issuing addresses for 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 RippleAPI, the transfer fee is specified in the transferRate field, as an integer which represents the amount you must send 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 a special case for no fee, equivalent to 1000000000.

    +

    A financial institution can send a Settings transaction from its issuing address to change the transferRate for its issuances.

    You can check an account's transferRate with the getSettings method.

    rippled

    -

    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.

    +

    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 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 case for no fee, equivalent to 1000000000.

    +

    A financial institution can submit an AccountSet transaction from its issuing address 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.

    diff --git a/content/concept-amendments.md b/content/concept-amendments.md index f0824103ec..b8aea0cbdb 100644 --- a/content/concept-amendments.md +++ b/content/concept-amendments.md @@ -9,16 +9,16 @@ When an Amendment has been enabled, it applies permanently to all ledger version ## Background ## -Any changes to transaction processing could cause servers to build a different ledger with the same set of transactions. If only a portion of _validators_ (`rippled` servers [participating in consensus](tutorial-rippled-setup.html#reasons-to-run-a-validator)) have upgraded to a new version of the software, this could cause anything from minor inconveniences to full outages. In the minor case, a minority of servers spend more time and bandwidth fetching the actual consensus ledger because they cannot build it using the transaction processing rules they already know. In the worst case, [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) might be unable to validate new ledger versions because servers with different rules could not reach a consensus on the exact ledger to build. +Any changes to transaction processing could cause servers to build a different ledger with the same set of transactions. If some _validators_ (`rippled` servers [participating in consensus](tutorial-rippled-setup.html#reasons-to-run-a-validator)) have upgraded to a new version of the software while other validators use the old version, this could cause anything from minor inconveniences to full outages. In the minor case, a minority of servers spend more time and bandwidth fetching the actual consensus ledger because they cannot build it using the transaction processing rules they already know. In the worst case, [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) might be unable to validate new ledger versions because servers with different rules could not reach a consensus on the exact ledger to build. -Amendments provide a solution to this problem, so that new features can be enabled only when enough validators support those features. +Amendments solve this problem, so that new features can be enabled only when enough validators support those features. -Users and businesses who rely on the Ripple Consensus Ledger can also use Amendments to provide advance notice of changes in transaction processing that might affect their business. However, API changes that do not impact transaction processing or [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) do not require Amendments. +Users and businesses who rely on the Ripple Consensus Ledger can also use Amendments to provide advance notice of changes in transaction processing that might affect their business. However, API changes that do not impact transaction processing or [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) do not need Amendments. ## About Amendments ## -An amendment is a fully-functional feature or change, waiting to be enabled by the peer-to-peer network as a part of the consensus process. A `rippled` server that wants to use an amendment has code for two modes: without the amendment (previous behavior) and with the amendment (new behavior). +An amendment is a fully-functional feature or change, waiting to be enabled by the peer-to-peer network as a part of the consensus process. A `rippled` server that wants to use an amendment has code for two modes: without the amendment (old behavior) and with the amendment (new behavior). Every amendment has a unique identifying hex value and a short name. The short name is for human use, and is not used in the amendment process. Two servers can support the same amendment ID while using different names to describe it. An amendment's name is not guaranteed to be unique. @@ -28,7 +28,7 @@ See also: [Known Amendments](#known-amendments) Every 256th ledger is called a "flag" ledger. The process of approving an amendment starts in the ledger version immediately before the flag ledger. When `rippled` validator servers send validation messages for that ledger, those servers also submit votes in favor of specific amendments. ([Fee Voting](concept-fee-voting.html) also occurs around flag ledgers.) -The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an [`EnableAmendment` pseudo-transaction](reference-transaction-format.html#enableamendment) into the following ledger. The flags of an EnableAmendment pseudo-transaction indicate what the server thinks happened: +The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an [`EnableAmendment` pseudo-transaction](reference-transaction-format.html#enableamendment) into the following ledger. The flags of an EnableAmendment pseudo-transaction show what the server thinks happened: * The `tfGotMajority` flag means that support for the amendment has increased to at least 80% of trusted validators. * The `tfLostMajority` flag means that support for the amendment has decreased to less than 80% of trusted validators. @@ -42,7 +42,7 @@ A server only inserts the pseudo-transaction to enable an amendment if all of th * The previous ledger in question has a close time that is at least **two weeks** before the close time of the latest flag ledger. * There are no EnableAmendment pseudo-transactions for this amendment with the `tfLostMajority` flag enabled in the consensus ledgers between the `tfGotMajority` pseudo-transaction and the current ledger. -It is theoretically possible (but extremely unlikely) that a `tfLostMajority` EnableAmendment pseudo-transaction could be included in the same ledger as the pseudo-transaction to enable an amendment. In this case, the pseudo-transaction with the `tfLostMajority` pseudo-transaction has no effect. +Theoretically, a `tfLostMajority` EnableAmendment pseudo-transaction could be included in the same ledger as the pseudo-transaction to enable an amendment. In this case, the pseudo-transaction with the `tfLostMajority` pseudo-transaction has no effect. ## Amendment Voting ## @@ -50,11 +50,11 @@ Operators of `rippled` validators can choose which amendments to support or reje The operator of a `rippled` validator can "veto" an amendment. In this case, that validator never sends a vote in favor of the amendment. If enough servers veto an amendment, that prevents it from reaching consistent 80% support, so the amendment does not apply. -As with all aspects of the consensus process, amendment votes are only taken into account by servers that trust the validators sending those votes. Currently, Ripple (the company) recommends only trusting the 5 default validators that Ripple (the company) operates. For now, trusting only those validators is sufficient to coordinate with Ripple (the company) on releasing new features. +As with all aspects of the consensus process, amendment votes are only taken into account by servers that trust the validators sending those votes. Ripple (the company) recommends only trusting the 5 default validators that Ripple (the company) operates. For now, trusting only those validators is enough to coordinate with Ripple (the company) on releasing new features. ### Configuring Amendment Voting ### -You can temporarily configure an amendment using the [`feature` command](reference-rippled.html#feature). To make a persistent change to your server's support for an amendment, modify your server's `rippled.cfg` file. +You can temporarily configure an amendment using the [`feature` command](reference-rippled.html#feature). To make a persistent change to your server's support for an amendment, change your server's `rippled.cfg` file. Use the `[veto_amendments]` stanza to list amendments you do not want the server to vote for. Each line should contain one amendment's unique ID, optionally followed by the short name for the amendment. For example: @@ -109,7 +109,7 @@ The following is a comprehensive list of all known amendments and their status o |--------------| | 42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE | -Changes the way the [transaction cost](concept-transaction-cost.html) applies to proposed transactions. Modifies the consensus process to prioritize transactions that pay a higher transaction cost. +Changes the way the [transaction cost](concept-transaction-cost.html) applies to proposed transactions. Modifies the consensus process to prioritize transactions that pay a higher transaction cost. This amendment introduces a fixed-size transaction queue for transactions that were not able to be included in the previous consensus round. If the `rippled` servers in the consensus network are under heavy load, they queue the transactions with the lowest transaction cost for later ledgers. Each consensus round prioritizes transactions from the queue with the largest transaction cost (`Fee` value), and includes as many transactions as the consensus network can process. If the transaction queue is full, transactions drop from the queue entirely, starting with the ones that have the lowest transaction cost. @@ -127,13 +127,13 @@ A transaction remains in the queue until one of the following happens: |--------------| | 4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 | -Introduces simple [multi-signing](reference-transaction-format.html#multi-signing) as a way to authorize transactions. Creates the [`SignerList` ledger node type](reference-ledger-format.html#signerlist) and the [`SignerListSet` transaction type](reference-transaction-format.html#signerlistset). Adds the optional `Signers` field to all transaction types. Modifies some transaction result codes. +Introduces [multi-signing](reference-transaction-format.html#multi-signing) as a way to authorize transactions. Creates the [`SignerList` ledger node type](reference-ledger-format.html#signerlist) and the [`SignerListSet` transaction type](reference-transaction-format.html#signerlistset). Adds the optional `Signers` field to all transaction types. Modifies some transaction result codes. This amendment allows addresses to have a list of signers who can authorize transactions from that address in a multi-signature. The list has a quorum and 1 to 8 weighted signers. This allows various configurations, such as "any 3-of-5" or "signature from A plus any other two signatures." Signers can be funded or unfunded addresses. Funded addresses in a signer list can sign using a regular key (if defined) or master key (unless disabled). Unfunded addresses can sign with a master key. Multi-signed transactions have the same permissions as transactions signed with a regular key. -An address with a SignerList can disable the master key even if a regular key is not defined. An address with a SignerList can also remove a regular key even if the master key is disabled. Therefore, the `tecMASTER_DISABLED` transaction result code is renamed `tecNO_ALTERNATIVE_KEY`. The `tecNO_REGULAR_KEY` transaction result is retired and replaced with `tecNO_ALTERNATIVE_KEY`. Additionally, this amendment adds the following new [transaction result codes](reference-transaction-format.html#result-categories): +An address with a SignerList can disable the master key even if a regular key is not defined. An address with a SignerList can also remove a regular key even if the master key is disabled. The `tecMASTER_DISABLED` transaction result code is renamed `tecNO_ALTERNATIVE_KEY`. The `tecNO_REGULAR_KEY` transaction result is retired and replaced with `tecNO_ALTERNATIVE_KEY`. Additionally, this amendment adds the following new [transaction result codes](reference-transaction-format.html#result-categories): * `temBAD_SIGNER` * `temBAD_QUORUM` @@ -149,7 +149,7 @@ An address with a SignerList can disable the master key even if a regular key is |--------------| | DA1BD556B42D85EA9C84066D028D355B52416734D3283F85E216EA5DA6DB7E13 | -Provides "Suspended Payments" for XRP as a means of escrow within the Ripple Consensus Ledger. Creates the `SuspendedPayment` ledger node type and the new transaction types `SuspendedPaymentCreate`, `SuspendedPaymentFinish`, and `SuspendedPaymentCancel`. +Provides "Suspended Payments" for XRP for escrow within the Ripple Consensus Ledger. Creates the `SuspendedPayment` ledger node type and the new transaction types `SuspendedPaymentCreate`, `SuspendedPaymentFinish`, and `SuspendedPaymentCancel`. This amendment is still in development. The current version is enabled on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/). @@ -161,7 +161,7 @@ This amendment is still in development. The current version is enabled on the [R Allows pre-authorization of accounting relationships (zero-balance trust lines) when using [Authorized Accounts](tutorial-gateway-guide.html#authorized-accounts). -With this amendment enabled, a `TrustSet` transaction with [`tfSetfAuth` enabled](reference-transaction-format.html#trustset-flags) can create a new [`RippleState` ledger node](reference-ledger-format.html#ripplestate) even if it keeps all the other values of the `RippleState` node in their default state. The new `RippleState` node has the [`lsfLowAuth` or `lsfHighAuth` flag](reference-ledger-format.html#ripplestate-flags) enabled accordingly. The sender of the transaction must have [`lsfRequireAuth` enabled](reference-ledger-format.html#accountroot-flags). +With this amendment enabled, a `TrustSet` transaction with [`tfSetfAuth` enabled](reference-transaction-format.html#trustset-flags) can create a new [`RippleState` ledger node](reference-ledger-format.html#ripplestate) even if it keeps all the other values of the `RippleState` node in their default state. The new `RippleState` node has the [`lsfLowAuth` or `lsfHighAuth` flag](reference-ledger-format.html#ripplestate-flags) enabled appropriately. The sender of the transaction must have [`lsfRequireAuth` enabled](reference-ledger-format.html#accountroot-flags). ## Tickets ## diff --git a/content/concept-fee-voting.md b/content/concept-fee-voting.md index 3995d40763..df72938f10 100644 --- a/content/concept-fee-voting.md +++ b/content/concept-fee-voting.md @@ -1,6 +1,6 @@ # Fee Voting # -Validators can vote for changes to basic [transaction cost](concept-transaction-cost.html) as well as [reserve requirements](concept-reserves.html). 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. +Validators can vote for changes to basic [transaction cost](concept-transaction-cost.html) as well as [reserve requirements](concept-reserves.html). 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 adjust to long-term changes in the value of XRP. Operators of [`rippled` validators](tutorial-rippled-setup.html#running-a-validator) 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: @@ -8,7 +8,7 @@ Operators of [`rippled` validators](tutorial-rippled-setup.html#running-a-valida |-----------|-------------|-------------------| | reference\_fee | Amount of XRP, in _drops_, that must be destroyed to send the reference transaction, the cheapest possible transaction. (1 XRP = 1 million drops.) The actual transaction cost is a multiple of this value, scaled dynamically based on the load of individual servers. | `10` (0.00001 XRP) | | account\_reserve | Minimum amount of XRP, in _drops_, that an account must have on reserve. This is the smallest amount that can be sent to fund a new account in the ledger. | `20000000` (20 XRP) | -| owner\_reserve | Additional amount of XRP, in _drops_, that an account must have on reserve for _each_ object it owns in the ledger. | `5000000` (5 XRP) | +| owner\_reserve | How much more XRP, in _drops_, that an address must hold for _each_ object it owns in the ledger. | `5000000` (5 XRP) | ## Voting Process ## @@ -16,7 +16,7 @@ Every 256th ledger is called a "flag" ledger. (A flag ledger is defined such tha 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](reference-transaction-format.html#setfee) 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](reference-transaction-format.html#setfee) into its proposal for the ledger following the flag ledger. Other validators who want the same change insert the same 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. In short: diff --git a/content/concept-fees.md b/content/concept-fees.md index dce2a07a2b..3523c5974c 100644 --- a/content/concept-fees.md +++ b/content/concept-fees.md @@ -9,19 +9,19 @@ However, the rules of the Ripple Consensus Ledger include several types of fees, ### Neutral Fees ### -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](concept-transaction-cost.html) for more information. +The _**transaction cost**_ (sometimes called the transaction fee) is a miniscule amount of XRP destroyed 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](concept-transaction-cost.html) 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 carelessly or maliciously. See [Reserves](concept-reserves.html) for more information. +The _**reserve requirement**_ is a minimum amount of XRP that an account must hold. It increases with the number of objects the account owns in the ledger. This disincentivizes users from increasing the size of the ledger carelessly or maliciously. See [Reserves](concept-reserves.html) for more information. ### Optional Fees ### -_**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](concept-transfer-fees.html) for more information. +_**Transfer fees**_ are optional percentage fees that issuers can charge to transfer the currencies they issue to other addresses within the Ripple Consensus Ledger. See [Transfer Fees](concept-transfer-fees.html) 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. +_**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 are like charging a fee. Trust line quality does not apply to XRP, which is not tied to a trust line. ## Outside the Ledger ## -Although the fees described above are the only fees built into the Ripple Consensus Ledger, people can still invent ways to charge fees associated with the ledger. For example, gateways commonly charge their customers to send money into and out of the Ripple Consensus Ledger. +Although the fees described above are the only fees built into the Ripple Consensus Ledger, people can still invent ways to charge fees associated with the ledger. For example, financial institutions commonly charge their customers to send money into and out of the Ripple Consensus Ledger. -Many other fees are also possible. Businesses might charge for access to a client application, maintenance of non-Ripple accounts, exchange services (especially when buying XRP on a private market instead of directly within the Ripple Consensus Ledger) and any number of other services. Always be aware of the fee schedule before doing business with any gateway or other financial institution. +Many other fees are also possible. Businesses might charge for access to a client application, maintenance of non-Ripple accounts, exchange services (especially when buying XRP on a private market instead of directly within the Ripple Consensus Ledger) and any number of other services. Always be aware of the fee schedule before doing business with any financial institution. diff --git a/content/concept-freeze.md b/content/concept-freeze.md index 3450c0e03f..b75a68204b 100644 --- a/content/concept-freeze.md +++ b/content/concept-freeze.md @@ -1,7 +1,7 @@ Freeze Features =============== -The Ripple Consensus Ledger gives accounts the ability to freeze non-XRP balances, which can be useful to comply with regulatory requirements, or while investigating suspicious activity. There are three settings related to freezes: +The Ripple Consensus Ledger gives addresses the ability to freeze non-XRP balances, which can be useful to meet regulatory requirements, or while investigating suspicious activity. There are three settings related to freezes: * [**Individual Freeze**](#individual-freeze) - Freeze one counterparty. * [**Global Freeze**](#global-freeze) - Freeze all counterparties. @@ -15,53 +15,53 @@ All freeze settings can be enacted regardless of whether the balance(s) to be fr Individual Freeze ----------------- -The **Individual Freeze** feature is a setting on a trust line. When an issuing account enables the Individual Freeze setting, the following rules apply: +The **Individual Freeze** feature is a setting on a trust line. When an issuing address enables the Individual Freeze setting, the following rules apply: * 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](reference-transaction-format.html#lifecycle-of-an-offer). -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.) +A financial institution can freeze the trust line linking it to a counterparty if that counterparty shows suspicious activity or violates the financial institution's terms of use. The financial institution should also freeze the counterparty in any other systems the financial institution operates that are connected to the Ripple Consensus Ledger. (Otherwise, an address might still be able to engage in undesired activity by sending payments through the financial institution.) -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 addresses](concept-issuing-and-operational-addresses.html), from sending that gateway's issued currency to the individual account. This type of individual freeze has no effect on offers. +An individual address can freeze its trust line to a financial institution. This has no effect on transactions between the institution and other users. It does, however, prevent other addresses, including [operational addresses](concept-issuing-and-operational-addresses.html), from sending that financial institution's issuances to the individual address. 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. +The Individual Freeze applies to a single currency only. To freeze multiple currencies with a particular counterparty, the address 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](#no-freeze) setting. +An address cannot enable the Individual Freeze setting if it has enabled the [No Freeze](#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: +The **Global Freeze** feature is a setting on an address. When an issuing address 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 addresses](concept-issuing-and-operational-addresses.html).) -* 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](reference-transaction-format.html#lifecycle-of-an-offer). +* All counterparties of the frozen issuing address can no longer decrease the balances in their trust lines to the frozen address, except in direct payments to the issuer. (This also affects any [operational addresses](concept-issuing-and-operational-addresses.html).) +* Counterparties of the frozen issuing address can still send and receive payments directly to and from the issuing address. +* All offers to sell currencies issued by the frozen address are [considered unfunded](reference-transaction-format.html#lifecycle-of-an-offer). -It can be useful to enable Global Freeze on a gateway's [issuing account](concept-issuing-and-operational-addresses.html) if the secret key to an operational address is compromised, or immediately after regaining control of a such an address. 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 be useful to enable Global Freeze on a financial institution's [issuing address](concept-issuing-and-operational-addresses.html) if the secret key to an operational address is compromised, even after regaining control of a such an address. 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. Besides 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](concept-issuing-and-operational-addresses.html), 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 also be useful to enable Global Freeze if a financial institution intends to migrate to a new [issuing address](concept-issuing-and-operational-addresses.html), or if the financial institution 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. +Global Freeze applies to _all_ currencies issued and held by the address. 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 addresses for each currency. -An account can always enable the Global Freeze setting. However, if the account has previously enabled the [No Freeze](#no-freeze) setting, it can never _disable_ Global Freeze. +An address can always enable the Global Freeze setting. However, if the address has enabled the [No Freeze](#no-freeze) setting, it can never _disable_ Global Freeze. No Freeze --------- -The **No Freeze** feature is a setting on an account that permanently gives up the ability to freeze counterparties. A business can use this feature to treat its issued funds as "more like physical money" in the sense that the business cannot interfere with customers trading it among themselves. The NoFreeze setting has two effects: +The **No Freeze** feature is a setting on an address that permanently gives up the ability to freeze counterparties. A business can use this feature to treat its issued funds as "more like physical money" in the sense that the business cannot interfere with customers trading it among themselves. The NoFreeze setting has two effects: -* The issuing account can no longer enable Individual Freeze on trust lines to any counterparty. -* The issuing account can still enable Global Freeze to enact a global freeze, but the account cannot _disable_ Global Freeze. +* The issuing address can no longer enable Individual Freeze on trust lines to any counterparty. +* The issuing address can still enable Global Freeze to enact a global freeze, but the address cannot _disable_ Global Freeze. -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 Ripple Consensus Ledger cannot force a financial institution 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. +The No Freeze setting applies to all currencies issued to and from an address. If you want to be able to freeze some currencies but not others, you should use different addresses 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](reference-transaction-format.html#setregularkey) or a [multi-signed transaction](reference-transaction-format.html#multi-signing) to enable No Freeze. +You can only enable the No Freeze setting with a transaction signed by your address's master key secret. You cannot use a [Regular Key](reference-transaction-format.html#setregularkey) or a [multi-signed transaction](reference-transaction-format.html#multi-signing) to enable No Freeze. # Technical Details # @@ -74,12 +74,12 @@ To enable or disable Individual Freeze on a specific trust line, send a `TrustSe | Field | Value | Description | |----------------------|--------|-------------| -| Account | String | The address of your Ripple account. | +| Account | String | The Ripple address to enable or disable the freeze. | | TransactionType | String | `TrustSet` | | LimitAmount | Object | Object defining the trust line to freeze. | | LimitAmount.currency | String | Currency of the trust line | | LimitAmount.issuer | String | The Ripple address of the counterparty to freeze | -| LimitAmount.value | String | The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a gateway, this is typically `"0"`. | +| LimitAmount.value | String | The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a financial institution, this is typically `"0"`. | | Flags | Number | To enable a freeze, use a value with the bit `0x00100000` (tfSetFreeze) enabled. To disable a freeze, use a value with the bit `0x00200000` (tfClearFreeze) enabled instead. | Set the `Fee`, `Sequence`, and `LastLedgerSequence` parameters [in the typical way](reference-transaction-format.html#signing-and-submitting-transactions). @@ -109,7 +109,7 @@ Example of submitting a TrustSet transaction to enable an individual freeze usin } ``` -(**Reminder**: Never transmit your account secret to an untrusted server or over an insecure channel.) +**Caution:** Never send your secret key to an untrusted server or over an insecure channel. ### Using RippleAPI ### @@ -120,7 +120,7 @@ To enable or disable Individual Freeze on a specific trust line, prepare a *Trus |--------------|--------|-------------| | currency | String | The [currency](reference-rippleapi.html#currency) of the trust line to freeze | | counterparty | String | The [Ripple address](reference-rippleapi.html#ripple-address) of the counterparty | -| limit | String | The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a gateway, this is typically `"0"`. | +| limit | String | The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a financial institution, this is typically `"0"`. | | frozen | Boolean | `true` to enable Individual Freeze on this trust line. `false` to disable Individual Freeze. | The rest of the [transaction flow](reference-rippleapi.html#transaction-flow) is the same as any other transaction. @@ -136,7 +136,7 @@ Example JavaScript (ECMAScript 6) code to enable Individual Freeze on a trust li ### Using `rippled` ### -To enable Global Freeze on an account, send an `AccountSet` transaction with the [asfGlobalFreeze flag value](reference-transaction-format.html#accountset-flags) in the `SetFlag` field. To disable Global Freeze, put the asfGlobalFreeze flag value in the `ClearFlag` field instead. +To enable Global Freeze on an address, send an `AccountSet` transaction with the [asfGlobalFreeze flag value](reference-transaction-format.html#accountset-flags) 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](reference-rippled.html#websocket-api): @@ -159,20 +159,20 @@ Example of submitting an AccountSet transaction to enable Global Freeze using th } ``` -(**Reminder**: Never transmit your account secret to an untrusted server or over an insecure channel.) +**Caution:** Never send your secret key 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](reference-rippleapi.html#preparesettings) method. The `settings` parameter should be an object set as follows: +To enable or disable Global Freeze on an address, prepare a **Settings** transaction using the [prepareSettings](reference-rippleapi.html#preparesettings) method. The `settings` parameter should be an object set as follows: | Field | Value | Description | |--------------|--------|-------------| -| globalFreeze | Boolean | `true` to enable a Global Freeze on this account. `false` to disable Global Freeze. | +| globalFreeze | Boolean | `true` to enable a Global Freeze on this address. `false` to disable Global Freeze. | The rest of the [transaction flow](reference-rippleapi.html#transaction-flow) is the same as any other transaction. -Example JavaScript (ECMAScript 6) code to enable Global Freeze on an account: +Example JavaScript (ECMAScript 6) code to enable Global Freeze on an address: ```js {% include 'code_samples/freeze/set-global-freeze.js' %} @@ -184,7 +184,7 @@ Example JavaScript (ECMAScript 6) code to enable Global Freeze on an account: ### Using `rippled` ### -To enable No Freeze on an account, send an `AccountSet` transaction with the [asfNoFreeze flag value](reference-transaction-format.html#accountset-flags) in the `SetFlag` field. You must sign this transaction using the master key. Once enabled, you cannot disable No Freeze. +To enable No Freeze on an address, send an `AccountSet` transaction with the [asfNoFreeze flag value](reference-transaction-format.html#accountset-flags) 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](reference-rippled.html#websocket-api): @@ -209,11 +209,11 @@ WebSocket request: } ``` -(**Reminder**: Never transmit your account secret to an untrusted server or over an insecure channel.) +**Caution:** Never send your secret key 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](reference-rippleapi.html#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 address, prepare a **Settings** transaction using the [prepareSettings](reference-rippleapi.html#preparesettings) method. Once enabled, you cannot disable No Freeze. The `settings` parameter should be an object set as follows: | Field | Value | Description | |----------|---------|-------------| @@ -221,7 +221,7 @@ To enable No Freeze on an account, prepare a **Settings** transaction using the You must [sign](reference-rippleapi.html#sign) this transaction using the master key. The rest of the [transaction flow](reference-rippleapi.html#transaction-flow) is the same as any other transaction. -Example JavaScript (ECMAScript 6) code to enable No Freeze on an account: +Example JavaScript (ECMAScript 6) code to enable No Freeze on an address: ```js {% include 'code_samples/freeze/set-no-freeze.js' %} @@ -236,15 +236,15 @@ To see if a trust line has an Individual Freeze enabled, use the [`account_lines | Field | Value | Description | |----------|---------|-------------| -| account | String | The Ripple address of the issuing account | -| peer | String | The Ripple address of the counterparty account | +| account | String | The Ripple address of the issuer | +| peer | String | The Ripple address of the counterparty | | ledger\_index | String | Use `validated` to get the most recently validated information. | -The response contains an array of trust lines, for each currency in which the issuing account and the counterparty are linked. Look for the following fields in each trust line object: +The response contains an array of trust lines, for each currency in which the issuing address and the counterparty are linked. Look for the following fields in each trust line object: | Field | Value | Description | |--------------|---------|-------------| -| freeze | Boolean | (May be omitted) `true` if the issuing account has frozen this trust line. If omitted, that is the same as `false`. | +| freeze | Boolean | (May be omitted) `true` if the issuing address has frozen this trust line. If omitted, that is the same as `false`. | | freeze\_peer | Boolean | (May be omitted) `true` if the counterparty has frozen this trust line. If omitted, that is the same as `false`. | Example WebSocket request to check for individual freeze: @@ -294,14 +294,14 @@ To see if a trust line has an Individual Freeze enabled, use the [`getTrustlines | Field | Value | Description | |---------------|---------|-------------| -| address | String | The Ripple address of the issuing account | -| options.counterparty | String | The Ripple address of the counterparty account | +| address | String | The Ripple address of the issuer | +| options.counterparty | String | The Ripple address of the counterparty | -The response contains an array of trust lines, for each currency in which the issuing account and the counterparty are linked. Look for the following fields in each trust line object: +The response contains an array of trust lines, for each currency in which the issuing address and the counterparty are linked. Look for the following fields in each trust line object: | Field | Value | Description | |----------------------|---------|-------------| -| specification.frozen | Boolean | (May be omitted) `true` if the issuing account has frozen the trust line. | +| specification.frozen | Boolean | (May be omitted) `true` if the issuing address has frozen the trust line. | | counterparty.frozen | Boolean | (May be omitted) `true` if the counterparty has frozen the trust line. | Example JavaScript (ECMAScript 6) code to check whether a trust line is frozen: @@ -315,11 +315,11 @@ Example JavaScript (ECMAScript 6) code to check whether a trust line is frozen: ### Using `rippled` ### -To see if an account has Global Freeze and/or No Freeze enabled, use the [`account_info` method](reference-rippled.html#account-lines) with the following parameters: +To see if an address has enabled Global Freeze, No Freeze, or both, use the [`account_info` method](reference-rippled.html#account-lines) with the following parameters: | Field | Value | Description | |----------|---------|-------------| -| account | String | The Ripple address of the issuing account | +| account | String | The Ripple address of the issuing address | | ledger\_index | String | Use `validated` to get the most recently validated information. | Check the value of the `account_data.Flags` field of the response using the [bitwise-AND](https://en.wikipedia.org/wiki/Bitwise_operation#AND) operator: @@ -387,11 +387,11 @@ console.log(currentFlags & lsfNoFreeze); //0 ### Using RippleAPI ### -To see if an account has Global Freeze and/or No Freeze enabled, use the [`getSettings` method](reference-rippleapi.html#getsettings) with the following parameters: +To see if an address has enabled Global Freeze, No Freeze, or both, use the [`getSettings` method](reference-rippleapi.html#getsettings) with the following parameters: | Field | Value | Description | |---------------|---------|-------------| -| address | String | The Ripple address of the issuing account | +| address | String | The Ripple address of the issuing address | Look for the following values in the response object: @@ -400,7 +400,7 @@ Look for the following values in the response object: | noFreeze | Boolean | (May be omitted) `true` if No Freeze is enabled. | | globalFreeze | Boolean | (May be omitted) `true` if Global Freeze is enabled. | -Example JavaScript (ECMAScript 6) code to check whether an account has Global Freeze or No Freeze enabled: +Example JavaScript (ECMAScript 6) code to check whether an address has Global Freeze or No Freeze enabled: ```js {% include 'code_samples/freeze/check-global-freeze-no-freeze.js' %} @@ -408,5 +408,5 @@ Example JavaScript (ECMAScript 6) code to check whether an account has Global Fr # See Also # -* [Gateway Bulletin GB-2014-02 New Feature: Balance Freeze](https://ripple.com/files/GB-2014-02.pdf) +* [GB-2014-02 New Feature: Balance Freeze](https://ripple.com/files/GB-2014-02.pdf) * [Freeze Code Samples](https://github.com/ripple/ripple-dev-portal/tree/gh-pages/content/code_samples/freeze) diff --git a/content/concept-issuing-and-operational-addresses.md b/content/concept-issuing-and-operational-addresses.md index ef37c6013a..ffe7a8250d 100644 --- a/content/concept-issuing-and-operational-addresses.md +++ b/content/concept-issuing-and-operational-addresses.md @@ -14,7 +14,7 @@ The issuing address sends issuances to a standby address, or directly to an oper ## Issuing Address ## -The issuing address is like a vault. Partners, customers, and operational addresses create accounting relationships (trust lines) to the issuing address, but this address sends as few transactions as possible. Periodically, a human operator creates and signs a transaction from the issuing address in order to refill the balances of a standby or operational address. Ideally, the secret key used to sign these transactions should never be accessible from any internet-connected computer. +The issuing address is like a vault. Partners, customers, and operational addresses create accounting relationships (trust lines) to the issuing address, but this address sends as few transactions as possible. Periodically, a human operator creates and signs a transaction from the issuing address to refill the balances of a standby or operational address. Ideally, the secret key used to sign these transactions should never be accessible from any internet-connected computer. Unlike a vault, the issuing address can receive payments directly from customers and partners. Since all transactions in the Ripple Consensus Ledger are public, automated systems can monitor for payments to the issuing address without needing a secret key. @@ -29,7 +29,7 @@ A financial institution can issue more than one currency in the Ripple Consensus ## Operational Addresses ## -An operational address is like a cash register. It makes payments on behalf of the institution by transferring issuances to customers and partners. In order to sign transactions automatically, the secret key for an operational address must be stored on a server that is connected to the internet. (The secret key can be stored encrypted, but the server must decrypt it in order to sign transactions.) Customers and partners do not, and should not, create accounting relationships with an operational address. +An operational address is like a cash register. It makes payments on behalf of the institution by transferring issuances to customers and partners. To sign transactions automatically, the secret key for an operational address must be stored on a server that is connected to the internet. (The secret key can be stored encrypted, but the server must decrypt it to sign transactions.) Customers and partners do not, and should not, create accounting relationships with an operational address. Each operational address has a limited balance of issuances. When the balance of an operational address gets low, the financial institution refills it by sending a payment from the issuing address or a standby address. @@ -48,4 +48,4 @@ As with operational addresses, a standby address must have an accounting relatio ### Standby Address Compromise ### -If a standby address is compromised, the results are similar to an operational address being compromised. A malicious actor can steal any balances possessed by the standby address, and the financial institution can change to a new standby address with no action from customers and partners. +If a standby address is compromised, the consequences are like an operational address being compromised. A malicious actor can steal any balances possessed by the standby address, and the financial institution can change to a new standby address with no action from customers and partners. diff --git a/content/concept-noripple.md b/content/concept-noripple.md index cca18a8e68..f7976be27e 100644 --- a/content/concept-noripple.md +++ b/content/concept-noripple.md @@ -4,11 +4,11 @@ In the Ripple Consensus Ledger (RCL), the "NoRipple" flag is a setting on a trus ## Background ## -"Rippling" occurs when more than one trust line is adjusted in order to make a payment. For example, if Alice owes Charlie money, and Alice also owes Bob money, then you could represent that in Ripple with trust lines like so: +"Rippling" occurs when more than one trust line is adjusted to make a payment. For example, if Alice owes Charlie money, and Alice also owes Bob money, then you could represent that in Ripple with trust lines like so: ![Charlie --($10)-- Alice -- ($20) -- Bob](img/noripple-01.png) -If Bob wants to pay $3 to Charlie, then he could say, "Alice, take $3 of the money you owe me, and pay it to Charlie." Alice simply transfers some of the debt from Bob to Charlie. In the end, the Ripple trust lines work out like so: +If Bob wants to pay $3 to Charlie, then he could say, "Alice, take $3 of the money you owe me, and pay it to Charlie." Alice transfers some of the debt from Bob to Charlie. In the end, the Ripple trust lines work out like so: ![Charlie --($13)-- Alice --($17)-- Bob](img/noripple-02.png) @@ -16,19 +16,19 @@ We call this process, where two addresses pay each other by adjusting the balanc ## Justification ## -Sometimes you do not want your balances to ripple. For example, imagine Emily has money at two different Gateways, like so +Sometimes you do not want your balances to ripple. For example, imagine Emily has money issued by two different financial institutions, like so -![Charlie --($10)-- Gateway A --($1)-- Emily --($100)-- Gateway B --($2)-- Daniel](img/noripple-03.png) +![Charlie --($10)-- Institution A --($1)-- Emily --($100)-- Institution B --($2)-- Daniel](img/noripple-03.png) Now Charlie can pay Daniel by rippling through Emily's address. For example, if Charlie pays Daniel $10: -![Charlie --($0)-- Gateway A --($11)-- Emily --($90)-- Gateway B --($12)-- Daniel](img/noripple-04.png) +![Charlie --($0)-- Institution A --($11)-- Emily --($90)-- Institution B --($12)-- Daniel](img/noripple-04.png) -This may surprise Emily, who does not know Charlie or Daniel. Even worse, if Gateway A charges her higher fees to withdraw her money than Gateway B, this could cost Emily money. The NoRipple flag exists to avoid this scenario. If Emily sets it on both trust lines, then payments cannot ripple through her address using those two trust lines. +This may surprise Emily, who does not know Charlie or Daniel. Even worse, if Institution A charges her higher fees to withdraw her money than Institution B, this could cost Emily money. The NoRipple flag exists to avoid this scenario. If Emily sets it on both trust lines, then payments cannot ripple through her address using those two trust lines. For example: -![Charlie --($10)-- Gateway A --($1, NoRipple)-- Emily --($100,NoRipple)-- Gateway B --($2)-- Daniel](img/noripple-05.png) +![Charlie --($10)-- Institution A --($1, NoRipple)-- Emily --($100,NoRipple)-- Institution B --($2)-- Daniel](img/noripple-05.png) Now the above scenario, where Charlie pays Daniel while rippling through Emily's address, is no longer possible. diff --git a/content/concept-paths.md b/content/concept-paths.md index 646357f49f..fd6b6a2f9f 100644 --- a/content/concept-paths.md +++ b/content/concept-paths.md @@ -1,6 +1,6 @@ # Paths # -In the Ripple Consensus Ledger, paths define a way for payments to flow through intermediary steps on their way from sender to receiver. Paths enable cross-currency payments by connecting sender and receiver via market makers. Paths also enable complex settlement of offsetting debts. +In the Ripple Consensus Ledger, paths define a way for payments to flow through intermediary steps on their way from sender to receiver. Paths enable cross-currency payments by connecting sender and receiver through order books. Paths also enable complex settlement of offsetting debts. A single Payment transaction in the Ripple Consensus Ledger can use multiple paths, combining liquidity from different sources to deliver the desired amount. Thus, a transaction includes a _path set_, which is a collection of possible paths to take. The paths in a path set must start and end with the same currency. @@ -10,14 +10,14 @@ Since XRP can be sent directly to any address, an XRP-to-XRP transaction does no A path is made of steps that connect the sender to the receiver of the payment. Every step is either: -* Rippling through another account in the same currency +* Rippling through another address with the same currency * Exchanging currency at an order book -Rippling through another account is the process of moving debt around. In the typical case, this involves reducing a gateway's obligation to one party and increasing the gateway's obligation to another party. Rippling can occur between any accounts that are connected by trust lines. See [Understanding the NoRipple Flag](concept-noripple.html) for more examples of rippling. +Rippling through another address is the process of moving debt around. In the typical case, this involves reducing an issuer's obligation to one party and increasing the obligation to another party. Rippling can occur between any addresses that are connected by trust lines. See [Understanding the NoRipple Flag](concept-noripple.html) for more examples of rippling. -In the case of a currency exchange step, the path step specifies which currency to change to, but does not record the state of the orders in the order book. Since the order of transactions is not finalized until a ledger is validated, it is impossible to determine for certain which offers a transaction will execute, until after the transaction has been validated. Consequently, you cannot know in advance which offers a transaction will take: only which order books the transaction will use. (You can make an educated guess, since each transaction takes the best available offers at the time it executes in the final ledger.) +In the case of a currency exchange step, the path step specifies which currency to change to, but does not record the state of the Offers in the order book. The canonical order of transactions is not final until a ledger is validated, so you cannot know for certain which Offers a transaction will take, until after the transaction has been validated. (You can make an educated guess, since each transaction takes the best available Offers at the time it executes in the final ledger.) -In both types of steps, each intermediate account gains and loses approximately equal value: either a balance ripples from a trust line to another trust line in the same currency, or they exchange currencies according to a previously-placed order. In some cases, the amounts gained and lost may not be exactly equivalent, due to [transfer fees](concept-transfer-fees.html), trust line quality, or rounding. +In both types of steps, each intermediate address gains and loses approximately equal value: either a balance ripples from a trust line to another trust line in the same currency, or they exchange currencies according to a previously-placed order. In some cases, the amounts gained and lost may not be exactly equivalent, due to [transfer fees](concept-transfer-fees.html), trust line quality, or rounding. [![Diagram of three example paths](img/paths-examples.png)](img/paths-examples.png) @@ -27,9 +27,11 @@ In both types of steps, each intermediate account gains and loses approximately ## Pathfinding ## -The `rippled` API has two methods that can be used for pathfinding. The [`ripple_path_find` command](reference-rippled.html#ripple-path-find) does a one-time lookup of possible path sets. The [`path_find` command](reference-rippled.html#path-find) (WebSocket only) expands on the initial search with follow-up responses whenever a ledger closes or the server finds a better path. +The `rippled` API has two methods that can be used for pathfinding. The [`ripple_path_find` command](reference-rippled.html#ripple-path-find) does a one-time lookup of possible path sets. The [`path_find` command](reference-rippled.html#path-find) (WebSocket only) expands on the 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](reference-rippled.html#sign) or [`submit` command (sign-and-submit mode)](reference-rippled.html#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.) +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](reference-rippled.html#sign) or [`submit` command (sign-and-submit mode)](reference-rippled.html#sign-and-submit-mode). However, we recommend pathfinding separately and confirming the results before signing, to avoid surprises. + +**Caution:** 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 actual cost to execute a payment along a path can change between submission and transaction execution. 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. @@ -40,19 +42,19 @@ By convention, several steps of a path are implied by the [fields of the Payment * 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 `SendMax` _is_ 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](reference-transaction-format.html#special-issuer-values-for-sendmax-and-amount) for details. + * If `issuer` of the `SendMax` _is_ the sending address, then the path starts at the sending address, and may use any of that address's trust lines in the given currency. See [special values for SendMax and Amount](reference-transaction-format.html#special-issuer-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. * Finally, last step of a path is always implied to be the receiver of a transaction, as defined by the transaction's `Destination` field. ## Default Paths ## -In addition to any paths that are specified in the transaction, a transaction can also execute along the _default path_. The default path is the simplest possible way to connect the [implied steps](#implied-steps) of the transaction. +In addition to explicitly specified paths, a transaction can execute along the _default path_. The default path is the simplest possible way to connect the [implied steps](#implied-steps) of the transaction. The default path could be any of the following: -* If the transaction is uses only one currency (regardless of issuer), then the default path assumes the payment will ripple through the accounts involved. This path will only work if there are trust lines connecting those accounts. - * If `SendMax` is omitted, or the `issuer` of the `SendMax` is the sender, the default path needs a trust line from the sending `Account` to the `issuer` of the destination `Amount` in order to work. +* If the transaction is uses only one currency (regardless of issuer), then the default path assumes the payment should ripple through the addresses involved. This path only works if those addresses are connected by trust lines. + * If `SendMax` is omitted, or the `issuer` of the `SendMax` is the sender, the default path needs a trust line from the sending `Account` to the `issuer` of the destination `Amount` to work. * If the `SendMax` and `Amount` have different `issuer` values, and neither are the sender or receiver, the default path is probably not useful because it would need to ripple across a trust line between the two issuers. Ripple (the company) typically discourages issuers from trusting one another directly. * For cross-currency transactions, the default path uses the order book between the source currency (as specified in the `SendMax` field) and the destination currency (as specified in the `Amount` field). @@ -68,7 +70,7 @@ A path set is an array. Each member of the path set is another array that repres | Field | Value | Description | |-------|-------|-------------| -| account | String - Address | (Optional) If present, this path step represents rippling through the specified account. | +| account | String - Address | (Optional) If present, this path step represents rippling through the specified address. | | currency | String - currency code | (Optional) If present, this path step represents changing currencies through an order book. The currency specified indicates the new currency. | | issuer | String - Address | (Optional) If the path step represents changing currencies through an order book, this field indicates the issuer of the new currency. This field is not present when changing to XRP. | | type | Integer | **DEPRECATED** (Optional) An indicator of which other fields are present. | @@ -78,6 +80,6 @@ The `type` field, used for the binary serialization of a path set, is actually c | Value (Hex) | Value (Decimal) | Description | |-------------|-----------------|-------------| -| 0x01 | 1 | A change of account (rippling): the `account` field is present. | +| 0x01 | 1 | A change of address (rippling): the `account` field is present. | | 0x10 | 16 | A change of currency: the `currency` field is present. | | 0x20 | 32 | A change of issuer: the `issuer` field is present. | diff --git a/content/concept-reserves.md b/content/concept-reserves.md index 9f4297f0c6..98c30c1d28 100644 --- a/content/concept-reserves.md +++ b/content/concept-reserves.md @@ -2,42 +2,42 @@ The Ripple Consensus Ledger applies _reserve requirements_, in XRP, to protect the shared global ledger from growing excessively large as the result of spam or malicious usage. The goal is to constrain the growth of the ledger to match [Moore's Law](https://en.wikipedia.org/wiki/Moore's_law) so that a current commodity-level machine can always fit the current ledger in RAM and the full ledger history on disk. -Each account in the shared global ledger must hold a minimum of XRP in order to submit transactions, and it cannot send this XRP to other accounts. You cannot create a new account unless you send enough XRP to meet the minimum reserve requirement. +To submit transactions, an address must hold a minimum amount of XRP in the shared global ledger. You cannot send this XRP to other addresses. To fund a new address, you must send enough XRP to meet the reserve requirement. -The current minimum reserve requirement is **20 XRP**. (This is the cost of an account that owns no additional objects in the ledger.) +The current minimum reserve requirement is **20 XRP**. (This is the cost of an address that owns no other objects in the ledger.) ## Base Reserve and Owner Reserve ## The reserve requirement is divided into two parts: -* The **Base Reserve** is a minimum amount of XRP that is required for every account in the ledger. Currently, this is 20 XRP (`20000000` drops). -* The **Owner Reserve** is an additional requirement that scales with the number of objects that the account owns in the ledger. Currently, this is 5 XRP (`5000000` drops) per item. +* The **Base Reserve** is a minimum amount of XRP that is required for every address in the ledger. Currently, this is 20 XRP (`20000000` drops). +* The **Owner Reserve** is an increase to the reserve requirement for each object that the address owns in the ledger. Currently, this is 5 XRP (`5000000` drops) per item. ### Owner Reserves ### -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. +Many objects in the ledger are owned by a particular address, and count toward the reserve requirement of that address. When objects are removed from the ledger, they no longer count against their owner's reserve requirement. -* [Offers](reference-ledger-format.html#offer) 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](reference-transaction-format.html#offercancel), or by sending an [OfferCreate transaction](reference-transaction-format.html#offercreate) that contains an `OfferSequence` parameter. -* [Trust lines](reference-ledger-format.html#ripplestate) 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](reference-ledger-format.html#contributing-to-the-owner-reserve) for details. +* [Offers](reference-ledger-format.html#offer) are owned by the address that placed them. Transaction automatically removes Offers that are fully consumed or found to be unfunded. Alternatively, the owner can cancel an Offer by sending an [OfferCancel transaction](reference-transaction-format.html#offercancel), or by sending an [OfferCreate transaction](reference-transaction-format.html#offercreate) that contains an `OfferSequence` parameter. +* [Trust lines](reference-ledger-format.html#ripplestate) are shared between two addresses. The owner reserve can apply to one or both of the addresses, depending on whether the fields that address controls are in their default state. See [Contributing to the Owner Reserve](reference-ledger-format.html#contributing-to-the-owner-reserve) for details. * A single [SignerList](reference-ledger-format.html#signerlist) counts as 3 to 10 objects for purposes of the owner reserve, depending on how many members it has. See also: [SignerLists and Reserves](reference-ledger-format.html#signerlists-and-reserves). -* [Owner directories](reference-ledger-format.html#directorynode) 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 directories](reference-ledger-format.html#directorynode) list all the ledger nodes that contribute to an address'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](reference-transaction-format.html#offercreate) 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](reference-transaction-format.html#lifecycle-of-an-offer). +The Ripple Consensus Ledger considers an [OfferCreate transaction](reference-transaction-format.html#offercreate) 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 hold enough XRP to also meet the owner reserve requirement of the new trust line, the offer is considered unfunded. See also: [Lifecycle of an Offer](reference-transaction-format.html#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](concept-transaction-cost.html) 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 address holds at least the reserve requirement in XRP. In the process, the [transaction cost](concept-transaction-cost.html) destroys some of the sending address's XRP balance. This can cause an address's XRP 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. +When an address holds less XRP than its current reserve requirement, it cannot send new transactions. Even so, the address continues to exist in the ledger, as all addresses do. Unless the reserve requirements decrease, the only way for the address 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](reference-transaction-format.html#offercreate) to acquire more XRP, or other currencies on its existing trust lines. These transactions cannot create new [trust lines](reference-ledger-format.html#ripplestate), or [Offer nodes in the ledger](reference-ledger-format.html#offer), so they can only execute trades that consume Offers that are already in the order books. +**Exception:** When an address is below the reserve requirement, it can send new [OfferCreate transactions](reference-transaction-format.html#offercreate) to acquire more XRP, or other currencies on its existing trust lines. These transactions cannot create new [trust lines](reference-ledger-format.html#ripplestate), or [Offer nodes in the ledger](reference-ledger-format.html#offer), 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](concept-fee-voting.html) for more information. +The Ripple Consensus Ledger has a mechanism to adjust the reserve requirements for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See [Fee Voting](concept-fee-voting.html) for more information. diff --git a/content/concept-stand-alone-mode.md b/content/concept-stand-alone-mode.md index 010807508d..735ae832ae 100644 --- a/content/concept-stand-alone-mode.md +++ b/content/concept-stand-alone-mode.md @@ -59,7 +59,7 @@ If you only want the most recent ledger, you can skip this step. If you want to load a specific historical ledger version, use the [`ledger_request` command](reference-rippled.html#ledger-request) to make `rippled` fetch it. If `rippled` does not already have the ledger version, you may have to run the `ledger_request` command multiple times until it has finished retrieving the ledger. -If you want to replay a specific historical ledger version, you must fetch both the ledger version to replay and the ledger version immediately before it. (The previous ledger version sets up the initial state upon which you apply the changes described by the ledger version you replay.) +If you want to replay a specific historical ledger version, you must fetch both the ledger version to replay and the ledger version before it. (The previous ledger version sets up the initial state upon which you apply the changes described by the ledger version you replay.) ### 4. Shut down `rippled`. ### diff --git a/content/concept-transaction-cost.md b/content/concept-transaction-cost.md index 982c600c2c..4a0def0391 100644 --- a/content/concept-transaction-cost.md +++ b/content/concept-transaction-cost.md @@ -1,8 +1,8 @@ # Transaction Cost # -In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of [XRP](https://ripple.com/knowledge_center/math-based-currency-2/). This _transaction cost_ is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network. +to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of [XRP](https://ripple.com/knowledge_center/math-based-currency-2/). This _transaction cost_ is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network. -Every transaction must [specify how much XRP it will destroy](#specifying-the-transaction-cost) in order to pay the transaction cost. +Every transaction must [specify how much XRP to destroy](#specifying-the-transaction-cost) to pay the transaction cost. ## Current Transaction Cost ## @@ -24,7 +24,7 @@ Some transactions have different transaction costs: ## Beneficiaries of the Transaction Cost ## -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. +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 benefits all holders of XRP by making XRP more valuable. ## Load Cost and Open Ledger Cost ## @@ -49,7 +49,7 @@ Each `rippled` server maintains a cost threshold based on its current load. If y A `rippled` server with the [FeeEscalation amendment](concept-amendments.html#feeescalation) enabled has a second mechanism for enforcing the transaction cost, called the _open ledger cost_. A transaction can only be included in the open ledger if it meets the open ledger cost requirement in XRP. Transactions that do not meet the open ledger cost are [queued for a following ledger](#queued-transactions) instead. -For each new ledger version, the server picks a soft limit on the number of transactions to be included in the open ledger, based on the number of transactions in the previous ledger. The open ledger cost is equal to the minimum un-scaled transaction cost until the number of transactions in the open ledger is equal to the soft limit. After that, the open ledger cost increases exponentially for each additional transaction included in the open ledger. For the next ledger, the server increases the soft limit if the current ledger contained more transactions than the soft limit, and decreases the soft limit if the consensus process takes more than 5 seconds. +For each new ledger version, the server picks a soft limit on the number of transactions to be included in the open ledger, based on the number of transactions in the previous ledger. The open ledger cost is equal to the minimum un-scaled transaction cost until the number of transactions in the open ledger is equal to the soft limit. After that, the open ledger cost increases exponentially for each transaction included in the open ledger. For the next ledger, the server increases the soft limit if the current ledger contained more transactions than the soft limit, and decreases the soft limit if the consensus process takes more than 5 seconds. The open ledger cost requirement is [proportional to the normal cost of the transaction](#fee-levels), not the absolute transaction cost. Transaction types that have a higher-than-normal requirement, such as [multi-signed transactions](reference-transaction-format.html#multi-signing) must pay more to meet the open ledger cost than transactions which have minimum transaction cost requirements. @@ -59,9 +59,9 @@ See also: [Fee Escalation explanation in `rippled` repository](https://github.co (Requires the [FeeEscalation amendment](concept-amendments.html#feeescalation)) -When `rippled` receives a transaction that meet the server's local load cost but not the open ledger cost, the server checks the transaction to see if it is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries minimize the amount of network load caused by transactions that would not pay a transaction cost, since [the transaction cost only applies when a transaction is included in a validated ledger](#transaction-costs-and-failed-transactions). +When `rippled` receives a transaction that meet the server's local load cost but not the open ledger cost, the server estimates whether the transaction is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries minimize the amount of network load caused by transactions that would not pay a transaction cost, since [the transaction cost only applies when a transaction is included in a validated ledger](#transaction-costs-and-failed-transactions). -The `rippled` server uses a variety of heuristics to determine which transactions are "likely to be included in a ledger." Most importantly, those transactions must be properly-formed and [authorized](reference-transaction-format.html#authorizing-transactions) with valid signatures. +The `rippled` server uses a variety of heuristics to estimate which transactions are "likely to be included in a ledger." Most importantly, those transactions must be properly-formed and [authorized](reference-transaction-format.html#authorizing-transactions) with valid signatures. When the current open ledger closes and the server starts a new open ledger, the server starts taking transactions from the queue to include in the new open ledger. The transaction queue is sorted with the transactions that would pay the highest transaction cost first, proportional to the un-scaled cost of those transactions. Transactions that pay the same transaction cost are queued in the order the server receives them. @@ -109,14 +109,14 @@ The [`server_state` command](reference-rippled.html#server-state) returns a dire Every signed transaction must include the transaction cost in the [`Fee` field](reference-transaction-format.html#common-fields). 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. +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 the specified amount 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](concept-reserves.html). -Before signing a transaction, we recommend [looking up the current load-based transaction cost](#querying-the-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. +Before signing a transaction, we recommend [looking up the current load-based transaction cost](#querying-the-transaction-cost). If the transaction cost is 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: +When you sign a transaction online, you can omit the `Fee` field. In this case, `rippled` or [RippleAPI](reference-rippleapi.html) checks the state of the peer-to-peer network for the current requirement and adds a `Fee` value 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](tutorial-reliable-transaction-submission.html) for best practices. @@ -129,24 +129,24 @@ When you sign a transaction online, you can omit the `Fee` field. In this case, ## 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](reference-transaction-format.html#result-categories) ("tec" stands for "Transaction Engine - Claimed fee only"). +Since the purpose of the transaction cost is to protect the Ripple peer-to-peer 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, to affect the shared global ledger, a transaction must be included in a validated ledger. Thus, `rippled` servers try to include failed transactions in ledgers, with [`tec` status codes](reference-transaction-format.html#result-categories) ("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](reference-transaction-format.html#finality-of-results), 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](reference-transaction-format.html#finality-of-results), the `rippled` server does not relay it to the network. The transaction does not get included in a validated ledger, so 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](reference-transaction-format.html#finality-of-results). -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. +When a transaction has already been distributed to the network, but the account does not have enough 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](reference-transaction-format.html#setregularkey) transaction with a transaction cost of `0`, as long as the account's [lsfPasswordSpent flag](reference-ledger-format.html#accountroot-flags) 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. +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 more XRP to it. The [lsfPasswordSpent flag](reference-ledger-format.html#accountroot-flags) starts out disabled. If enabled, it gets disabled again when the account receives a [Payment](reference-transaction-format.html#payment) of XRP. @@ -155,4 +155,4 @@ When the [FeeEscalation amendment](concept-amendments.html#feeescalation) is ena ## 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](concept-fee-voting.html) for more information. +The Ripple Consensus Ledger has a mechanism for changing the minimum transaction cost to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See [Fee Voting](concept-fee-voting.html) for more information. diff --git a/content/concept-transfer-fees.md b/content/concept-transfer-fees.md index 29b20e8fc4..3f8fa331b8 100644 --- a/content/concept-transfer-fees.md +++ b/content/concept-transfer-fees.md @@ -1,10 +1,13 @@ # Transfer Fees # -The `TransferRate` setting in the Ripple Consensus Ledger allows [issuing gateways](https://ripple.com/knowledge_center/gateways/) to charge users a _transfer fee_ for sending that gateway's issuances to other users. When a gateway sets a transfer fee, it costs extra to send a transfer of that gateway's issuances. The sender of the transfer is debited an extra percentage based on the transfer fee, while the recipient of the transfer is credited the intended amount. The difference is the transfer fee, which becomes the property of the issuing gateway, and is no longer tracked in the Ripple Consensus Ledger. The transfer fee does not apply when sending or receiving _directly_ to and from the issuing account, but it does apply when transferring from a [hot wallet](concept-issuing-and-operational-addresses.html) to another user. +The `TransferRate` setting in the Ripple Consensus Ledger (RCL) allows [financial institutions that issue currency in the RCL](https://ripple.com/knowledge_center/gateways/) to charge users a _transfer fee_ for sending the currencies issued by that financial institution. The sender of the transfer is debited an extra percentage based on the transfer fee, while the recipient of the transfer is credited the intended amount. The difference is the transfer fee, which becomes the property of the issuing address, and is no longer tracked in the Ripple Consensus Ledger. The transfer fee does not apply when sending or receiving _directly_ to and from the issuing account, but it does apply when transferring from an [operational address][] to another user. + +[operational address]: concept-issuing-and-operational-addresses.html +[issuing address]: concept-issuing-and-operational-addresses.html XRP never has a transfer fee, because it never has an issuer. -For example, ACME Gateway might set the transfer fee to 0.5% for ACME issuances. In order for the recipient of a payment to get 2 EUR.ACME, the sender must send 2.01 EUR.ACME. After the transaction, ACME's outstanding obligations in Ripple have decreased by 0.01€, which means that it is no longer obliged to hold that amount in the account backing its Ripple issuances. +For example, ACME Bank might set the transfer fee to 0.5% for ACME issuances. For the recipient of a payment to get 2 EUR.ACME, the sender must send 2.01 EUR.ACME. After the transaction, ACME's outstanding obligations in Ripple have decreased by 0.01€, which means that ACME no longer needs to hold that amount in the account backing its Ripple issuances. The following diagram shows a Ripple payment of 2 EUR.ACME from Alice to Charlie with a transfer fee of 1%: @@ -12,32 +15,32 @@ The following diagram shows a Ripple payment of 2 EUR.ACME from Alice to Charlie ## Transfer Fees in Payment Paths ## -A transfer fee applies whenever an individual transfer would shift issuances from one party to another through the issuing account. In more complex transactions, this can occur multiple times. Transfer fees apply starting from the end and working backwards, so that ultimately the initial sender of a payment must send enough to account for all fees. For example: +A transfer fee applies whenever an individual transfer would shift issuances from one party to another through the issuing account. In more complex transactions, this can occur multiple times. Transfer fees apply starting from the end and working backwards, so that ultimately the sender of a payment must send enough to account for all fees. For example: ![Diagram of cross-currency payment with transfer fees](img/transfer_fees_example.png) -In this scenario, Salazar (the sender) holds EUR issued by ACME, and wants to deliver 100 USD issued by WayGate to Rosa (the recipient). FXMaker is a market maker with the best offer in the order book, at a rate of 1 USD.WayGate for every 0.9 EUR.ACME. If there were no transfer fees, Salazar could deliver 100 USD to Rosa by sending 90 EUR. However, ACME has a transfer fee of 1% and WayGate has a transfer fee of 0.2%. This means: +In this scenario, Salazar (the sender) holds EUR issued by ACME, and wants to deliver 100 USD issued by WayGate to Rosa (the recipient). FXMaker is a currency trader with the best offer in the order book, at a rate of 1 USD.WayGate for every 0.9 EUR.ACME. If there were no transfer fees, Salazar could deliver 100 USD to Rosa by sending 90 EUR. However, ACME has a transfer fee of 1% and WayGate has a transfer fee of 0.2%. This means: -* FXMaker must send 100.20 USD.WayGate in order for Rosa to receive 100 USD.WayGate. -* FXMaker's current ask is 90.18 EUR.ACME in order to send 100.20 USD.WayGate. -* In order for FXMaker to receive 90.18 EUR.ACME, Salazar must send 91.0818 EUR.ACME. +* FXMaker must send 100.20 USD.WayGate for Rosa to receive 100 USD.WayGate. +* FXMaker's current ask is 90.18 EUR.ACME to send 100.20 USD.WayGate. +* For FXMaker to receive 90.18 EUR.ACME, Salazar must send 91.0818 EUR.ACME. # Technical Details # -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. +The transfer fee is represented by a setting on the [issuing address][]. 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 [issuing addresses][issuing address] for 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. +In RippleAPI, the transfer fee is specified in the `transferRate` field, as an integer which represents the amount you must send 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 a special case for no fee, equivalent to `1000000000`. -A gateway can send a [Settings transaction](reference-rippleapi.html#settings) with its cold wallet to change the `transferRate` for its issuances. +A financial institution can send a [Settings transaction](reference-rippleapi.html#settings) from its [issuing address][] to change the `transferRate` for its issuances. You can check an account's `transferRate` with the [getSettings method](reference-rippleapi.html#getsettings). ## rippled ## -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. +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 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 case for no fee, equivalent to `1000000000`. -A gateway can submit an [AccountSet transaction](reference-transaction-format.html#accountset) from its cold wallet to change the `TransferRate` for its issuances. +A financial institution can submit an [AccountSet transaction](reference-transaction-format.html#accountset) from its [issuing address][] to change the `TransferRate` for its issuances. You can check an account's `TransferRate` with the [`account_info` command](reference-rippled.html#account-info). If the `TransferRate` is omitted, then that indicates no fee. diff --git a/content/data_types/account_sequence.md b/content/data_types/account_sequence.md index 38b34494b9..8a5d198904 100644 --- a/content/data_types/account_sequence.md +++ b/content/data_types/account_sequence.md @@ -1,5 +1,5 @@ A Sequence number is a 32-bit unsigned integer used to identify a transaction or Offer relative to a specific account. -Every [account object in the Ripple Consensus Ledger](reference-ledger-format.html#accountroot) has a Sequence number, which starts at 1. For a transaction to be relayed to the network and possibly included in a validated ledger, it must have a `Sequence` field that matches the sending account's current `Sequence` number. An account's Sequence field is incremented whenever a transaction from that account is included in a validated ledger (regardless of whether the transaction succeeded or failed). This preserves the order of transactions submitted by an account, and differentiates transactions that would otherwise be identical. +Every [account object in the Ripple Consensus Ledger](reference-ledger-format.html#accountroot) has a Sequence number, which starts at 1. For a transaction to be relayed to the network and possibly included in a validated ledger, it must have a `Sequence` field that matches the sending account's current `Sequence` number. An account's Sequence field is incremented whenever a transaction from that account is included in a validated ledger (regardless of whether the transaction succeeded or failed). This preserves the order of transactions submitted by an account, and differentiates transactions that would otherwise be the same. Every [Offer node in the Ripple Consensus Ledger](reference-ledger-format.html#offer) is marked with the sending `Account` [Address][] and the `Sequence` value of the [OfferCreate transaction](reference-transaction-format.html#offercreate) that created it. These two fields, together, uniquely identify the Offer. diff --git a/content/data_types/address.md b/content/data_types/address.md index 8496be88d0..e78bceeb58 100644 --- a/content/data_types/address.md +++ b/content/data_types/address.md @@ -10,7 +10,7 @@ Ripple Accounts are identified by a base-58 Ripple Address, which is derived fro [ACCOUNT_ONE]: #special-addresses [ACCOUNT_ZERO]: #special-addresses -Some addresses have special meaning, or historical uses, in the Ripple Consensus Ledger. In many cases, these are "black hole" addresses, meaning the address is not derived from a known secret key. Since it is almost impossible to guess a secret key from just an address, any XRP possessed by those addresses is lost forever. +Some addresses have special meaning, or historical uses, in the Ripple Consensus Ledger. In many cases, these are "black hole" addresses, meaning the address is not derived from a known secret key. Since it is almost impossible to guess a secret key from only an address, any XRP possessed by those addresses is lost forever. | Address | Name | Meaning | Black Hole? | |-----------------------------|------|---------|-------------| @@ -19,4 +19,3 @@ Some addresses have special meaning, or historical uses, in the Ripple Consensus | rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh | The genesis account | When `rippled` starts a new genesis ledger from scratch (for example, in stand-alone mode), this account holds all the XRP. This address is generated from the seed value "masterpassphrase" which is [hard-coded](https://github.com/ripple/rippled/blob/94ed5b3a53077d815ad0dd65d490c8d37a147361/src/ripple/app/ledger/Ledger.cpp#L184). | No | | rrrrrrrrrrrrrrrrrNAMEtxvNvQ | Ripple Name reservation black-hole | In the past, Ripple asked users to send XRP to this account to reserve Ripple Names.| Yes | | rrrrrrrrrrrrrrrrrrrn5RM1rHd | NaN Address | Previous versions of [ripple-lib](https://github.com/ripple/ripple-lib) generated this address when base-58 encoding the value [NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN). | Yes | - diff --git a/content/data_types/hash.md b/content/data_types/hash.md index 670c8694b5..87a25cbab5 100644 --- a/content/data_types/hash.md +++ b/content/data_types/hash.md @@ -1,4 +1,4 @@ -Many objects in Ripple, particularly transactions and ledgers, are uniquely identified by a 256-bit hash value. This value is typically calculated as a "SHA-512Half", which calculates a [SHA-512](http://dx.doi.org/10.6028/NIST.FIPS.180-4) hash from some contents, then takes the first 64 characters of the hexadecimal representation. Since the hash of an object is derived from the contents in a way that is extremely unlikely to produce collisions, two objects with the same hash can be considered identical. +Many objects in Ripple, particularly transactions and ledgers, are uniquely identified by a 256-bit hash value. This value is typically calculated as a "SHA-512Half", which calculates a [SHA-512](http://dx.doi.org/10.6028/NIST.FIPS.180-4) hash from some contents, then takes the first 64 characters of the hexadecimal representation. Since the hash of an object is derived from the contents in a way that is extremely unlikely to produce collisions, two objects with the same hash can be considered the same. A Ripple hash value has the following characteristics: @@ -7,4 +7,3 @@ A Ripple hash value has the following characteristics: * Typically written in upper case. **Note:** SHA-512Half has similar security to the officially-defined _SHA-512/256_ hash function. However, Ripple's usage predates SHA-512/256 and is also easier to implement on top of an existing SHA-512 function. (As of this writing, SHA-512 support in cryptographic libraries is much more common than for SHA-512/256.) - diff --git a/content/data_types/ledger_index.md b/content/data_types/ledger_index.md index 95b694d052..f50258bcd9 100644 --- a/content/data_types/ledger_index.md +++ b/content/data_types/ledger_index.md @@ -1,7 +1,7 @@ -A ledger index is a 32-bit unsigned integer used to identify a ledger. The ledger index is also known as the ledger's sequence number. The very first ledger was ledger index 1, and each subsequent ledger has a ledger index 1 higher than that of the ledger immediately before it. +A ledger index is a 32-bit unsigned integer used to identify a ledger. The ledger index is also known as the ledger's sequence number. The very first ledger was ledger index 1, and each new ledger has a ledger index 1 higher than that of the ledger immediately before it. -The ledger index indicates the order of the ledgers; the [Hash][] value identifies the exact contents of the ledger. Two ledgers with the same hash are always identical. For validated ledgers, hash values and sequence numbers are equally valid and correlate 1:1. However, this is not true for in-progress ledgers: +The ledger index indicates the order of the ledgers; the [Hash][] value identifies the exact contents of the ledger. Two ledgers with the same hash are always the same. For validated ledgers, hash values and sequence numbers are equally valid and correlate 1:1. However, this is not true for in-progress ledgers: * Two different `rippled` servers may have different contents for a current ledger with the same ledger index, due to latency in propagating transactions throughout the network. * There may be multiple closed ledger versions competing to be validated by consensus. These ledger versions have the same sequence number but different contents (and different hashes). Only one of these closed ledgers can become validated. -* A current ledger's contents change over time, which would cause its hash to change, even though its ledger index number stays the same. Therefore, the hash of a ledger is not calculated until the ledger is closed. +* A current ledger's contents change over time, which would cause its hash to change, even though its ledger index number stays the same. The hash of a ledger is not calculated until the ledger is closed. diff --git a/content/reference-data-api.md b/content/reference-data-api.md index 2c984326d2..4113c4c4ee 100644 --- a/content/reference-data-api.md +++ b/content/reference-data-api.md @@ -1,7 +1,7 @@ Ripple Data API v2 ================== -The Ripple Data API v2 provides access to information about changes in the Ripple Consensus Ledger, including transaction history and processed analytical data. This information is stored in a database for easy access, which frees `rippled` servers to maintain fewer historical ledger versions. Additionally, the Data API v2 acts as data source for applications such as [Ripple Charts](https://www.ripplecharts.com/) and [ripple.com](https://www.ripple.com). +The Ripple Data API v2 provides access to information about changes in the Ripple Consensus Ledger, including transaction history and processed analytical data. This information is stored in a dedicated database, which frees `rippled` servers to keep fewer historical ledger versions. The Data API v2 also acts as data source for applications such as [Ripple Charts](https://www.ripplecharts.com/) and [ripple.com](https://www.ripple.com). Ripple provides a live instance of the Data API with as complete a transaction record as possible at the following address: @@ -95,15 +95,15 @@ The following URL parameters are required by this API endpoint: | Field | Value | Description | |-------|-------|-------------| -| ledger_identifier | Ledger [Hash][], [Ledger Index][], or [Timestamp][] | (Optional) An identifier for the ledger to retrieve: either the full hash in hex, an integer sequence number, or a date-time. If a date-time is provided, retrieve the ledger that was most recently closed at that time. If omitted, retrieve the latest validated ledger. | +| `ledger_identifier` | Ledger [Hash][], [Ledger Index][], or [Timestamp][] | (Optional) An identifier for the ledger to retrieve: either the full hash in hex, an integer sequence number, or a date-time. If a date-time is provided, retrieve the ledger that was most recently closed at that time. If omitted, retrieve the latest validated ledger. | Optionally, you can also include the following query parameters: | Field | Value | Description | |-------|-------|-------------| -| transactions | Boolean | If `true`, include the identifying hashes of all transactions that are part of this ledger. | -| binary | Boolean | If `true`, include all transactions from this ledger as hex-formatted binary data. (If provided, overrides `transactions`.) | -| expand | Boolean | If `true`, include all transactions from this ledger as nested JSON objects. (If provided, overrides `binary` and `transactions`.) | +| `transactions` | Boolean | If `true`, include the identifying hashes of all transactions that are part of this ledger. | +| `binary` | Boolean | If `true`, include all transactions from this ledger as hex-formatted binary data. (If provided, overrides `transactions`.) | +| `expand` | Boolean | If `true`, include all transactions from this ledger as nested JSON objects. (If provided, overrides `binary` and `transactions`.) | #### Response Format #### @@ -111,8 +111,8 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| ledger | [Ledger object](#ledger-objects) | The requested ledger | +| `result` | String | The value `success` indicates that this is a successful response. | +| `ledger` | [Ledger object](#ledger-objects) | The requested ledger | #### Example #### @@ -167,13 +167,13 @@ The following URL parameters are required by this API endpoint: | Field | Value | Description | |-------|-------|-------------| -| hash | String - [Hash][] | The identifying hash of the transaction. | +| `hash` | String - [Hash][] | The identifying hash of the transaction. | Optionally, you can also include the following query parameters: | Field | Value | Description | |-------|-------|-------------| -| binary | Boolean | If `true`, return transaction data in binary format, as a hex string. Otherwise, return transaction data as nested JSON. Defaults to false. | +| `binary` | Boolean | If `true`, return transaction data in binary format, as a hex string. Otherwise, return transaction data as nested JSON. Defaults to false. | #### Response Format #### @@ -181,8 +181,8 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| transaction | [Transaction object](#transaction-objects) | The requested transaction | +| `result` | String | The value `success` indicates that this is a successful response. | +| `transaction` | [Transaction object](#transaction-objects) | The requested transaction | #### Example #### @@ -275,24 +275,24 @@ Optionally, you can include the following query parameters: | Field | Value | Description | |------------|-------|-------------| -| start | String - [Timestamp][] | Filter results to this time and later. | -| end | String - [Timestamp][] | Filter results to this time and earlier. | -| descending | Boolean | If true, return results in reverse chronological order. Defaults to false. | -| type | String | Filter transactions to a specific [transaction type](reference-transaction-format.html). | -| result | String | Filter transactions for a specific [transaction result](reference-transaction-format.html#transaction-results). | -| binary | Boolean | If true, return transactions in binary form. Defaults to false. | -| limit | Integer | Maximum results per page. Defaults to 20. Cannot be more than 100. | -| marker | String | [Pagination](#pagination) marker from a previous response. | +| `start` | String - [Timestamp][] | Filter results to this time and later. | +| `end` | String - [Timestamp][] | Filter results to this time and earlier. | +| `descending` | Boolean | If true, return results in reverse chronological order. Defaults to false. | +| `type` | String | Filter transactions to a specific [transaction type](reference-transaction-format.html). | +| `result` | String | Filter transactions for a specific [transaction result](reference-transaction-format.html#transaction-results). | +| `binary` | Boolean | If true, return transactions in binary form. Defaults to false. | +| `limit` | Integer | Maximum results per page. Defaults to 20. Cannot be more than 100. | +| `marker` | String | [Pagination](#pagination) marker from a previous response. | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of Transactions returned. | -| marker | String | (May be omitted) Pagination marker | -| transactions | Array of [Transaction object](#transaction-objects) | The requested transactions | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of Transactions returned. | +| `marker` | String | (May be omitted) Pagination marker | +| `transactions` | Array of [Transaction object](#transaction-objects) | The requested transactions | #### Example #### @@ -439,19 +439,19 @@ This method accepts the following URL parameters: | Field | Value | Description | |-----------|--------|-------------| -| :currency | String | (Optional) Currency code, followed by `+` and a counterparty address. (Or just `XRP`.) If omitted, return payments for all currencies. | +| :currency | String | (Optional) Currency code, followed by `+` and a counterparty address. (Or `XRP` with no counterparty.) If omitted, return payments for all currencies. | Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Filter results to this time and later. | -| end | String - [Timestamp][] | Filter results to this time and earlier. | -| interval | String | If provided and `currency` is also specified, return results aggregated into intervals of the specified length instead of individual payments. Valid intervals are `day`, `week`, or `month`. | -| descending | Boolean | Reverse chronological order. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Filter results to this time and later. | +| `end` | String - [Timestamp][] | Filter results to this time and earlier. | +| `interval` | String | If provided and `currency` is also specified, return results aggregated into intervals of the specified length instead of individual payments. Valid intervals are `day`, `week`, or `month`. | +| `descending` | Boolean | Reverse chronological order. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -460,24 +460,24 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of Transactions returned | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| payments | Array of [Payment Objects][], or array of aggregate objects | The requested payments | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of Transactions returned | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `payments` | Array of [Payment Objects][], or array of aggregate objects | The requested payments | ##### Aggregate Results ##### -If the request specifies a `currency` and an `interval`, the result includes objects summarizing activity over a specific time period instead of listing individual payments. Each interval summary object has the following fields: +If the request specifies a `currency` and an `interval`, the result includes objects summarizing activity over a specific time period instead of listing individual payments. Each interval summary object has the following fields: | Field | Value | Description | |--------|-------|-------------| -| count | Number | The number of payments that occurred during this interval. | -| currency | String - Currency Code | This summary describes payments that delivered the specified currency. | -| issuer | String - Address | (Omitted for XRP) This summary describes payments that delivered the currency issued by this address. | -| start | String - [Timestamp][] | The start time of this interval | -| total\_amount | Number | The amount of the `currency` delivered during this interval. | -| average\_amount | Number | The average amount of currency delivered by a single payment during this interval. | +| `count` | Number | The number of payments that occurred during this interval. | +| `currency` | String - Currency Code | This summary describes payments that delivered the specified currency. | +| `issuer` | String - Address | (Omitted for XRP) This summary describes payments that delivered the currency issued by this address. | +| `start` | String - [Timestamp][] | The start time of this interval | +| `total_amount` | Number | The amount of the `currency` delivered during this interval. | +| `average_amount` | Number | The average amount of currency delivered by a single payment during this interval. | #### Example #### @@ -584,32 +584,32 @@ This method requires the following URL parameters: | Field | Value | Description | |-------|-------|-------------| -| base | String | Base currency of the pair, as a [Currency Code][], followed by `+` and the issuer [Address][] unless it's XRP. | -| counter | String | Counter currency of the pair, as a [Currency Code][], followed by `+` and the issuer [Address][] unless it's XRP. | +| `base` | String | Base currency of the pair, as a [Currency Code][], followed by `+` and the issuer [Address][] unless it's XRP. | +| `counter` | String | Counter currency of the pair, as a [Currency Code][], followed by `+` and the issuer [Address][] unless it's XRP. | Optionally, you can also include the following query parameters: | Field | Value | Description | |-------------|-------|-------------| -| start | String - [Timestamp][] | Filter results to this time and later. | -| end | String - [Timestamp][] | Filter results to this time and earlier. | -| interval | String | Aggregation interval: `1minute`, `5minute`, `15minute`, `30minute`, `1hour`, `2hour`, `4hour`, `1day`, `3day`, `7day`, or `1month`. Defaults to non-aggregated results. | -| descending | Boolean | If true, return results in reverse chronological order. | -| reduce | Boolean | Aggregate all individual results. Defaults to false. | -| limit | Integer | Maximum results per page (defaults to 200). Cannot be more than 20,000 if `reduce` is true. Otherwise cannot be more than 1,000. | -| marker | String | [Pagination](#pagination) key from previously returned response. | -| autobridged | Boolean | If true, filter results to autobridged exchanges only. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json` | +| `start` | String - [Timestamp][] | Filter results to this time and later. | +| `end` | String - [Timestamp][] | Filter results to this time and earlier. | +| `interval` | String | Aggregation interval: `1minute`, `5minute`, `15minute`, `30minute`, `1hour`, `2hour`, `4hour`, `1day`, `3day`, `7day`, or `1month`. Defaults to non-aggregated results. | +| `descending` | Boolean | If true, return results in reverse chronological order. | +| `reduce` | Boolean | Aggregate all individual results. Defaults to false. | +| `limit` | Integer | Maximum results per page (defaults to 200). Cannot be more than 20,000 if `reduce` is true. Otherwise cannot be more than 1,000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response. | +| `autobridged` | Boolean | If true, filter results to autobridged exchanges only. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json` | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of Transactions returned. | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| exchanges | Array of [Exchange Objects][] | The requested exchanges | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of Transactions returned. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `exchanges` | Array of [Exchange Objects][] | The requested exchanges | #### Example #### @@ -723,8 +723,8 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |--------|---------|-------------| -| date | String - [Timestamp][] | Return an exchange rate for the specified time. Defaults to the current time. | -| strict | Boolean | If false, allow rates derived from less than 10 exchanges. Defaults to true. | +| `date` | String - [Timestamp][] | Return an exchange rate for the specified time. Defaults to the current time. | +| `strict` | Boolean | If false, allow rates derived from less than 10 exchanges. Defaults to true. | #### Response Format #### @@ -732,8 +732,8 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| rate | Number | The requested exchange rate, or `0` if the exchange rate could not be determined. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `rate` | Number | The requested exchange rate, or `0` if the exchange rate could not be determined. | All exchange rates are calcuated by converting the base currency and counter currency to XRP. @@ -782,13 +782,13 @@ This method uses the following query parameters: | Field | Value | Description | |-------------------|---------|-------------| -| amount | Number | (Required) Amount of currency to normalize | -| currency | String - [Currency Code][] | The currency code of the `amount` to convert from. (Defaults to XRP.) | -| issuer | String - [Address][] | The issuer of the currency to convert from. (Required if `currency` is not XRP.) | -| exchange\_currency | String - [Currency Code][] | The currency to convert to. (Defaults to XRP.) | -| exchange\_issuer | String - [Address][] | The issuer of the currency to convert to. (Required if `exchange_currency` is not XRP.) | -| date | String - [Timestamp][] | Convert according to the exchange rate at this time. (Defaults to the current time.) | -| strict | Boolean | If true, do not use exchange rates that are determined by less than 10 exchanges. (Defaults to true.) | +| `amount` | Number | (Required) Amount of currency to normalize | +| `currency` | String - [Currency Code][] | The currency code of the `amount` to convert from. (Defaults to XRP.) | +| `issuer` | String - [Address][] | The issuer of the currency to convert from. (Required if `currency` is not XRP.) | +| `exchange_currency` | String - [Currency Code][] | The currency to convert to. (Defaults to XRP.) | +| `exchange_issuer` | String - [Address][] | The issuer of the currency to convert to. (Required if `exchange_currency` is not XRP.) | +| `date` | String - [Timestamp][] | Convert according to the exchange rate at this time. (Defaults to the current time.) | +| `strict` | Boolean | If true, do not use exchange rates that are determined by less than 10 exchanges. (Defaults to true.) | #### Response Format #### @@ -796,10 +796,10 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| amount | Number | Pre-conversion amount specified in the request | -| converted | Number | Post-conversion amount of the `exchange_currency`, or `0` if the exchange rate could not be determined. | -| rate | Number | Exchange rate used to calculate the conversion, or `0` if the exchange rate could not be determined. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `amount` | Number | Pre-conversion amount specified in the request | +| `converted` | Number | Post-conversion amount of the `exchange_currency`, or `0` if the exchange rate could not be determined. | +| `rate` | Number | Exchange rate used to calculate the conversion, or `0` if the exchange rate could not be determined. | All exchange rates are calculating by converting both currencies to XRP. @@ -848,17 +848,17 @@ This method uses the following URL parameters: | Field | Value | Description | |-------|--------|-------------| -| date | String | (Optional) UTC query date. If omitted, use the current day. | +| `date` | String | (Optional) UTC query date. If omitted, use the current day. | Optionally, you can also include the following query parameters: | Field | Value | Description | |----------|---------|-------------| -| accounts | Boolean | If true, include lists of counterparty accounts. Defaults to false. | -| payments | Boolean | If true, include lists of individual payments. Defaults to false. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response | +| `accounts` | Boolean | If true, include lists of counterparty accounts. Defaults to false. | +| `payments` | Boolean | If true, include lists of individual payments. Defaults to false. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | #### Response Format #### @@ -866,13 +866,13 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| date | String - [Timestamp][] | The date for which this report applies. | -| count | Integer | Number of reports returned. | -| marker | String | (May be omitted) [Pagination](#pagination) marker. | -| reports | Array of [Reports Objects][] | The requested reports. Each report pertains to a single account. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `date` | String - [Timestamp][] | The date for which this report applies. | +| `count` | Integer | Number of reports returned. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker. | +| `reports` | Array of [Reports Objects][] | The requested reports. Each report pertains to a single account. | -**WARNING:** This method may return a very large amount of data (more than 1 megabyte), which may cause poor performance in your client application. +**Caution:** This method may return a very large amount of data (more than 1 megabyte), which may cause poor performance in your client application. #### Example #### @@ -1012,15 +1012,15 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| family | String | If provided, filter results to a single family of stats: `type`, `result`, or `metric`. By default, provides all stats from all families. | -| metrics | String | Filter results to one or more metrics (in a comma-separated list). Requires the `family` of the metrics to be specified. By default, provides all metrics in the family. | -| start | String - [Timestamp][] | Filter results to this time and later. | -| end | String - [Timestamp][] | Filter results to this time and earlier | -| interval | String | Aggregation interval (`hour`,`day`,`week`, defaults to `day`) | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response. | -| descending | Boolean | If true, return results in reverse chronological order. Defaults to false. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `family` | String | If provided, filter results to a single family of stats: `type`, `result`, or `metric`. By default, provides all stats from all families. | +| `metrics` | String | Filter results to one or more metrics (in a comma-separated list). Requires the `family` of the metrics to be specified. By default, provides all metrics in the family. | +| `start` | String - [Timestamp][] | Filter results to this time and later. | +| `end` | String - [Timestamp][] | Filter results to this time and earlier | +| `interval` | String | Aggregation interval (`hour`,`day`,`week`, defaults to `day`) | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response. | +| `descending` | Boolean | If true, return results in reverse chronological order. Defaults to false. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | ##### Families and Metrics ##### @@ -1028,9 +1028,9 @@ The `family` and `metrics` query parameters provide a way to filter results to a | Family | Included Metrics | Meaning | |--------|------------------|---------| -| type | All Ripple [transaction types](reference-transaction-format.html), including `Payment`, `AccountSet`, `OfferCreate`, and others. | Number of transactions of the given type that occurred during the interval. | -| result | All [transaction result codes](reference-transaction-format.html#transaction-results) (string codes, not the numeric codes), including `tesSUCCESS`, `tecPATH_DRY`, and many others. | Number of transactions that resulted in the given code during the interval. | -| metric | Data-API defined Special Transaction Metrics. | (Varies) | +| `type` | All Ripple [transaction types](reference-transaction-format.html), including `Payment`, `AccountSet`, `OfferCreate`, and others. | Number of transactions of the given type that occurred during the interval. | +| `result` | All [transaction result codes](reference-transaction-format.html#transaction-results) (string codes, not the numeric codes), including `tesSUCCESS`, `tecPATH_DRY`, and many others. | Number of transactions that resulted in the given code during the interval. | +| `metric` | Data-API defined Special Transaction Metrics. | (Varies) | ##### Special Transaction Metrics ##### @@ -1038,12 +1038,12 @@ The Data API derives the following values for every interval. These metrics are | Field | Value | Description | |--------|-------|-------------| -| accounts\_created | Number | The number of new accounts funded during this interval. | -| exchanges\_count | Number | The number of currency exchanges that occurred during this interval. | -| ledger\_count | Number | The number of ledgers closed during this interval. | -| ledger\_interval | Number | The average number of seconds between ledgers closing during this interval. | -| payments\_count | Number | The number of payments from one account to another during this interval. | -| tx\_per\_ledger | Number | The average number of transactions per ledger in this interval. | +| `accounts_created` | Number | The number of new accounts funded during this interval. | +| `exchanges_count` | Number | The number of currency exchanges that occurred during this interval. | +| `ledger_count` | Number | The number of ledgers closed during this interval. | +| `ledger_interval` | Number | The average number of seconds between ledgers closing during this interval. | +| `payments_count` | Number | The number of payments from one account to another during this interval. | +| `tx_per_ledger` | Number | The average number of transactions per ledger in this interval. | If any of the metrics have a value of 0, they are omitted from the results. @@ -1052,10 +1052,10 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of reports returned. | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| stats | Array of stats objects | The requested stats. Omits metrics with a value of 0, and intervals that have no nonzero metrics. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of reports returned. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `stats` | Array of stats objects | The requested stats. Omits metrics with a value of 0, and intervals that have no nonzero metrics. | #### Example #### @@ -1123,14 +1123,14 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to `2013-01-01T00:00:00Z`. | -| end | String - [Timestamp][] | End time of query range. Defaults to the current time. | -| interval | String | Aggregation interval - `day`, `week`, or `month`. Defaults to `day`. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| descending | Boolean | If true, return results in reverse chronological order. Defaults to false. | -| adjusted | Boolean | If true, do not count known issuer-owned wallets towards market capitalization. Defaults to true. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to `2013-01-01T00:00:00Z`. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the current time. | +| `interval` | String | Aggregation interval - `day`, `week`, or `month`. Defaults to `day`. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `descending` | Boolean | If true, return results in reverse chronological order. Defaults to false. | +| `adjusted` | Boolean | If true, do not count known issuer-owned addresses towards market capitalization. Defaults to true. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | If the request omits both `start` and `end`, the API returns only the most recent sample. @@ -1140,19 +1140,19 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of reports returned. | -| currency | String | Currency requested | -| issuer | String | Issuer requested | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| rows | Array of issuer capitalization objects | The requested capitalization data | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of reports returned. | +| `currency` | String | Currency requested | +| `issuer` | String | Issuer requested | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `rows` | Array of issuer capitalization objects | The requested capitalization data | Each **issuer capitalization object** has the following fields: | Field | Value | Description | |--------|-------|-------------| -| date | String - [Timestamp][] | The start time of the interval this object represents. | -| amount | [String - Number][] | The total amount of currency issued by the issuer as of the start of this interval. | +| `date` | String - [Timestamp][] | The start time of the interval this object represents. | +| `amount` | [String - Number][] | The total amount of currency issued by the issuer as of the start of this interval. | #### Example #### @@ -1249,37 +1249,37 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |--------------------|---------|-------------| -| period | String | Get results for trading activity during a chosen time period. Valid periods are `1day`, `3day`, or `7day`. Defaults to `1day`. | -| date | String | Get results for the period starting at this time. Defaults to the most recent period available. | -| include\_exchanges | Boolean | Include individual exchanges for each account in the results. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `period` | String | Get results for trading activity during a chosen time period. Valid periods are `1day`, `3day`, or `7day`. Defaults to `1day`. | +| `date` | String | Get results for the period starting at this time. Defaults to the most recent period available. | +| `include_exchanges` | Boolean | Include individual exchanges for each account in the results. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of accounts returned. | -| exchanges\_count | Integer | Total number of exchanges in the period. | -| accounts | Array of active Account Trading Objects | Active trading accounts for the period | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of accounts returned. | +| `exchanges_count` | Integer | Total number of exchanges in the period. | +| `accounts` | Array of active Account Trading Objects | Active trading accounts for the period | -Each "Account Trading Object" describes the activity of a single account during the period, and has the following fields: +Each "Account Trading Object" describes the activity of a single account during this time period, and has the following fields: | Field | Value | Description | |-----------------|------------------|-------------| -| buy | Object | Summary of currency exchanges buying the base currency| -| buy.base\_volume | Number | Amount of base currency the account bought in this period. | -| buy.counter\_volume | Number | Amount of counter currency the account sold in this period. | -| buy.count | Number | Number of trades that bought the base currency in this period. | -| sell | Object | Summary of currency changes selling the base currency | -| sell.base\_volume | Number | Amount of the base currency the account sold this period. | -| sell.counter\_volume | Number | Amount of the counter currency the account bought this period. | -| sell.count | Number | Number of trades that sold the base currency. | -| account | String - Address | The address whose activity this object describes | -| base\_volume | Number | The total volume of the base currency the account bought and sold in this period. | -| counter\_volume | Number | The total volume of the counter currency the account bought and sold in this period. | -| count | Number | The total number of exchanges the account made during this period. | +| `buy` | Object | Summary of currency exchanges buying the base currency| +| `buy.base_volume` | Number | Amount of base currency the account bought in this period. | +| `buy.counter_volume` | Number | Amount of counter currency the account sold in this period. | +| `buy.count` | Number | Number of trades that bought the base currency in this period. | +| `sell` | Object | Summary of currency changes selling the base currency | +| `sell.base_volume` | Number | Amount of the base currency the account sold this period. | +| `sell.counter_volume` | Number | Amount of the counter currency the account bought this period. | +| `sell.count` | Number | Number of trades that sold the base currency. | +| `account` | String - Address | The address whose activity this object describes | +| `base_volume` | Number | The total volume of the base currency the account bought and sold in this period. | +| `counter_volume` | Number | The total volume of the counter currency the account bought and sold in this period. | +| `count` | Number | The total number of exchanges the account made during this period. | #### Example #### @@ -1395,34 +1395,34 @@ Optionally, you can include the following query parameters: | Field | Value | Description | |----------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | -| end | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | -| interval | String | Aggregation interval - valid intervals are `day`, `week`, or `month`. Defaults to `day`. | -| exchange\_currency | String - [Currency Code][] | Normalize all amounts to use this as a display currency. If not XRP, `exchange_issuer` is also required. Defaults to XRP. | -| exchange\_issuer | String - [Address][] | Normalize results to the specified `currency` issued by this issuer. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | +| `interval` | String | Aggregation interval - valid intervals are `day`, `week`, or `month`. Defaults to `day`. | +| `exchange_currency` | String - [Currency Code][] | Normalize all amounts to use this as a display currency. If not XRP, `exchange_issuer` is also required. Defaults to XRP. | +| `exchange_issuer` | String - [Address][] | Normalize results to the specified `currency` issued by this issuer. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of results returned. | -| rows | Array of exchange [Volume Objects][] | Exchange volumes for each interval in the requested time period. (By default, this method only returns the most recent interval.) | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of results returned. | +| `rows` | Array of exchange [Volume Objects][] | Exchange volumes for each interval in the requested time period. (By default, this method only returns the most recent interval.) | Each object in the `components` array of the Volume Objects represent the volume of exchanges in a market between two currencies, and has the following fields: | Field | Value | Description | |--------|--------|-------------| -| count | Number | The number of exchanges in this market during this interval. | -| rate | Number | The exchange rate from the base currency to the display currency. | -| amount | Number | The amount of volume in the market, in units of the base currency. | -| base | Object | The `currency` and `issuer` that identify the base currency of this market. There is no `issuer` for XRP. | -| counter | Object | The `currency` and `issuer` that identify the counter currency of this market. There is no `issuer` for XRP. | -| converted\_amount | Number | The total amount of volume in the market, converted to the display currency. _(Before [v2.1.0][], this was `convertedAmount`.)_ | +| `count` | Number | The number of exchanges in this market during this interval. | +| `rate` | Number | The exchange rate from the base currency to the display currency. | +| `amount` | Number | The amount of volume in the market, in units of the base currency. | +| `base` | Object | The `currency` and `issuer` of the base currency of this market. There is no `issuer` for XRP. | +| `counter` | Object | The `currency` and `issuer` of the counter currency of this market. There is no `issuer` for XRP. | +| `converted_amount` | Number | The total amount of volume in the market, converted to the display currency. _(Before [v2.1.0][], this was `convertedAmount`.)_ | #### Example #### @@ -1543,34 +1543,34 @@ Optionally, you can include the following query parameters: | Field | Value | Description | |----------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | -| end | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | -| interval | String | Aggregation interval - valid intervals are `day`, `week`, or `month`. Defaults to `day`. | -| exchange\_currency | String - [Currency Code][] | Normalize all amounts to use this as a display currency. If not XRP, `exchange_issuer` is also required. Defaults to XRP. | -| exchange\_issuer | String - [Address][] | Normalize results to the specified `currency` issued by this issuer. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | +| `interval` | String | Aggregation interval - valid intervals are `day`, `week`, or `month`. Defaults to `day`. | +| `exchange_currency` | String - [Currency Code][] | Normalize all amounts to use this as a display currency. If not XRP, `exchange_issuer` is also required. Defaults to XRP. | +| `exchange_issuer` | String - [Address][] | Normalize results to the specified `currency` issued by this issuer. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of results returned. | -| rows | Array of payment [Volume Objects][] | Payment volumes for each interval in the requested time period. (By default, this method only returns the most recent interval.) | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of results returned. | +| `rows` | Array of payment [Volume Objects][] | Payment volumes for each interval in the requested time period. (By default, this method only returns the most recent interval.) | Each object in the `components` array of the Volume Objects represent the volume of payments for one currencies and issuer, and has the following fields: | Field | Value | Description | |--------|--------|-------------| -| currency | String - [Currency Code][] | The currency of this payment volume object. | -| issuer | String - [Address][] | (Omitted for XRP) The issuer of this payment volume object. | -| amount | Number | Total payment volume for this currency during the interval, in units of the currency itself. | -| count | Number | The total number of payments in this currency | -| rate | Number | The exchange rate between this currency and the display currency. | -| converted\_amount | Number | Total payment volume for this currency, converted to the display currency. _(Before [v2.1.0][], this was `convertedAmount`.)_ | +| `currency` | String - [Currency Code][] | The currency of this payment volume object. | +| `issuer` | String - [Address][] | (Omitted for XRP) The issuer of this payment volume object. | +| `amount` | Number | Total payment volume for this currency during the interval, in units of the currency itself. | +| `count` | Number | The total number of payments in this currency | +| `rate` | Number | The exchange rate between this currency and the display currency. | +| `converted_amount` | Number | Total payment volume for this currency, converted to the display currency. _(Before [v2.1.0][], this was `convertedAmount`.)_ | #### Example #### @@ -1650,7 +1650,7 @@ Response: ## Get Issued Value ## [[Source]
    ](https://github.com/ripple/rippled-historical-database/blob/develop/api/routesV2/network/getMetric.js "Source") -Get the total value of all currencies issued by a selection of major gateways over time. By default, returns only the most recent measurement. _(New in [v2.0.4][])_ +Get the total value of all currencies issued by major gateways over time. By default, returns only the most recent measurement. _(New in [v2.0.4][])_ The API returns results in units of a single _display currency_ rather than many different currencies. The conversion uses standard rates to and from XRP. @@ -1672,13 +1672,13 @@ Optionally, you can include the following query parameters: | Field | Value | Description | |--------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | -| end | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | -| exchange\_currency | String - [Currency Code][] | Normalize all amounts to use this as a display currency. If not XRP, `exchange_issuer` is also required. Defaults to XRP. | -| exchange\_issuer | String - [Address][] | Normalize results to the specified `currency` issued by this issuer. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | +| `exchange_currency` | String - [Currency Code][] | Normalize all amounts to use this as a display currency. If not XRP, `exchange_issuer` is also required. Defaults to XRP. | +| `exchange_issuer` | String - [Address][] | Normalize results to the specified `currency` issued by this issuer. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -1686,19 +1686,19 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of results returned. | -| rows | Array of Issued Value Objects | Aggregated capitalization at the requested point(s) in time. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of results returned. | +| `rows` | Array of Issued Value Objects | Aggregated capitalization at the requested point(s) in time. | Each Issued Value Object represents the total value issued at one point in time, and has the following fields: | Field | Value | Description | |--------|-------|-------------| -| components | Array of Objects | The data on individual issuers that was used to assemble this total. | -| exchange | Object | Indicates the display currency used, as with fields `currency` and (except for XRP) `issuer`. All amounts are normalized by first converting to XRP, and then to the display currency specified in the request. | -| exchangeRate | Number | The exchange rate to the displayed currency from XRP. -| time | String - [Timestamp][] | The time at which this data was measured. | -| total | Number | Total value of all issued assets at this time, in units of the display currency. | +| `components` | Array of Objects | The data on individual issuers that was used to assemble this total. | +| `exchange` | Object | Indicates the display currency used, as with fields `currency` and (except for XRP) `issuer`. All amounts are normalized by first converting to XRP, and then to the display currency specified in the request. | +| `exchangeRate` | Number | The exchange rate to the displayed currency from XRP. +| `time` | String - [Timestamp][] | The time at which this data was measured. | +| `total` | Number | Total value of all issued assets at this time, in units of the display currency. | #### Example #### @@ -1791,22 +1791,22 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| date | String - [Timestamp][] | The time at which this data was measured. | -| count | Integer | Number of objects in the `currencies` field. | -| currencies | Array of Top Currency Objects | The top currencies for this data sample. Each member represents one currency, by currency code and issuer. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `date` | String - [Timestamp][] | The time at which this data was measured. | +| `count` | Integer | Number of objects in the `currencies` field. | +| `currencies` | Array of Top Currency Objects | The top currencies for this data sample. Each member represents one currency, by currency code and issuer. | Each Top Currency Object has the following fields: | Field | Value | Description | |--------|-------|-------------| -| currency | String - [Currency Code][] | The currency this object describes | -| issuer | String - [Address][] | The Ripple address that issues this currency | -| avg_exchange_count | [String - Number][] | Daily average number of [exchanges](#exchange-objects) | -| avg_exchange_volume | [String - Number][] | Daily average volume of exchanges, normalized to XRP | -| avg_payment_count | [String - Number][] | Daily average number of [payments](#payment-objects) | -| avg_payment_volume | [String - Number][] | Daily average volume of payments, normalized to XRP | -| issued_value | [String - Number][] | Total amount of this currency issued by this issuer, normalized to XRP | +| `currency` | String - [Currency Code][] | The currency this object describes | +| `issuer` | String - [Address][] | The Ripple address that issues this currency | +| `avg_exchange_count` | [String - Number][] | Daily average number of [exchanges](#exchange-objects) | +| `avg_exchange_volume` | [String - Number][] | Daily average volume of exchanges, normalized to XRP | +| `avg_payment_count` | [String - Number][] | Daily average number of [payments](#payment-objects) | +| `avg_payment_volume` | [String - Number][] | Daily average volume of payments, normalized to XRP | +| `issued_value` | [String - Number][] | Total amount of this currency issued by this issuer, normalized to XRP | #### Example #### @@ -1892,23 +1892,23 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| date | String - [Timestamp][] | The end of the rolling window over which this data was calculated. | -| count | Integer | Number of results in the `markets` field. | -| markets | Array of Top Market Objects | The top markets for this data sample. Each member represents a currency pair. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `date` | String - [Timestamp][] | The end of the rolling window over which this data was calculated. | +| `count` | Integer | Number of results in the `markets` field. | +| `markets` | Array of Top Market Objects | The top markets for this data sample. Each member represents a currency pair. | Each Top Market object has the following fields: | Field | Value | Description | |--------|-------|-------------| -| base_currency | String - [Currency Code][] | The base currency for this market | -| base_issuer | String - [Address][] | (Omitted if `base_currency` is XRP) The Ripple address that issues the base currency | -| counter_currency | String - [Currency Code][] | The counter currency for this market | -| counter_issuer | String - [Address][] | (Omitted if `counter_currency` is XRP) The Ripple address that issues the counter currency | -| avg_base_volume | String | Daily average volume in terms of the base currency | -| avg_counter_volume | String | Daily average volume in terms of the counter currency | -| avg_exchange_count | String | Daily average number of [exchanges](#exchange-objects) | -| avg_volume | String | Daily average volume, normalized to XRP | +| `base_currency` | String - [Currency Code][] | The base currency for this market | +| `base_issuer` | String - [Address][] | (Omitted if `base_currency` is XRP) The Ripple address that issues the base currency | +| `counter_currency` | String - [Currency Code][] | The counter currency for this market | +| `counter_issuer` | String - [Address][] | (Omitted if `counter_currency` is XRP) The Ripple address that issues the counter currency | +| `avg_base_volume` | String | Daily average volume in terms of the base currency | +| `avg_counter_volume` | String | Daily average volume in terms of the counter currency | +| `avg_exchange_count` | String | Daily average number of [exchanges](#exchange-objects) | +| `avg_volume` | String | Daily average volume, normalized to XRP | #### Example #### @@ -1990,11 +1990,11 @@ Each field in the top level JSON object is a [Currency Code][]. The content of e | Field | Value | Description | |----------|---------|-------------| -| name | String | A human-readable proper name for the gateway. | -| account | String - [Address][] | The issuing account (cold wallet) that issues the currency. | -| featured | Boolean | Whether this gateway is considered a "featured" issuer of the currency. Ripple decides which gateways to feature based on responsible business practices, volume, and other measures. | -| label | String | (May be omitted) Only provided when the [Currency Code][] is a 40-character hexadecimal value. This is an alternate human-readable name for the currency issued by this gateway. -| assets | Array of Strings | Graphics filenames available for this gateway, if any. (Mostly, these are logos used by Ripple Charts.) | +| `name` | String | A human-readable proper name for the gateway. | +| `account` | String - [Address][] | The [issuing address](concept-issuing-and-operational-addresses.html) of this currency. | +| `featured` | Boolean | Whether this gateway is considered a "featured" issuer of the currency. Ripple decides which gateways to feature based on responsible business practices, volume, and other measures. | +| `label` | String | (May be omitted) Only provided when the [Currency Code][] is a 40-character hexadecimal value. This is an alternate human-readable name for the currency issued by this gateway. +| `assets` | Array of Strings | Graphics filenames available for this gateway, if any. (Mostly, these are logos used by Ripple Charts.) | #### Example #### @@ -2059,6 +2059,7 @@ Response: ## Get Gateway ## [[Source]
    ](https://github.com/ripple/rippled-historical-database/blob/develop/api/routesV2/gateways.js "Source") + Get information about a specific gateway from [the Data API's list of known gateways](https://github.com/ripple/rippled-historical-database/blob/v2.0.4/api/gateways/gateways.json). _(New in [v2.0.4][])_ #### Request Format #### @@ -2089,20 +2090,20 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |-------------|--------|-------------| -| name | String | Human-readable name of the gateway -| start\_date | String - [Timestamp][] | The approximate date of the first time exchanges for this gateway's currencies appeared in the ledger. | -| accounts | Array | A list of [issuing addresses](concept-issuing-and-operational-addresses.html) (cold wallets) used by this gateway. (Gateways may use different issuing accounts for different currencies.) | -| hotwallets | Array of [Address][]es | The addresses of the Ripple accounts this gateway uses as [operational addresses](concept-issuing-and-operational-addresses.html) (hot wallets). | -| domain | String | The domain name where this gateway does business. Typically the gateway hosts a [`ripple.txt`](https://wiki.ripple.com/Ripple.txt) there. | -| normalized | String | A normalized version of the `name` field suitable for including in URLs. | -| assets | Array of Strings | Graphics filenames available for this gateway, if any. (Mostly, these are logos used by Ripple Charts.) | +| `name` | String | Human-readable name of the gateway | +| `start_date` | String - [Timestamp][] | The approximate date of the first time exchanges for this gateway's currencies appeared in the ledger. | +| `accounts` | Array | A list of [issuing addresses](concept-issuing-and-operational-addresses.html) used by this gateway. (Gateways may use different issuing accounts for different currencies.) | +| `hotwallets` | Array of [Address][]es | This gateway's [operational addresses](concept-issuing-and-operational-addresses.html). | +| `domain` | String | The domain name where this gateway does business. Typically the gateway hosts a [`ripple.txt`](https://wiki.ripple.com/Ripple.txt) there. | +| `normalized` | String | A normalized version of the `name` field suitable for including in URLs. | +| `assets` | Array of Strings | Graphics filenames available for this gateway, if any. (Mostly, these are logos used by Ripple Charts.) | Each object in the `accounts` field array has the following fields: | Field | Value | Description | |------------|--------|-------------| -| address | String | The [Address][] of an [issuing address](concept-issuing-and-operational-addresses.html) (cold wallet) used by this gateway. | -| currencies | Object | Each field in this object is a [Currency Code][] corresponding to a currency issued from this address. Each value is an object with a `featured` boolean indicating whether that currency is featured. Ripple decides which currencies and gateways to feature based on responsible business practices, volume, and other measures. | +| `address` | String | The [issuing address](concept-issuing-and-operational-addresses.html) used by this gateway. | +| `currencies` | Object | Each field in this object is a [Currency Code][] corresponding to a currency issued from this address. Each value is an object with a `featured` boolean indicating whether that currency is featured. Ripple decides which currencies and gateways to feature based on responsible business practices, volume, and other measures. | #### Example #### @@ -2232,25 +2233,25 @@ Optionally, you can include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range | -| end | String - [Timestamp][] | End time of query range | -| interval | String | Aggregation interval (`hour`,`day`,`week`). If omitted, return individual accounts. Not compatible with the `parent` parameter. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1,000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| descending | Boolean | Reverse chronological order | -| parent | String | Filter results to children of the specified parent account. Not compatible with the `interval` parameter. | -| reduce | Boolean | Return a count of results only | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range | +| `end` | String - [Timestamp][] | End time of query range | +| `interval` | String | Aggregation interval (`hour`,`day`,`week`). If omitted, return individual accounts. Not compatible with the `parent` parameter. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1,000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `descending` | Boolean | Reverse chronological order | +| `parent` | String | Filter results to children of the specified parent account. Not compatible with the `interval` parameter. | +| `reduce` | Boolean | Return a count of results only | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of accounts returned. | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| accounts | Array | If the request used the `interval` query parameter, each member of the array is an interval object. Otherwise, this field is an array of [account creation objects](#account-creation-objects). | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of accounts returned. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `accounts` | Array | If the request used the `interval` query parameter, each member of the array is an interval object. Otherwise, this field is an array of [account creation objects](#account-creation-objects). | ##### Interval Objects ##### @@ -2258,8 +2259,8 @@ If the request uses the `interval` query parameter, the response has an array of | Field | Value | Description | |--------|-------|-------------| -| date | String - [Timestamp] | The time at which this interval starts. (The length of the interval is determined by the request.) | -| count | Number | How many accounts were created in this interval. | +| `date` | String - [Timestamp] | The time at which this interval starts. (The length of the interval is determined by the request.) | +| `count` | Number | How many accounts were created in this interval. | #### Example #### @@ -2330,7 +2331,7 @@ This method requires the following URL parameters: | Field | Value | Description | |---------|--------|-------------| -| address | String | Ripple address to query | +| `address` | String | Ripple address to query | #### Response Format #### @@ -2338,8 +2339,8 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| account | Object - [Account Creation](#account-creation-objects) | The requested account | +| `result` | String | The value `success` indicates that this is a successful response. | +| `account` | Object - [Account Creation](#account-creation-objects) | The requested account | #### Example #### @@ -2388,31 +2389,31 @@ This method requires the following URL parameters: | Field | Value | Description | |----------|--------|-------------| -| address | String | Ripple address to query | +| `address` | String | Ripple address to query | Optionally, you can also include the following query parameters: | Field | Value | Description | |--------------|---------|-------------| -| ledger_index | Integer | Index of ledger for historical balances. | -| ledger_hash | String | Ledger hash for historical balances. | -| date | String | UTC date for historical balances. | -| currency | String | Restrict results to specified currency. | -| counterparty | String | Restrict results to specified counterparty/issuer. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be greater than 400, but you can use the value `all` to return all results. (Caution: When using limit=all to retrieve very many results, the request may time out. Large gateways can have several tens of thousands of results.) | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `ledger_index` | Integer | Index of ledger for historical balances. | +| `ledger_hash` | String | Ledger hash for historical balances. | +| `date` | String | UTC date for historical balances. | +| `currency` | String | Restrict results to specified currency. | +| `counterparty` | String | Restrict results to specified counterparty/issuer. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be greater than 400, but you can use the value `all` to return all results. (Caution: When using limit=all to retrieve very many results, the request may time out. For large issuers, there can be several tens of thousands of results.) | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### A successful response uses the HTTP code **200 OK** and has a JSON body with the following: | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| ledger_index | Integer | ledger index for balances query. | -| close_time | String | close time of the ledger. | -| limit | String | number of results returned, if limit was exceeded. | -| marker | String | (May be omitted) [Pagination](#pagination) marker. | -| balances | Array of [Balance Object][]s | The requested balances. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `ledger_index` | Integer | ledger index for balances query. | +| `close_time` | String | close time of the ledger. | +| `limit` | String | number of results returned, if limit was exceeded. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker. | +| `balances` | Array of [Balance Object][]s | The requested balances. | #### Example #### @@ -2474,17 +2475,17 @@ This method requires the following URL parameters: | Field | Value | Description | |----------|--------|-------------| -| address | String - [Address][] | Ripple address to query | +| `address` | String - [Address][] | Ripple address to query | Optionally, you can also include the following query parameters: | Field | Value | Description | |---------------|---------|-------------| -| ledger\_index | Integer | Get orders as of this ledger. Not compatible with `ledger_hash` or `date`. | -| ledger\_hash | String | Get orders as of this ledger. Not compatible with `ledger_index` or `date`. | -| date | String - [Timestamp][] | Get orders at this time. Not compatible with `ledger_index` or `ledger_hash`. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be greater than 400. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `ledger_index` | Integer | Get orders as of this ledger. Not compatible with `ledger_hash` or `date`. | +| `ledger_hash` | String | Get orders as of this ledger. Not compatible with `ledger_index` or `date`. | +| `date` | String - [Timestamp][] | Get orders at this time. Not compatible with `ledger_index` or `ledger_hash`. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be greater than 400. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | If none of `ledger_index`, `ledger_hash`, or `date` are specified, the API uses the most current data available. @@ -2493,24 +2494,24 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| ledger\_index | Integer | `ledger_index` of the ledger version used. | -| close\_time | String | Close time of the ledger version used. | -| limit | String | The `limit` from the request. | -| orders | Array of order objects | The requested orders. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `ledger_index` | Integer | `ledger_index` of the ledger version used. | +| `close_time` | String | Close time of the ledger version used. | +| `limit` | String | The `limit` from the request. | +| `orders` | Array of order objects | The requested orders. | Each order object has the following fields: | Field | Value | Description | |------------------------------|--------|-------------| -| specification | Object | Details of this order's current state. | -| specification.direction | String | Either `buy` or `sell`. | -| specification.quantity | [Balance Object][] | The maximum amount of the base currency this order would buy or sell (depending on the direction). This value decreases as the order gets partially filled. | -| specification.totalPrice | [Balance Object][] | The maximum amount of the counter currency that will be spent or gained in order to buy or sell the base currency. This value decreases as the order gets partially filled. | -| properties | Object | Details of how the order was placed. | -| properties.maker | String - [Address][] | The Ripple account that placed the order. | -| properties.sequence | Number | The sequence number of the transaction that placed this order. | -| properties.makerExchangeRate | [String - Number][] | The exchange rate from the point of view of the account that submitted the order. | +| `specification` | Object | Details of this order's current state. | +| `specification.direction` | String | Either `buy` or `sell`. | +| `specification.quantity` | [Balance Object][] | The maximum amount of the base currency this order would buy or sell (depending on the direction). This value decreases as the order gets partially filled. | +| `specification.totalPrice` | [Balance Object][] | The maximum amount of the counter currency the order can spend or gain to buy or sell the base currency. This value decreases as the order gets partially filled. | +| `properties` | Object | Details of how the order was placed. | +| `properties.maker` | String - [Address][] | The Ripple account that placed the order. | +| `properties.sequence` | Number | The sequence number of the transaction that placed this order. | +| `properties.makerExchangeRate` | [String - Number][] | The exchange rate from the point of view of the account that submitted the order. | #### Example #### @@ -2606,17 +2607,17 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |--------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to the earliest date available. | -| end | String - [Timestamp][] | End time of query range. Defaults to the current date. | -| min_sequence | String | Minimum sequence number to query | -| max_sequence | String | Max sequence number to query | -| type | String | Restrict results to a specified [transaction type](reference-transaction-format.html) | -| result | String | Restrict results to specified transaction result | -| binary | Boolean | Return results in binary format | -| descending | Boolean | Reverse chronological order | -| limit | Integer | Maximum results per page. Defaults to 20. Cannot be more than 1,000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to the earliest date available. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the current date. | +| `min_sequence` | String | Minimum sequence number to query | +| `max_sequence` | String | Max sequence number to query | +| `type` | String | Restrict results to a specified [transaction type](reference-transaction-format.html) | +| `result` | String | Restrict results to specified transaction result | +| `binary` | Boolean | Return results in binary format | +| `descending` | Boolean | Reverse chronological order | +| `limit` | Integer | Maximum results per page. Defaults to 20. Cannot be more than 1,000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -2625,10 +2626,10 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | The number of objects contained in the `transactions` field. | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| transactions | Array of [transaction objects](#transaction-objects) | All transactions matching the request. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | The number of objects contained in the `transactions` field. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `transactions` | Array of [transaction objects](#transaction-objects) | All transactions matching the request. | #### Example #### @@ -2737,7 +2738,7 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |--------|---------|-------------| -| binary | Boolean | Return transaction in binary format | +| `binary` | Boolean | Return transaction in binary format | #### Response Format #### @@ -2746,8 +2747,8 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| transaction | [transaction object](#transaction-objects) | requested transaction | +| `result` | String | The value `success` indicates that this is a successful response. | +| `transaction` | [transaction object](#transaction-objects) | requested transaction | #### Example #### @@ -2804,17 +2805,17 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range | -| end | String - [Timestamp][] | End time of query range | -| type | String | Type of payment - `sent` or `received` | -| currency | String - [Currency Code][] | Filter results to specified currency | -| issuer | String - [Address][] | Filter results to specified issuer | -| source\_tag | Integer | Filter results to specified source tag | -| destination\_tag | Integer | Filter results to specified destination tag | -| descending | Boolean | Reverse chronological order | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1,000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range | +| `end` | String - [Timestamp][] | End time of query range | +| `type` | String | Type of payment - `sent` or `received` | +| `currency` | String - [Currency Code][] | Filter results to specified currency | +| `issuer` | String - [Address][] | Filter results to specified issuer | +| `source_tag` | Integer | Filter results to specified source tag | +| `destination_tag` | Integer | Filter results to specified destination tag | +| `descending` | Boolean | Reverse chronological order | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1,000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -2823,10 +2824,10 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | The number of objects contained in the `payments` field. | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| payments | Array of [payment objects][] | All payments matching the request. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | The number of objects contained in the `payments` field. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `payments` | Array of [payment objects][] | All payments matching the request. | #### Example #### @@ -2919,12 +2920,12 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range | -| end | String - [Timestamp][] | End time of query range | -| descending | Boolean | Reverse chronological order | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range | +| `end` | String - [Timestamp][] | End time of query range | +| `descending` | Boolean | Reverse chronological order | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -2932,10 +2933,10 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of exchanges returned. | -| marker | String | (May be omitted) [Pagination](#pagination) marker | -| exchanges | Array of [Exchange Objects][] | The requested exchanges | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of exchanges returned. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker | +| `exchanges` | Array of [Exchange Objects][] | The requested exchanges | #### Example #### @@ -3028,14 +3029,14 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| currency | String | Restrict results to specified currency. | -| counterparty | String | Restrict results to specified counterparty/issuer. | -| start | String - [Timestamp][] | Start time of query range. | -| end | String - [Timestamp][] | End time of query range. | -| descending | Boolean | If true, return results in reverse chronological order. Defaults to false. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response. | -| format | String | Format of returned results: `csv` or`json`. Defaults to `json`. | +| `currency` | String | Restrict results to specified currency. | +| `counterparty` | String | Restrict results to specified counterparty/issuer. | +| `start` | String - [Timestamp][] | Start time of query range. | +| `end` | String - [Timestamp][] | End time of query range. | +| `descending` | Boolean | If true, return results in reverse chronological order. Defaults to false. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response. | +| `format` | String | Format of returned results: `csv` or`json`. Defaults to `json`. | #### Response Format #### @@ -3043,10 +3044,10 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of balance changes returned. | -| marker | String | (May be omitted) [Pagination](#pagination) marker. | -| exchanges | Array of [balance change descriptors][] | The requested balance changes. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of balance changes returned. | +| `marker` | String | (May be omitted) [Pagination](#pagination) marker. | +| `exchanges` | Array of [balance change descriptors][] | The requested balance changes. | #### Example #### @@ -3137,12 +3138,12 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to start of current date. Ignored if `date` specified. | -| end | String - [Timestamp][] | End time of query range. Defaults to current date. Ignored if `date` specified. | -| accounts | Boolean | If true, provide lists with addresses of all `sending_counterparties` and `receiving_counterparties` in results. Otherwise, return only the number of sending and receiving counterparties. | -| payments | Boolean | Include [Payment Summary Objects][] in the `payments` field for each interval, with the payments that occurred during that interval. | -| descending | Boolean | If true, sort results with most recent first. By default, sort results with oldest first. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to start of current date. Ignored if `date` specified. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to current date. Ignored if `date` specified. | +| `accounts` | Boolean | If true, provide lists with addresses of all `sending_counterparties` and `receiving_counterparties` in results. Otherwise, return only the number of sending and receiving counterparties. | +| `payments` | Boolean | Include [Payment Summary Objects][] in the `payments` field for each interval, with the payments that occurred during that interval. | +| `descending` | Boolean | If true, sort results with most recent first. By default, sort results with oldest first. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -3150,9 +3151,9 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of reports in the `reports` field. | -| reports | Array of [Reports Objects][] | Daily summaries of account activity for the given account and date range. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of reports in the `reports` field. | +| `reports` | Array of [Reports Objects][] | Daily summaries of account activity for the given account and date range. | #### Example #### @@ -3242,12 +3243,12 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to the earliest date available. | -| end | String - [Timestamp][] | End time of query range. Defaults to the current date. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| descending | Boolean | If true, sort results with most recent first. By default, sort results with oldest first. | -| marker | String | [Pagination](#pagination) key from previously returned response. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to the earliest date available. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the current date. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `descending` | Boolean | If true, sort results with most recent first. By default, sort results with oldest first. | +| `marker` | String | [Pagination](#pagination) key from previously returned response. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -3255,18 +3256,18 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of transaction stats objects in the `rows` field. | -| rows | Array of Transaction Stats Objects | Daily summaries of account transaction activity for the given account. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of transaction stats objects in the `rows` field. | +| `rows` | Array of Transaction Stats Objects | Daily summaries of account transaction activity for the given account. | Each Transaction Stats Object has the following fields: | Field | Value | Description | |--------|-------|-------------| -| date | String - [Timestamp][] | This object describes activity on this date. | -| transaction\_count | Integer | The total number of transactions sent by the account on this date. | -| result | Object | Map of [transaction result codes](reference-transaction-format.html#transaction-results), indicating how many of each result code occurred in the transactions sent by this account on this date. | -| type | Object | Map of [transaction types](reference-transaction-format.html), indicating how many of each transaction type the account sent on this date. | +| `date` | String - [Timestamp][] | This object describes activity on this date. | +| `transaction_count` | Integer | The total number of transactions sent by the account on this date. | +| `result` | Object | Map of [transaction result codes](reference-transaction-format.html#transaction-results), indicating how many of each result code occurred in the transactions sent by this account on this date. | +| `type` | Object | Map of [transaction types](reference-transaction-format.html), indicating how many of each transaction type the account sent on this date. | #### Example #### @@ -3340,12 +3341,12 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| start | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | -| end | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | -| limit | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | -| marker | String | [Pagination](#pagination) key from previously returned response. | -| descending | Boolean | If true, sort results with most recent first. By default, sort results with oldest first. | -| format | String | Format of returned results: `csv` or `json`. Defaults to `json`. | +| `start` | String - [Timestamp][] | Start time of query range. Defaults to the start of the most recent interval. | +| `end` | String - [Timestamp][] | End time of query range. Defaults to the end of the most recent interval. | +| `limit` | Integer | Maximum results per page. Defaults to 200. Cannot be more than 1000. | +| `marker` | String | [Pagination](#pagination) key from previously returned response. | +| `descending` | Boolean | If true, sort results with most recent first. By default, sort results with oldest first. | +| `format` | String | Format of returned results: `csv` or `json`. Defaults to `json`. | #### Response Format #### @@ -3353,17 +3354,17 @@ A successful response uses the HTTP code **200 OK** and has a JSON body with the | Field | Value | Description | |--------|-------|-------------| -| result | String | The value `success` indicates that this is a successful response. | -| count | Integer | Number of value stats objects in the `rows` field. | -| rows | Array of Value Stats Objects | Daily summaries of account value for the given account. | +| `result` | String | The value `success` indicates that this is a successful response. | +| `count` | Integer | Number of value stats objects in the `rows` field. | +| `rows` | Array of Value Stats Objects | Daily summaries of account value for the given account. | Each Value Stats Object has the following fields: | Field | Value | Description | |--------|-------|-------------| -| date | String - [Timestamp][] | This object describes activity on this date. | -| value | [String - Number][] | The total of all currency held by this account, normalized to XRP. | -| balance_change_count | Number | The number of times the account's balance changed on this date. | +| `date` | String - [Timestamp][] | This object describes activity on this date. | +| `value` | [String - Number][] | The total of all currency held by this account, normalized to XRP. | +| `balance_change_count` | Number | The number of times the account's balance changed on this date. | #### Example #### @@ -3417,8 +3418,8 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| threshold | Integer | Consider the API unhealthy if the database does not respond within this amount of time, in seconds. Defaults to 5 seconds. | -| verbose | Boolean | If true, return a JSON response with data points. By default, return an integer value only. | +| `threshold` | Integer | Consider the API unhealthy if the database does not respond within this amount of time, in seconds. Defaults to 5 seconds. | +| `verbose` | Boolean | If true, return a JSON response with data points. By default, return an integer value only. | #### Response Format #### @@ -3436,9 +3437,9 @@ If the request specifies `verbose=true` in the query parameters, the response bo | Field | Value | Description | |--------|-------|-------------| -| score | 0-2 | Health value, as defined above. | -| response\_time | String - Human-readable time | The actual response time of the database. | -| response\_time\_threshold | String - Human-readable time | The maximum response time to be considered healthy. | +| `score` | 0-2 | Health value, as defined above. | +| `response_time` | String - Human-readable time | The actual response time of the database. | +| `response_time_threshold` | String - Human-readable time | The maximum response time to be considered healthy. | #### Example #### @@ -3478,9 +3479,9 @@ Optionally, you can also include the following query parameters: | Field | Value | Description | |------------|---------|-------------| -| threshold | Integer | Consider the Importer unhealthy if more than this amount of time, in seconds, has elapsed since the latest validated ledger was imported. Defaults to 300 seconds. | +| `threshold` | Integer | Consider the Importer unhealthy if more than this amount of time, in seconds, has elapsed since the latest validated ledger was imported. Defaults to 300 seconds. | | threshold2 | Integer | Consider the Importer unhealthy if more than this amount of time, in seconds, has elapsed since the latest ledger of any kind was imported. Defaults to 60 seconds. | -| verbose | Boolean | If true, return a JSON response with data points. By default, return an integer value only. | +| `verbose` | Boolean | If true, return a JSON response with data points. By default, return an integer value only. | #### Response Format #### @@ -3499,12 +3500,12 @@ If the request specifies `verbose=true` in the query parameters, the response bo | Field | Value | Description | |--------|-------|-------------| -| score | 0-3 | Health value, as defined above. | -| response\_time | String | The actual response time of the database. | -| ledger\_gap | String - Human-readable time | Difference between the close time of the last saved ledger and the current time. | -| ledger\_gap\_threshold | String - Human-readable time | Maximum ledger gap to be considered healthy. | -| valildation\_gap | String - Human-readable time | Difference between the close time of the last imported validated ledger and the current time. | -| validation\_gap\_threshold | String - Human-readable time | Maximum validation gap to be considered healthy. | +| `score` | 0-3 | Health value, as defined above. | +| `response_time` | String | The actual response time of the database. | +| `ledger_gap` | String - Human-readable time | Difference between the close time of the last saved ledger and the current time. | +| `ledger_gap_threshold` | String - Human-readable time | Maximum ledger gap to be considered healthy. | +| `valildation_gap` | String - Human-readable time | Difference between the close time of the last imported validated ledger and the current time. | +| `validation_gap_threshold` | String - Human-readable time | Maximum validation gap to be considered healthy. | #### Example #### @@ -3556,7 +3557,7 @@ The precision for amounts of **non-XRP currency** in Ripple is as follows: * Minimum value: `-9999999999999999e80` * 15 decimal digits of precision -**XRP** has a different internal representation, and consequently its precision is different: +**XRP** has a different internal representation, and its precision is different: * Minimum value: `0` * Maximum value: `100000000000` (`1e11`) @@ -3586,7 +3587,7 @@ All dates and times are written in ISO 8601 Timestamp Format, using UTC. This fo * Four-digit year * Two-digit month * Two-digit day -* The letter `T` indicating the beginning of the time portion +* The letter `T` separating the date part and the time part * Two-digit hour using a 24-hour clock * Two digit minute * The letter `Z` indicating zero offset from UTC. @@ -3614,7 +3615,7 @@ Many queries may return more data than is reasonable to return in a single HTTP The `limit` query parameter to many requests restricts the response to a specific number of results in the response. The types of results and default values vary based on the method. For most methods, the `limit` is **200** by default, and can be set as high as **1000**. If you specify a `limit` larger than the maximum, the API uses the maximum value instead. -When a query has additional objects that are not contained in the current response, the JSON response contains a top-level field `marker` which indicates that you can retrieve additional results by including the contents of the `marker` field as the `marker` query parameter of a subsequent request. For the follow-up request, you should use the same parameters as the initial request. When the response omits the `marker` parameter, that indicates that you have reached the end of the queryable data. +When a query has additional objects that are not contained in the current response, the JSON response contains a top-level field `marker` which indicates that you can retrieve additional results. To do so, make more requests with the previous value of the `marker` field as the `marker` query parameter. For each additional request, use the same parameters as the first request (except `marker`). When the response omits the `marker` parameter, that indicates that you have reached the end of the queryable data. When a `marker` is or would be present, the response contains a [`Link` header](https://tools.ietf.org/html/rfc5988#section-5) with `rel="next"`. This is a full URL to the next page of results. You can use this to paginate over results when the response is in `csv` format instead of `json`. _(New in [v2.0.4][])_ @@ -3626,21 +3627,21 @@ Transactions have two formats - a compact "binary" format where the defining fie | Field | Value | Description | |-------|-------|-------------| -| hash | String - [Hash][] | An identifying hash value unique to this transaction, as a hex string. | -| date | String - [Timestamp][] | The time when this transaction was included in a validated ledger. | -| ledger_index | Number - [Ledger Index][] | The sequence number of the ledger that included this ledger. | -| tx | Object | The fields of this transaction object, as defined by the [Transaction Format](reference-transaction-format.html) | -| meta | Object | Metadata about the results of this transaction. | +| `hash` | String - [Hash][] | An identifying hash value unique to this transaction, as a hex string. | +| `date` | String - [Timestamp][] | The time when this transaction was included in a validated ledger. | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger that included this ledger. | +| `tx` | Object | The fields of this transaction object, as defined by the [Transaction Format](reference-transaction-format.html) | +| `meta` | Object | Metadata about the results of this transaction. | ### Binary Format ### | Field | Value | Description | |-------|-------|-------------| -| hash | String - [Hash][] | An identifying hash value unique to this transaction, as a hex string. | -| date | String - [Timestamp][] | The time when this transaction was included in a validated ledger. | -| ledger_index | Number - [Ledger Index][] | The sequence number of the ledger that included this ledger. | -| tx | String | The binary data that represents this transaction, as a hexadecimal string. | -| meta | String | The binary data that represents this transaction's metadata, as a hex string. | +| `hash` | String - [Hash][] | An identifying hash value unique to this transaction, as a hex string. | +| `date` | String - [Timestamp][] | The time when this transaction was included in a validated ledger. | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger that included this ledger. | +| `tx` | String | The binary data that represents this transaction, as a hexadecimal string. | +| `meta` | String | The binary data that represents this transaction's metadata, as a hex string. | ## Ledger Objects ## @@ -3648,17 +3649,17 @@ A "ledger" is one version of the shared global ledger. Each ledger object has th | Field | Value | Description | |--------------|-------|-------------| -| ledger\_hash | String - [Hash][] | An identifying hash unique to this ledger, as a hex string. | -| ledger\_index | Number - [Ledger Index][] | The sequence number of the ledger. Each new ledger has a ledger index 1 higher than the ledger that came before it. | -| parent\_hash | String - [Hash][] | The identifying hash of the previous ledger. | -| total\_coins | [String - Number][] | The total number of "drops" of XRP still in existence at the time of the ledger. (Each XRP is 1,000,000 drops.) | -| close\_time\_res | Number | The ledger close time is rounded to approximately this many seconds. | -| accounts\_hash | String - [Hash][] | Hash of the account information contained in this ledger, as hex. | -| transactions\_hash | String - [Hash][] | Hash of the transaction information contained in this ledger, as hex. | -| close\_time | Number | The time at which this ledger was closed, in UNIX time. | -| close\_time\_human | String - [Timestamp][] | The time at which this ledger was closed. | +| `ledger_hash` | String - [Hash][] | An identifying hash unique to this ledger, as a hex string. | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger. Each new ledger has a ledger index 1 higher than the ledger that came before it. | +| `parent_hash` | String - [Hash][] | The identifying hash of the previous ledger. | +| `total_coins` | [String - Number][] | The total number of "drops" of XRP still in existence at the time of the ledger. (Each XRP is 1,000,000 drops.) | +| `close_time_res` | Number | The ledger close time is rounded to this many seconds. | +| `accounts_hash` | String - [Hash][] | Hash of the account information contained in this ledger, as hex. | +| `transactions_hash` | String - [Hash][] | Hash of the transaction information contained in this ledger, as hex. | +| `close_time` | Number | The time at which this ledger was closed, in UNIX time. | +| `close_time_human` | String - [Timestamp][] | The time at which this ledger was closed. | -**Note:** Ledger close times are approximate, typically rounded to about 10 seconds. Consequently, two subsequent ledgers could have the same close time recorded, when actual close times were several seconds apart. The sequence number (`ledger_index`) of the ledger makes it unambiguous which ledger closed first. +**Note:** Ledger close times are approximate, typically rounded to about 10 seconds. Two ledgers could have the same `close_time` values, when their actual close times were several seconds apart. The sequence number (`ledger_index`) of the ledger makes it unambiguous which ledger closed first. ### Genesis Ledger ### @@ -3670,14 +3671,14 @@ An account creation object represents the action of creating an account in the R | Field | Value | Description | |-------|-------|-------------| -| address | String - [Address][] | The identifying address of this account, in base-58. | -| inception | String - [Timestamp][] | The UTC timestamp that the account was created. For genesis accounts, this is the timestamp of ledger 32570. | -| ledger\_index | Number - [Ledger Index][] | The sequence number of the ledger when the account was created, or 32570 for genesis accounts. | -| parent | String - [Address][] | (Omitted for genesis accounts) The identifying address of the account that provided the initial funding for this account. | -| tx\_hash | String - [Hash][] | (Omitted for genesis accounts) The identifying hash of the transaction that funded this account. | -| initial\_balance | [String - Number][] | (Omitted for genesis accounts) The amount of XRP that funded this account. | -| genesis\_balance | [String - Number][] | (Genesis accounts only) The amount of XRP this account held as of ledger #32570. | -| genesis\_index | Number - [Sequence Number][] | (Genesis accounts only) The transaction sequence number of the account as of ledger #32570. | +| `address` | String - [Address][] | The identifying address of this account, in base-58. | +| `inception` | String - [Timestamp][] | The UTC timestamp when the address was funded. For genesis accounts, this is the timestamp of ledger 32570. | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger when the account was created, or 32570 for genesis accounts. | +| `parent` | String - [Address][] | (Omitted for genesis accounts) The address that provided the XRP to fund this address. | +| `tx_hash` | String - [Hash][] | (Omitted for genesis accounts) The identifying hash of the transaction that funded this account. | +| `initial_balance` | [String - Number][] | (Omitted for genesis accounts) The amount of XRP that funded this account. | +| `genesis_balance` | [String - Number][] | (Genesis accounts only) The amount of XRP this account held as of ledger #32570. | +| `genesis_index` | Number - [Sequence Number][] | (Genesis accounts only) The transaction sequence number of the account as of ledger #32570. | ## Exchange Objects ## @@ -3685,29 +3686,29 @@ An account creation object represents the action of creating an account in the R An exchange object represents an actual exchange of currency, which can occur in the Ripple Consensus Ledger as the result of executing either an OfferCreate transaction or a Payment transaction. In order for currency to actually change hands, there must be a previously-unfilled Offer previously placed in the ledger with an OfferCreate transaction. -A single transaction can cause several exchanges to occur. In this case, the sender of the transaction is the taker for all the exchanges, but each exchange will have a different provider, currency pair, or both. +A single transaction can cause several exchanges to occur. In this case, the sender of the transaction is the taker for all the exchanges, but each exchange has a different provider, currency pair, or both. | Field | Value | Description | |-------|-------|-------------| -| base\_amount | Number | The amount of the base currency that was traded | -| counter\_amount | Number | The amount of the counter currency that was traded | -| rate | Number | The amount of the counter currency acquired per 1 unit of the base currency | -| autobridged\_currency | String - [Currency Code][] | (May be omitted) If the offer was autobridged (XRP order books were used to bridge two non-XRP currencies), this is the other currency from the offer that executed this exchange. | -| autobridged\_issuer | String - [Address][] | (May be omitted) If the offer was autobridged (XRP order books were used to bridge two non-XRP currencies), this is the other currency from the offer that executed this exchange. | -| base\_currency | String - [Currency Code][] | The base currency | -| base\_issuer | String - [Address][] | (Omitted for XRP) The account that issued the base currency | -| buyer | String - [Address][] | The account that acquired the base currency | -| client | String | (May be omitted) If the transaction contains a memo indicating what client application sent it, this is the contents of the memo. | -| counter\_currency | String - [Currency Code][] | The counter currency | -| counter\_issuer | String - [Address][] | (Omitted for XRP) The account that issued the counter currency | -| executed\_time | String - [Timestamp][] | The time the exchange occurred | -| ledger\_index | Number - [Ledger Index][] | The sequence number of the ledger that included this transaction | -| offer\_sequence | Number - [Sequence Number][] | The sequence number of the `provider`'s existing offer in the ledger. | -| provider | String - [Address][] | The account that had an existing Offer in the ledger | -| seller | String - [Address][] | The account that acquired the counter currency | -| taker | String - [Address][] | The account that sent the transaction which executed this exchange | -| tx\_hash | String - [Hash][] | The identifying hash of the transaction that executed this exchange. (**Note:** This exchange may be one of several executed in a single transaction.) | -| tx\_type | String | The type of transaction that executed this exchange, either `Payment` or `OfferCreate`. | +| `base_amount` | Number | The amount of the base currency that was traded | +| `counter_amount` | Number | The amount of the counter currency that was traded | +| `rate` | Number | The amount of the counter currency acquired per 1 unit of the base currency | +| `autobridged_currency` | String - [Currency Code][] | (May be omitted) If the offer was autobridged (XRP order books were used to bridge two non-XRP currencies), this is the other currency from the offer that executed this exchange. | +| `autobridged_issuer` | String - [Address][] | (May be omitted) If the offer was autobridged (XRP order books were used to bridge two non-XRP currencies), this is the other currency from the offer that executed this exchange. | +| `base_currency` | String - [Currency Code][] | The base currency | +| `base_issuer` | String - [Address][] | (Omitted for XRP) The account that issued the base currency | +| `buyer` | String - [Address][] | The account that acquired the base currency | +| `client` | String | (May be omitted) If the transaction contains a memo indicating what client application sent it, this is the contents of the memo. | +| `counter_currency` | String - [Currency Code][] | The counter currency | +| `counter_issuer` | String - [Address][] | (Omitted for XRP) The account that issued the counter currency | +| `executed_time` | String - [Timestamp][] | The time the exchange occurred | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger that included this transaction | +| `offer_sequence` | Number - [Sequence Number][] | The sequence number of the `provider`'s existing offer in the ledger. | +| `provider` | String - [Address][] | The account that had an existing Offer in the ledger | +| `seller` | String - [Address][] | The account that acquired the counter currency | +| `taker` | String - [Address][] | The account that sent the transaction which executed this exchange | +| `tx_hash` | String - [Hash][] | The identifying hash of the transaction that executed this exchange. (**Note:** This exchange may be one of several executed in a single transaction.) | +| `tx_type` | String | The type of transaction that executed this exchange, either `Payment` or `OfferCreate`. | ## Reports Objects ## @@ -3717,18 +3718,18 @@ Reports objects show the activity of a given account over a specific interval of | Field | Value | Description | |-------|-------|-------------| -| account | String - [Address][] | The address of the account to which this report pertains. | -| date | String - [Timestamp][] | The start of the interval to which this report pertains. | -| high\_value\_received | [String - Number][] | Largest amount received in a single transaction, normalized to XRP (as closely as possible). This includes payments and exchanges. | -| high\_value\_sent | [String - Number][] | The largest amount sent in a single transaction, normalized to XRP (as closely as possible). | -| payments | Array of [Payment Summary Objects][] | (May be omitted) Array with information on each payment sent or received by the account during this interval. | -| payments\_received | Number | The number of payments sent to this account. (This only includes payments for which this account was the destination, not payments that only rippled through the account or consumed the account's offers.) | -| payments\_sent | Number | The number of payments sent by this account. | -| receiving\_counterparties | Array or Number | If account lists requested, an array of addresses that received payments from this account. Otherwise, the number of different accounts that received payments from this account. | -| sending\_counterparties | Array or Number | If account lists requested, an array of addresses that sent payments to this account. Otherwise, the number of different accounts that sent payments to this account. | -| total\_value | [String - Number][] | Sum of total value received and sent in payments, normalized to XRP (as closely as possible). | -| total\_value\_received | [String - Number][] | Sum value of all payments to this account, normalized to XRP (as closely as possible). | -| total\_value\_sent | [String - Number][] | Sum value of all payments from this account, normalized to XRP (as closely as possible). +| `account` | String - [Address][] | The address of the account to which this report pertains. | +| `date` | String - [Timestamp][] | The start of the interval to which this report pertains. | +| `high_value_received` | [String - Number][] | Largest amount received in a single transaction, normalized to XRP (as closely as possible). This includes payments and exchanges. | +| `high_value_sent` | [String - Number][] | The largest amount sent in a single transaction, normalized to XRP (as closely as possible). | +| `payments` | Array of [Payment Summary Objects][] | (May be omitted) Array with information on each payment sent or received by the account during this interval. | +| `payments_received` | Number | The number of payments sent to this account. (This only includes payments for which this account was the destination, not payments that only rippled through the account or consumed the account's offers.) | +| `payments_sent` | Number | The number of payments sent by this account. | +| `receiving_counterparties` | Array or Number | If account lists requested, an array of addresses that received payments from this account. Otherwise, the number of different accounts that received payments from this account. | +| `sending_counterparties` | Array or Number | If account lists requested, an array of addresses that sent payments to this account. Otherwise, the number of different accounts that sent payments to this account. | +| `total_value` | [String - Number][] | Sum of total value received and sent in payments, normalized to XRP (as closely as possible). | +| `total_value_received` | [String - Number][] | Sum value of all payments to this account, normalized to XRP (as closely as possible). | +| `total_value_sent` | [String - Number][] | Sum value of all payments from this account, normalized to XRP (as closely as possible). ## Payment Summary Objects ## [Payment Summary Objects]: #payment-summary-objects @@ -3737,11 +3738,11 @@ A Payment Summary Object contains a reduced amount of information about a single | Field | Value | Description | |-------|-------|-------------| -| tx\_hash | String - [Hash][] | The identifying hash of the transaction that caused the payment. | -| delivered\_amount | [String - Number][] | The amount of the destination `currency` actually received by the destination account. | -| currency | String - [Currency Code][] | The currency delivered to the recipient of the transaction. | -| issuer | String - [Address][] | The gateway issuing the currency, or an empty string for XRP. | -| type | String | Either `sent` or `received`, indicating whether the perspective account is sender or receiver of this transaction. | +| `tx_hash` | String - [Hash][] | The identifying hash of the transaction that caused the payment. | +| `delivered_amount` | [String - Number][] | The amount of the destination `currency` actually received by the destination account. | +| `currency` | String - [Currency Code][] | The currency delivered to the recipient of the transaction. | +| `issuer` | String - [Address][] | The gateway issuing the currency, or an empty string for XRP. | +| `type` | String | Either `sent` or `received`, indicating whether the perspective account is sender or receiver of this transaction. | ## Payment Objects ## @@ -3753,20 +3754,20 @@ Payment objects have the following fields: | Field | Value | Description | |-------|-------|-------------| -| amount | [String - Number][] | The amount of the destination `currency` that the transaction was instructed to send. In the case of Partial Payments, this is a "maximum" amount. | -| delivered\_amount | [String - Number][] | The amount of the destination `currency` actually received by the destination account. | -| destination\_balance\_changes | Array | Array of [balance change objects][], indicating all changes made to the `destination` account's balances. | -| source\_balance\_changes | Array | Array of [balance change objects][], indicating all changes to the `source` account's balances (except the XRP transaction cost). | -| transaction\_cost | [String - Number][] | The amount of XRP spent by the `source` account on the transaction cost. (Prior to [v2.0.4][], this parameter was called `fee`.) | -| destination\_tag | Integer | (May be omitted) A [destination tag](tutorial-gateway-guide.html#source-and-destination-tags) specified in this payment. | -| source\_tag | Integer | (May be omitted) A [source tag](tutorial-gateway-guide.html#source-and-destination-tags) specified in this payment. | -| currency | String - [Currency Code][] | The currency that the `destination` account received. | -| destination | String - [Address][] | The account that received the payment. | -| executed\_time | String - [Timestamp][] | The time the ledger that included this payment closed. | -| ledger\_index | Number - [Ledger Index][] | The sequence number of the ledger that included this payment. | -| source | String - [Address][] | The account that sent the payment. | -| source\_currency | String - [Currency Code][] | The currency that the `source` account spent. | -| tx\_hash | String - [Hash][] | The identifying hash of the transaction that caused the payment. | +| `amount` | [String - Number][] | The amount of the destination `currency` that the transaction was instructed to send. In the case of Partial Payments, this is a "maximum" amount. | +| `delivered_amount` | [String - Number][] | The amount of the destination `currency` actually received by the destination account. | +| `destination_balance_changes` | Array | Array of [balance change objects][], indicating all changes made to the `destination` account's balances. | +| `source_balance_changes` | Array | Array of [balance change objects][], indicating all changes to the `source` account's balances (except the XRP transaction cost). | +| `transaction_cost` | [String - Number][] | The amount of XRP spent by the `source` account on the transaction cost. (Prior to [v2.0.4][], this parameter was called `fee`.) | +| `destination_tag` | Integer | (May be omitted) A [destination tag](tutorial-gateway-guide.html#source-and-destination-tags) specified in this payment. | +| `source_tag` | Integer | (May be omitted) A [source tag](tutorial-gateway-guide.html#source-and-destination-tags) specified in this payment. | +| `currency` | String - [Currency Code][] | The currency that the `destination` account received. | +| `destination` | String - [Address][] | The account that received the payment. | +| `executed_time` | String - [Timestamp][] | The time the ledger that included this payment closed. | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger that included this payment. | +| `source` | String - [Address][] | The account that sent the payment. | +| `source_currency` | String - [Currency Code][] | The currency that the `source` account spent. | +| `tx_hash` | String - [Hash][] | The identifying hash of the transaction that caused the payment. | ## Balance Objects and Balance Change Objects ## @@ -3781,9 +3782,9 @@ Balance objects and Balance Change objects have the same format, with the follow | Field | Value | Description | |-------|-------|-------------| -| counterparty | String - [Address][] | The counterparty, or issuer, of the `currency`. In the case of XRP, this is an empty string. | -| currency | String - [Currency Code][] | The currency for which this balance changed. | -| value | [String - Number][] | The amount of the `currency` that the associated account gained or lost. In balance change objects, this value can be positive (for amounts gained) or negative (for amounts lost). In balance objects, this value can be positive (for amounts the counterparty owes the account) or negative (for amounts owed to the counterparty). | +| `counterparty` | String - [Address][] | The counterparty, or issuer, of the `currency`. In the case of XRP, this is an empty string. | +| `currency` | String - [Currency Code][] | The currency for which this balance changed. | +| `value` | [String - Number][] | The amount of the `currency` that the associated account gained or lost. In balance change objects, this value can be positive (for amounts gained) or negative (for amounts lost). In balance objects, this value can be positive (for amounts the counterparty owes the account) or negative (for amounts owed to the counterparty). | ## Balance Change Descriptors ## @@ -3795,16 +3796,16 @@ Balance Change Descriptors have the following fields: | Field | Value | Description | |-------|-------|-------------| -| amount\_change | [String - Number][] | The difference in the amount of currency held before and after this change. _(Prior to [v2.0.6][], this field was called `change`.)_ | -| final\_balance | [String - Number][] | The balance after the change occurred. | -| node\_index | Number (or `null`)| This balance change is represented by the entry at this index of the ModifiedNodes array within the metadata section of the transaction that executed this balance change. **Note:** When the transaction cost is combined with other changes to XRP balance, the transaction cost has a `node_index` of **null** instead. | -| tx\_index | Number | The transaction that executed this balance change is at this index in the array of transactions for the ledger that included it. | -| change\_type | String | One of several [](#change-types) describing what caused this balance change to occur. | -| currency | String - [Currency Code][] | The change affected this currency. | -| executed\_time | String - [Timestamp][] | The time the change occurred. (This is based on the close time of the ledger that included the transaction that executed the change. | -| counterparty | String - [Address][] | (Omitted for XRP) The `currency` is held in a trust line to or from this account. _(Prior to [v2.0.6][], this field was called `issuer`.)_ | -| ledger\_index | Number - [Ledger Index][] | The sequence number of the ledger that included the transaction that executed this balance change. | -| tx\_hash | String - [Hash][] | The identifying hash of the transaction that executed this balance change. | +| `amount_change` | [String - Number][] | The difference in the amount of currency held before and after this change. _(Prior to [v2.0.6][], this field was called `change`.)_ | +| `final_balance` | [String - Number][] | The balance after the change occurred. | +| `node_index` | Number (or `null`)| This balance change is represented by the entry at this index of the ModifiedNodes array within the metadata section of the transaction that executed this balance change. **Note:** When the transaction cost is combined with other changes to XRP balance, the transaction cost has a `node_index` of **null** instead. | +| `tx_index` | Number | The transaction that executed this balance change is at this index in the array of transactions for the ledger that included it. | +| `change_type` | String | One of several [](#change-types) describing what caused this balance change to occur. | +| `currency` | String - [Currency Code][] | The change affected this currency. | +| `executed_time` | String - [Timestamp][] | The time the change occurred. (This is based on the close time of the ledger that included the transaction that executed the change. | +| `counterparty` | String - [Address][] | (Omitted for XRP) The `currency` is held in a trust line to or from this account. _(Prior to [v2.0.6][], this field was called `issuer`.)_ | +| `ledger_index` | Number - [Ledger Index][] | The sequence number of the ledger that included the transaction that executed this balance change. | +| `tx_hash` | String - [Hash][] | The identifying hash of the transaction that executed this balance change. | ### Change Types ### @@ -3820,17 +3821,17 @@ The following values are valid for the `change_type` field of a Balance Change D ## Volume Objects ## [Volume Objects]: #volume-objects -Volume objects represent the total volumes of money moved, in either payments or exchanges, during a given time period. +Volume objects represent the total volumes of money moved, in either payments or exchanges, during a given period. | Field | Value | Description | |--------|-------|-------------| -| components | Array of Objects | The data that was used to assemble this total. For payment volume, each object represents payments in a particular currency and issuer. For exchange volume, each object represents a market between two currencies. | -| count | Number | The total number of exchanges in this period. | -| endTime | String - [Timestamp][] | The end time of this interval. | -| exchange | Object | Indicates the display currency used, as with fields `currency` and (except for XRP) `issuer`. All amounts are normalized by first converting to XRP, and then to the display currency specified in the request. | -| exchangeRate | Number | The exchange rate to the displayed currency from XRP. -| startTime | String - [Timestamp][] | The start of this time period. | -| total | Number | Total volume of all recorded exchanges in the time period. | +| `components` | Array of Objects | The data that was used to assemble this total. For payment volume, each object represents payments in a particular currency and issuer. For exchange volume, each object represents a market between two currencies. | +| `count` | Number | The total number of exchanges in this period. | +| `endTime` | String - [Timestamp][] | The end time of this interval. | +| `exchange` | Object | Indicates the display currency used, as with fields `currency` and (except for XRP) `issuer`. All amounts are normalized by first converting to XRP, and then to the display currency specified in the request. | +| `exchangeRate` | Number | The exchange rate to the displayed currency from XRP. +| `startTime` | String - [Timestamp][] | The start of this period. | +| `total` | Number | Total volume of all recorded exchanges in the period. | @@ -3838,7 +3839,7 @@ Volume objects represent the total volumes of money moved, in either payments or # Running the Historical Database # -You can also serve the Data API v2 from your own instance of the Historical Database software, and populate it with transactions from your own `rippled` instance. This is useful if you do not want to depend on Ripple to operate the historical database indefinitely, or you want access to historical transactions from within your own intranet. +You can also serve the Data API v2 from your own instance of the Historical Database software, and populate it with transactions from your own `rippled` instance. This is useful if you do not want to depend on Ripple to run the historical database indefinitely, or you want access to historical transactions from within your own intranet. ## Installation ## @@ -3855,19 +3856,23 @@ Version 2 of the Historical Database requires HBase instead of [PostgreSQL](http ### Installation Process ### -Starting in +To install the Data API v2: 1. Install HBase. For production use, configure it in distributed mode. 2. Clone the rippled Historical Database Git Repository: - `git clone https://github.com/ripple/rippled-historical-database.git` + + git clone https://github.com/ripple/rippled-historical-database.git + (You can also download and extract a zipped release instead.) 3. Use npm to install additional modules: - `cd rippled-historical-database` - `npm install` - The install script will also create the required config files: `config/api.config.json` and `config/import.config.json` - 4. Modify the API and import config files as needed. Remove the `postgres` section from `api.config.json`. -Reports, stats, and aggregated exchange data needs additional processing before the API can make it available. This processing uses Apache Storm as well as some custom scripts. See [Storm Setup](https://github.com/ripple/rippled-historical-database/blob/develop/storm/README.md) for more information. + cd rippled-historical-database + npm install + + The install script creates the required config files: `config/api.config.json` and `config/import.config.json` + 4. Change the config files as needed. Remove the `postgres` section from `api.config.json`. + +Reports, stats, and aggregated exchange data needs more processing before the API can make it available. This processing uses Apache Storm as well as some custom scripts. See [Storm Setup](https://github.com/ripple/rippled-historical-database/blob/develop/storm/README.md) for more information. At this point, the rippled Historical Database is installed. See [Services](#services) for the different components that you can run. @@ -3892,13 +3897,13 @@ The `rippled` Historical Database consists of several processes that can be run Command: `node import/postgres/backfill` * API Server - Provides [REST API access](#api-method-reference) to the data. Command: `npm start` (restarts the server automatically when source files change), - or `node api/server.js` (simple start) + or `node api/server.js` (start once) ## Importing Data ## In order to retrieve data from the `rippled` Historical Database, you must first populate it with data. Broadly speaking, there are two ways this can happen: -* Connect to a `rippled` server that has the historical ledgers, and retrieve them. (Later, you can reconfigure the `rippled` server not to maintain history older than what you have in your Historical Database.) +* Connect to a `rippled` server that has the historical ledgers, and retrieve them. (Later, you can reconfigure the `rippled` server not to keep history older than what you have in your Historical Database.) * You can choose to retrieve only new ledgers as they are validated, or you can retrieve old ledgers, too. * Or, you can load a dump from a database that already has the historical ledger data. (At this time, there are no publicly-available database dumps of historical data.) Use the standard process for your database. @@ -3906,7 +3911,7 @@ In all cases, keep in mind that the integrity of the data is only as good as the ### Live Ledger Importer ### -The Live Ledger Importer is a service that connects to a `rippled` server using the WebSocket API, and listens for ledger close events. Each time a new ledger is closed, the Importer requests the latest validated ledger. Although this process has some fault tolerance built in to prevent ledgers from being skipped, it is still possible that the Importer may miss ledgers. +The Live Ledger Importer is a service that connects to a `rippled` server using the WebSocket API, and listens for ledger close events. Each time a new ledger is closed, the Importer requests the latest validated ledger. Although this process has some fault tolerance built in to prevent ledgers from being skipped, the Importer may still miss ledgers. The Live Ledger Importer includes a secondary process that runs periodically to validate the data already imported and check for gaps in the ledger history. @@ -3927,7 +3932,7 @@ The `--startIndex` parameter defines the most-recent ledger to retrieve. The Bac The `--stopIndex` parameter defines the oldest ledger to retrieve. The Backfiller stops after it retrieves this ledger. If omitted, the Backfiller continues as far back as possible. Because backfilling goes from most recent to least recent, the stop index should be a smaller than the start index. -**Warning:** The Backfiller is best for filling in relatively short histories of transactions. Importing a complete history of all Ripple transactions using the Backfiller could take weeks. If you want a full history, we recommend acquiring a database dump with early transctions, and importing it directly. For the public server, Ripple (the company) used the internal SQLite database from an offline `rippled` to populate its historical databases with the early transactions, then used the Backfiller to catch up to date after the import finished. +**Caution:** The Backfiller is best for filling in relatively short histories of transactions. Importing a complete history of all Ripple transactions using the Backfiller could take weeks. If you want a full history, we recommend acquiring a database dump with early transctions, and importing it directly. For the public server, Ripple (the company) used the internal SQLite database from an offline `rippled` to populate its historical databases with the early transactions, then used the Backfiller to catch up to date after the import finished. Example usage: diff --git a/content/reference-ledger-format.md b/content/reference-ledger-format.md index 3ab0e2cdd2..707ca0473a 100644 --- a/content/reference-ledger-format.md +++ b/content/reference-ledger-format.md @@ -1,17 +1,17 @@ # The Ledger # -The point of the Ripple software is to maintain a shared, global ledger that is open to all, so that individual participants can trust the integrity of the ledger without having to trust any single institution to manage it. The `rippled` server software accomplishes this by maintaining a ledger database that can only be updated according to very specific rules. Each instance of `rippled` maintains a full copy of the ledger, and the peer-to-peer network of `rippled` servers distributes candidate transactions among themselves. The consensus process determines which transactions get applied to each new version of the ledger. See also: [The Consensus Process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/). +The Ripple Consensus Ledger is a shared, global ledger that is open to all. Individual participants can trust the integrity of the ledger without having to trust any single institution to manage it. The `rippled` server software accomplishes this by managing a ledger database that can only be updated according to very specific rules. Each instance of `rippled` keeps a full copy of the ledger, and the peer-to-peer network of `rippled` servers distributes candidate transactions among themselves. The consensus process determines which transactions get applied to each new version of the ledger. See also: [The Consensus Process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/). ![Diagram: Each ledger is the result of applying transactions to the previous ledger version.](img/ledger-process.png) -The shared global ledger is actually a series of individual ledgers, or ledger versions, which `rippled` keeps in its internal database. Every ledger version has a [ledger index](#ledger-index) which identifies the order in which ledgers occur. Each closed ledger version also has an identifying hash value, which uniquely identifies the contents of that ledger. At any given time, a `rippled` instance has an in-progress "current" open ledger, plus some number of closed ledgers that have not yet been approved by consensus, and any number of historical ledgers that have been validated by consensus. Only the validated ledgers are certain to be accurate and immutable. +The shared global ledger is actually a series of individual ledgers, or ledger versions, which `rippled` keeps in its internal database. Every ledger version has a [ledger index](#ledger-index) which identifies the order in which ledgers occur. Each closed ledger version also has an identifying hash value, which uniquely identifies the contents of that ledger. At any given time, a `rippled` instance has an in-progress "current" open ledger, plus some number of closed ledgers that have not yet been approved by consensus, and any number of historical ledgers that have been validated by consensus. Only the validated ledgers are certain to be correct and immutable. -A single ledger version consists of several components: +A single ledger version consists of several parts: ![Diagram: A ledger has transactions, a state node, and a header with the close time and validation info](img/ledger-components.png) * A **header** - The [ledger index](#ledger-index), hashes of its other contents, and other metadata. -* A **transaction tree** - The [transactions](reference-transaction-format.html) that were applied to the previous ledger to make this one. Transactions are the _only_ way to modify the ledger. +* A **transaction tree** - The [transactions](reference-transaction-format.html) that were applied to the previous ledger to make this one. Transactions are the _only_ way to change the ledger. * A **state tree** - All the [ledger nodes](#ledger-node-types) that contain the settings, balances, and objects in the ledger as of this version. @@ -36,7 +36,7 @@ Every ledger version has a unique header that describes the contents. You can lo | [ledger\_index](#ledger-index) | String | UInt32 | The sequence number of the ledger. Some API methods display this as a quoted integer; some display it as a native JSON number. | | ledger\_hash | String | Hash256 | The SHA-512Half of the ledger header, excluding the `ledger_hash` itself. This serves as a unique identifier for this ledger and all its contents. | | account\_hash | String | Hash256 | The SHA-512Half of this ledger's state tree information. | -| close\_time | Number | UInt32 | The approximate time this ledger closed, as the number of seconds since the Ripple Epoch of 2000-01-01 00:00:00. This value is rounded based on the `close_time_resolution`, so it is possible for subsequent ledgers to have the same value. | +| close\_time | Number | UInt32 | The approximate time this ledger closed, as the number of seconds since the Ripple Epoch of 2000-01-01 00:00:00. This value is rounded based on the `close_time_resolution`, so later ledgers can have the same value. | | closed | Boolean | bool | If true, this transaction is no longer accepting new transactions. (However, unless this ledger is validated, it might be replaced by a different ledger with a different set of transactions.) | | parent\_hash | String | Hash256 | The `ledger_hash` value of the previous ledger that was used to build this one. If there are different versions of the previous ledger index, this indicates from which one the ledger was derived. | | total\_coins | String | UInt64 | The total number of drops of XRP owned by accounts in the ledger. This subtracts XRP that has been destroyed by transaction fees. The actual amount of XRP in circulation is lower because some accounts are "black holes" whose keys are not known by anyone. | @@ -53,9 +53,9 @@ Every ledger version has a unique header that describes the contents. You can lo ### Close Flags ### -Currently, the ledger has only one flag defined for closeFlags: **sLCF_NoConsensusTime** (value `1`). If this flag is enabled, it means that validators were in conflict regarding the correct close time for the ledger, but built otherwise the same ledger, so they declared consensus while "agreeing to disagree" on the close time. In this case, the consensus ledger contains a `close_time` value that is 1 second after that of the previous ledger. (In this case, there is no official close time, but the actual real-world close time is probably 3-6 seconds later than the specified `close_time`.) +The ledger has only one flag defined for closeFlags: **sLCF_NoConsensusTime** (value `1`). If this flag is enabled, it means that validators had different close times for the ledger, but built otherwise the same ledger, so they declared consensus while "agreeing to disagree" on the close time. In this case, the consensus ledger contains a `close_time` value that is 1 second after that of the previous ledger. (In this case, there is no official close time, but the actual real-world close time is probably 3-6 seconds later than the specified `close_time`.) -The `closeFlags` field is not included in any JSON representations of a ledger, but it is a part of the binary representation of a ledger, and is one of the fields that determine the ledger's hash. +The `closeFlags` field is not included in any JSON representations of a ledger, but is included in the binary representation of a ledger, and is one of the fields that determine the ledger's hash. @@ -125,12 +125,12 @@ AccountRoot nodes can have the following flag values: |-----------|-----------|---------------|-------------|-------------------------------| | lsfPasswordSpent | 0x00010000 | 65536 | Indicates that the account has used its free SetRegularKey transaction. | (None) | | lsfRequireDestTag | 0x00020000 | 131072 | Requires incoming payments to specify a Destination Tag. | asfRequireDest | -| lsfRequireAuth | 0x00040000 | 262144 | This account must individually approve other users in order for those users to hold this account's issuances. | asfRequireAuth | +| lsfRequireAuth | 0x00040000 | 262144 | This account must individually approve other users for those users to hold this account's issuances. | asfRequireAuth | | lsfDisallowXRP | 0x00080000 | 524288 | Client applications should not send XRP to this account. Not enforced by `rippled`. | asfDisallowXRP | | lsfDisableMaster | 0x00100000 | 1048576 | Disallows use of the master key to sign transactions for this account. | asfDisableMaster | -| lsfNoFreeze | 0x00200000 | 209715 | This account cannot freeze trust lines connected to it. Once enabled, cannot be disabled. | asfNoFreeze | -| lsfGlobalFreeze | 0x00400000 | 4194304 | All assets issued by this account are frozen. | asfGlobalFreeze | -| lsfDefaultRipple | 0x00800000 | 8388608 | Enable [rippling](concept-noripple.html) on this account's trust lines by default. Required for gateways; discouraged for other accounts. | asfDefaultRipple | +| lsfNoFreeze | 0x00200000 | 209715 | This address cannot freeze trust lines connected to it. Once enabled, cannot be disabled. | asfNoFreeze | +| lsfGlobalFreeze | 0x00400000 | 4194304 | All assets issued by this address are frozen. | asfGlobalFreeze | +| lsfDefaultRipple | 0x00800000 | 8388608 | Enable [rippling](concept-noripple.html) on this addresses's trust lines by default. Required for issuing addresses; discouraged for others. | asfDefaultRipple | ### AccountRoot Index Format ### @@ -148,7 +148,7 @@ The `DirectoryNode` node type provides a list of links to other nodes in the led There are two kinds of Directories: * **Owner directories** list other nodes owned by an account, such as RippleState or Offer nodes. -* **Offer directories** list the offers currently available in the distributed exchange. A single Offer Directory contains all the offers that have the same exchange rate for the same issuances. +* **Offer directories** list the offers available in the distributed exchange. A single Offer Directory contains all the offers that have the same exchange rate for the same issuances. Example Directories: @@ -212,7 +212,7 @@ There are three different formulas for creating the index of a DirectoryNode, de * The first page (also called the root) of an Owner Directory, * The first page of an Offer Directory, _or_ -* Subsequent pages of either type +* Later pages of either type **The first page of an Owner Directory** has an `index` that is the SHA-512Half of the following values put together: @@ -239,9 +239,9 @@ The lower 64 bits of an Offer Directory's index represent the TakerPays amount d ## Offer ## [[Source]
    ](https://github.com/ripple/rippled/blob/5d2d88209f1732a0f8d592012094e345cbe3e675/src/ripple/protocol/impl/LedgerFormats.cpp#L57 "Source") -The `Offer` node type describes an offer to exchange currencies, more traditionally known as an _order_, which is currently in an order book in Ripple's distributed exchange. An [OfferCreate transaction](reference-transaction-format.html#offercreate) only creates an Offer node in the ledger when the offer cannot be fully executed immediately by consuming other offers already in the ledger. +The `Offer` node type describes an offer to exchange currencies, more traditionally known as an _order_, in Ripple's distributed exchange. An [OfferCreate transaction](reference-transaction-format.html#offercreate) only creates an Offer node in the ledger when the offer cannot be fully executed immediately by consuming other offers already in the ledger. -An offer can become unfunded through other activities in the network, while remaining in the ledger. However, `rippled` will automatically prune any unfunded offers it happens across in the course of transaction processing (and _only_ transaction processing, because the ledger state must only be changed by transactions). For more information, see [lifecycle of an offer](reference-transaction-format.html#lifecycle-of-an-offer). +An offer can become unfunded through other activities in the network, while remaining in the ledger. However, `rippled` automatically prunes any unfunded offers it happens across in the course of transaction processing (and _only_ transaction processing, because the ledger state must only be changed by transactions). For more information, see [lifecycle of an offer](reference-transaction-format.html#lifecycle-of-an-offer). Example Offer node: @@ -281,7 +281,7 @@ An Offer node has the following fields: | OwnerNode | String | UInt64 | A hint indicating which page of the owner directory links to this node, in case the directory consists of multiple nodes. **Note:** The offer does not contain a direct link to the owner directory containing it, since that value can be derived from the `Account`. | | PreviousTxnID | String | Hash256 | The identifying hash of the transaction that most recently modified this node. | | PreviousTxnLgrSeq | Number | UInt32 | The [index of the ledger](#ledger-index) that contains the transaction that most recently modified this node. | -| Expiration | Number | UInt32 | (Optional) Indicates the time after which this offer will be considered unfunded. See [Specifying Time](reference-rippled.html#specifying-time) for details. | +| Expiration | Number | UInt32 | (Optional) Indicates the time after which this offer is considered unfunded. See [Specifying Time](reference-rippled.html#specifying-time) for details. | ### Offer Flags ### @@ -306,7 +306,7 @@ The `index` of an Offer node is the SHA-512Half of the following values put toge ## RippleState ## [[Source]
    ](https://github.com/ripple/rippled/blob/5d2d88209f1732a0f8d592012094e345cbe3e675/src/ripple/protocol/impl/LedgerFormats.cpp#L70 "Source") -The `RippleState` node type connects two accounts in a single currency. Conceptually, a RippleState node represents two _trust lines_ between the accounts, one from each side. Each account can modify the settings for its side of the RippleState node, but the balance is a single shared value. A trust line that is entirely in its default state is considered the same as trust line that does not exist, so `rippled` deletes RippleState nodes when their properties are entirely default. +The `RippleState` node type connects two accounts in a single currency. Conceptually, a RippleState node represents two _trust lines_ between the accounts, one from each side. Each account can change the settings for its side of the RippleState node, but the balance is a single shared value. A trust line that is entirely in its default state is considered the same as trust line that does not exist, so `rippled` deletes RippleState nodes when their properties are entirely default. Since no account is privileged in the Ripple ledger, a RippleState node sorts their account addresses numerically, to ensure a canonical form. Whichever address is numerically lower is deemed the "low account" and the other is the "high account". @@ -467,7 +467,7 @@ Each member of the `SignerEntries` field is an object that describes that signer | Account | String | AccountID | A Ripple address whose signature contributes to the multi-signature. It does not need to be a funded address in the ledger. | | SignerWeight | Number | UInt16 | The weight of a signature from this signer. A multi-signature is only valid if the sum weight of the signatures provided meets or exceeds the SignerList's `SignerQuorum` value. | -When processing a multi-signed transaction, the server dereferences the `Account` values with respect to the ledger at the time of transaction execution. If the address _does not_ correspond to a funded [AccountRoot node](#accountroot), then only the master secret associated with that address can be used to produce a valid signature. If the account _does_ exist in the ledger, then it depends on the state of that account. If the account has a Regular Key configured, the Regular Key can be used. The account's master key can only be used if it is not disabled. A multi-signature cannot be used as a component of another multi-signature. +When processing a multi-signed transaction, the server dereferences the `Account` values with respect to the ledger at the time of transaction execution. If the address _does not_ correspond to a funded [AccountRoot node](#accountroot), then only the master secret associated with that address can be used to produce a valid signature. If the account _does_ exist in the ledger, then it depends on the state of that account. If the account has a Regular Key configured, the Regular Key can be used. The account's master key can only be used if it is not disabled. A multi-signature cannot be used as part of another multi-signature. ### SignerLists and Reserves ### diff --git a/content/reference-rippled.md b/content/reference-rippled.md index df0cdd2bc2..a7d1797e93 100755 --- a/content/reference-rippled.md +++ b/content/reference-rippled.md @@ -1,6 +1,6 @@ # rippled # -The core peer-to-peer server that operates the Ripple Network is called `rippled`. Each `rippled` server connects to the Ripple Network, relays cryptographically signed transactions, and maintains a local copy of the complete shared global ledger. The source code for `rippled` is written in C++, and is [available on GitHub under an open-source license](https://github.com/ripple/rippled). +The core peer-to-peer server that manages the Ripple Consensus Ledger (RCL) is called `rippled`. Each `rippled` server connects to a network of peers, relays cryptographically signed transactions, and maintains a local copy of the complete shared global ledger. The source code for `rippled` is written in C++, and is [available on GitHub under an open-source license](https://github.com/ripple/rippled). * [`rippled` Setup](tutorial-rippled-setup.html) * [API Reference](#api-methods) @@ -11,7 +11,7 @@ The core peer-to-peer server that operates the Ripple Network is called `rippled If you want to communicate directly with a `rippled` server, you can use either the WebSocket API or the JSON-RPC API. Both APIs use the same list of commands, with almost entirely the same parameters in each command. Alternatively, you can use [RippleAPI](reference-rippleapi.html), which is a simplified JavaScript client library, which communicates directly with a `rippled` server from [Node.js](http://nodejs.org/) or a web browser. * The WebSocket API uses the [WebSocket protocol](http://www.html5rocks.com/en/tutorials/websockets/basics/), available in most browsers and Javascript implementations, to achieve persistent two-way communication. There is not a 1:1 correlation between requests and responses. Some requests prompt the server to send multiple messages back asynchronously; other times, responses may arrive in a different order than the requests that prompted them. The `rippled` server can be configured to accept secured (wss:), unsecured (ws:) WebSocket connections, or both. -* The JSON-RPC API relies on simple request-response communication via HTTP or HTTPS. (The `rippled` server can be configured to accept HTTP, HTTPS, or both.) For commands that prompt multiple responses, you can provide a callback URL. +* The JSON-RPC API relies on request-response communication via HTTP or HTTPS. (The `rippled` server can be configured to accept HTTP, HTTPS, or both.) For commands that prompt multiple responses, you can provide a callback URL. * The `rippled` program can also be used as a quick commandline client to make JSON-RPC requests to a running `rippled` server. This is only intended for administrative purposes, and is not a supported API. In general, we recommend using WebSocket, because WebSocket's push paradigm has less latency and less network overhead. WebSocket is also more reliable; you can worry less about missing messages and establishing multiple connections. On the other hand, there is widespread support for JSON-RPC because you can use a standard HTTP library to connect to `rippled`'s JSON-RPC API. @@ -26,7 +26,7 @@ The WebSocket and JSON-RPC APIs are still in development, and are subject to cha Before you can run any commands against a `rippled` server, you must know which server you are connecting to. Most servers are configured not to accept requests directly from the outside network. -Alternatively, you can [run your own local copy of `rippled`](tutorial-rippled-setup.html). This is required if you want to access any of the [Admin Commands](#list-of-admin-commands). In this case, you should use whatever IP and port you configured the server to bind. (For example, `127.0.0.1:54321`) Additionally, in order to access admin functionality, you must connect from a port/IP address marked as admin in the config file. +Alternatively, you can [run your own local copy of `rippled`](tutorial-rippled-setup.html). This is required if you want to access any of the [Admin Commands](#list-of-admin-commands). In this case, you should use whatever IP and port you configured the server to bind. (For example, `127.0.0.1:54321`) Additionally, to access admin functionality, you must connect from a port/IP address marked as admin in the config file. The [example config file](https://github.com/ripple/rippled/blob/d7def5509d8338b1e46c0adf309b5912e5168af0/doc/rippled-example.cfg#L831-L854) listens for connections on the local loopback network (127.0.0.1), with JSON-RPC (HTTP) on port 5005 and WebSocket (WS) on port 6006, and treats all connected clients as admin. @@ -34,7 +34,7 @@ The [example config file](https://github.com/ripple/rippled/blob/d7def5509d8338b ### WebSocket API ### -If you are just looking to try out some methods on the Ripple network, you can skip writing your own WebSocket code and go straight to using the API at the [Ripple WebSocket API Tool](ripple-api-tool.html). Later on, when you want to connect to your own `rippled` server, you can build your own client in Javascript to run in a browser (See [this example](http://www.websocket.org/echo.html) ) or possibly [Node.js](https://github.com/einaros/ws). +If you are looking to try out some methods on the Ripple Consensus Ledger, you can skip writing your own WebSocket code and go straight to using the API at the [Ripple WebSocket API Tool](ripple-api-tool.html). Later on, when you want to connect to your own `rippled` server, you can build your own client in Javascript to run in a browser (See [this example](http://www.websocket.org/echo.html) ) or possibly [Node.js](https://github.com/einaros/ws). #### Request Formatting #### @@ -222,15 +222,15 @@ The fields of a successful response include: | Field | Type | Description | |-------|------|-------------| | `id` | (Varies) | (WebSocket only) ID provided in the request that prompted this response | -| `status` (WebSocket) `result.status` (JSON-RPC and Commandline) | String | `"success"` if the request successfully completed. In the WebSocket API responses, this is included at the top level; in JSON-RPC and Commandline responses, this is included as a sub-field of the `"result"` object. | +| `status` (WebSocket) `result.status` (JSON-RPC and Commandline) | String | `"success"` if the request was successful. In the WebSocket API responses, this is included at the top level; in JSON-RPC and Commandline responses, this is included as a sub-field of the `"result"` object. | | `type` | String | (WebSocket only) Typically `"response"`, which indicates a successful response to a command. Asynchronous notifications use a different value such as `"ledgerClosed"` or `"transaction"`. | | `result` | Object | The result of the query; contents vary depending on the command. | #### Commandline #### -The response format for commandline methods is identical to JSON-RPC responses, because they use the same interface. +The response format for commandline methods is the same as JSON-RPC responses, because they use the same interface. ## Error Responses ## -It is impossible to enumerate all the possible ways an error can occur. Some may occur in the transport layer (for example, loss of network connectivity), in which case the results will vary depending on what client and transport you are using. However, if the `rippled` server successfully receives your request, it will try to respond in a standardized error format. +It is impossible to list all the possible ways an error can occur. Some may occur in the transport layer (for example, loss of network connectivity), in which case the results vary depending on what client and transport you are using. However, if the `rippled` server successfully receives your request, it tries to respond in a standardized error format. Some example errors: @@ -301,7 +301,7 @@ HTTP Status: 200 OK | request | Object | A copy of the request that prompted this error, in JSON format. **Caution:** If the request contained any account secrets, they are copied here! | #### JSON-RPC API Error Response Format #### -Some JSON-RPC requests will respond with an error code on the HTTP layer. In these cases, the response is a plain-text explanation in the response body. For example, if you forgot to specify the command in the `method` parameter, the response is like this: +Some JSON-RPC request respond with an error code on the HTTP layer. In these cases, the response is a plain-text explanation in the response body. For example, if you forgot to specify the command in the `method` parameter, the response is like this: ``` HTTP Status: 400 Bad Request @@ -330,7 +330,7 @@ All methods can potentially return any of the following values for the `error` c * JSON-RPC returns a 400 Bad Request HTTP error in this case instead. * `missingCommand` - (WebSocket only) The request did not specify a `command` field. * JSON-RPC returns a 400 Bad Request HTTP error in this case instead. -* `tooBusy` - The server is under too much load to perform this command right now. Generally not returned if you are connected as an admin. +* `tooBusy` - The server is under too much load to do this command right now. Generally not returned if you are connected as an admin. * `noNetwork` - The server is having trouble connecting to the rest of the Ripple Network (and is not running in stand-alone mode). * `noCurrent` - The server does not know what the current ledger is, due to high load, network problems, validator failures, incorrect configuration, or some other problem. * `noClosed` - The server does not have a closed ledger, typically because it has not finished starting up. @@ -378,7 +378,7 @@ Each closed *Ledger* has a [Ledger Index][] and a [Hash][] value. When [Specifyi ### Specifying Ledgers ### -Many API methods require you to specify an instance of the ledger, with the data retrieved being considered accurate and up-to-date as of that particular version of the shared ledger. The commands that accept a ledger version all work the same way. There are three ways you can specify which ledger you want to use: +Many API methods require you to specify an instance of the ledger, with the data retrieved being considered up-to-date as of that particular version of the shared ledger. The commands that accept a ledger version all work the same way. There are three ways you can specify which ledger you want to use: 1. Specify a ledger by its [Ledger Index][] in the `ledger_index` parameter. Each closed ledger has an identifying sequence number that is 1 higher than the previously-validated ledger. (The Genesis Ledger has sequence number 0) 2. Specify a ledger by its [Hash][] value in the `ledger_hash` parameter. @@ -389,7 +389,9 @@ Many API methods require you to specify an instance of the ledger, with the data There is also a deprecated `ledger` parameter which accepts any of the above three formats. *Do not* use this parameter; it may be removed without further notice. -If you do not specify a ledger, the `current` (in-progress) ledger will be chosen by default. If you provide more than one field specifying ledgers, the deprecated `ledger` field will be used first if it exists, falling back to `ledger_hash`. The `ledger_index` field is ignored unless neither of the other two are present. **Note:** Do not rely on this default behavior; it is subject to change. Instead, you should always specify a ledger version in each call. +If you do not specify a ledger, the `current` (in-progress) ledger is chosen by default. If you provide more than one field specifying ledgers, the deprecated `ledger` field is used first if it exists, falling back to `ledger_hash`. The `ledger_index` field is ignored unless neither of the other two are present. + +**Note:** Do not rely on this default behavior for specifying a ledger; it is subject to change. Always specify a ledger version in the request if you can. ## Currencies ## @@ -407,7 +409,7 @@ There are two kinds of currencies in the Ripple Consensus Ledger: XRP, and every ### Specifying Currency Amounts ### -Some API methods require you to specify an amount of currency. Depending on whether you are dealing in the network's native XRP currency or other currency units (sometimes referred to as IOUs), the style for specifying it is very different. +Some API methods require you to specify an amount of currency. Depending on whether you are dealing in the network's native XRP currency or other currency units (called _issuances_), the style for specifying it is very different. #### XRP #### [drops of XRP]: #xrp @@ -450,7 +452,7 @@ If you are specifying a non-XRP currency without an amount (typically for defini If you are specifying XRP without an amount (typically for defining an order book) you should specify it as a JSON object with _only_ a `currency` field. Never include an `issuer` field for XRP. -Finally, if the recipient account of the payment trusts multiple gateways for a currency, you can indicate that the payment should be made in any combination of issuers that the recipient accepts. To do this, specify the recipient account's address as the `issuer` value in the JSON object. +Finally, if the recipient account of the payment trusts multiple issuers for a currency, you can indicate that the payment should be made in any combination of issuers that the recipient accepts. To do this, specify the recipient account's address as the `issuer` value in the JSON object. ### Currency Codes ### [Currency Code]: #currency-codes @@ -460,13 +462,13 @@ Finally, if the recipient account of the payment trusts multiple gateways for a ## Specifying Time ## -The `rippled` server and its APIs represent time as an unsigned integer. This number measures the number of seconds since the "Ripple Epoch" of January 1, 2000 (00:00 UTC). This is similar to the way the [Unix epoch](http://en.wikipedia.org/wiki/Unix_time) works, except the Ripple Epoch is 946684800 seconds after the Unix Epoch. +The `rippled` server and its APIs represent time as an unsigned integer. This number measures the number of seconds since the "Ripple Epoch" of January 1, 2000 (00:00 UTC). This is like the way the [Unix epoch](http://en.wikipedia.org/wiki/Unix_time) works, except the Ripple Epoch is 946684800 seconds after the Unix Epoch. Don't convert Ripple Epoch times to UNIX Epoch times in 32-bit variables: this could lead to integer overflows. ## Possible Server States ## -Depending on how the `rippled` server is configured, how long it has been running, and other factors, a server may be participating in the global Ripple Network to different degrees. This is represented as the `server_state` field in the responses to the [`server_info`](#server-info) and [`server_state`](#server-state) commands. The possible responses follow a range of ascending interaction, with each subsequent value superseding the previous one. Their definitions are as follows (in order of increasing priority): +Depending on how the `rippled` server is configured, how long it has been running, and other factors, a server may be participating in the global Ripple Network to different degrees. This is represented as the `server_state` field in the responses to the [`server_info`](#server-info) and [`server_state`](#server-state) commands. The possible responses follow a range of ascending interaction, with each later value superseding the previous one. Their definitions are as follows (in order of increasing priority): | Value | Description | |-------|-------------| @@ -482,16 +484,16 @@ Depending on how the `rippled` server is configured, how long it has been runnin ## Markers and Pagination ## -Some methods return more data than can efficiently fit into one response. When there are more results than contained, the response includes a `marker` field. You can use this to retrieve more pages of data across multiple calls. In each subsequent request, pass the `marker` value from the previous response in order to resume from the point where you left off. If the `marker` is omitted from a response, then you have reached the end of the data set. +Some methods return more data than can efficiently fit into one response. When there are more results than contained, the response includes a `marker` field. You can use this to retrieve more pages of data across multiple calls. In each request, pass the `marker` value from the previous response to resume from the point where you left off. If the `marker` is omitted from a response, then you have reached the end of the data set. The format of the `marker` field is intentionally undefined. Each server can define a `marker` field as desired, so it may take the form of a string, a nested object, or another type. Different servers, and different methods provided by the same server, can have different `marker` definitions. Each `marker` is ephemeral, and may not work as expected after 10 minutes. ## Modifying the Ledger ## -All changes to Ripple's global shared ledger happen as the result of transactions. Consequently, this means that there is *only one* public API method that causes a change in the state of the Ripple Network at all: the [*submit*](#submit) command. Most of the other methods represent different ways to view the data represented in the Ripple Network, and the remaining ones just generate data for your convenience. (The [wallet_propose](#wallet-propose), [path_find](#path-find), and [random](#random) commands fall into this category.) +All changes to the Ripple Consensus Ledger (RCL) happen as the result of transactions. The only API methods that can change the contents of the RCL are the [`submit` command](#submit) and the [`submit_multisigned` command](#submit-multisigned). Most other methods represent different ways to view the data represented in the RCL. The remaining commands generate data for your convenience. (The [`wallet_propose`](#wallet-propose), [`path_find`](#path-find), and [`random`](#random) commands fall into this category.) -For more information on the various transactions you can submit, consult the [Transaction Format](reference-transaction-format.html). +For more information on the various transactions you can submit, see the [Transaction Format](reference-transaction-format.html). @@ -565,20 +567,20 @@ The following admin commands are deprecated and may be removed without further n ## Commandline Access ## -The `rippled` application, in addition to acting as a server, can be run (as a separate instance) to act as a JSON-RPC client. In this mode, it has syntax for triggering most API methods with a single line from the command prompt, as described in each method. However, some methods don't have a commandline shortcut, so it also provides the following catch-all method for performing commands: +You can use the `rippled` application (as a separate instance) as a JSON-RPC client. In this mode, it has syntax for triggering most API methods with a single line from the command prompt, as described in each method. However, some methods or options don't have commandline syntax. For otherwise unsupported syntax, you can use the following method: * [`json` - Pass JSON through the commandline](#json) # Account Information # -Accounts are the core unit of authentication in the Ripple Network. Each account can hold balances in multiple currencies, and all transactions must be signed by an account's secret key. In order for an account to exist in a validated ledger version, it must hold a minimum reserve amount of XRP. (The [reserve for an account](concept-reserves.html) increases with the amount of data it is responsible for in the shared ledger.) It is expected that accounts will correspond loosely to individual users. +Accounts are the core unit of authentication in the Ripple Consensus Ledger. Each account can hold balances in multiple currencies, and all transactions must be signed by an account's secret key. In order for an account to exist in a validated ledger version, it must hold a minimum reserve amount of XRP. (The [reserve for an account](concept-reserves.html) increases with the amount of data it owns in the shared ledger.) It is expected that accounts correspond loosely to individual users. ## account_currencies ## [[Source]
    ](https://github.com/ripple/rippled/blob/df966a9ac6dd986585ecccb206aff24452e41a30/src/ripple/rpc/handlers/AccountCurrencies.cpp "Source") -The `account_currencies` command retrieves a simple list of currencies that an account can send or receive, based on its trust lines. (This is not a thoroughly confirmed list, but it can be used to populate user interfaces.) +The `account_currencies` command retrieves a list of currencies that an account can send or receive, based on its trust lines. (This is not a thoroughly confirmed list, but it can be used to populate user interfaces.) #### Request Format #### An example of the request format: @@ -715,7 +717,7 @@ The response follows the [standard format](#response-formatting), with a success | send\_currencies | Array of Strings | Array of [Currency Code][]s for currencies that this account can send. | | validated | Boolean | If `true`, this data comes from a validated ledger. | -*Note:* The currencies that an account can send or receive are defined based on a simple check of its trust lines. If an account has a trust line for a currency and enough room to increase its balance, it can receive that currency. If the trust line's balance can go down, the account can send that currency. This method *doesn't* check whether the trust line is [frozen](concept-freeze.html) or authorized. +**Note:** The currencies that an account can send or receive are defined based on a check of its trust lines. If an account has a trust line for a currency and enough room to increase its balance, it can receive that currency. If the trust line's balance can go down, the account can send that currency. This method _doesn't_ check whether the trust line is [frozen](concept-freeze.html) or authorized. #### Possible Errors #### @@ -780,7 +782,7 @@ The request contains the following parameters: | Field | Type | Description | |-------|------|-------------| | account | String | A unique identifier for the account, most commonly the account's [Address][]. | -| strict | Boolean | (Optional, defaults to False) If set to True, then the `account` field will only accept a public key or account address. | +| strict | Boolean | (Optional, defaults to False) If set to True, then the `account` field only accepts a public key or Ripple address. | | ledger_hash | String | (Optional) A 20-byte hex string for the ledger version to use. (See [Specifying a Ledger](#specifying-ledgers)) | | ledger_index | String or Unsigned Integer| (Optional) The sequence number of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying a Ledger](#specifying-ledgers))| | signer\_lists | Boolean | (Optional) If `true`, and the [MultiSign amendment](concept-amendments.html#multisign) is enabled, also returns any [SignerList objects](reference-ledger-format.html#signerlist) associated with this account. _(New in [version 0.31.0][])_ | @@ -997,7 +999,7 @@ The response follows the [standard format](#response-formatting), with a success | ledger\_current\_index | Integer | (Omitted if `ledger_hash` or `ledger_index` provided) Sequence number of the ledger version used when retrieving this data. _(New in [version 0.26.4-sp1][])_ | | ledger\_index | Integer | (Omitted if `ledger_current_index` provided instead) Sequence number, provided in the request, of the ledger version that was used when retrieving this data. _(New in [version 0.26.4-sp1][])_ | | ledger\_hash | String | (May be omitted) Hex hash, provided in the request, of the ledger version that was used when retrieving this data. _(New in [version 0.26.4-sp1][])_ | -| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call in order to resume where this call left off. Omitted when there are no additional pages after this one. _(New in [version 0.26.4][])_ | +| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call to resume where this call left off. Omitted when there are no additional pages after this one. _(New in [version 0.26.4][])_ | Each trust-line object has some combination of the following fields: @@ -1192,7 +1194,7 @@ The response follows the [standard format](#response-formatting), with a success | ledger\_current\_index | Integer | (Omitted if `ledger_hash` or `ledger_index` provided) Sequence number of the ledger version used when retrieving this data. _(New in [version 0.26.4-sp1][])_ | | ledger\_index | Integer | (Omitted if `ledger_current_index` provided instead) Sequence number, provided in the request, of the ledger version that was used when retrieving this data. _(New in [version 0.26.4-sp1][])_ | | ledger\_hash | String | (May be omitted) Hex hash, provided in the request, of the ledger version that was used when retrieving this data. _(New in [version 0.26.4-sp1][])_ | -| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call in order to resume where this call left off. Omitted when there are no pages of information after this one. _(New in [version 0.26.4][])_ | +| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call to resume where this call left off. Omitted when there are no pages of information after this one. _(New in [version 0.26.4][])_ | Each offer object contains the following fields: @@ -1814,7 +1816,7 @@ The response follows the [standard format](#response-formatting), with a success | ledger\_index | Number | (May be omitted) The sequence number of the ledger version that was used to generate this response. | | ledger\_current\_index | Number | (May be omitted) The sequence number of the current in-progress ledger version that was used to generate this response. | | limit | Number | (May be omitted) The limit that was used in this request, if any. | -| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call in order to resume where this call left off. Omitted when there are no additional pages after this one. | +| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call to resume where this call left off. Omitted when there are no additional pages after this one. | | validated | Boolean | If `true`, this information comes from ledger version that has been validated by consensus. | #### Possible Errors #### @@ -2397,7 +2399,7 @@ The response follows the [standard format](#response-formatting), with a success | ledger\_index\_min | Integer | The sequence number of the earliest ledger actually searched for transactions. | | ledger\_index\_max | Integer | The sequence number of the most recent ledger actually searched for transactions. | | limit | Integer | The `limit` value used in the request. (This may differ from the actual limit value enforced by the server.) | -| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call in order to resume where this call left off. | +| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call to resume where this call left off. | | offset | Integer | The `offset` value used in the request. | | transactions | Array | Array of transactions matching the request's criteria, as explained below. | | validated | Boolean | If included and set to `true`, the information in this request comes from a validated ledger version. Otherwise, the information is subject to change. | @@ -2473,7 +2475,7 @@ The request includes the following parameters: | Field | Type | Description | |-------|------|-------------| | account | String | A unique identifier for the account, most commonly the account's address. | -| role | String | Whether the account refers to a `gateway` or `user`. Recommendations depend on the role of the account. Gateways must have DefaultRipple enabled and must disable NoRipple on all trust lines. Users should have DefaultRipple disabled, and should enable NoRipple on all trust lines. | +| role | String | Whether the address refers to a `gateway` or `user`. Recommendations depend on the role of the account. Issuers must have DefaultRipple enabled and must disable NoRipple on all trust lines. Users should have DefaultRipple disabled, and should enable NoRipple on all trust lines. | | transactions | Boolean | (Optional) If `true`, include an array of suggested [transactions](reference-transaction-format.html), as JSON objects, that you can sign and submit to fix the problems. Defaults to false. | | limit | Unsigned Integer | (Optional) The maximum number of trust line problems to include in the results. Defaults to 300. | | ledger_hash | String | (Optional) A 20-byte hex string for the ledger version to use. (See [Specifying a Ledger](#specifying-ledgers)) | @@ -2609,7 +2611,7 @@ The response follows the [standard format](#response-formatting), with a success ## gateway_balances ## [[Source]
    ](https://github.com/ripple/rippled/blob/9111ad1a9dc37d49d085aa317712625e635197c0/src/ripple/rpc/handlers/GatewayBalances.cpp "Source") -The `gateway_balances` command calculates the total balances issued by a given account, optionally excluding amounts held by specific "hot wallet" addresses. _(New in [version 0.28.2][].)_ +The `gateway_balances` command calculates the total balances issued by a given account, optionally excluding amounts held by [operational addresses](concept-issuing-and-operational-addresses.html). _(New in [version 0.28.2][].)_ #### Request Format #### An example of the request format: @@ -2654,9 +2656,9 @@ The request includes the following parameters: | Field | Type | Description | |-----------|---------|-------------| -| account | String | The [Address][] of the account to use | +| account | String | The [Address][] to check. This should be the [issuing address](concept-issuing-and-operational-addresses.html) | | strict | Boolean | (Optional) If true, only accept an address or public key for the account parameter. Defaults to false. | -| hotwallet | String or Array | The [Address][] of a hot wallet account to exclude from the balances issued, or an array of such addresses. | +| hotwallet | String or Array | An [operational address](concept-issuing-and-operational-addresses.html) to exclude from the balances issued, or an array of such addresses. | | ledger\_hash | String | (Optional) A 20-byte hex string for the ledger version to use. (See [Specifying a Ledger](#specifying-ledgers)) | | ledger\_index | String or Unsigned Integer| (Optional) The sequence number of the ledger version to use, or a shortcut string to choose a ledger automatically. (See [Specifying a Ledger](#specifying-ledgers))| @@ -2809,9 +2811,9 @@ The response follows the [standard format](#response-formatting), with a success | Field | Type | Description | |-------|------|-------------| -| obligations | Object | (Omitted if empty) Total amounts issued to accounts that are not hot wallets, as a map of currencies to the total value issued. | -| balances | Object | (Omitted if empty) Amounts issued to the `hotwallet` accounts from the request. The keys are hot wallet addresses and the values are arrays of currency amounts they hold. The issuer (omitted from the currency amounts) is the account from the request. | -| assets | Object | (Omitted if empty) Total amounts held that are issued by others. For the recommended gateway configuration, there should be none. | +| obligations | Object | (Omitted if empty) Total amounts issued to addresses not excluded, as a map of currencies to the total value issued. | +| balances | Object | (Omitted if empty) Amounts issued to the `hotwallet` addresses from the request. The keys are addresses and the values are arrays of currency amounts they hold. | +| assets | Object | (Omitted if empty) Total amounts held that are issued by others. In the recommended configuration, the [issuing address](concept-issuing-and-operational-addresses.html) should have none. | | ledger\_hash | String | (May be omitted) The identifying hash of the ledger that was used to generate this response. | | ledger\_index | Number | (May be omitted) The sequence number of the ledger version that was used to generate this response. | | ledger\_current\_index | Number | (May be omitted) The sequence number of the current in-progress ledger version that was used to generate this response. | @@ -3018,7 +3020,7 @@ The key generated by this method can also be used as a regular key for an accoun # Ledger Information # -The globally-shared ledger is the core of the Ripple Network. Each `rippled` server keeps a current version of the ledger, which contains all the accounts, transactions, offers, and other data in the network in an optimized tree format. As transactions and offers are proposed, each server incorporates them into its current copy of the ledger, closes it periodically, and (if configured) participates in the process of advancing the globally-validated version. After the network reaches consensus, that ledger version is validated and becomes permanently immutable. Any transactions that were not included in one ledger become candidates to be included in the next validated version. +The globally-shared ledger is the core of the Ripple Network. Each `rippled` server keeps a current version of the ledger, which contains all the accounts, transactions, offers, and other data in the network in an optimized tree format. As transactions and offers are proposed, each server incorporates them into its current copy of the ledger, closes it periodically, and (if configured) participates in advancing the globally-validated version. After the network reaches consensus, that ledger version is validated and becomes permanently immutable. Any transactions that were not included in one ledger become candidates to be included in the next validated version. ## ledger ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/LedgerHandler.cpp "Source") @@ -3085,7 +3087,7 @@ The request can contain the following parameters: | full | Boolean | (Optional, defaults to false) **Admin required** If true, return full information on the entire ledger. Ignored if you did not specify a ledger. (Equivalent to enabling `transactions`, `accounts`, and `expand`.) **Caution:** This is a very large amount of data -- on the order of several hundred megabytes! | | accounts | Boolean | (Optional, defaults to false) **Admin required.** If true, return information on accounts in the ledger. Ignored if you did not specify a ledger. **Caution:** This returns a very large amount of data! | | transactions | Boolean | (Optional, defaults to false) If true, return information on transactions in the specified ledger version. Ignored if you did not specify a ledger. | -| expand | Boolean | (Optional, defaults to false) Provide full JSON-formatted information for transaction/account information instead of just hashes. Ignored unless transactions and/or accounts are requested. | +| expand | Boolean | (Optional, defaults to false) Provide full JSON-formatted information for transaction/account information instead of only hashes. Ignored unless you requested transactions, accounts, or both. | | owner\_funds | Boolean | (Optional, defaults to false) Include `owner_funds` field in the metadata of OfferCreate transactions in the response. Ignored unless transactions are included and `expand` is true. | | binary | Boolean | (Optional, defaults to false) If `transactions` and `expand` are both true, and this option is also true, return transaction information in binary format instead of JSON format. _(New in [version 0.28.0][])_ | @@ -3382,7 +3384,7 @@ A `ledger_hash` field is not provided, because the hash of the current ledger is ## ledger_data ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/LedgerData.cpp "Source") -The `ledger_data` method retrieves contents of the specified ledger. You can iterate through several calls in order to retrieve the entire contents of a single ledger version. +The `ledger_data` method retrieves contents of the specified ledger. You can iterate through several calls to retrieve the entire contents of a single ledger version. #### Request Format #### An example of the request format: @@ -3620,7 +3622,7 @@ The response follows the [standard format](#response-formatting), with a success | ledger_index | Unsigned Integer | Sequence number of this ledger | | ledger_hash | String | Unique identifying hash of the entire ledger. | | state | Array | Array of JSON objects containing data from the tree, as defined below | -| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call in order to resume where this call left off. | +| marker | [(Not Specified)](#markers-and-pagination) | Server-defined value. Pass this to the next call to resume where this call left off. | The format of each object in the `state` array depends on whether `binary` was set to true or not in the request. Each `state` object may include the following fields: @@ -3685,12 +3687,12 @@ An example of the request format: This method can retrieve several different types of data. You can select which type of item to retrieve by passing the appropriate parameters. Specifically, you should provide exactly one of the following fields: 1. `index` - Retrieve any type of ledger node by its unique index -2. `account_root` - Retrieve an [AccountRoot node](reference-ledger-format.html#accountroot), similar to the [account_info](#account-info) command +2. `account_root` - Retrieve an [AccountRoot node](reference-ledger-format.html#accountroot). This is roughly equivalent to the [account_info](#account-info) command. 3. `directory` - Retrieve a [DirectoryNode](reference-ledger-format.html#directorynode), which contains a list of other nodes 4. `offer` - Retrieve an [Offer node](reference-ledger-format.html#offer), which defines an offer to exchange currency 5. `ripple_state` - Retrieve a [RippleState node](reference-ledger-format.html#ripplestate), which tracks a (non-XRP) currency balance between two accounts. -If you specify more than one of the above items, the server will retrieve only of them; it is undefined which one will be chosen. +If you specify more than one of the above items, the server retrieves only of them; it is undefined which it chooses. The full list of parameters recognized by this method is as follows: @@ -3830,7 +3832,7 @@ You must provide either `ledger_index` or `ledger_hash` but not both. The response follows the [standard format](#response-formatting). However, the request returns a failure response if it does not have the specified ledger _even if it successfully instructed the `rippled` server to start retrieving the ledger_. -**Note:** In order to retrieve a ledger, the rippled server must have a direct peer with that ledger in its history. If none of the peers have the requested ledger, you can use the [`connect` command](#connect) or the `fixed_ips` section of the config file to add Ripple's full-history server at `s2.ripple.com` and then make the `ledger_request` request again. +**Note:** To retrieve a ledger, the rippled server must have a direct peer with that ledger in its history. If none of the peers have the requested ledger, you can use the [`connect` command](#connect) or the `fixed_ips` section of the config file to add Ripple's full-history server at `s2.ripple.com` and then make the `ledger_request` request again. A failure response indicates the status of fetching the ledger. A successful response contains the information for the ledger in a similar format to the [`ledger` command](#ledger). @@ -3942,7 +3944,7 @@ Connecting to 127.0.0.1:5005 The three possible response formats are as follows: 1. When returning a `lgrNotFound` error, the response has a field, `acquiring` with a [Ledger Request Object](#ledger-request-object) indicating the progress of fetching the ledger from the peer-to-peer network. -2. When the response represents an in-progress attempt to acquire the ledger, the body of the result is a [Ledger Request Object](#ledger-request-object) indicating the progress of fetching the ledger from the peer-to-peer network. +2. When the response shows the server is currently fetching the ledger, the body of the result is a [Ledger Request Object](#ledger-request-object) indicating the progress of fetching the ledger from the peer-to-peer network. 3. When the ledger is fully available, the response is a representation of the [ledger header](reference-ledger-format.html#header-format). #### Ledger Request Object #### @@ -3957,8 +3959,8 @@ When the server is in the progress of fetching a ledger, but has not yet finishe | have\_transactions | Boolean | (May be omitted) Whether the server has the transaction section of the requested ledger. | | needed\_state\_hashes | Array of Strings | (May be omitted) Up to 16 hashes of nodes in the [state tree](reference-ledger-format.html#tree-format) that the server still needs to retrieve. | | needed\_transaction\_hashes | Array of Strings | (May be omitted) Up to 16 hashes of nodes in the transaction tree that the server still needs to retrieve. | -| peers | Number | How many peers the server is querying in its attempt to find this ledger. | -| timeouts | Number | Number of times this attempt to fetch the ledger has timed out so far. | +| peers | Number | How many peers the server is querying to find this ledger. | +| timeouts | Number | Number of times fetching this ledger has timed out so far. | #### Possible Errors #### @@ -4033,7 +4035,7 @@ The response follows the [standard format](#response-formatting), with a success Transactions are the only thing that can modify the shared global ledger of the Ripple Network. All business on the Ripple Network takes the form of transactions, which include not only payments, but also currency-exchange offers, account settings, and changes to the properties of the network itself (like adopting new features). -There are several sources of complication in transactions. Unlike traditional banking, where a trusted third party (the bank, or the [ACH](http://en.wikipedia.org/wiki/Automated_Clearing_House)) verifies the participants' identities and ensures their balances are adjusted accurately, Ripple uses cryptography and decentralized computing power to accomplish the same thing. Sending XRP, the Ripple Network's native crypto-currency, requires no third party aside from the distributed network itself. However, that is missing out on the key feature of Ripple: unlike individual crypto-currencies, the Ripple Network natively supports balances in any currency. This brings far more power, but it also means that the system must account for [counterparty risk](http://en.wikipedia.org/wiki/Counterparty_risk#Counterparty_risk), currency conversions, and other issues. The Ripple Network must be robust to keep track of which transactions have been completely validated, even when subject to hardware failures, attacks, or natural disasters. +There are several sources of complication in transactions. Unlike traditional banking, where a trusted third party (the bank, or the [ACH](http://en.wikipedia.org/wiki/Automated_Clearing_House)) verifies the participants' identities and ensures their balances are adjusted accurately, Ripple uses cryptography and decentralized computing power to do the same thing. Sending XRP, the Ripple Network's native crypto-currency, requires no third party aside from the distributed network itself. However, that is missing out on the key feature of Ripple: unlike individual crypto-currencies, the Ripple Network natively supports balances in any currency. This brings far more power, but it also means that the system must account for [counterparty risk](http://en.wikipedia.org/wiki/Counterparty_risk#Counterparty_risk), currency conversions, and other issues. The Ripple Network must be robust to keep track of which transactions have been completely validated, even when subject to hardware failures, attacks, or natural disasters. ## tx ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/Tx.cpp "Source") @@ -4448,7 +4450,7 @@ The response follows the [standard format](#response-formatting), with a success There are a couple possible reasons the server may fail to find the transaction: -* The transaction just does not exist +* The transaction does not exist * The transaction exists, but not in the specified ledger version * The server does not have the specified ledger version available. Another server that has the correct version on hand may have a different response. @@ -4466,7 +4468,7 @@ There are a couple possible reasons the server may fail to find the transaction: ## tx_history ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/TxHistory.cpp "Source") -The `tx_history` method retrieves a selection of the most recent transactions made. +The `tx_history` method retrieves some of the most recent transactions made. **Caution:** This method is deprecated, and may be removed without further notice. @@ -5370,7 +5372,7 @@ There are three different modes, or sub-commands, of the path_find command. Spec * `close` - Stop sending pathfinding information * `status` - Get the information of the currently-open pathfinding request -Although the `rippled` server attempts to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths in order to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers operated by different parties, to minimize the risk of a single server returning poor results. (**Note:** A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.) +Although the `rippled` server tries to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers run by different parties, to minimize the risk of a single server returning poor results. (**Note:** A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.) ### path_find create ### [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/PathFind.cpp#L38 "Source") @@ -5802,15 +5804,15 @@ The initial response follows the [standard format](#response-formatting), with a | destination\_account | String | Unique address of the account that would receive a transaction | | destination\_amount | String or Object | [Currency amount](#specifying-currency-amounts) that the destination would receive in a transaction | | id | (Various) | (WebSocket only) The ID provided in the WebSocket request is included again at this level. | -| source\_account | String | Unique address of the account that would initiate a transaction | -| full\_reply | Boolean | If `false`, this is the result of an incomplete search, and a subsequent reply may have a better path. If `true`, then this is the best path found. (It is still theoretically possible that a better path could exist, but rippled won't find it.) Until you close the pathfinding request, rippled will continue to send updates each time a new ledger closes. _(New in [version 0.29.0][])_ | +| source\_account | String | Unique address that would send a transaction | +| full\_reply | Boolean | If `false`, this is the result of an incomplete search. A later reply may have a better path. If `true`, then this is the best path found. (It is still theoretically possible that a better path could exist, but `rippled` won't find it.) Until you close the pathfinding request, `rippled` continues to send updates each time a new ledger closes. _(New in [version 0.29.0][])_ | Each element in the `alternatives` array is an object that represents a path from one possible source currency (held by the initiating account) to the destination account and currency. This object has the following fields: | Field | Type | Description | |-------|------|-------------| | paths\_computed | Array | Array of arrays of objects defining [payment paths](concept-paths.html) | -| source\_amount | String or Object | [Currency amount](#specifying-currency-amounts) that the source would have to send along this path in order for the destination to receive the desired amount | +| source\_amount | String or Object | [Currency amount](#specifying-currency-amounts) that the source would have to send along this path for the destination to receive the desired amount | #### Possible Errors #### @@ -5943,11 +5945,11 @@ If there was no outstanding pathfinding request, an error is returned instead. ## ripple_path_find ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/RipplePathFind.cpp "Source") -The `ripple_path_find` method is a simplified version of [`path_find`](#path-find) that provides a single response with a [payment path](concept-paths.html) you can use right away. It is available in both the WebSocket and JSON-RPC APIs. However, the results tend to become outdated as time passes. Instead of making many subsequent calls, you should use [`path_find`](#path-find) instead where possible. +The `ripple_path_find` method is a simplified version of [`path_find`](#path-find) that provides a single response with a [payment path](concept-paths.html) you can use right away. It is available in both the WebSocket and JSON-RPC APIs. However, the results tend to become outdated as time passes. Instead of making multiple calls to stay updated, you should use [`path_find`](#path-find) instead where possible. -Although the `rippled` server attempts to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. +Although the `rippled` server tries to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. -**Caution:** Be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths in order to earn money for its operators. A server may also return poor results when under heavy load. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers operated by different parties, to minimize the risk of a single server returning poor results. +**Caution:** Be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths to earn money for its operators. A server may also return poor results when under heavy load. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers run by different parties, to minimize the risk of a single server returning poor results. #### Request Format #### An example of the request format: @@ -6024,7 +6026,7 @@ The request includes the following parameters: | destination\_account | String | Unique address of the account that would receive funds in a transaction | | destination\_amount | String or Object | [Currency amount](#specifying-currency-amounts) that the destination account would receive in a transaction. **Special case:** _(New in [version 0.30.0][])_ You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for non-XRP currencies). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). | | send\_max | String or Object | (Optional) [Currency amount](#specifying-currency-amounts) that would be spent in the transaction. Cannot be used with `source_currencies`. _(New in [version 0.30.0][])_ | -| source\_currencies | Array | (Optional) Array of currencies that the source account might want to spend. Each entry in the array should be a JSON object with a mandatory `currency` field and optional `issuer` field, similar to [currency amounts](#specifying-currency-amounts). Cannot contain more than **18** source currencies. By default, uses all source currencies available up to a maximum of **88** different currency/issuer pairs. | +| source\_currencies | Array | (Optional) Array of currencies that the source account might want to spend. Each entry in the array should be a JSON object with a mandatory `currency` field and optional `issuer` field, like how [currency amounts](#specifying-currency-amounts) are specified. Cannot contain more than **18** source currencies. By default, uses all source currencies available up to a maximum of **88** different currency/issuer pairs. | | ledger\_hash | String | (Optional) A 20-byte hex string for the ledger version to use. (See [Specifying a Ledger](#specifying-ledgers)) | | ledger\_index | String or Unsigned Integer| (Optional) The sequence number of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying a Ledger](#specifying-ledgers))| @@ -6266,7 +6268,7 @@ Each element in the `alternatives` array is an object that represents a path fro | Field | Type | Description | |-------|------|-------------| | paths\_computed | Array | Array of arrays of objects defining [payment paths](concept-paths.html) | -| source\_amount | String or Object | [Currency amount](#specifying-currency-amounts) that the source would have to send along this path in order for the destination to receive the desired amount | +| source\_amount | String or Object | [Currency amount](#specifying-currency-amounts) that the source would have to send along this path for the destination to receive the desired amount | The following fields are deprecated, and may be omitted: `paths_canonical`, and `paths_expanded`. If they appear, you should disregard them. @@ -6290,7 +6292,7 @@ The following fields are deprecated, and may be omitted: `paths_canonical`, and The `sign` method takes a [transaction in JSON format](reference-transaction-format.html) and a secret key, and returns a signed binary representation of the transaction. The result is always different, even when you provide the same transaction JSON and secret key. To contribute one signature to a multi-signed transaction, use the [`sign_for` command](#sign-for) instead. -**Caution:** Unless you operate the `rippled` server, you should do [local signing with RippleAPI](reference-rippleapi.html#sign) instead of using this command. An untrustworthy server could change the transaction before signing it, or use your secret key to sign additional arbitrary transactions as if they came from you. +**Caution:** Unless you run the `rippled` server yourself, you should do [local signing with RippleAPI](reference-rippleapi.html#sign) instead of using this command. An untrustworthy server could change the transaction before signing it, or use your secret key to sign additional arbitrary transactions as if they came from you. #### Request Format #### An example of the request format: @@ -6370,14 +6372,14 @@ The request includes the following parameters: | seed\_hex | String | (Optional) Secret key of the account supplying the transaction, used to sign it. Must be in hexadecimal format. If provided, you must also specify the `key_type`. Cannot be used with `secret`, `seed`, or `passphrase`. | | passphrase | String | (Optional) Secret key of the account supplying the transaction, used to sign it, as a string passphrase. If provided, you must also specify the `key_type`. Cannot be used with `secret`, `seed`, or `seed_hex`. | | key\_type | String | (Optional) Type of cryptographic key provided in this request. Valid types are `secp256k1` or `ed25519`. Defaults to `secp256k1`. Cannot be used with `secret`. **Caution:** Ed25519 support is experimental. | -| offline | Boolean | (Optional, defaults to false) If true, when constructing the transaction, do not attempt to automatically fill in or validate values. | +| offline | Boolean | (Optional, defaults to false) If true, when constructing the transaction, do not try to automatically fill in or validate values. | | build_path | Boolean | (Optional) If provided for a Payment-type transaction, automatically fill in the `Paths` field before signing. **Caution:** The server looks for the presence or absence of this field, not its value. This behavior may change. | | fee\_mult\_max | Integer | (Optional, defaults to 10; recommended value 1000) Limits how high the [automatically-provided `Fee` field](reference-transaction-format.html#auto-fillable-fields) can be. Signing fails with the error `rpcHIGH_FEE` if the current [load multiplier on the transaction cost](concept-transaction-cost.html#local-load-cost) is greater than (`fee_mult_max` ÷ `fee_div_max`). Ignored if you specify the `Fee` field of the transaction ([transaction cost](concept-transaction-cost.html)). | | fee\_div\_max | Integer | (Optional, defaults to 1) Signing fails with the error `rpcHIGH_FEE` if the current [load multiplier on the transaction cost](concept-transaction-cost.html#local-load-cost) is greater than (`fee_mult_max` ÷ `fee_div_max`). Ignored if you specify the `Fee` field of the transaction ([transaction cost](concept-transaction-cost.html)). _(New in [version 0.30.1][])_ | ### Auto-Fillable Fields ### -The server automatically attempts to fill in certain fields in `tx_json` (the [Transaction object](reference-transaction-format.html)) automatically if you omit them. The server provides the following fields before signing, unless the request specified `offline` as `true`: +The server automatically tries to fill in certain fields in `tx_json` (the [Transaction object](reference-transaction-format.html)) automatically if you omit them. The server provides the following fields before signing, unless the request specified `offline` as `true`: * `Sequence` - The server automatically uses the next Sequence number from the sender's account information. * **Caution:** The next sequence number for the account is not incremented until this transaction is applied. If you sign multiple transactions without submitting and waiting for the response to each one, you must manually provide the correct sequence numbers for each transaction after the first. @@ -6742,7 +6744,7 @@ The `submit` method applies a [transaction](reference-transaction-format.html) a This command has two modes: -* Submit-only mode takes a signed, serialized transaction as a binary blob, and submits it to the network as-is. Since signed transaction objects are immutable, no portion of the transaction can be modified or automatically filled in after submission. +* Submit-only mode takes a signed, serialized transaction as a binary blob, and submits it to the network as-is. Since signed transaction objects are immutable, no part of the transaction can be modified or automatically filled in after submission. * Sign-and-submit mode takes a JSON-formatted Transaction object, completes and signs the transaction in the same manner as the [sign command](#sign), and then submits the signed transaction. We recommend only using this mode for testing and development. To send a transaction as robustly as possible, you should construct and [`sign`](#sign) it in advance, persist it somewhere that you can access even after a power outage, then `submit` it as a `tx_blob`. After submission, monitor the network with the [`tx`](#tx) command to see if the transaction was successfully applied; if a restart or other problem occurs, you can safely re-submit the `tx_blob` transaction: it won't be applied twice since it has the same sequence number as the old transaction. @@ -6815,7 +6817,7 @@ The request includes the following parameters: | passphrase | String | (Optional) Secret key of the account supplying the transaction, used to sign it, as a string passphrase. If provided, you must also specify the `key_type`. Cannot be used with `secret`, `seed`, or `seed_hex`. | | key\_type | String | (Optional) Type of cryptographic key provided in this request. Valid types are `secp256k1` or `ed25519`. Defaults to `secp256k1`. Cannot be used with `secret`. **Caution:** Ed25519 support is experimental. | | fail\_hard | Boolean | (Optional, defaults to false) If true, and the transaction fails locally, do not retry or relay the transaction to other servers | -| offline | Boolean | (Optional, defaults to false) If true, when constructing the transaction, do not attempt to automatically fill in or validate values. | +| offline | Boolean | (Optional, defaults to false) If true, when constructing the transaction, do not try to automatically fill in or validate values. | | build\_path | Boolean | (Optional) If provided for a Payment-type transaction, automatically fill in the `Paths` field before signing. You must omit this field if the transaction is a direct XRP-to-XRP transfer. **Caution:** The server looks for the presence or absence of this field, not its value. This behavior may change. | | fee\_mult\_max | Integer | (Optional, defaults to 10, recommended value 1000) If the `Fee` parameter is omitted, this field limits the automatically-provided `Fee` value so that it is less than or equal to the long-term base transaction cost times this value. | | fee\_div\_max | Integer | (Optional, defaults to 1) Used with `fee_mult_max` to create a fractional multiplier for the limit. Specifically, the server multiplies its base [transaction cost](concept-transaction-cost.html) by `fee_mult_max`, then divides by this value (rounding down to an integer) to get a limit. If the automatically-provided `Fee` value would be over the limit, the submit command fails. _(New in [version 0.30.1][])_ | @@ -7275,7 +7277,7 @@ The response follows the [standard format](#response-formatting), with a success ## book_offers ## [[Source]
    ](https://github.com/ripple/rippled/blob/develop/src/ripple/rpc/handlers/BookOffers.cpp "Source") -The `book_offers` method retrieves a list of offers, also known as the [order book](http://www.investopedia.com/terms/o/order-book.asp), between two currencies. If the results are very large, a partial result is returned with a marker so that subsequent requests can resume from where the previous one left off. +The `book_offers` method retrieves a list of offers, also known as the [order book](http://www.investopedia.com/terms/o/order-book.asp), between two currencies. If the results are very large, a partial result is returned with a marker so that later requests can resume from where the previous one left off. #### Request Format #### An example of the request format: @@ -7338,12 +7340,12 @@ The request includes the following parameters: |-------|------|-------------| | ledger_hash | String | (Optional) A 20-byte hex string for the ledger version to use. (See [Specifying a Ledger](#specifying-ledgers)) | | ledger_index | String or Unsigned Integer| (Optional) The sequence number of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying a Ledger](#specifying-ledgers))| -| limit | Unsigned Integer | (Optional) If provided, the server will not provide more than this many offers in the results. *Note:* Depending on the number of unfunded orders in the ledger, fewer results may be returned. | +| limit | Unsigned Integer | (Optional) If provided, the server does not provide more than this many offers in the results. The total number of results returned may be fewer than the limit, because the server omits unfunded offers. | | taker | String | (Optional, defaults to [ACCOUNT\_ONE][]) The [Address][] of an account to use as a perspective. (This affects which unfunded offers are returned.) | -| taker\_gets | Object | Specification of which currency the account taking the offer would receive, as an object with `currency` and `issuer` fields (omit issuer for XRP), similar to [currency amounts](#specifying-currency-amounts). | -| taker\_pays | Object | Specification of which currency the account taking the offer would pay, as an object with `currency` and `issuer` fields (omit issuer for XRP), similar to [currency amounts](#specifying-currency-amounts). | +| taker\_gets | Object | Specification of which currency the account taking the offer would receive, as an object with `currency` and `issuer` fields (omit issuer for XRP), like [currency amounts](#specifying-currency-amounts). | +| taker\_pays | Object | Specification of which currency the account taking the offer would pay, as an object with `currency` and `issuer` fields (omit issuer for XRP), like [currency amounts](#specifying-currency-amounts). | -Normally, offers that are not funded are omitted; however, offers made by the specified `taker` account are always displayed. This allows you to look up your own unfunded offers in order to cancel them with an OfferCancel transaction. +Normally, offers that are not funded are omitted; however, offers made by the specified `taker` account are always displayed. This allows you to look up your own unfunded offers to cancel them with an OfferCancel transaction. #### Response Format #### @@ -7461,7 +7463,7 @@ In addition to the standard Offer fields, the following fields may be included i # Subscriptions # -Using subscriptions, you can have the server push updates to your client when various events happen, so that you can know right away and react accordingly. Subscriptions are only supported in the WebSocket API, where you can receive additional responses in the same channel. +Using subscriptions, you can have the server push updates to your client when various events happen, so that you can know and react right away. Subscriptions are only supported in the WebSocket API, where you can receive additional responses in the same channel. JSON-RPC support for subscription callbacks is deprecated and may not work as expected. @@ -7528,7 +7530,7 @@ The request includes the following parameters: | accounts | Array | (Optional) Array with the unique base-58 addresses of accounts to monitor for validated transactions. The server sends a notification for any transaction that affects at least one of these accounts. | | accounts_proposed | Array | (Optional) Like `accounts`, but include transactions that are not yet finalized. | | books | Array | (Optional) Array of objects defining [order books](http://www.investopedia.com/terms/o/order-book.asp) to monitor for updates, as detailed below. | -| url | String | (Optional for Websocket; Required otherwise) URL where the server will send a JSON-RPC callback with each event. *Admin-only.* | +| url | String | (Optional for Websocket; Required otherwise) URL where the server sends a JSON-RPC callbacks for each event. *Admin-only.* | | url\_username | String | (Optional) Username to provide for basic authentication at the callback URL. | | url\_password | String | (Optional) Password to provide for basic authentication at the callback URL. | @@ -7588,14 +7590,14 @@ The response follows the [standard format](#response-formatting). The fields con * `noPermission` - The request included the `url` field, but you are not connected as an admin. * `unknownStream` - One or more the members of the `streams` field in the request was not recognized as a valid stream name. * `malformedStream` - The `streams` field of the request was not formatted properly. -* `malformedAccount` - One of the addresses in the `accounts` or `accounts_proposed` fields of the request is not a properly-formatted Ripple address. (**Note:**: You _can_ subscribe to the stream of an address that does not yet have an entry in the global ledger; if your subscription is still active, you will get a message when that account receives the payment that creates it.) +* `malformedAccount` - One of the addresses in the `accounts` or `accounts_proposed` fields of the request is not a properly-formatted Ripple address. (**Note:**: You _can_ subscribe to the stream of an address that does not yet have an entry in the global ledger to get a message when that address becomes funded.) * `srcCurMalformed` - One or more `taker_pays` sub-fields of the `books` field in the request is not formatted properly. * `dstAmtMalformed` - One or more `taker_gets` sub-fields of the `books` field in the request is not formatted properly. * `srcIsrMalformed` - The `issuer` field of one or more `taker_pays` sub-fields of the `books` field in the request is not valid. * `dstIsrMalformed` - The `issuer` field of one or more `taker_gets` sub-fields of the `books` field in the request is not valid. * `badMarket` - One or more desired order books in the `books` field does not exist; for example, offers to exchange a currency for itself. -When you subscribe to a particular stream, you will receive periodic responses on that stream until you unsubscribe or close the WebSocket connection. The content of those responses depends on what you subscribed to. Here are some examples: +When you subscribe to a particular stream, you receive periodic responses on that stream until you unsubscribe or close the WebSocket connection. The content of those responses depends on what you subscribed to. Here are some examples: ### Ledger Stream ### @@ -7676,7 +7678,7 @@ The `transactions_proposed` stream, strictly speaking, is a superset of the `tra * There is no `meta` or `metadata` field. * Instead of `ledger_hash` and `ledger_index` fields specifying in which ledger version the transactions were finalized, there is a `ledger_current_index` field specifying in which ledger version they are currently proposed. -Otherwise, the messages from the `transactions_proposed` stream are identical to ones from the `transactions` stream. +Otherwise, the messages from the `transactions_proposed` stream are the same as ones from the `transactions` stream. Since the only thing that can modify an account or an order book is a transaction, the messages that are sent as a result of subscribing to particular `accounts` or `books` also take the form of transaction messages, the same as the ones in the `transactions` stream. The only difference is that you only receive messages for transactions that affect the accounts or order books you're watching. @@ -7800,7 +7802,7 @@ Transaction stream messages have the following fields: ### Peer Status Stream ### -The admin-only `peer_status` stream reports a large amount of information regarding the activities of other `rippled` servers to which this server is connected, in particular regarding their status in the consensus process. +The admin-only `peer_status` stream reports a large amount of information on the activities of other `rippled` servers to which this server is connected, in particular their status in the consensus process. Example of a Peer Status stream message: @@ -7837,7 +7839,7 @@ The `action` field of a Peer Status stream message can have the following values | CLOSING\_LEDGER | The peer closed a ledger version with this [Ledger Index][], which usually means it is about to start consensus. | | ACCEPTED\_LEDGER | The peer built this ledger version as the result of a consensus round. **Note:** This ledger is still not certain to become immutably validated. | | SWITCHED\_LEDGER | The peer concluded it was not following the rest of the network and switched to a different ledger version. | -| LOST\_SYNC | The peer fell behind the rest of the network state regarding which ledger versions are validated and which are undergoing consensus. | +| LOST\_SYNC | The peer fell behind the rest of the network in tracking which ledger versions are validated and which are undergoing consensus. | ### Order Book Streams ### @@ -8031,8 +8033,8 @@ The objects in the `books` array are defined almost like the ones from subscribe | Field | Type | Description | |-------|------|-------------| -| taker_gets | Object | Specification of which currency the account taking the offer would receive, as an object with `currency` and `issuer` fields (omit issuer for XRP), similar to [currency amounts](#specifying-currency-amounts). | -| taker_pays | Object | Specification of which currency the account taking the offer would pay, as an object with `currency` and `issuer` fields (omit issuer for XRP), similar to [currency amounts](#specifying-currency-amounts). | +| taker_gets | Object | Specification of which currency the account taking the offer would receive, as an object with `currency` and `issuer` fields (omit issuer for XRP), like [currency amounts](#specifying-currency-amounts). | +| taker_pays | Object | Specification of which currency the account taking the offer would pay, as an object with `currency` and `issuer` fields (omit issuer for XRP), like [currency amounts](#specifying-currency-amounts). | | both | Boolean | (Optional, defaults to false) If true, remove a subscription for both sides of the order book. | #### Response Format #### @@ -8062,7 +8064,8 @@ The response follows the [standard format](#response-formatting), with a success * `invalidParams` - One or more fields are specified incorrectly, or one or more required fields are missing. * `noPermission` - The request included the `url` field, but you are not connected as an admin. * `malformedStream` - The `streams` field of the request was not formatted properly. -* `malformedAccount` - One of the addresses in the `accounts` or `accounts_proposed` fields of the request is not a properly-formatted Ripple address. (**Note:**: You _can_ subscribe to the stream of an address that does not yet have an entry in the global ledger; if your subscription is still active, you will get a message when that account receives the payment that creates it.) +* `malformedAccount` - One of the addresses in the `accounts` or `accounts_proposed` fields of the request is not a properly-formatted Ripple address. + * **Note:**: You _can_ subscribe to the stream of an address that does not yet have an entry in the global ledger to get a message when that address becomes funded. * `srcCurMalformed` - One or more `taker_pays` sub-fields of the `books` field in the request is not formatted properly. * `dstAmtMalformed` - One or more `taker_gets` sub-fields of the `books` field in the request is not formatted properly. * `srcIsrMalformed` - The `issuer` field of one or more `taker_pays` sub-fields of the `books` field in the request is not valid. @@ -8330,14 +8333,14 @@ The `info` object may have some arrangement of the following fields: | build_version | String | The version number of the running `rippled` version. | | complete_ledgers | String | Range expression indicating the sequence numbers of the ledger versions the local rippled has in its database. It is possible to be a disjoint sequence, e.g. "2500-5000,32570-7695432". | | hostid | String | On an admin request, returns the hostname of the server running the `rippled` instance; otherwise, returns a unique four letter word. | -| io\_latency\_ms | Number | Amount of time spent waiting for I/O operations to be performed, in milliseconds. If this number is not very, very low, then the `rippled` server is probably having serious load issues. | +| io\_latency\_ms | Number | Amount of time spent waiting for I/O operations, in milliseconds. If this number is not very, very low, then the `rippled` server is probably having serious load issues. | | last_close | Object | Information about the last time the server closed a ledger, including the amount of time it took to reach a consensus and the number of trusted validators participating. | | load | Object | *Admin only* Detailed information about the current load state of the server | -| load.job\_types | Array | *Admin only* Information about the rate of different types of jobs being performed by the server and how much time it spends on each. | -| load.threads | Number | *Admin only* The number of threads in the server's main job pool, performing various Ripple Network operations. | +| load.job\_types | Array | *Admin only* Information about the rate of different types of jobs the server is doing and how much time it spends on each. | +| load.threads | Number | *Admin only* The number of threads in the server's main job pool. | | load\_factor | Number | The load factor the server is currently enforcing, as a multiplier on the base transaction cost. The load factor is determined by the highest of the individual server's load factor, cluster's load factor, and the overall network's load factor. **Note:** This `load_factor` is calculated as the ratio of the `load_factor` and the `load_base` that are reported by the [`server_state` command](#server-state) | | peers | Number | How many other `rippled` servers the node is currently connected to. | -| pubkey_node | String | Public key used to verify this node for internal communications; this key is automatically generated by the server the first time it starts up. (If deleted, the node can just create a new pair of keys.) | +| pubkey_node | String | Public key used to verify this node for internal communications; this key is automatically generated by the server the first time it starts up. (If deleted, the node can create a new pair of keys.) | | pubkey\_validator | String | *Admin only* Public key used by this node to sign ledger validations. | | server\_state | String | A string indicating to what extent the server is participating in the network. See [Possible Server States](#possible-server-states) for more details. | | state\_accounting | Object | A map of various [server states](#possible-server-states) with information about the time the server spends in each. This can be useful for tracking the long-term health of your server's connectivity to the network. _(New in [version 0.30.1][])_ | @@ -8349,9 +8352,9 @@ The `info` object may have some arrangement of the following fields: | validated\_ledger.base\_fee\_xrp | Number | Base fee, in XRP. This may be represented in scientific notation such as 1e-05 for 0.00005 | | validated\_ledger.hash | String | Unique hash for the ledger, as hex | | validated\_ledger.reserve\_base\_xrp | Unsigned Integer | Minimum amount of XRP (not drops) necessary for every account to keep in reserve | -| validated\_ledger.reserve\_inc\_xrp | Unsigned Integer | Amount of XRP (not drops) added to the account reserve for each object an account is responsible for in the ledger | +| validated\_ledger.reserve\_inc\_xrp | Unsigned Integer | Amount of XRP (not drops) added to the account reserve for each object an account owns in the ledger | | validated\_ledger.seq | Number - [Ledger Index][] | The ledger index of the latest validate ledger | -| validation\_quorum | Number | Minimum number of trusted validations required in order to validate a ledger version. Some circumstances may cause the server to require more validations. | +| validation\_quorum | Number | Minimum number of trusted validations required to validate a ledger version. Some circumstances may cause the server to require more validations. | #### Possible Errors #### @@ -8362,7 +8365,7 @@ The `info` object may have some arrangement of the following fields: ## server_state ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/ServerState.cpp "Source") -The `server_state` command asks the server for various machine-readable information about the `rippled` server's current state. The results are very similar to [`server_info`](#server-info), but generally the units are chosen to be easier to process instead of easier to read. (For example, XRP values are given in integer drops instead of scientific notation or decimal values, and time is given in milliseconds instead of seconds.) +The `server_state` command asks the server for various machine-readable information about the `rippled` server's current state. The results are almost the same as [`server_info`](#server-info), but using units that are easier to process instead of easier to read. (For example, XRP values are given in integer drops instead of scientific notation or decimal values, and time is given in milliseconds instead of seconds.) #### Request Format #### An example of the request format: @@ -8611,10 +8614,10 @@ The `state` object may have some arrangement of the following fields: |-------|------|-------------| | build_version | String | The version number of the running `rippled` version. | | complete\_ledgers | String | Range expression indicating the sequence numbers of the ledger versions the local rippled has in its database. It is possible to be a disjoint sequence, e.g. "2500-5000,32570-7695432". | -| io\_latency\_ms | Number | Amount of time spent waiting for I/O operations to be performed, in milliseconds. If this number is not very, very low, then the `rippled` server is probably having serious load issues. | +| io\_latency\_ms | Number | Amount of time spent waiting for I/O operations, in milliseconds. If this number is not very, very low, then the `rippled` server is probably having serious load issues. | | load | Object | *Admin only* Detailed information about the current load state of the server | -| load.job\_types | Array | *Admin only* Information about the rate of different types of jobs being performed by the server and how much time it spends on each. | -| load.threads | Number | *Admin only* The number of threads in the server's main job pool, performing various Ripple Network operations. | +| load.job\_types | Array | *Admin only* Information about the rate of different types of jobs the server is doing and how much time it spends on each. | +| load.threads | Number | *Admin only* The number of threads in the server's main job pool. | | load\_base | Number | This amount of server load is the baseline that is used to decide how much to charge in transaction fees; if the `load_factor` is equal to the `load_base` then only the base fee is enforced; if the `load_factor` is double the `load_base` then transaction fees are doubled. | | load\_factor | Number | The load factor the server is currently enforcing. The ratio between this value and the load\_base determines the multiplier for transaction fees. The load factor is determined by the highest of the individual server's load factor, cluster's load factor, and the overall network's load factor. | | peers | Number | How many other `rippled` servers the node is currently connected to. | @@ -8632,7 +8635,7 @@ The `state` object may have some arrangement of the following fields: | validated\_ledger.reserve\_base | Unsigned Integer | Minimum amount, in drops of XRP, necessary for every account to keep in reserve | | validated\_ledger.reserve\_inc | Unsigned Integer | Amount, in drops of XRP, that is added to the account reserve for each item the account owns in the ledger. | | validated\_ledger.seq | Unsigned Integer | Unique sequence number of this ledger -| validation\_quorum | Number | Minimum number of trusted validations required in order to validate a ledger version. Some circumstances may cause the server to require more validations. | +| validation\_quorum | Number | Minimum number of trusted validations required to validate a ledger version. Some circumstances may cause the server to require more validations. | #### Possible Errors #### @@ -8688,7 +8691,7 @@ The request includes the following optional parameter: | Field | Type | Description | |-------|------|-------------| -| can\_delete | String or Integer | The maximum ledger to allow to be deleted. For `ledger_index` or `ledger_hash`, see [Specifying a Ledger](#specifying-ledgers). `never` sets the value to 0, and effectively disables online deletion until another `can_delete` is appropriately called. `always` sets the value to the maximum possible ledger (4294967295), and online deletion will occur as of each configured `online_delete` interval. `now` triggers online deletion at the next validated ledger that meets or exceeds the configured `online_delete` interval, but no further. | +| can\_delete | String or Integer | The maximum ledger to allow to be deleted. For `ledger_index` or `ledger_hash`, see [Specifying a Ledger](#specifying-ledgers). `never` sets the value to 0, and effectively disables online deletion until another `can_delete` is appropriately called. `always` sets the value to the maximum possible ledger (4294967295), and online deletion occurs as of each configured `online_delete` interval. `now` triggers online deletion at the next validated ledger that meets or exceeds the configured `online_delete` interval, but no further. | If no parameter is specified, no change is made. @@ -8929,7 +8932,7 @@ The following is an incomplete summary of fields that may be contained in the `i | peer\_positions | Object | Map of peers and their proposed versions of the ledger in the consensus process. | | proposers | Number | The number of trusted validators participating in this consensus process. Which validators are trusted depends on this server's configuration. | | synched | Boolean | Whether this server considers itself in sync with the network. | -| state | String | What portion of the consensus process is currently in progress: `open`, `consensus`, `finished`, or `accepted`. | +| state | String | What part of the consensus process is currently in progress: `open`, `consensus`, `finished`, or `accepted`. | It is also normal to get a minimal result where the only field in `info` is `"consensus": "none"`. This indicates that the server is in between consensus rounds. @@ -9809,7 +9812,7 @@ Otherwise, the request contains the following field: ## logrotate ## [[Source]
    ](https://github.com/ripple/rippled/blob/743bd6c9175c472814448ea889413be79dfd1c07/src/ripple/rpc/handlers/LogRotate.cpp "Source") -The `logrotate` command closes and reopens the log file. This is intended to facilitate log rotation on Linux file systems. +The `logrotate` command closes and reopens the log file. This is intended to help with log rotation on Linux file systems. _The `logrotate` method is an [admin command](#connecting-to-rippled) that cannot be run by unpriviledged users._ @@ -10475,7 +10478,7 @@ Each member of the `peers` array is a peer object with the following fields: | load | Number | A measure of the amount of load the peer server is putting on the local server. Larger numbers indicate more load. (The units by which load is measured are not formally defined.) | | protocol | String | (May be omitted) The protocol version that the peer is using, if not the same as the local server. | | public\_key | String | (May be omitted) A public key that can be used to verify the integrity of the peer's messages. This is not the same key that is used for validations, but it follows the same format. | -| sanity | String | (May be omitted) Whether this peer is following the same rules and ledger sequence as the current server. A value of `insane` probably indicates that the peer is part of a parallel network. The value `unknown` indicates that the current server is unsure whether the peer is compatible. | +| sanity | String | (May be omitted) Whether this peer is following the same rules and ledger sequence as the current server. A value of `insane` probably indicates that the peer is part of a parallel network. The value `unknown` indicates that the current server is unsure whether the peer is compatible. | | status | String | (May be omitted) The most recent status message from the peer. Could be `connecting`, `connected`, `monitoring`, `validating`, or `shutting`. | | uptime | Number | The number of seconds that your `rippled` server has been continuously connected to this peer. _(New in [version 0.30.1][])_ | | version | string | (May be omitted) The `rippled` version number of the peer server | @@ -10721,7 +10724,7 @@ The response follows the [standard format](#response-formatting). Additional fie # Convenience Functions # -The rippled server also provides a few simple commands purely for convenience. +The rippled server also provides a few commands purely for convenience. ## ping ## [[Source]
    ](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/Ping.cpp "Source") diff --git a/content/reference-transaction-format.md b/content/reference-transaction-format.md index 285c86d2a5..0ab64a6a14 100644 --- a/content/reference-transaction-format.md +++ b/content/reference-transaction-format.md @@ -4,7 +4,7 @@ A *Transaction* is the only way to modify the Ripple Ledger. All transactions ha * [Common Fields](#common-fields) -There are several different types of transactions that perform different actions, each with additional fields relevant to that type of action: +There are several different types of transactions that do different actions, each with additional fields relevant to that type of action: * [Payment - Send funds from one account to another](#payment) * [AccountSet - Set options on an account](#accountset) @@ -28,7 +28,7 @@ Transactions are only valid if signed, submitted, and accepted into a validated ## Authorizing Transactions ## -In the decentralized Ripple Consensus Ledger, a digital signature proves that a transaction is authorized to perform a specific set of actions. Only signed transactions can be submitted to the network and included in a validated ledger. A signed transaction is immutable: its contents cannot change, and the signature is not valid for any other transaction. +In the decentralized Ripple Consensus Ledger, a digital signature proves that a transaction is authorized to do a specific set of actions. Only signed transactions can be submitted to the network and included in a validated ledger. A signed transaction is immutable: its contents cannot change, and the signature is not valid for any other transaction. A transaction can be authorized by any of the following types of signatures: @@ -76,7 +76,7 @@ Here is an example of an unsigned [Payment-type transaction](#payment) in JSON: The Ripple Consensus Ledger only relays and executes a transaction if the transaction object has been authorized by the sending address (in the `Account`) field. For transactions authorized by only a single signature, you have two options: 1. Convert it to a binary blob and sign it offline. This is preferable, since it means that the account secret used for signing the transaction is never transmitted over any network connection. - * You can use [RippleAPI](reference-rippleapi.html#sign) to perform offline signing. + * You can use [RippleAPI](reference-rippleapi.html#sign) for offline signing. 2. Have a `rippled` server sign the transaction for you. The [sign command](reference-rippled.html#sign) takes a JSON-format transaction and secret and returns the signed binary transaction format ready for submission. (Transmitting your account secret is dangerous, so you should only do this from within a trusted and encrypted connection, or through a local connection, and only to a server you control.) * As a shortcut, you can use the [submit command](reference-rippled.html#submit) with a `tx_json` object to sign and submit a transaction all at once. This is only recommended for testing and development purposes. @@ -209,12 +209,12 @@ For more information, see [How to Multi-Sign](tutorial-multisign.html). Reliably submitting transactions is the process of achieving both of the following: -* Idempotency - A transaction will be processed once and only once, or not at all. +* Idempotency - A transaction should be processed once and only once, or not at all. * Verifiability - Applications can determine the final result of a transaction. -To accomplish both of these, your application should: +To have both qualities when submitting a transaction, an application should: -1. Construct and sign the transaction first, including a [`LastLedgerSequence`](#lastledgersequence) parameter that gives the transaction a limited viable lifespan. +1. Construct and sign the transaction first, including a [`LastLedgerSequence`](#lastledgersequence) parameter that gives the transaction a limited lifespan. 2. Persist details of the transaction before submitting. 3. Submit the transaction. 4. Confirm that the transaction was either included in a validated ledger, or that it has expired due to `LastLedgerSequence`. @@ -226,7 +226,7 @@ Main article: [Reliable Transaction Submission](tutorial-reliable-transaction-su The `"hash"` is the unique value that identifies a particular transaction. The server provides the hash in the response when you submit the transaction; you can also look up a transaction in an account's transaction history with the [account_tx command](reference-rippled.html#account-tx). -The transaction hash can be used as a "proof of payment" since anyone can [look up the transaction by its hash](#looking-up-transaction-results) in order to verify its final status. +The transaction hash can be used as a "proof of payment" since anyone can [look up the transaction by its hash](#looking-up-transaction-results) to verify its final status. ## Common Fields ## @@ -243,7 +243,7 @@ Every transaction type has the same set of fundamental fields: | [Sequence](#canceling-or-skipping-a-transaction) | Unsigned Integer | UInt32 | (Required, but [auto-fillable](#auto-fillable-fields)) The sequence number, relative to the initiating account, of this transaction. A transaction is only valid if the `Sequence` number is exactly 1 greater than the last-valided transaction from the same account. | | SigningPubKey | String | PubKey | (Automatically added when signing) Hex representation of the public key that corresponds to the private key used to sign this transaction. If an empty string, indicates a multi-signature is present in the `Signers` field instead. | | [Signers](#signers-field) | Array | Array | (Optional) Array of objects that represent a [multi-signature](#multi-signing) which authorizes this transaction. | -| SourceTag | Unsigned Integer | UInt32 | (Optional) Arbitrary integer used to identify the reason for this payment, or the hosted wallet on whose behalf this transaction is made. Conventionally, a refund should specify the initial payment's `SourceTag` as the refund payment's `DestinationTag`. | +| SourceTag | Unsigned Integer | UInt32 | (Optional) Arbitrary integer used to identify the reason for this payment, or a sender on whose behalf this transaction is made. Conventionally, a refund should specify the initial payment's `SourceTag` as the refund payment's `DestinationTag`. | | TransactionType | String | UInt16 | The type of transaction. Valid types include: `Payment`, `OfferCreate`, `OfferCancel`, `TrustSet`, `AccountSet`, `SetRegularKey`, and `SignerListSet`. | | TxnSignature | String | VariableLength | (Automatically added when signing) The signature that verifies this transaction as originating from the account it says it is from. | @@ -265,7 +265,7 @@ The [`Paths` field](#paths) of the [Payment](#payment) transaction type can also ### Transaction Cost ### -In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This _[transaction cost](concept-transaction-cost.html)_ is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network. +To protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This _[transaction cost](concept-transaction-cost.html)_ is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network. The `Fee` field specifies an amount, in [drops of XRP](reference-rippled.html#specifying-currency-amounts), to destroy as the cost for relaying this transaction. If the transaction is included in a validated ledger (whether or not it achieves its intended purpose), then the amount of XRP specified in the `Fee` parameter is destroyed forever. You can [look up the transaction cost](concept-transaction-cost.html#querying-the-transaction-cost) in advance, or [let `rippled` set it automatically](concept-transaction-cost.html#automatically-specifying-the-transaction-cost) when you sign a transaction. @@ -276,9 +276,9 @@ The `Fee` field specifies an amount, in [drops of XRP](reference-rippled.html#sp An important and intentional feature of the Ripple Network is that a transaction is final as soon as it has been incorporated in a validated ledger. -However, if a transaction has not yet been included in a validated ledger, you can effectively cancel it by rendering it invalid. Typically, this means sending another transaction with the same `Sequence` value from the same account. If you do not want to perform the same transaction again, you can perform an [AccountSet](#accountset) transaction with no options. +However, if a transaction has not yet been included in a validated ledger, you can effectively cancel it by rendering it invalid. Typically, this means sending another transaction with the same `Sequence` value from the same account. If you do not want the replacement transaction to do anything, send an [AccountSet](#accountset) transaction with no options. -For example, if you attempted to submit 3 transactions with sequence numbers 11, 12, and 13, but transaction 11 gets lost somehow or does not have a high enough [transaction cost](#transaction-cost) to be propagated to the network, then you can cancel transaction 11 by submitting an AccountSet transaction with no options and sequence number 11. This does nothing (except destroying the transaction cost for the new transaction 11), but it allows transactions 12 and 13 to become valid. +For example, if you try to submit 3 transactions with sequence numbers 11, 12, and 13, but transaction 11 gets lost somehow or does not have a high enough [transaction cost](#transaction-cost) to be propagated to the network, then you can cancel transaction 11 by submitting an AccountSet transaction with no options and sequence number 11. This does nothing (except destroying the transaction cost for the new transaction 11), but it allows transactions 12 and 13 to become valid. This approach is preferable to renumbering and resubmitting transactions 12 and 13, because it prevents transactions from being effectively duplicated under different sequence numbers. @@ -288,19 +288,19 @@ In this way, an AccountSet transaction with no options is the canonical "[no-op] We strongly recommend that you specify the `LastLedgerSequence` parameter on every transaction. Provide a value of about 3 higher than [the most recent ledger index](reference-rippled.html#ledger) to ensure that your transaction is either validated or rejected within a matter of seconds. -Without the `LastLedgerSequence` parameter, there is a particular situation that can occur and cause your transaction to be stuck in an undesirable state where it is neither validated nor rejected for a long time. Specifically, if the load-based [transaction cost](#transaction-cost) of the network increases after you send a transaction, your transaction may not get propagated enough to be included in a validated ledger, but you would have to pay the (increased) transaction cost in order to send another transaction canceling it. Later, if the transaction cost decreases again, the transaction may become viable again. The `LastLedgerSequence` places a hard upper limit on how long the transaction can wait to be validated or rejected. +Without the `LastLedgerSequence` parameter, a transaction can become stuck in an undesirable state where it is neither validated nor rejected for a long time. Specifically, if the load-based [transaction cost](#transaction-cost) of the network increases after you send a transaction, your transaction may not get propagated enough to be included in a validated ledger, but you would have to pay the (increased) transaction cost to [send another transaction canceling it](#canceling-or-skipping-a-transaction). Later, if the transaction cost decreases again, the transaction can become included in a future ledger. The `LastLedgerSequence` places a hard upper limit on how long the transaction can wait to be validated or rejected. ### AccountTxnID ### The `AccountTxnID` field lets you chain your transactions together, so that a current transaction is not valid unless the previous one (by Sequence Number) is also valid and matches the transaction you expected. -One situation in which this is useful is if you have a primary system for submitting transactions and a passive backup system. If the passive backup system becomes disconnected from the primary, but the primary is not fully dead, and they both begin operating at the same time, you could potentially encounter serious problems like some transactions sending twice and others not at all. Chaining your transactions together with `AccountTxnID` ensures that, even if both systems are active, only one of them can submit valid transactions at a time. +One situation in which this is useful is if you have a primary system for submitting transactions and a passive backup system. If the passive backup system becomes disconnected from the primary, but the primary is not fully dead, and they both begin operating at the same time, you could potentially have serious problems like some transactions sending twice and others not at all. Chaining your transactions together with `AccountTxnID` ensures that, even if both systems are active, only one of them can submit valid transactions at a time. -In order to use AccountTxnID, you must first set the [asfAccountTxnID](#accountset-flags) flag, so that the ledger keeps track of the ID for the account's previous transaction. +To use AccountTxnID, you must first set the [asfAccountTxnID](#accountset-flags) flag, so that the ledger keeps track of the ID for the account's previous transaction. ### Memos ### -The `Memos` field allows for arbitrary messaging data that can accompany the transaction. It is presented as an array of objects. Each object has only one field, `Memo`, which in turn contains another object with *one or more* of the following fields: +The `Memos` field includes arbitrary messaging data with the transaction. It is presented as an array of objects. Each object has only one field, `Memo`, which in turn contains another object with *one or more* of the following fields: | Field | Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description | |-------|------|--------------------------------------------------------|-------------| @@ -310,7 +310,7 @@ The `Memos` field allows for arbitrary messaging data that can accompany the tra The MemoType and MemoFormat fields should only consist of the following characters: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=%` -The `Memos` field is currently limited to no more than 1KB in size (when serialized in binary format). +The `Memos` field is limited to no more than 1KB in size (when serialized in binary format). Example of a transaction with a Memos field: @@ -349,7 +349,7 @@ Because signature verification is a compute-intensive task, multi-signed transac ### Flags ### -The `Flags` field allows for additional boolean options regarding the behavior of a transaction. They are represented as binary values that can be combined with bitwise-or operations to set multiple flags at once. +The `Flags` field can contain various options that affect how a transaction should behave. The options are represented as binary values that can be combined with bitwise-or operations to set multiple flags at once. Most flags only have meaning for a specific transaction type. The same bitwise value may be reused for flags on different transaction types, so it is important to pay attention to the `TransactionType` field when setting and reading flags. @@ -364,7 +364,7 @@ The only flag that applies globally to all transactions is as follows: ## Payment ## [[Source]
    ](https://github.com/ripple/rippled/blob/5425a90f160711e46b2c1f1c93d68e5941e4bfb6/src/ripple/app/transactors/Payment.cpp "Source") -A Payment transaction represents a transfer of value from one account to another. (Depending on the path taken, additional exchanges of value may occur atomically to facilitate the payment.) +A Payment transaction represents a transfer of value from one account to another. (Depending on the path taken, this can involve additional exchanges of value, which occur atomically.) Payments are also the only way to [create accounts](#creating-accounts). @@ -390,7 +390,7 @@ Example payment: |-------|-----------|--------------------------------------------------------|-------------| | Amount | String (XRP)
    Object (Otherwise) | Amount | The amount of currency to deliver. *Note:* If the [*tfPartialPayment* flag](#payment-flags) is set, this is not the amount actually received. (Formatted as per [Specifying Currency Amounts](reference-rippled.html#specifying-currency-amounts).) | | Destination | String | Account | The unique address of the account receiving the payment. | -| DestinationTag | Unsigned Integer | UInt32 | (Optional) Arbitrary tag that identifies the reason for the payment to the destination, or the hosted wallet to make a payment to. | +| DestinationTag | Unsigned Integer | UInt32 | (Optional) Arbitrary tag that identifies the reason for the payment to the destination, or a hosted recipient to pay. | | InvoiceID | String | Hash256 | (Optional) Arbitrary 256-bit hash representing a specific reason or identifier for this payment. | | Paths | Array of path arrays | PathSet | (Optional, auto-fillable) Array of [payment paths](https://ripple.com/wiki/Payment_paths) to be used for this transaction. Must be omitted for XRP-to-XRP transactions. | | SendMax | String/Object | Amount | (Optional) Highest amount of source currency this transaction is allowed to cost, including [transfer fees](concept-transfer-fees.html), exchange rates, and [slippage](http://en.wikipedia.org/wiki/Slippage_%28finance%29). Does not include the [XRP destroyed as a cost for submitting the transaction](#transaction-cost). (Also see [Specifying Currency Amounts](reference-rippled.html#specifying-currency-amounts)) Must be supplied for cross-currency/cross-issue payments. Must be omitted for XRP-to-XRP payments. | @@ -398,28 +398,28 @@ Example payment: ### Special issuer Values for SendMax and Amount ### -Most of the time, the `issuer` field of a non-XRP [currency amount](reference-rippled.html#specifying-currency-amounts) indicates the account of the gateway that issues that currency. However, when describing payments, there are special rules for the `issuer` field in the `Amount` and `SendMax` fields of a payment. +Most of the time, the `issuer` field of a non-XRP [currency amount](reference-rippled.html#specifying-currency-amounts) indicates a financial institution's [issuing address](concept-issuing-and-operational-addresses.html). However, when describing payments, there are special rules for the `issuer` field in the `Amount` and `SendMax` fields of a payment. -* There is only ever one balance for the same currency between two accounts. This means that, sometimes, the `issuer` field of an amount actually refers to a counterparty that is redeeming issuances, instead of the account that created the issuances. -* When the `issuer` field of the destination `Amount` field matches the `Destination` account address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all accounts to which the destination has extended trust lines, as well as issuances created by the destination which may be held on other trust lines. -* When the `issuer` field of the `SendMax` field matches the source account's address, it is treated as a special case meaning "any issuer that the source can use." This includes creating new issuances on trust lines that other accounts have extended to the source account, as well as issuances from other accounts that the source account possesses. +* There is only ever one balance for the same currency between two addresses. This means that, sometimes, the `issuer` field of an amount actually refers to a counterparty that is redeeming issuances, instead of the address that created the issuances. +* When the `issuer` field of the destination `Amount` field matches the `Destination` address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all addresses to which the destination has extended trust lines, as well as issuances created by the destination which are held on other trust lines. +* When the `issuer` field of the `SendMax` field matches the source account's address, it is treated as a special case meaning "any issuer that the source can use." This includes creating new issuances on trust lines that other accounts have extended to the source account, and sending issuances the source account holds from other issuers. ### Creating Accounts ### -The Payment transaction type is the only way to create new accounts in the shared Ripple ledger. To do so, send an amount of XRP that is equal or greater than the [account reserve](concept-reserves.html) to a mathematically-valid account address that does not exist yet. When the payment is processed, a new [AccountRoot node](reference-ledger-format.html#accountroot) will be added to the ledger to reflect the newly-created account. +The Payment transaction type is the only way to create new accounts in the Ripple Consensus Ledger. To do so, send an amount of XRP that is equal or greater than the [account reserve](concept-reserves.html) to a mathematically-valid account address that does not exist yet. When the Payment is processed, a new [AccountRoot node](reference-ledger-format.html#accountroot) is added to the ledger. -If you attempt to send an insufficient amount of XRP, or any other currency, the Payment will fail. +If you send an insufficient amount of XRP, or any other currency, the Payment fails. ### Paths ### -If present, the `Paths` field must contain a _path set_ - an array of path arrays. Each individual path represents one way value can flow from the sender to receiver through various intermediary accounts and order books. A single transaction can potentially use multiple paths, for example if the transaction exchanges currency using several different order books in order to achieve the best rate. +If present, the `Paths` field must contain a _path set_ - an array of path arrays. Each individual path represents one way value can flow from the sender to receiver through various intermediary accounts and order books. A single transaction can potentially use multiple paths, for example if the transaction exchanges currency using several different order books to achieve the best rate. You must omit the `Paths` field for direct payments, including: * An XRP-to-XRP transfer. -* A simple transfer on a trust line that connects the sender and receiver. +* A direct transfer on a trust line that connects the sender and receiver. -If the `Paths` field is provided, the server decides at transaction processing time which paths to use, from the provided set plus a _default path_ (the simplest possible way to connect the specified accounts). This decision is deterministic and attempts to minimize costs, but it is not guaranteed to be perfect. +If the `Paths` field is provided, the server decides at transaction processing time which paths to use, from the provided set plus a _default path_ (the most direct way possible to connect the specified accounts). This decision is deterministic and attempts to minimize costs, but it is not guaranteed to be perfect. The `Paths` field must not be an empty array, nor an array whose members are all empty arrays. @@ -441,11 +441,11 @@ Transactions of the Payment type support additional values in the [`Flags` field A partial payment allows a payment to succeed by reducing the amount received, instead of increasing the `SendMax`. Partial payments are useful for [returning payments](https://wiki.ripple.com/Returning_payments) without incurring additional costs to oneself. -By default, the `Amount` field of a Payment transaction specifies the amount of currency that is *received* by the account that is the destination of the payment. Any additional amount needed for fees or currency exchange is deducted from the sending account's balances, up to the `SendMax` amount. (If `SendMax` is not specified, that is equivalent to setting the `SendMax` to the `Amount` field.) If the amount needed in order to make the payment exceeds the `SendMax` parameter, or the full amount cannot be delivered for any other reason, the transaction fails. +By default, the `Amount` field of a Payment transaction specifies the amount of currency that is *received* by the account that is the destination of the payment. Any additional amount needed for fees or currency exchange is deducted from the sending account's balances, up to the `SendMax` amount. (If `SendMax` is not specified, that is equivalent to setting the `SendMax` to the `Amount` field.) If the amount needed to make the payment exceeds the `SendMax` parameter, or the full amount cannot be delivered for any other reason, the transaction fails. The [*tfPartialPayment* flag](#payment-flags) allows you to make a "partial payment" instead. When this flag is enabled for a payment, it delivers as much as possible, up to the `Amount` value, without exceeding the `SendMax` value. Fees and currency exchange rates are calculated the same way, but the amount being sent automatically scales down until the total amount deducted from the sending account's balances is within `SendMax`. The transaction is considered successful as long as it delivers equal or more than the `DeliverMin` value; if DeliverMin is omitted, then any positive amount is considered a success. This means that partial payments can succeed at sending *some* of the intended value despite limitations including fees, lack of liquidity, insufficient space in the receiving account's trustlines, or other reasons. -A partial payment cannot provide the initial XRP to fund an account; this case returns the error code `telNO_DST_PARTIAL`. Direct XRP-to-XRP payments also cannot be partial payments `temBAD_SEND_XRP_PARTIAL`. +A partial payment cannot provide the XRP to fund an address; this case returns the error code `telNO_DST_PARTIAL`. Direct XRP-to-XRP payments also cannot be partial payments `temBAD_SEND_XRP_PARTIAL`. The amount of XRP used for the [transaction cost](#transaction-cost) is always deducted from the sender’s account, regardless of the *tfPartialPayment* flag. @@ -458,11 +458,11 @@ When the [*tfPartialPayment* flag](#payment-flags) is enabled, the `Amount` fiel Ripple defines the "quality" of a currency exchange as the ratio of the numeric amount in to the numeric amount out. For example, if you spend $2 USD to receive £1 GBP, then the "quality" of that exchange is `0.5`. -The [*tfLimitQuality* flag](#payment-flags) allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination `Amount` divided by the `SendMax` amount (just the numeric amounts, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality. +The [*tfLimitQuality* flag](#payment-flags) allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination `Amount` divided by the `SendMax` amount (the numeric amounts only, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality. By itself, the tfLimitQuality flag reduces the number of situations in which a transaction can succeed. Specifically, it rejects payments where some part of the payment uses an unfavorable conversion, even if the overall average *average* quality of conversions in the payment is equal or better than the limit quality. If a payment is rejected in this way, the [transaction result](#transaction-results) is `tecPATH_DRY`. -Consider the following example. If I am trying to send you 100 Chinese Yuan (`Amount` = 100 CNY) for 20 United States dollars (`SendMax` = 20 USD) or less, then the limit quality is `5`. Imagine one market maker is offering ¥95 for $15 (a ratio of about `6.3` CNY per USD), but the next best offer in the market is ¥5 for $2 (a ratio of `2.5` CNY per USD). If I were to take both offers in order to send you 100 CNY, then it would cost me 17 USD, for an average quality of about `5.9`. +Consider the following example. If I am trying to send you 100 Chinese Yuan (`Amount` = 100 CNY) for 20 United States dollars (`SendMax` = 20 USD) or less, then the limit quality is `5`. Imagine one trader is offering ¥95 for $15 (a ratio of about `6.3` CNY per USD), but the next best offer in the market is ¥5 for $2 (a ratio of `2.5` CNY per USD). If I were to take both offers to send you 100 CNY, then it would cost me 17 USD, for an average quality of about `5.9`. Without the tfLimitQuality flag set, this transaction would succeed, because the $17 it costs me is within my specified `SendMax`. However, with the tfLimitQuality flag enabled, the transaction would fail instead, because the path to take the second offer has a quality of `2.5`, which is worse than the limit quality of `5`. @@ -517,11 +517,11 @@ Client applications can use the [ripple.txt](https://ripple.com/wiki/Ripple.txt) There are several options which can be either enabled or disabled for an account. Account options are represented by different types of flags depending on the situation: -* The `AccountSet` transaction type has several "AccountSet Flags" (prefixed *asf*) that can enable an option when passed as the `SetFlag` parameter, or disable an option when passed as the `ClearFlag` parameter. -* The `AccountSet` transaction type has several transaction flags (prefixed *tf*) that can be used to enable or disable specific account options when passed in the `Flags` parameter. This style is discouraged, and new account options will not have new corresponding transaction flags. -* The `AccountRoot` ledger node type has several ledger-specific-flags (prefixed *lsf*) which represent the state of particular account options within a particular ledger. Naturally, the values apply until a later ledger version changes them. +* The `AccountSet` transaction type has several "AccountSet Flags" (prefixed **asf**) that can enable an option when passed as the `SetFlag` parameter, or disable an option when passed as the `ClearFlag` parameter. +* The `AccountSet` transaction type has several transaction flags (prefixed **tf**) that can be used to enable or disable specific account options when passed in the `Flags` parameter. This style is discouraged. New account options do not have corresponding transaction (tf) flags. +* The `AccountRoot` ledger node type has several ledger-specific-flags (prefixed **lsf**) which represent the state of particular account options within a particular ledger. Naturally, the values apply until a later ledger version changes them. -The preferred way to enable and disable Account Flags is using the `SetFlag` and `ClearFlag` parameters of an AccountSet transaction. AccountSet flags have names that begin with *asf*. +The preferred way to enable and disable Account Flags is using the `SetFlag` and `ClearFlag` parameters of an AccountSet transaction. AccountSet flags have names that begin with **asf**. All flags are off by default. @@ -530,7 +530,7 @@ The available AccountSet flags are: | Flag Name | Decimal Value | Description | Corresponding Ledger Flag | |-----------|---------------|-------------|---------------------------| | asfRequireDest | 1 | Require a destination tag to send transactions to this account. | lsfRequireDestTag | -| asfRequireAuth | 2 | Require authorization for users to hold balances issued by this account. (This prevents users unknown to a gateway from holding funds issued by that gateway.) | lsfRequireAuth | +| asfRequireAuth | 2 | Require authorization for users to hold balances issued by this address. Can only be enabled if the address has no trust lines connected to it. | lsfRequireAuth | | asfDisallowXRP | 3 | XRP should not be sent to this account. (Enforced by client applications, not by `rippled`) | lsfDisallowXRP | | asfDisableMaster | 4 | Disallow use of the master key. Can only be enabled if the account has configured another way to sign transactions, such as a [Regular Key](#setregularkey) or a [Signer List](#signerlistset). | lsfDisableMaster | | asfAccountTxnID | 5 | Track the ID of this account's most recent transaction. Required for [AccountTxnID](#accounttxnid) | (None) | @@ -538,7 +538,7 @@ The available AccountSet flags are: | asfGlobalFreeze | 7 | [Freeze](concept-freeze.html) all assets issued by this account. | lsfGlobalFreeze | | asfDefaultRipple | 8 | Enable [rippling](concept-noripple.html) on this account's trust lines by default. _(New in [rippled 0.27.3](https://github.com/ripple/rippled/releases/tag/0.27.3))_ | lsfDefaultRipple | -_New in [rippled 0.28.0][]:_ In order to enable the `asfDisableMaster` or `asfNoFreeze` flags, you must [authorize the transaction](#authorizing-transactions) by signing it with the master key. You cannot use a regular key or a multi-signature. +_New in [rippled 0.28.0][]:_ To enable the `asfDisableMaster` or `asfNoFreeze` flags, you must [authorize the transaction](#authorizing-transactions) by signing it with the master key. You cannot use a regular key or a multi-signature. The following [Transaction flags](#flags), specific to the AccountSet transaction type, serve the same purpose, but are discouraged: @@ -555,17 +555,17 @@ The following [Transaction flags](#flags), specific to the AccountSet transactio #### Blocking Incoming Transactions #### -Incoming transactions with unclear purposes may be an inconvenience for some gateways, which would have to identify whether a mistake was made, and then potentially refund accounts or adjust balances depending on the mistake. The `asfRequireDest` and `asfDisallowXRP` flags are intended to protect users from accidentally sending funds to a gateway in a way that is unclear about the reason the funds were sent. +Incoming transactions with unclear purposes may be an inconvenience for financial institutions, who would have to recognize when a customer made a mistake, and then potentially refund accounts or adjust balances depending on the mistake. The `asfRequireDest` and `asfDisallowXRP` flags are intended to protect users from accidentally sending funds in a way that is unclear about the reason the funds were sent. -For example, a destination tag is typically used to identify which hosted balance should be credited when the gateway receives a payment. If the destination tag is omitted, it may be unclear which account should be credited, creating a need for refunds, among other problems. By using the `asfRequireDest` tag, the gateway (or any account) can ensure that every incoming payment has a destination tag, which makes it harder to send an ambiguous payment by accident. +For example, a destination tag is typically used to identify which hosted balance should be credited when a financial institution receives a payment. If the destination tag is omitted, it may be unclear which account should be credited, creating a need for refunds, among other problems. By using the `asfRequireDest` tag, you can ensure that every incoming payment has a destination tag, which makes it harder for others to send you an ambiguous payment by accident. -Accounts can protect against unwanted incoming payments for non-XRP currencies simply by not creating trust lines in those currencies. Since XRP does not require trust, the `asfDisallowXRP` flag is used to discourage users from sending XRP to an account. However, this flag is not enforced in `rippled` because it could potentially cause accounts to become unusable. (If an account did not have enough XRP to send a transaction that disabled the flag, the account would be completely unusable.) Instead, client applications should disallow or discourage XRP payments to accounts with the `asfDisallowXRP` flag enabled. +You can protect against unwanted incoming payments for non-XRP currencies by not creating trust lines in those currencies. Since XRP does not require trust, the `asfDisallowXRP` flag is used to discourage users from sending XRP to an account. However, this flag is not enforced in `rippled` because it could potentially cause accounts to become unusable. (If an account did not have enough XRP to send a transaction that disabled the flag, the account would be completely unusable.) Instead, client applications should disallow or discourage XRP payments to accounts with the `asfDisallowXRP` flag enabled. ### TransferRate ### -The TransferRate field specifies a fee to charge whenever a gateway's issuances change hands. See [Transfer Fees article](https://ripple.com/knowledge_center/transfer-fees/) in the Knowledge Center for more information. +The TransferRate field specifies a fee to charge whenever counterparties transfer the currency you issue. See [Transfer Fees article](https://ripple.com/knowledge_center/transfer-fees/) in the Knowledge Center for more information. -In rippled's WebSocket and JSON-RPC APIs, the TransferRate is represented as an integer, the amount that must be sent in order for 1 billion units to arrive. For example, a 20% transfer fee is represented as the value `1200000000`. The value cannot be less than 1000000000. (Less than that would indicate giving away money for sending transactions, which is exploitable.) You can specify 0 as a shortcut for 1000000000, meaning no fee. +In `rippled`'s WebSocket and JSON-RPC APIs, the TransferRate is represented as an integer, the amount that must be sent for 1 billion units to arrive. For example, a 20% transfer fee is represented as the value `1200000000`. The value cannot be less than 1000000000. (Less than that would indicate giving away money for sending transactions, which is exploitable.) You can specify 0 as a shortcut for 1000000000, meaning no fee. @@ -631,11 +631,11 @@ An OfferCreate transaction is effectively a [limit order](http://en.wikipedia.or ### Lifecycle of an Offer ### -When an OfferCreate transaction is processed, it automatically consumes matching or crossing offers to the extent possible. (If existing offers provide a better rate than requested, the offer creator could pay less than the full `TakerGets` amount in order to receive the entire `TakerPays` amount.) If that does not completely fulfill the `TakerPays` amount, then the offer becomes an Offer node in the ledger. (You can use [OfferCreate Flags](#offercreate-flags) to modify this behavior.) +When an OfferCreate transaction is processed, it automatically consumes matching or crossing offers to the extent possible. (If existing offers provide a better rate than requested, the offer creator could pay less than the full `TakerGets` amount to receive the entire `TakerPays` amount.) If that does not completely fulfill the `TakerPays` amount, then the offer becomes an Offer node in the ledger. (You can use [OfferCreate Flags](#offercreate-flags) to modify this behavior.) An offer in the ledger can be fulfilled either by additional OfferCreate transactions that match up with the existing offers, or by [Payments](#payment) that use the offer to connect the payment path. Offers can be partially fulfilled and partially funded. A single transaction can consume up to 850 Offers from the ledger. (Any more than that, and the metadata becomes too large, resulting in [`tecOVERSIZE`](#tec-codes).) -You can create an offer so long as you have at least some (any positive, nonzero amount) of the currency specified by the `TakerGets` parameter of the offer. Any amount of that currency you have, up to the `TakerGets` amount, will be sold until the `TakerPays` amount is satisfied. An offer cannot place anyone in debt. +You can create an offer so long as you have at least some (any positive, nonzero amount) of the currency specified by the `TakerGets` parameter of the offer. The offer sells as much of the currency as you have, up to the `TakerGets` amount, until the `TakerPays` amount is satisfied. An offer cannot place anyone in debt. It is possible for an offer to become temporarily or permanently *unfunded*: @@ -647,27 +647,26 @@ It is possible for an offer to become temporarily or permanently *unfunded*: * The offer becomes funded again when the creator obtains more XRP, or the reserve requirements decrease. * If the Expiration time included in the offer is before the close time of the most recently-closed ledger. (See [Expiration](#expiration).) -An unfunded offer can remain on the ledger indefinitely, but it does not have any effect. The only ways an offer can be *permanently* removed from the ledger are: +An unfunded offer can stay on the ledger indefinitely, but it does not have any effect. The only ways an offer can be *permanently* removed from the ledger are: * It becomes fully claimed by a Payment or a matching OfferCreate transaction. -* A subsequent OfferCancel or OfferCreate transaction explicitly cancels the offer. -* A subsequent OfferCreate from the same account crosses the earlier offer. (In this case, the older offer is automatically canceled.) +* An OfferCancel or OfferCreate transaction explicitly cancels the offer. +* An OfferCreate transaction from the same account crosses the earlier offer. (In this case, the older offer is automatically canceled.) * An offer is found to be unfunded during transaction processing, typically because it was at the tip of the orderbook. - * This includes cases where one side or the other of an offer is found to be closer to 0 than `rippled`'s precision supports. -* *Note:* there is a bug that can cause offers to be removed incorrectly in rare circumstances. (See [RIPD-456](https://ripplelabs.atlassian.net/browse/RIPD-456) for status.) + * This includes cases where one side or the other of an offer is found to be closer to 0 than `rippled`'s precision supports. #### Tracking Unfunded Offers #### -Tracking the funding status of all offers can be computationally taxing. In particular, accounts that are actively trading may have a large number of offers open and be frequently involved in transactions that affect the funding status of their offers. Because of this, `rippled` does not proactively find and remove offers. +Tracking the funding status of all offers can be computationally taxing. In particular, addresses that are actively trading may have a large number of offers open. A single balance can affect the funding status of many offers to buy different currencies. Because of this, `rippled` does not proactively find and remove offers. A client application can locally track the funding status of offers. To do this, first retreive an order book using the [`book_offers` command](reference-rippled.html#book-offers) and check the `taker_gets_funded` field of offers. Then, [subscribe](reference-rippled.html#subscribe) to the `transactions` stream and watch the transaction metadata to see which offers are modified. ### Offers and Trust ### -The limit values of trust lines (See [TrustSet](#trustset)) do not affect offers. In other words, you can use an offer to acquire more than the maximum amount you trust an issuing gateway to redeem. +The limit values of trust lines (See [TrustSet](#trustset)) do not affect offers. In other words, you can use an offer to acquire more than the maximum amount you trust an issuer to redeem. -However, possessing non-XRP balances still requires a trust line to the account issuing those balances. When an offer is taken, it automatically creates any necessary trust lines, setting their limits to 0. Because [trust lines increase the reserve an account must hold](concept-reserves.html), any offers that would require a new trust line also require the account to have the necessary XRP to pay the reserve for that trust line. +However, holding non-XRP balances still requires a trust line to the address issuing those balances. When an offer is taken, it automatically creates any necessary trust lines, setting their limits to 0. Because [trust lines increase the reserve an account must hold](concept-reserves.html), any offers that would require a new trust line also require the address to have enough XRP to meet the reserve for that trust line. A trust line indicates an issuer you trust enough to accept their issuances as payment, within limits. Offers are explicit instructions to acquire certain issuances, so they are allowed to go beyond those limits. @@ -679,17 +678,19 @@ When offers of the same quality are placed in the same ledger version, the order ### Expiration ### -Since transactions can take time to propagate and confirm, the timestamp of a ledger is used to determine offer validity. An offer only expires when its Expiration time occurs prior to the most-recently validated ledger. In other words, an offer with an `Expiration` field is still considered "active" if its expiration time is later than the timestamp of the most-recently validated ledger, regardless of what your local clock says. +Since transactions can take time to propagate and confirm, the timestamp of a ledger is used to determine offer validity. An offer only expires when its Expiration time is before the most-recently validated ledger. In other words, an offer with an `Expiration` field is still considered "active" if its expiration time is later than the timestamp of the most-recently validated ledger, regardless of what your local clock says. You can determine the final disposition of an offer with an `Expiration` as soon as you see a fully-validated ledger with a close time equal to or greater than the expiration time. -*Note:* Since only new transactions can modify the ledger, an expired offer can remain on the ledger after it becomes inactive. The offer is treated as unfunded and has no effect, but it can continue to appear in results (for example, from the [ledger_entry](reference-rippled.html#ledger-entry) command). Later on, the expired offer can get finally deleted as a result of another transaction (such as another OfferCreate) if the server encounters it while processing. +**Note:** Since only new transactions can modify the ledger, an expired offer can stay on the ledger after it becomes inactive. The offer is treated as unfunded and has no effect, but it can continue to appear in results (for example, from the [ledger_entry](reference-rippled.html#ledger-entry) command). Later on, the expired offer can get finally deleted as a result of another transaction (such as another OfferCreate) if the server finds it while processing. + +If an OfferCreate transaction has an `Expiration` time that has already passed when the transaction first gets included in a ledger, the transaction does not execute the offer but still results in a `tesSUCCESS` transaction code. (This is because such a transaction could still successfully cancel another offer.) ### Auto-Bridging ### Any OfferCreate that would exchange two non-XRP currencies could potentially use XRP as an intermediary currency in a synthetic order book. This is because of auto-bridging, which serves to improve liquidity across all currency pairs by using XRP as a vehicle currency. This works because of XRP's nature as a native cryptocurrency to the Ripple Consensus Ledger. Offer execution can use a combination of direct and auto-bridged offers to achieve the best total exchange rate. -Example: _Anita places an offer to sell GBP and buy BRL. She might fund that this uncommon currency market has few offers. There is one offer with a good rate, but it has insufficient quantity to satisfy Anita's trade. However, both GBP and BRL have active, competitive markets to XRP. Auto-bridging software finds a way to complete Anita's offer by purchasing XRP with GBP from one trader, then selling the XRP to another trader in order to buy BRL. Anita automatically gets the best rate possible by combining the small offer in the direct GBP:BRL market with the better composite rates created by pairing GBP:XRP and XRP:BRL offers._ +Example: _Anita places an offer to sell GBP and buy BRL. She might fund that this uncommon currency market has few offers. There is one offer with a good rate, but it has insufficient quantity to satisfy Anita's trade. However, both GBP and BRL have active, competitive markets to XRP. Auto-bridging software finds a way to complete Anita's offer by purchasing XRP with GBP from one trader, then selling the XRP to another trader to buy BRL. Anita automatically gets the best rate possible by combining the small offer in the direct GBP:BRL market with the better composite rates created by pairing GBP:XRP and XRP:BRL offers._ Auto-bridging happens automatically on any OfferCreate transaction. [Payment transactions](#payment) _do not_ autobridge by default, but path-finding can find paths that have the same effect. @@ -700,9 +701,9 @@ Transactions of the OfferCreate type support additional values in the [`Flags` f | Flag Name | Hex Value | Decimal Value | Description | |-----------|-----------|---------------|-------------| -| tfPassive | 0x00010000 | 65536 | If enabled, the offer will not consume offers that exactly match it, and instead becomes an Offer node in the ledger. It will still consume offers that cross it. | -| tfImmediateOrCancel | 0x00020000 | 131072 | Treat the offer as an [Immediate or Cancel order](http://en.wikipedia.org/wiki/Immediate_or_cancel). If enabled, the offer will never become a ledger node: it only attempts to match existing offers in the ledger. | -| tfFillOrKill | 0x00040000 | 262144 | Treat the offer as a [Fill or Kill order](http://en.wikipedia.org/wiki/Fill_or_kill). Only attempt to match existing offers in the ledger, and only do so if the entire `TakerPays` quantity can be obtained. | +| tfPassive | 0x00010000 | 65536 | If enabled, the offer does not consume offers that exactly match it, and instead becomes an Offer node in the ledger. It still consumes offers that cross it. | +| tfImmediateOrCancel | 0x00020000 | 131072 | Treat the offer as an [Immediate or Cancel order](http://en.wikipedia.org/wiki/Immediate_or_cancel). If enabled, the offer never becomes a ledger node: it only tries to match existing offers in the ledger. | +| tfFillOrKill | 0x00040000 | 262144 | Treat the offer as a [Fill or Kill order](http://en.wikipedia.org/wiki/Fill_or_kill). Only try to match existing offers in the ledger, and only do so if the entire `TakerPays` quantity can be obtained. | | tfSell | 0x00080000 | 524288 | Exchange the entire `TakerGets` amount, even if it means obtaining more than the `TakerPays` amount in exchange. | The following invalid flag combination prompts a temINVALID_FLAG error: @@ -772,9 +773,9 @@ Create or modify a trust line linking two accounts. ### Trust Limits ### -All balances on the Ripple Network, except for XRP, represent value owed in the world outside the Ripple Ledger. The account that issues those funds in Ripple (identified by the `issuer` field of the `LimitAmount` object) is responsible for paying the balance back, outside of the Ripple Network, when users redeem their Ripple balances by returning them to the issuing account. +All balances on the Ripple Consensus Ledger (RCL), except for XRP, represent value owed in the world outside the Ripple Ledger. The address that issues those funds in Ripple (identified by the `issuer` field of the `LimitAmount` object) is expected to pay the balance back, outside of the Ripple Consensus LEdger, when users redeem their Ripple balances by returning them to the issuer. -Since a computer program cannot force the gateway to keep its promise and not default in real life, trust lines represent a way of configuring how much you are willing to trust the issuing account to hold on your behalf. Since a large, reputable issuing gateway is more likely to be able to pay you back than, say, your broke roommate, you can set different limits on each trust line, to indicate the maximum amount you are willing to let the issuing account "owe" you (off the network) for the funds that you hold on the network. In the case that the issuing gateway defaults or goes out of business, you can lose up to that much money because the balances you hold in the Ripple Network can no longer be exchanged for equivalent balances off the network. (The Ripple Ledger will still reflect that you possess the same balance with that issuing gateway, but you won't be able to redeem, making it unlikely to be worth anything.) +Since a computer program cannot force a someone to keep its promise and not default in real life, trust lines represent a way of configuring how much you trust issuing address to hold on your behalf. Since a large, reputable financial institution is more likely to be able to pay you back than, say, your broke roommate, you can set different limits on each trust line, to indicate the maximum amount you are willing to let the issuer "owe" you in the RCL. If the issuer defaults or goes out of business, you can lose up to that much money because the balances you hold in the Ripple Consensus Ledger can no longer be exchanged for equivalent balances elsewhere. (You can still keep or trade the issuances in the RCL, but they no longer have any reason to be worth anything.) There are two cases where you can hold a balance on a trust line that is *greater* than your limit: when you acquire more of that currency through [trading](#offercreate), or when you decrease the limit on your trust line. @@ -869,7 +870,7 @@ Some of the fields that are mandatory for normal transactions do not make sense A change in [transaction cost](concept-transaction-cost.html) or [account reserve](concept-reserves.html) requirements as a result of [Fee Voting](concept-fee-voting.html). -**Note:** You cannot send a pseudo-transaction, but you may encounter one when processing ledgers. +**Note:** You cannot send a pseudo-transaction, but you may find one when processing ledgers. ``` { @@ -900,7 +901,7 @@ A change in [transaction cost](concept-transaction-cost.html) or [account reserv Tracks the progress of the [amendment process](concept-amendments.html#amendment-process) for changes in transaction processing. This can indicate that a proposed amendment gained or lost majority approval, or that an amendment has been enabled. -**Note:** You cannot send a pseudo-transaction, but you may encounter one when processing ledgers. +**Note:** You cannot send a pseudo-transaction, but you may find one when processing ledgers. | Field | JSON Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description | |-------|-----------|--------------------------------------------------------|-------------| @@ -934,7 +935,7 @@ The response from `submit` contains the following fields: | engine\_result\_code | Signed Integer | A number that corresponds to the `engine_result`, although exact values are subject to change. | | engine\_result\_message | String | A human-readable message explaining what happened. This message is intended for developers to diagnose problems, and is subject to change without notice. | -If nothing went wrong in the process of submitting and applying the transaction locally, the response looks like this: +If nothing went wrong when submitting and applying the transaction locally, the response looks like this: ```js "engine_result": "tesSUCCESS", @@ -972,8 +973,8 @@ Both the `engine_result` and the `meta.TransactionResult` use standard codes to | Malformed transaction | [tem](#tem-codes) | The transaction was not valid, due to improper syntax, conflicting options, a bad signature, or something else. | | Failure | [tef](#tef-codes) | The transaction cannot be applied to the server's current (in-progress) ledger or any later one. It may have already been applied, or the condition of the ledger makes it impossible to apply in the future. | | Retry | [ter](#ter-codes) | The transaction could not be applied, but it might be possible to apply later. | -| Success | [tes](#tes-success) | (Not an error) The transaction succeeded. This result is not final unless it appears in a validated ledger. | -| Claimed cost only | [tec](#tec-codes) | The transaction did not achieve its intended purpose, but the [transaction cost](concept-transaction-cost.html) was destroyed. This result is not final unless it appears in a validated ledger. | +| Success | [tes](#tes-success) | (Not an error) The transaction succeeded. This result only final in a validated ledger. | +| Claimed cost only | [tec](#tec-codes) | The transaction did not achieve its intended purpose, but the [transaction cost](concept-transaction-cost.html) was destroyed. This result is only final in a validated ledger. | | Client library error | [tej](#tej-codes) | (ripple-lib only) The transaction was not submitted, because the client library blocked it, as part of its additional error checking. | The distinction between a local error (`tel`) and a malformed transaction (`tem`) is a matter of protocol-level rules. For example, the protocol sets no limit on the maximum number of paths that can be included in a transaction. However, a server may define a finite limit of paths it can process. If two different servers are configured differently, then one of them may return a `tel` error for a transaction with many paths, while the other server could successfully process the transaction. If enough servers are able to process the transaction that it survives consensus, then it can still be included in a validated ledger. @@ -990,7 +991,7 @@ Although it may seem unfair to charge a [transaction cost](concept-transaction-c ## Finality of Results ## -The order in which transactions apply to the consensus ledger is not final until a ledger is closed and the exact transaction set is approved by the consensus process. Therefore, a transaction that succeeded initially could still fail, and a transaction that failed initially could still succeed. Additionally, a transaction that was rejected by the consensus process in one round could achieve consensus in a subsequent round. +The order in which transactions apply to the consensus ledger is not final until a ledger is closed and the exact transaction set is approved by the consensus process. A transaction that succeeded initially could still fail, and a transaction that failed initially could still succeed. Additionally, a transaction that was rejected by the consensus process in one round could achieve consensus in a later round. A validated ledger can include successful transactions (`tes` result codes) as well as failed transactions (`tec` result codes). No transaction with any other result is included in a ledger. @@ -1004,7 +1005,7 @@ For any other result code, it can be difficult to determine if the result is fin | `tefPAST_SEQ` | Final when another transaction with the same sequence number is included in a validated ledger | | `tefMAX_LEDGER` | Final when a validated ledger has a sequence number higher than the transaction's `LastLedgerSequence` field, and no validated ledger includes the transaction | -Any other transaction result is potentially not final. In that case, the transaction could still succeed or fail later, especially if conditions change such that the transaction is no longer prevented from applying. For example, attempting to send a non-XRP currency to an account that does not exist yet would fail, but it could succeed if another transaction sends enough XRP to create the destination account. A server might even store a temporarily-failed, signed transaction and then successfully apply it later without asking first. +Any other transaction result is potentially not final. In that case, the transaction could still succeed or fail later, especially if conditions change such that the transaction is no longer prevented from applying. For example, trying to send a non-XRP currency to an account that does not exist yet would fail, but it could succeed if another transaction sends enough XRP to create the destination account. A server might even store a temporarily-failed, signed transaction and then successfully apply it later without asking first. @@ -1029,7 +1030,7 @@ The `Amount` of a [Payment transaction](#payment) indicates the amount to delive The `delivered_amount` field of transaction metadata is included in all successful Payment transactions, and is formatted like a normal currency amount. However, the delivered amount is not available for transactions that meet both of the following criteria: * Is a partial payment, and -* Included in a validated ledger prior to 2014-01-20 +* Included in a validated ledger before 2014-01-20 If both conditions are true, then `delivered_amount` contains the string value `unavailable` instead of an actual amount. If this happens, you can only figure out the actual delivered amount by reading the AffectedNodes in the transaction's metadata. @@ -1083,7 +1084,7 @@ These codes indicate that the transaction was malformed, and cannot succeed acco | temINVALID | The transaction is otherwise invalid. For example, the transaction ID may not be the right format, the signature may not be formed properly, or something else went wrong in understanding the transaction. | | temINVALID\_FLAG | The transaction includes a [Flag](#flags) that does not exist, or includes a contradictory combination of flags. | | temMALFORMED | Unspecified problem with the format of the transaction. | -| temREDUNDANT | The transaction would accomplish nothing; for example, it is sending a payment directly to the sending account, or creating an offer to buy and sell the same currency from the same issuer. | +| temREDUNDANT | The transaction would do nothing; for example, it is sending a payment directly to the sending account, or creating an offer to buy and sell the same currency from the same issuer. | | temREDUNDANT\_SEND\_MAX | _(Removed in [rippled 0.28.0][])_ | | temRIPPLE\_EMPTY | The [Payment](#payment) transaction includes an empty `Paths` field, but paths are necessary to complete this payment. | | temBAD_WEIGHT | The [SignerListSet](#signerlistset) transaction includes a `SignerWeight` that is invalid, for example a zero or negative value. | @@ -1091,12 +1092,12 @@ These codes indicate that the transaction was malformed, and cannot succeed acco | temBAD_QUORUM | The [SignerListSet](#signerlistset) transaction has an invalid `SignerQuorum` value. Either the value is not greater than zero, or it is more than the sum of all signers in the list. | | temUNCERTAIN | Used internally only. This code should never be returned. | | temUNKNOWN | Used internally only. This code should never be returned. | -| temDISABLED | The transaction requires logic that is currently disabled. Typically this means you are trying to use an [amendment](concept-amendments.html) that is not enabled for the current ledger. | +| temDISABLED | The transaction requires logic that is disabled. Typically this means you are trying to use an [amendment](concept-amendments.html) that is not enabled for the current ledger. | ### tef Codes ### -These codes indicate that the transaction failed to apply, but the transaction could have succeeded in some theoretical ledger. Typically this means that the transaction can no longer succeed in any future ledger. They have numerical values in the range -199 to -100. The exact code for any given error is subject to change, so don't rely on it. +These codes indicate that the transaction failed and was not included in a ledger, but the transaction could have succeeded in some theoretical ledger. Typically this means that the transaction can no longer succeed in any future ledger. They have numerical values in the range -199 to -100. The exact code for any given error is subject to change, so don't rely on it. | Code | Explanation | |------|-------------| @@ -1110,17 +1111,17 @@ These codes indicate that the transaction failed to apply, but the transaction c | tefCREATED |**DEPRECATED.** | | tefEXCEPTION | While processing the transaction, the server entered an unexpected state. This may be caused by unexpected inputs, for example if the binary data for the transaction is grossly malformed. If you can reproduce this error, please [report an issue](https://github.com/ripple/rippled/issues) to get it fixed. | | tefFAILURE | Unspecified failure in applying the transaction. | -| tefINTERNAL | While attempting to apply the transaction, the server entered an unexpected state. If you can reproduce this error, please [report an issue](https://github.com/ripple/rippled/issues) to get it fixed. | +| tefINTERNAL | When trying to apply the transaction, the server entered an unexpected state. If you can reproduce this error, please [report an issue](https://github.com/ripple/rippled/issues) to get it fixed. | | tefMASTER\_DISABLED | The transaction was signed with the account's master key, but the account has the `lsfDisableMaster` field set. | | tefMAX\_LEDGER | The transaction included a [`LastLedgerSequence`](#lastledgersequence) parameter, but the current ledger's sequence number is already higher than the specified value. | -| tefNO\_AUTH\_REQUIRED | The [TrustSet](#trustset) transaction attempted to mark a trustline as authorized, but the `lsfRequireAuth` flag is not enabled for the corresponding account, so authorization is not necessary. | +| tefNO\_AUTH\_REQUIRED | The [TrustSet](#trustset) transaction tried to mark a trustline as authorized, but the `lsfRequireAuth` flag is not enabled for the corresponding account, so authorization is not necessary. | | tefNOT\_MULTI\_SIGNING | The transaction was [multi-signed](#multi-signing), but the sending account has no SignerList defined. | | tefPAST\_SEQ | The sequence number of the transaction is lower than the current sequence number of the account sending the transaction. | | tefWRONG\_PRIOR | The transaction contained an `AccountTxnID` field (or the deprecated `PreviousTxnID` field), but the transaction specified there does not match the account's previous transaction. | ### ter Codes ### -These codes indicate that the transaction failed to apply, but it could apply successfully if some other transaction was applied first. They have numerical values in the range -99 to -1. The exact code for any given error is subject to change, so don't rely on it. +These codes indicate that the transaction failed, but it could apply successfully if some other transaction was applied first. They have numerical values in the range -99 to -1. The exact code for any given error is subject to change, so don't rely on it. | Code | Explanation | |------|-------------| @@ -1137,7 +1138,7 @@ These codes indicate that the transaction failed to apply, but it could apply su ### tes Success ### -The code `tesSUCCESS` is the only code that indicates a transaction succeeded. This does not necessarily mean it accomplished its goal (for example, an [OfferCancel](#offercancel) can "succeed" if there is no offer for it to cancel). Success uses the numerical value 0. +The code `tesSUCCESS` is the only code that indicates a transaction succeeded. This does not always mean it did what it was supposed to do. (For example, an [OfferCancel](#offercancel) can "succeed" even if there is no offer for it to cancel.) Success uses the numerical value 0. | Code | Explanation | |------|-------------| @@ -1145,7 +1146,7 @@ The code `tesSUCCESS` is the only code that indicates a transaction succeeded. T ### tec Codes ### -These codes indicate that the transaction failed, but it was applied to a ledger in order to apply the [transaction cost](concept-transaction-cost.html). They have numerical values in the range 100 to 199. The exact codes sometimes appear in ledger data, so they do not change, but we recommend not relying on the numeric value regardless. +These codes indicate that the transaction failed, but it was applied to a ledger to apply the [transaction cost](concept-transaction-cost.html). They have numerical values in the range 100 to 199. The exact codes sometimes appear in ledger data, so they do not change, but we recommend not relying on the numeric value regardless. | Code | Value | Explanation | |------|-------|-------------| @@ -1158,20 +1159,20 @@ These codes indicate that the transaction failed, but it was applied to a ledger | tecINSUF\_RESERVE\_OFFER | 123 | The transaction failed because the sending account does not have enough XRP to create a new Offer. (See: [Reserves](concept-reserves.html)) | | tecINSUFFICIENT\_RESERVE | 141 | The [SignerListSet](#signerlistset) or other transaction would increase the [reserve requirement](concept-reserves.html) higher than the sending account's balance. See [SignerLists and Reserves](reference-ledger-format.html#signerlists-and-reserves) for more information. | | tecINTERNAL | 144 | Unspecified internal error, with transaction cost applied. This error code should not normally be returned. | -| tecNEED\_MASTER\_KEY | 142 | This transaction attempted to cause changes that require the master key, such as [disabling the master key or giving up the ability to freeze balances](#accountset-flags). _(New in [rippled 0.28.0](https://github.com/ripple/rippled/releases/tag/0.28.0-rc1))_ | +| tecNEED\_MASTER\_KEY | 142 | This transaction tried to cause changes that require the master key, such as [disabling the master key or giving up the ability to freeze balances](#accountset-flags). _(New in [rippled 0.28.0](https://github.com/ripple/rippled/releases/tag/0.28.0-rc1))_ | | tecNO\_ALTERNATIVE\_KEY | 130 | The transaction tried to remove the only available method of [authorizing transactions](#authorizing-transactions). This could be a [SetRegularKey transaction](#setregularkey) to remove the regular key, a [SignerListSet transaction](#signerlistset) to delete a SignerList, or an [AccountSet transaction](#accountset) to disable the master key. (Prior to [rippled 0.30.0](https://github.com/ripple/rippled/releases/tag/0.30.0), this was called `tecMASTER_DISABLED`.) | | tecNO\_AUTH | 134 | The transaction failed because it needs to add a balance on a trust line to an account with the `lsfRequireAuth` flag enabled, and that trust line has not been authorized. If the trust line does not exist at all, tecNO\_LINE occurs instead. | -| tecNO\_DST | 124 | The account on the receiving end of the transaction does not exist. This includes Payment and TrustSet transaction types. (It could be created if it received sufficient XRP.) | +| tecNO\_DST | 124 | The account on the receiving end of the transaction does not exist. This includes Payment and TrustSet transaction types. (It could be created if it received enough XRP.) | | tecNO\_DST\_INSUF_XRP | 125 | The account on the receiving end of the transaction does not exist, and the transaction is not sending enough XRP to create it. | | tecNO\_ENTRY | 140 | Reserved for future use. | | tecNO\_ISSUER | 133 | The account specified in the `issuer` field of a currency amount does not exist. | | tecNO\_LINE | 135 | The `TakerPays` field of the [OfferCreate transaction](#offercreate) specifies an asset whose issuer has `lsfRequireAuth` enabled, and the account making the offer does not have a trust line for that asset. (Normally, making an offer implicitly creates a trust line if necessary, but in this case it does not bother because you cannot hold the asset without authorization.) If the trust line exists, but is not authorized, `tecNO_AUTH` occurs instead. | | tecNO\_LINE\_INSUF\_RESERVE | 126 | The transaction failed because the sending account does not have enough XRP to create a new trust line. (See: [Reserves](concept-reserves.html)) This error occurs when the counterparty does not have a trust line to this account for the same currency. (See tecINSUF\_RESERVE\_LINE for the other case.) | -| tecNO\_LINE\_REDUNDANT | 127 | The transaction failed because it attempted to set a trust line to its default state, but the trust line did not exist. | +| tecNO\_LINE\_REDUNDANT | 127 | The transaction failed because it tried to set a trust line to its default state, but the trust line did not exist. | | tecNO\_PERMISSION | 139 | Reserved for future use. | | tecNO\_REGULAR\_KEY | 131 | The [AccountSet transaction](#accountset) tried to disable the master key, but the account does not have another way to [authorize transactions](#authorizing-transactions). If [multi-signing](#multi-signing) is enabled, this code is deprecated and `tecNO_ALTERNATIVE_KEY` is used instead. | | tecNO\_TARGET | 138 | Reserved for future use. | -| tecOVERSIZE | 145 | This transaction could not be processed, because attempted transaction processing created an excessively large amount of metadata. _(New in [rippled 0.29.0-hf1](https://github.com/ripple/rippled/releases/tag/0.29.0-hf1) )_ | +| tecOVERSIZE | 145 | This transaction could not be processed, because the server created an excessively large amount of metadata when it tried to apply the transaction. _(New in [rippled 0.29.0-hf1](https://github.com/ripple/rippled/releases/tag/0.29.0-hf1) )_ | | tecOWNERS | 132 | The transaction requires that account sending it has a nonzero "owners count", so the transaction cannot succeed. For example, an account cannot enable the [`lsfRequireAuth`](#accountset-flags) flag if it has any trust lines or available offers. | | tecPATH\_DRY | 128 | The transaction failed because the provided paths did not have enough liquidity to send anything at all. This could mean that the source and destination accounts are not linked by trust lines. | | tecPATH\_PARTIAL | 101 | The transaction failed because the provided paths did not have enough liquidity to send the full amount. | @@ -1191,8 +1192,8 @@ These codes are only ever returned by the `ripple-lib` client library, not by `r | tejInvalidFlag | One of the flags specified was invalid, or does not apply to this transaction type. | | tejLocalSigningRequired | The transaction could not be resubmitted because local signing is disabled. | | tejMaxFeeExceeded | The [transaction cost](concept-transaction-cost.html) that would be necessary to send the transaction is higher than the maximum transaction cost setting, which is either the `_MaxFee` parameter of the Transaction (if provided) or the maximum transaction cost configured for the remote. The default value is 1 XRP (100000 drops). | -| tejMaxLedger | Currently-validated ledgers have surpassed the `LastLedgerSequence` parameter of the transaction without including it, so it can no longer succeed. (Also see [Reliable Transaction Submission](tutorial-reliable-transaction-submission.html).) When using ripple-lib, this error effectively replaces all non-final errors, including tel-, tef-, and ter-class response codes. | +| tejMaxLedger | Validated ledgers have surpassed the `LastLedgerSequence` parameter of the transaction without including it, so it can no longer succeed. (Also see [Reliable Transaction Submission](tutorial-reliable-transaction-submission.html).) When using ripple-lib, this error effectively replaces all non-final errors, including tel-, tef-, and ter-class response codes. | | tejSecretInvalid | The secret included for signing this transaction was not a properly-formatted secret. | | tejSecretUnknown | The secret for a given account was omitted from the transaction, and ripple-lib was unable to automatically fill it in from saved data. | | tejServerUntrusted | The application attempted to submit an account secret to an untrusted server for transaction signing. | -| tejUnconnected | The application is not connected to a `rippled` server, but it needs to be in order to process the transaction. | +| tejUnconnected | The application is not connected to a `rippled` server, but it needs to be to process the transaction. | diff --git a/content/snippets/gateways-intro.md b/content/snippets/gateways-intro.md new file mode 100644 index 0000000000..a10c6ac9f8 --- /dev/null +++ b/content/snippets/gateways-intro.md @@ -0,0 +1,5 @@ +Gateways are businesses that provide a way for money and other forms of value to move in and out of the Ripple Consensus Ledger. There are three major models that gateways can follow, with different purposes and modes of operation. + +* An **Issuing Gateway** receives money (or other assets of value) outside of Ripple, and creates issuances in the Ripple Consensus Ledger. This provides a direct way for customers to get money in and out of the RCL. All currencies in the Ripple Consensus Ledger, except for XRP, take the form of issuances tied to a specific issuing gateway. +* A **Private Exchange** holds XRP and lets its customers buy and sell that XRP in its own system. Most cryptocurrencies rely on private exchanges to provide a market for the cryptocurrency, but the Ripple Consensus Ledger has a currency exchange built into the protocol itself. +* **Merchants** accept payment within the Ripple Consensus Ledger in exchange for goods and services in the outside world. Currently, Ripple does not have widespread support for merchant operations. diff --git a/content/snippets/issuing-and-operational-addresses-intro.md b/content/snippets/issuing-and-operational-addresses-intro.md index 7d14c038cd..6c82fcbc53 100644 --- a/content/snippets/issuing-and-operational-addresses-intro.md +++ b/content/snippets/issuing-and-operational-addresses-intro.md @@ -1,5 +1,5 @@ In the Ripple Consensus Ledger, financial institutions typically use multiple Ripple addresses to minimize the risk associated with a compromised secret key. Ripple strongly recommends the following separation of roles: -* One **issuing address**, also known as a "cold wallet." This address is the hub of the financial institution's accounting relationships in the ledger, but sends as few transactions as possible. -* One or more **operational addresses**, also known as "hot wallets." Automated, internet-connected systems use the secret keys to these addresses to conduct day-to-day business like transfers to customers and partners. -* Optional **standby addresses**, also known as "warm wallets." Trusted human operators use these addresses to transfer money to the operational addresses. +* One **issuing address**, also known as a "cold wallet." This address is the hub of the financial institution's accounting relationships in the ledger, but sends as few transactions as possible. +* One or more **operational addresses**, also known as "hot wallets." Automated, internet-connected systems use the secret keys to these addresses to conduct day-to-day business like transfers to customers and partners. +* Optional **standby addresses**, also known as "warm wallets." Trusted human operators use these addresses to transfer money to the operational addresses. diff --git a/content/tutorial-gateway-guide.md b/content/tutorial-gateway-guide.md index a66f8e831a..a514ddfc5d 100644 --- a/content/tutorial-gateway-guide.md +++ b/content/tutorial-gateway-guide.md @@ -11,7 +11,7 @@ This document explains the concepts and steps necessary to become a Ripple gatew ## Contact Information ## -You are not on your own. Ripple depends on the success of individual gateways, so we are here to help. Please contact us if you need any assistance building and growing your gateway. +You are not on your own. Ripple depends on the success of individual gateways, so we are here to help. Please contact us if you need help building and growing your gateway. * Contact [partners@ripple.com](mailto:partners@ripple.com) for enterprise-class integrations, infrastructure advice, and other business development needs. * Contact [developers@ripple.com](mailto:developers@ripple.com) for technical questions, clarifications, bug reports, and feature requests. @@ -19,50 +19,48 @@ You are not on your own. Ripple depends on the success of individual gateways, s ## Ripple Gateways Explained ## -A Ripple _*Gateway*_ is an entity that exchanges value in the Ripple Consensus Ledger for value anywhere else. There are three major models that gateways can follow, with different purposes and modes of operation. +{% include 'snippets/gateways-intro.md' %} -* An **Issuing Gateway** receives money (or other assets of value) outside of Ripple, and creates _*issuances*_ in the Ripple Consensus Ledger. This provides a direct way for customers to get money in and out of the RCL. This document focuses primarily on how to become an issuing gateway. -* A **Private Exchange** lets its customers purchase and trade XRP among customers of the private exchange. This is similar to being an exchange for any other commodity or cryptocurrency. However, unlike other cryptocurrencies, there is also an exchange built into the Ripple Consensus Ledger itself. -* A **Merchant** accepts payment within the RCL for goods or services outside the network. Unlike an issuing gateway, a merchant business does not create its own currency, but accepts issuances that are created by other gateways. This guide does not describe how to accept Ripple payments as a merchant. +This guide focuses on running an **issuing gateway**. ### Ripple Trust Lines and Issuances ### -All assets in the Ripple Consensus Ledger, except for the native cryptocurrency XRP, are represented as _issuances_, which are digital assets that reflect traditional assets held by a gateway. Within the RCL, issuances can be sent and traded without the gateway's intervention and very low barriers to entry. Issuances get their value from gateway's agreement to honor the obligation that the issuances represent; there is no computer system that can force a Ripple gateway to honor that obligation. +All assets in the Ripple Consensus Ledger, except for the native cryptocurrency XRP, are represented as _issuances_, which are digital balances that represent currency or assets of value held by an issuer. Within the RCL, counterparties can send and trade issuances without requiring intervention from the issuer. Typically, a gateway sends issuances to customers when it receives money in systems and ledgers outside the RCL, and promises to send money to customers in outside systems in exchange for being repaid in issuances in the RCL. Issuances get their value from a gateway's agreement to honor the obligation that the issuances represent. No computer system can force a Ripple gateway to honor that obligation. -The Ripple Consensus Ledger has a system of directional accounting relationships, called _trust lines_, to ensure that users only hold issuances from gateways they trust to pay out when needed. +The Ripple Consensus Ledger has a system of directional accounting relationships, called _trust lines_, to make sure that users only hold issuances from counterparties they trust. A "trust line" is link between two addresses in Ripple. A trust line represents an explicit statement of willingness to hold gateway debt obligations. When a customer sends money into the RCL, a gateway takes custody of those assets outside of Ripple, and sends issuances in the RCL to the customer's address. When a customer sends money out of the RCL, she makes a Ripple payment to the gateway, and the gateway credits the customer in its own system of record, or in some other account. ### XRP ### -XRP is the native [cryptocurrency](https://ripple.com/knowledge_center/math-based-currency/) of the Ripple Consensus Ledger. Like issuances, XRP can be freely sent and exchanged among Ripple addresses. Unlike issuances, XRP is not tied to an accounting relationship. XRP can be sent directly from any Ripple address to any other, without going through a gateway or liquidity provider. This helps make XRP a convenient [bridge currency](https://ripple.com/knowledge_center/bridge-currency-2/) to facilitate currency exchanges. +XRP is the native [cryptocurrency](https://ripple.com/knowledge_center/math-based-currency/) of the Ripple Consensus Ledger. Like issuances, XRP can be freely sent and exchanged among Ripple addresses. Unlike issuances, XRP is not tied to an accounting relationship. XRP can be sent directly from any Ripple address to any other, without going through a gateway or liquidity provider. This helps make XRP a convenient [bridge currency](https://ripple.com/knowledge_center/bridge-currency-2/). -XRP also serves other purposes in the RCL, in particular as [a protective measure against spamming the network](https://ripple.com/knowledge_center/abuse-protection/). All Ripple addresses need a small amount of XRP in order to pay the costs of maintaining the Ripple Consensus Ledger. The [transaction cost](concept-transaction-cost.html) and [reserve](concept-reserves.html) are neutral fees not paid to any party. +XRP also serves other purposes in the RCL, in particular as [a protective measure against spamming the network](https://ripple.com/knowledge_center/abuse-protection/). All Ripple addresses need a small amount of XRP to pay the costs of maintaining the Ripple Consensus Ledger. The [transaction cost](concept-transaction-cost.html) and [reserve](concept-reserves.html) are neutral fees not paid to any party. -Issuing gateways do not need to accumulate or exchange XRP. They must only maintain a small balance of XRP to send transactions through the network. The XRP equivalent of $10 USD should be enough for a busy gateway to operate for a year. +Issuing gateways do not need to accumulate or exchange XRP. They must only hold a small balance of XRP to send transactions through the network. The XRP equivalent of $10 USD should be enough for at least one year of transaction costs for a busy gateway. -Private exchanges and liquidity providers may choose to hold additional XRP to use as a means of exchange. Ripple (the company) **does not** promote XRP as a speculative investment. +Private exchanges and liquidity providers may choose to hold additional XRP for trading. Ripple (the company) **does not** promote XRP as a speculative investment. ### Liquidity and Currency Exchange ### -The Ripple Consensus Ledger contains a distributed financial exchange, where any user can place and fulfill bids to exchange XRP and _issuances_ in any combination. Cross-currency payments automatically use the financial exchange to convert currency atomically when the transaction is executed. In this way, users who choose make offers in the distributed exchange provide the liquidity that makes the Ripple Consensus Ledger useful. +The Ripple Consensus Ledger contains a currency exchange, where any user can place and fulfill bids to exchange XRP and _issuances_ in any combination. Cross-currency payments automatically use the currency exchange to convert currency atomically when the transaction is executed. In this way, users who choose make offers in the distributed exchange provide the liquidity that makes the RCL useful. -When adding a new gateway to the RCL, it is important to establish liquidity to other popular currencies. Because third parties provide the Liquidity, a gateway's customers can exchange currencies through the RCL, without the gateway needing to float a large reserve in various destination currencies. The gateway also does not need to take on the risk of financial exchange. +Currency traders who hold a gateway's issuances can provide liquidity to other popular currencies, without the gateway needing to float a large reserve in various destination currencies. The gateway also does not need to take on the risk of financial exchange. However, a gateway may still want to provide liquidity to XRP or other popular currencies at a baseline rate, especially when the gateway is new to the exchange. If you do provide liquidity, use a different address for trading than your issuing address. -Third-party liquidity providers can use [RippleAPI](reference-rippleapi.html), [Ripple Stream](https://ripple.com/technology/), or a [third-party client application](https://ripple.com/knowledge_center/wallet-providers/) to participate in the distributed exchange. Some client applications look up the addresses associated with a gateway using [ripple.txt](#rippletxt), so it can be helpful to publish a good ripple.txt. +Third-party liquidity providers can use [RippleAPI](reference-rippleapi.html), [Ripple Stream](https://ripple.com/technology/), or a [third-party client application](https://ripple.com/knowledge_center/wallet-providers/) to access the distributed exchange. Some client applications look up the addresses associated with a gateway using [ripple.txt](#rippletxt), so it can be helpful to publish a good ripple.txt. -Contact [partners@ripple.com](mailto:partners@ripple.com) for help establishing a market between your gateway and others. +Contact [partners@ripple.com](mailto:partners@ripple.com) for help establishing liquidity between your gateway and others. ## Suggested Business Practices ## -The value of a gateway's issuances in the Ripple Consensus Ledger comes directly from the trust that customers can redeem them with the gateway when needed. Since a gateway cannot pay out if it shuts down, it is also in customers' interest that a gateway does not shut down. There are a number of precaution a gateway can take that reduce the risk of business interruptions: +The value of a gateway's issuances in the Ripple Consensus Ledger comes directly from the trust that customers can redeem them with the gateway when needed. We recommend the following precautions to reduce the risk of business interruptions: * Use separate [Issuing and Operational Addresses](concept-issuing-and-operational-addresses.html) to limit your risk profile on the network. * Comply with anti-money-laundering regulations for your jurisdiction, such as the [Bank Secrecy Act](http://en.wikipedia.org/wiki/Bank_Secrecy_Act). This usually includes requirements to collect ["Know-Your-Customer" (KYC) information](http://en.wikipedia.org/wiki/Know_your_customer). * Read and stay up-to-date with [Gateway Bulletins](https://ripple.com/knowledge_center/gateway-bulletins/), which provide news and suggestions for Ripple gateways. -* Clearly publicize all your policies and fees. +* Publicize all your policies and fees. ### Hot and Cold Wallets ### @@ -74,18 +72,18 @@ For more information, see [Issuing and Operational Addresses](concept-issuing-an ## Fees and Revenue Sources ## -There are several ways in which a gateway can seek to benefit financially from Ripple integration. These can include: +There are several ways in which a gateway can seek to profit from Ripple integration. These can include: -* Withdrawal and Deposit fees. It is typical for a gateway to charge a small fee (such as 1%) for the service of adding or removing money from Ripple. You have the power to determine the rate you credit people when they move money onto and off of Ripple through your gateway. +* Withdrawal and Deposit fees. Gateways typically charge a small fee (such as 1%) for the service of adding or removing money from Ripple. You have the power to determine the rate you credit people when they move money onto and off of Ripple through your gateway. * Transfer fees. You can set a percentage fee to charge automatically when customers send each other issuances created by your issuing address. This amount is debited from the Ripple Consensus Ledger, decreasing your obligation each time your issuances change hands. See [TransferRate](#transferrate) for details. * Indirect revenue from value added. Ripple integration can provide valuable functionality for your customers that distinguishes your business from your competitors. -* Interest on Ripple-backed funds. You can keep the collateral for the funds you issue in RCL in a bank account that earns interest. Just make sure you can always access enough funds to service customer withdrawals. +* Interest on Ripple-backed funds. You can keep the collateral for the funds you issue in RCL in a bank account that earns interest. Make sure you can always access enough funds to service customer withdrawals. * [Financial Exchange](#liquidity-and-currency-exchange). A gateway can also make offers to buy and sell its issuances for other issuances in the RCL, providing liquidity to cross-currency payments and possibly making a profit. (As with all financial exchange, profits are not guaranteed.) ### Choosing Fee Rates ### -Fees imposed by gateways are optional. Obviously, higher fees mean more revenue when a gateway's services are used. On the other hand, having high fees decreases the desirability of your gateway's issuances and services, which incentivizes customers to use other gateways instead. Consider the fees that are charged by other gateways, especially ones issuing similar currencies, as well as traditional payment systems outside of Ripple, such as wire fees. Choosing the right fee structure is a matter of balancing your pricing with what the market will pay. +Fees imposed by gateways are optional. Higher fees earn more revenue when a gateway's services are used. On the other hand, high fees discourage customers from using your services. Consider the fees that are charged by other gateways, especially ones issuing similar currencies, as well as traditional payment systems outside of Ripple, such as wire fees. Choosing the right fee structure is a matter of balancing your pricing with what the market is willing to pay. @@ -93,7 +91,7 @@ Fees imposed by gateways are optional. Obviously, higher fees mean more revenue ## Before Ripple Integration ## -Our example exchange, ACME, already accepts withdrawals and deposits from customers using some existing system, and uses its own system of record to track how much balance each user has with the exchange. Such a system can be modeled simply with a balance sheet and tracking how much currency each user has with ACME. +Our example exchange, ACME, already accepts withdrawals and deposits from customers using some existing system, and uses its own system of record to track how much balance each user has with the exchange. Such a system can be modeled with a balance sheet and tracking how much currency each user has with ACME. In the following diagram, ACME Exchange starts with €5 on hand, including €1 that belongs to Bob, €2 that belongs to Charlie, and an additional €2 of equity that belongs to ACME itself. Alice deposits €5, so ACME adds her to its balance sheet and ends up with €10. @@ -126,18 +124,18 @@ An example flow for a payment into the RCL: ### Requirements for Sending to RCL ### -There are several prerequisites that ACME must meet in order for this to happen: +There are several prerequisites that ACME must meet for this to happen: - ACME sets aside money that is issued in the Ripple Consensus Ledger. ACME can query the RCL to see who holds its issuances at any time. There are several ways ACME may do this: - ACME may create a Ripple Consensus Ledger collateral account in ACME's system of record. - ACME can store the funds allocated to Ripple in a separate bank account. - If ACME is a cryptocurrency exchange, ACME can create a separate wallet to hold the funds allocated to Ripple, as publicly-verifiable proof to customers that the gateway is solvent. - ACME must control an address in the Ripple Consensus Ledger. Ripple's best practices recommend using a separate issuing address and operational address. See [Issuing and Operational Addresses](concept-issuing-and-operational-addresses.html) for details. - - ACME must enable the [DefaultRipple Flag](#defaultripple) on its issuing address in order for customers to send and receive its issuances. + - ACME must enable the [DefaultRipple Flag](#defaultripple) on its issuing address for customers to send and receive its issuances. - Alice must create an accounting relationship (trust line) from her Ripple address to ACME's issuing address. She can do this from any Ripple client application as long as she knows ACME's issuing address. - ACME should publicize its issuing address on its website where customers can find it. It can also use [ripple.txt](#rippletxt) to publish the issuing address to automated systems. - ACME must create a user interface for Alice to send funds from ACME into Ripple. - - In order to do this, ACME needs to know Alice's Ripple address. ACME can have Alice input her Ripple addresss as part of the interface, or ACME can require Alice to input and verify her Ripple address in advance. + - ACME needs to know Alice's Ripple address. ACME can have Alice input her Ripple addresss as part of the interface, or ACME can require Alice to input and verify her Ripple address in advance. See [Sending Payments to Customers](#sending-payments-to-customers) for an example of how to send payments into Ripple. @@ -155,7 +153,7 @@ Payments going from the Ripple Consensus Ledger to a gateway can be single-curre ### Requirements for Receiving from RCL ### -In addition to the [requirements for sending into Ripple](#requirements-for-sending-to-rcl), there are several prerequisites that ACME must meet in order to process payments coming from Ripple: +In addition to the [requirements for sending into Ripple](#requirements-for-sending-to-rcl), there are several prerequisites that ACME must meet to process payments coming from Ripple: - ACME must monitor its Ripple addresses for incoming payments. - ACME must know which user to credit in its system of record for the incoming payments. @@ -169,8 +167,8 @@ Processing payments to and from Ripple naturally comes with some risks, so a gat - Protect yourself against reversible deposits. Ripple payments are irreversible, but many electronic money systems like credit cards or PayPal are not. Scammers can abuse this to take their fiat money back by canceling a deposit after receiving Ripple issuances. - When sending into Ripple, specify the issuing address as the issuer of the currency. Otherwise, you might accidentally use paths that deliver the same currency issued by other addresses. -- Before sending a payment into Ripple, double check the cost of the payment. A simple payment from your operational address to a customer should not cost more than the destination amount plus any [transfer fee](#transferrate) you have set. -- Before processing a payment out of Ripple, make sure you know the customer's identity. This makes it harder for anonymous attackers to scam you, and it is also an important element of most anti-money-laundering regulations. This is especially important because the users sending money from the RCL could be different than the ones that initially received the money in the RCL. +- Before sending a payment into Ripple, double check the cost of the payment. A payment from your operational address to a customer should not cost more than the destination amount plus any [transfer fee](#transferrate) you have set. +- Before processing a payment out of Ripple, make sure you know the customer's identity. This makes it harder for anonymous attackers to scam you. Most anti-money-laundering regulations require this anyway. This is especially important because the users sending money from the RCL could be different than the ones that initially received the money in the RCL. - Follow the guidelines for [reliable transaction submission](#reliable-transaction-submission) when sending Ripple transactions. - [Robustly monitor for incoming payments](#robustly-monitoring-for-payments), and read the correct amount. Don't mistakenly credit someone the full amount if they only sent a [partial payment](reference-transaction-format.html#partial-payments). - Track your obligations and balances within the Ripple Consensus Ledger, and compare with the assets in your collateral account. If they do not match up, stop processing withdrawals and deposits until you resolve the discrepancy. @@ -186,7 +184,7 @@ Processing payments to and from Ripple naturally comes with some risks, so a gat After the issuances have been created in the Ripple Consensus Ledger, they can be freely transferred and traded by RCL users. There are several consequences of this situation: - Anyone can buy/sell EUR.ACME on Ripple. If ACME issues multiple currencies on Ripple, a separate trust line is necessary for each. - - This includes RCL users who do not have an account in ACME Exchange's systems. In order to withdraw the funds successfully from ACME, users still have to register with ACME. + - This includes RCL users who do not have an account in ACME Exchange's systems. To withdraw the funds successfully from ACME, users still have to register with ACME. - Optionally, ACME uses the [Authorized Accounts](#authorized-accounts) feature to limit who can hold EUR.ACME in the RCL. - If ACME determines that a customer has acted in bad faith, ACME can [Freeze](#freeze) that user's accounting relationships to ACME in the RCL, so that the user can no longer trade in the gateway's issuances. - RCL users trading and sending EUR.ACME to one another requires no intervention by ACME. @@ -200,11 +198,11 @@ The following diagram depicts a Ripple payment sending 2EUR.ACME from Alice to C ## Freeze ## -A gateway can freeze accounting relationships in the Ripple Consensus Ledger as a means of complying with regulatory requirements: +A gateway can freeze accounting relationships in the Ripple Consensus Ledger to meet regulatory requirements: * Gateways can freeze individual accounting relationships, in case a customer address shows suspicious activity or violates a gateway's terms of use. * Gateways can freeze all accounting relationships to their issuing address, in case of a major security compromise or for migrating to a new issuing address. -* Furthermore, gateways can permanently opt out of their ability to freeze accounting relationships. This allows a gateway to assure its customers that it will continue to provide "physical-money-like" services. +* Furthermore, gateways can permanently opt out of their ability to freeze accounting relationships. This allows a gateway to assure its customers that it will continue to provide "physical-money-like" services. For more information, see the [Freeze article](concept-freeze.html). @@ -226,7 +224,7 @@ See [RequireAuth](#requireauth) for technical details on how to use Authorized A ## Source and Destination Tags ## -*Destination Tags* are a feature of Ripple payments can be used to identify the beneficiary or destination for a payment. For example, a Ripple payment to a gateway may include a destination tag to indicate which customer should be credited for the payment. A gateway should maintain a mapping of destination tags to accounts in the gateway's system of record. +*Destination Tags* are a feature of Ripple payments can be used to indicate the beneficiary or destination for a payment. For example, a Ripple payment to a gateway may include a destination tag to indicate which customer should be credited for the payment. A gateway should keep a mapping of destination tags to accounts in the gateway's system of record. Similarly, *Source Tags* indicate the originator or source of a payment. Most commonly, a Source Tag is included so that the recipient of the payment knows where to bounce the payment. When you bounce an incoming payment, use the Source Tag from the incoming payment as the Destination Tag of the outgoing (bounce) payment. @@ -244,7 +242,7 @@ See [Generating Source and Destination Tags](#generating-source-and-destination- ## Infrastructure ## -For the gateway's own security as well as the stability of the network, we recommend that each gateway operate its own `rippled` servers, along with any other important infrastructure necessary for the gateway's operation. Ripple provides detailed and individualized recommendations to businesses interested in operating a significant Ripple-based business. +For the gateway's own security as well as the stability of the network, we recommend that each gateway run its own `rippled` servers. Ripple (the company) provides detailed and individualized recommendations to businesses interested in running a significant Ripple-based business. Contact [partners@ripple.com](mailto:partners@ripple.com) to see how Ripple can help. @@ -253,14 +251,14 @@ Contact [partners@ripple.com](mailto:partners@ripple.com) to see how Ripple can There are several interfaces you can use to connect to the Ripple Consensus Ledger, depending on your needs and your existing software: * [`rippled`](reference-rippled.html) provides JSON-RPC and WebSocket APIs that can be used as a low-level interface to all core Ripple functionality. -* [RippleAPI](reference-rippleapi.html) provides a simple API for JavaScript applications. +* [RippleAPI](reference-rippleapi.html) provides a simplified API for JavaScript applications. ## Tool Security ## -Any time you submit a Ripple transaction, it must be signed using your secret key. The secret key gives full control over your Ripple address. Therefore, you should never transmit your secret to a server operated by someone else. Instead, use your own `rippled` server, or sign the transactions locally before sending them to a `rippled` server. +Any time you submit a Ripple transaction, it must be signed using your secret key. The secret key gives full control over your Ripple address. **Never** send your secret key to a server operated by someone else. Either use your own `rippled` server, or sign the transactions locally before sending them to a `rippled` server. -The examples in this document show API methods that include a secret key. This is only safe if you control `rippled` server yourself, *and* you connect to it over a connection that is secure from outside listeners. (For example, you could connect over a loopback (localhost) network, a private subnet, or an encrypted VPN.) Alternatively, you could use [RippleAPI](reference-rippleapi.html) to perform local signing before submitting your transactions to a third-party server. +The examples in this document show API methods that include a secret key. This is only safe if you control `rippled` server yourself, *and* you connect to it over a connection that is secure from outside listeners. (For example, you could connect over a loopback (localhost) network, a private subnet, or an encrypted VPN.) Alternatively, you could use [RippleAPI](reference-rippleapi.html) to sign transactions locally before submitting them to a third-party server. ## DefaultRipple ## @@ -326,9 +324,9 @@ To confirm that an address has DefaultRipple enabled, look up the address using You need a scheme to create Source and Destination tags for your customers and payments. (See [Source and Destination Tags](#source-and-destination-tags) for an explanation of what Source and Destination Tags are.) -For greater privacy and security, we recommend *not* using monotonically-incrementing numbers as destination tags that correlate 1:1 with customers. Instead, we recommend using convenient internal IDs, but mapping those to destination tags through the use of a quick hash or cipher function such as [Hasty Pudding](http://en.wikipedia.org/wiki/Hasty_Pudding_cipher). You should set aside ranges of internal numbers for different uses of destination tags. +For greater privacy and security, we recommend *not* using monotonically-incrementing numbers as destination tags that correlate 1:1 with customers. Instead, we recommend using convenient internal IDs, but mapping those to destination tags using a quick hash or cipher function such as [Hasty Pudding](http://en.wikipedia.org/wiki/Hasty_Pudding_cipher). You should set aside ranges of internal numbers for different uses of destination tags. -After passing the internal numbers through your hash function, you can use the result as a destination tag. You should check for collisions just to be safe, and do not reuse destination tags unless they have explicit expiration dates (like quotes and customer-generated tags). +After passing the internal numbers through your hash function, you can use the result as a destination tag. To be safe, you should check for collisions. Do not reuse destination tags unless they have explicit expiration dates (like quotes and customer-generated tags). We recommend making a user interface to generate a destination tag on-demand when a customer intends to send money to the gateway. Then, consider that destination tag valid only for a payment with the expected amount. Later, bounce any other transactions that reuse the same destination tag. @@ -337,7 +335,7 @@ Enable the [RequireDest](#requiredest) flag on your issuing and operational addr ## DisallowXRP ## -The DisallowXRP setting (`disallowIncomingXRP` in RippleAPI) is designed to discourage RCL users from sending XRP to an address by accident. This reduces the costs and effort of bouncing undesired payments, if you operate a gateway that does not trade XRP. The DisallowXRP flag is not strictly enforced, because doing so could allow addresses to become permanently unusable if they run out of XRP. Client applications should honor the DisallowXRP flag, but it is intentionally possible to work around. +The DisallowXRP setting (`disallowIncomingXRP` in RippleAPI) is designed to discourage RCL users from sending XRP to an address by accident. This reduces the costs and effort of bouncing undesired payments, if your gateway does not trade XRP. The DisallowXRP flag is not strictly enforced, because doing so could allow addresses to become permanently unusable if they run out of XRP. Client applications should honor the DisallowXRP flag by default. An issuing gateway that does not trade XRP should enable the DisallowXRP flag on the gateway's issuing and operational addresses. A private exchange that trades in XRP should only enable the DisallowXRP flag on addresses that are not expected to receive XRP. @@ -525,18 +523,18 @@ _(**Reminder:** Don't send your secret to a server you do not control.)_ ## Robustly Monitoring for Payments ## -In order to robustly monitor incoming payments, gateways should do the following: +To robustly check for incoming payments, gateways should do the following: * Keep a record of the most-recently-processed transaction and ledger. That way, if you temporarily lose connectivity, you know how far to go back. * Check the result code of every incoming payment. Some payments go into the ledger to charge an anti-spam fee, even though they failed. Only transactions with the result code `tesSUCCESS` can change non-XRP balances. Only transactions from a validated ledger are final. * [Look out for Partial Payments](https://ripple.com/knowledge_center/partial-payment-flag/ "Partial Payment Flag Gateway Bulletin"). Payments with the partial-payment flag enabled can be considered "successful" if any non-zero amount is delivered, even miniscule amounts. * In `rippled`, check the transaction for a `meta.delivered_amount` field. If present, that field indicates how much money *actually* got delivered to the `Destination` address. * In RippleAPI, you can search the `outcome.BalanceChanges` field to see how much the destination address received. In some cases, this can be divided into multiple parts on different trust lines. -* Some transactions modify your balances without being payments directly to or from one of your addresses. For example, if ACME sets a nonzero [TransferRate](#transferrate), then ACME's issuing address's outstanding obligations decrease each time Bob and Charlie exchange ACME issuances. See [TransferRate](#transferrate) for more information. +* Some transactions change your balances without being payments directly to or from one of your addresses. For example, if ACME sets a nonzero [TransferRate](#transferrate), then ACME's issuing address's outstanding obligations decrease each time Bob and Charlie exchange ACME issuances. See [TransferRate](#transferrate) for more information. To make things simpler for your customers, we recommend accepting payments to either operational addresses and issuing addresses. -As an added precaution, we recommend comparing the balances of your issuing address with the Ripple-backing funds in your internal accounting system each time there is a new Ripple ledger version. The issuing address's negative balances should match the assets you have allocated to RCL outside the network. If the two do not match up, then you should suspend processing payments into and out of the RCL until you have resolved the discrepancy. +As an added precaution, we recommend comparing the balances of your issuing address with the Ripple-backing funds in your internal accounting system as of each new Ripple ledger version. The issuing address's negative balances should match the assets you have allocated to RCL outside the network. If the two do not match up, then you should suspend processing payments into and out of the RCL until you have resolved the discrepancy. * Use [`rippled`'s `gateway_balances` command](reference-rippled.html#gateway-balances) or [RippleAPI's `getTrustlines` method](reference-rippleapi.html#gettrustlines) to check your balances. * If you have a [TransferRate](#transferrate) set, then your obligations within the RCL decrease slightly whenever other Ripple addresses transfer your issuances among themselves. @@ -598,19 +596,19 @@ Response: All Ripple addresses, including operational and standby addresses, are subject to the transfer fee. If you set a nonzero transfer fee, then you must send extra (to pay the TransferRate) when making payments from your operational address or standby address. In other words, your addresses must pay back a little of the balance your issuing address created, each time you make a payment. -* In `rippled`'s APIs, you can accomplish this by setting the [`SendMax` transaction parameter](reference-transaction-format.html#payment) higher than the destination `Amount` parameter. -* In RippleAPI, you can accomplish this by setting the `source.maxAmount` parameter higher than the `destination.amount` parameter; or, by setting the `source.amount` parameter higher than the `destination.minAmount` parameter. +* In `rippled`'s APIs, you should set the [`SendMax` transaction parameter](reference-transaction-format.html#payment) higher than the destination `Amount` parameter. +* In RippleAPI, you should set the `source.maxAmount` parameter higher than the `destination.amount` parameter; or, set the `source.amount` parameter higher than the `destination.minAmount` parameter. **Note:** The TransferRate does not apply when sending issuances directly to the issuing address. The issuing address must always accept its issuances at face value in the RCL. This means that customers don't have to pay the TransferRate if they send payments to the issuing address directly, but they do when sending to an operational address. If you accept payments at both addresses, you may want to adjust the amount you credit customers in your system of record when customers send payments to the operational address, to compensate for the TransferRate the customer pays. -For example: If ACME sets a transfer fee of 1%, a Ripple payment to deliver 5 EUR.ACME from a customer address to ACME's issuing address would cost exactly 5 EUR.ACME. However, the customer would need to send 5.05 EUR.ACME in order to deliver 5 EUR.ACME to ACME's operational address. (The issuing address's total obligations in the RCL decrease by 0.05 EUR.ACME.) When ACME credits customers for payments to ACME's operational address, ACME credits the customer for the amount delivered to the operational address _and_ the transfer fee, giving the customer €5,05 in ACME's systems. +For example: If ACME sets a transfer fee of 1%, a Ripple payment to deliver 5 EUR.ACME from a customer address to ACME's issuing address would cost exactly 5 EUR.ACME. However, the customer would need to send 5.05 EUR.ACME to deliver 5 EUR.ACME to ACME's operational address. (The issuing address's total obligations in the RCL decrease by 0.05 EUR.ACME.) When ACME credits customers for payments to ACME's operational address, ACME credits the customer for the amount delivered to the operational address _and_ the transfer fee, giving the customer €5,05 in ACME's systems. ## Sending Payments to Customers ## -When you build an automated system to send payments into Ripple for your customers, you must ensure that it constructs payments carefully. Malicious actors are constantly trying to find ways to trick a system into paying them more money than it should. +When you build an automated system to send payments into Ripple for your customers, you must make sure that it constructs payments carefully. Malicious actors are constantly trying to find ways to trick a system into paying them more money than it should. -One common pitfall is performing pathfinding before sending sending a payment to customers in Ripple. If you specify the issuers correctly, the [default paths](concept-paths.html#default-paths) are sufficient to deliver the currency as intended. +One common pitfall is performing pathfinding before sending sending a payment to customers in Ripple. If you specify the issuers correctly, the [default paths](concept-paths.html#default-paths) can deliver the currency as intended. The following is an example of using a locally-hosted `rippled`'s [`submit` command](reference-rippled.html#submit) to send a payment from the operational address rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn to the customer address raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n, sending and delivering funds issued by the issuing address rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW. @@ -680,14 +678,14 @@ Response: In particular, note the following features of the [Payment Transaction](reference-transaction-format.html#payment): -- No `Paths` field. The payment will only succeed if it can use a [default path](concept-paths.html#default-paths), which is preferable. Using less direct paths can become much more expensive. +- No `Paths` field. The payment only succeeds if it can use a [default path](concept-paths.html#default-paths), which is preferable. Using less direct paths can become much more expensive. - The `issuer` of both the `SendMax` and the `Amount` is the issuing address. This ensures that the transaction sends and delivers issuances from the issuing address, and not from some other gateway. -- The `value` of the `SendMax` amount is slightly higher than the destination `Amount`, in order to compensate for the [transfer fee](#transferrate). In this case, the transfer fee is 0.5%, so the `SendMax` amount is exactly 1.005 times the destination `Amount`. +- The `value` of the `SendMax` amount is slightly higher than the destination `Amount`, to compensate for the [transfer fee](#transferrate). In this case, the transfer fee is 0.5%, so the `SendMax` amount is exactly 1.005 times the destination `Amount`. ## Bouncing Payments ## -When one of your addresses receives a payment whose purpose is unclear, we recommend that you make an attempt to return the money to its sender. While this is more work than simply pocketing the money, it demonstrates good faith towards customers. You can have an operator bounce payments manually, or create a system to do so automatically. +When one of your addresses receives a payment whose purpose is unclear, we recommend that you try to return the money to its sender. While this is more work than pocketing the money, it demonstrates good faith towards customers. You can have an operator bounce payments manually, or create a system to do so automatically. The first requirement to bouncing payments is [robustly monitoring for incoming payments](#robustly-monitoring-for-payments). You do not want to accidentally refund a customer for more than they sent you! (This is particularly important if your bounce process is automated.) The [Partial Payment Flag Gateway Bulletin](https://ripple.com/knowledge_center/partial-payment-flag/) explains how to avoid a common problem. @@ -696,7 +694,7 @@ Second, you should send bounced payments as Partial Payments. Since third partie * To send a Partial Payment using `rippled`, enable the [tfPartialPayment flag](reference-transaction-format.html#payment-flags) on the transaction. Set the `Amount` field to the amount you received and omit the `SendMax` field. * To send a Partial Payment using RippleAPI, set the `allowPartialPayment` field of the [Payment object](reference-rippleapi.html#payment) to `true`. Set the `source.maxAmount` and `destination.amount` both equal to the amount you received. -It is conventional that you take the `SourceTag` field from the incoming payment (`source.tag` in RippleAPI) and use that value as the `DestinationTag` field (`destination.tag` in RippleAPI) for the return payment. +You should use the `SourceTag` value (`source.tag` in RippleAPI) from the incoming payment as the `DestinationTag` value (`destination.tag` in RippleAPI) for the return payment. To prevent two systems from bouncing payments back and forth indefinitely, you can set a new Source Tag for the outgoing return payment. If you receive an unexpected payment whose Destination Tag matches the Source Tag of a return you sent, then do not bounce it back again. @@ -705,16 +703,16 @@ To prevent two systems from bouncing payments back and forth indefinitely, you c The goal of reliably submitting transactions is to achieve the following two properties in a finite amount of time: -* Idempotency - Transactions will be processed once and only once, or not at all. +* Idempotency - Transactions should be processed once and only once, or not at all. * Verifiability - Applications can determine the final result of a transaction. -In order to achieve this, there are several steps you can take when submitting transactions: +To submit transactions reliably, follow these guidelines: * Persist details of the transaction before submitting it. * Use the `LastLedgerSequence` parameter. (RippleAPI does this by default.) * Resubmit a transaction if it has not appeared in a validated ledger whose sequence number is less than or equal to the transaction's `LastLedgerSequence` parameter. -For additional information, consult the [Reliable Transaction Submission](tutorial-reliable-transaction-submission.html) guide. +For more information, see [Reliable Transaction Submission](tutorial-reliable-transaction-submission.html). ## ripple.txt ## @@ -722,3 +720,5 @@ For additional information, consult the [Reliable Transaction Submission](tutori The [ripple.txt](https://wiki.ripple.com/Ripple.txt) standard provides a way to publish information about your gateway so that automated tools and applications can read and understand it. For example, if you run a validating `rippled` server, you can use ripple.txt to publish the public key of your validating server. You can also publish information about what currencies your gateway issues, and which Ripple addresses you control, to protect against impostors or confusion. + + diff --git a/content/tutorial-multisign.md b/content/tutorial-multisign.md index 700b2dba84..752e269696 100644 --- a/content/tutorial-multisign.md +++ b/content/tutorial-multisign.md @@ -76,7 +76,7 @@ Take note of the `account_id` (Ripple Address) and `master_seed` (Ripple secret In this example, the SignerList has 3 members, with the weights and quorum set up such that multi-signed transactions need a signature from rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW plus at least one signature from the other two members of the list. -**Caution:** Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network. +**Caution:** Never submit a secret key to a server you do not control. Do not send a secret key unencrypted over the network. $ rippled submit shqZZy2Rzs9ZqWTCQAdqc3bKgxnYq '{ > "Flags": 0, @@ -240,7 +240,7 @@ Before you can multi-sign a transaction, first [set up multi-signing](#setting- Create a JSON object that represents the transaction you want to submit. You have to specify _everything_ about this transaction, including `Fee` and `Sequence`. Also include the field `SigningPubKey` as an empty string, to indicate that the transaction is multi-signed. -Keep in mind that the `Fee` for multi-signed transactions is significantly higher than for regularly-signed transactions. It should be (N+1) times the normal [transaction cost](concept-transaction-cost.html), where N is the number of signatures you plan to provide. Given that it sometimes takes a while to collect signatures from multiple sources, you may want to include additional buffer in case the [transaction cost](concept-transaction-cost.html) increases in that time. +Keep in mind that the `Fee` for multi-signed transactions is significantly higher than for regularly-signed transactions. It should be at least (N+1) times the normal [transaction cost](concept-transaction-cost.html), where N is the number of signatures you plan to provide. Since it sometimes takes a while to collect signatures from multiple sources, you may want to specify more than the current minimum, in case the [transaction cost](concept-transaction-cost.html) increases in that time. Here's an example transaction ready to be multi-signed: @@ -265,7 +265,7 @@ Here's an example transaction ready to be multi-signed: Use the [`sign_for` command](reference-rippled.html#sign-for) with the secret key and address of one of the members of your SignerList to get a signature for that member. -**Caution:** Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network. +**Caution:** Never submit a secret key to a server you do not control. Do not send a secret key unencrypted over the network. $ rippled sign_for rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW '{ > "TransactionType": "TrustSet", @@ -322,7 +322,7 @@ You can collect additional signatures in parallel or in serial: * In parallel: Use the `sign_for` command with the original JSON for the transaction. Each response has a single signature in the `Signers` array. * In serial: Use the `sign_for` command with the `tx_json` value from the previous `sign_for` response. Each response adds a new signature to the existing `Signers` array. -**Caution:** Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network. +**Caution:** Never submit a secret key to a server you do not control. Do not send a secret key unencrypted over the network. $ rippled sign_for rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v '{ > "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC", diff --git a/content/tutorial-reliable-transaction-submission.md b/content/tutorial-reliable-transaction-submission.md index 3b8d3eb1b8..d31e7f6f1d 100644 --- a/content/tutorial-reliable-transaction-submission.md +++ b/content/tutorial-reliable-transaction-submission.md @@ -1,10 +1,10 @@ # Reliable Transaction Submission -Gateways and back-end applications should use the best practices described here to ensure that transactions are validated or rejected in a verifiable and timely fashion. You should submit transactions to trusted (locally operated) `rippled` servers. +Financial institutions and other services using the Ripple Consensus Ledger should use the best practices described here to make sure that transactions are validated or rejected in a verifiable and prompt way. You should submit transactions to trusted (locally operated) `rippled` servers. The best practices detailed in this document allow applications to submit transactions to the Ripple network while achieving: -1. [Idempotency](https://en.wikipedia.org/wiki/Idempotence) - Transactions will be processed once and only once, or not at all. +1. [Idempotency](https://en.wikipedia.org/wiki/Idempotence) - Transactions should be processed once and only once, or not at all. 2. Verifiability - Applications can determine the final result of a transaction. Applications which fail to implement best practices are at risk of the following errors: @@ -19,9 +19,9 @@ These types of errors can potentially lead to serious problems. For example, an The Ripple protocol provides a ledger shared across all nodes in the network. Through a [process of consensus and validation](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/), the network agrees on order in which transactions are applied to (or omitted from) the ledger. -Well-formed transactions submitted to trusted Ripple network nodes are usually validated or rejected in a matter of seconds. There are cases, however, in which a well-formed transaction is neither validated nor rejected this quickly. One specific case can occur if the global [transaction cost](concept-transaction-cost.html) increases after an application sends a transaction. If the transaction cost increases above what has been specified in the transaction, the transaction will not be included in the next validated ledger. If at some later date the global transaction cost decreases, the transaction may become viable again. If the transaction does not include expiration, there is no limit to how much later this can occur. +Well-formed transactions submitted to trusted Ripple network nodes are usually validated or rejected in a matter of seconds. There are cases, however, in which a well-formed transaction is neither validated nor rejected this quickly. One specific case can occur if the global [transaction cost](concept-transaction-cost.html) increases after an application sends a transaction. If the transaction cost increases above what has been specified in the transaction, the transaction is not included in the next validated ledger. If at some later date the global transaction cost decreases, the transaction could be included in a later ledger. If the transaction does not specify an expiration, there is no limit to how much later this can occur. -Applications face additional challenges, in the event of power or network loss, ascertaining the status of submitted transactions. Applications must take care both to properly submit a transaction and later to properly ascertain its authoritative results. +If a power or network outage occurs, applications face more challenges finding the status of submitted transactions. Applications must take care both to properly submit a transaction and later to properly get authoritative results. @@ -36,15 +36,15 @@ Ripple provides several APIs for submitting transactions, including [`rippled`]( - Well-formed transactions may provisionally succeed, then later fail. - Well-formed transactions may provisionally fail, then later succeed. - Well-formed transactions may provisionally succeed, and then later succeed in a slightly different way. (For example, by consuming a different offer and achieving a better or worse exchange rate than the provisional execution.) -3. Through consensus and validation, the transaction is applied to the ledger. Even some failed transactions are applied, in order to enforce a cost for being propagated through the network. +3. Through consensus and validation, the transaction is applied to the ledger. Even some failed transactions are applied, to enforce a cost for being propagated through the network. 4. The validated ledger includes the transaction, and its effects are reflected in the ledger state. - Transaction results are no longer provisional, success or failure is now final and immutable. -*Note:* When submitting a transaction via `rippled`, a successful status code returned from a submit command indicates the `rippled` server has received the candidate transaction, and does not indicate the transaction will be finally applied to the ledger. +**Note:** When submitting a transaction via `rippled`, a successful status code returned from a submit command indicates the `rippled` server has received the candidate transaction. The transaction may or may not be applied to a validated ledger. APIs may return provisional results based on the result of applying candidate transactions to the current, in-progress ledger. Applications must not confuse these with the final, *immutable*, results of a transaction. Immutable results are found only in validated ledgers. Applications may need to query the status of a transaction repeatedly, until the ledger containing the transaction results is validated. -While applying transactions, `rippled` servers use the *last validated ledger*, a snapshot of the ledger state based on transactions the entire network has validated. The process of consensus and validation apply a set of new transactions to the last validated ledger in canonical order, resulting in a new validated ledger. This new validated ledger instance and the ones that preceded it comprise the ledger history. +While applying transactions, `rippled` servers use the *last validated ledger*, a snapshot of the ledger state based on transactions the entire network has validated. The process of consensus and validation apply a set of new transactions to the last validated ledger in canonical order, resulting in a new validated ledger. This new validated ledger instance and the ones that preceded it form the ledger history. Each validated ledger instance has a sequence number, which is one greater than the sequence number of the preceding instance. Each ledger also has an identifying hash value, which is uniquely determined from its contents. There may be many different versions of in-progress ledgers, which have the same sequence number but different hash values. Only one version can ever be validated. @@ -56,9 +56,9 @@ Each validated ledger has a canonical order in which transactions apply. This or [`LastLedgerSequence`](reference-transaction-format.html#lastledgersequence) is an optional parameter of all transactions. This instructs the Ripple Consensus Ledger that a transaction must be validated on or before a specific ledger instance. The Ripple Consensus Ledger never includes a transaction in a ledger instance whose sequence number is higher than the transaction's `LastLedgerSequence` parameter. -Use the `LastLedgerSequence` parameter to prevent undesirable cases where a transaction is not promptly validated yet could become viable at some point in the future. Gateways and other back-end applications should specify the `LastLedgerSequence` parameter on every transaction. Automated processes should use a value of 4 greater than the sequence number of the last validated ledger[1] to ensure that a transaction is validated or rejected in a predictable and timely fashion. +Use the `LastLedgerSequence` parameter to prevent undesirable cases where a transaction is not confirmed promptly but could be included in a future ledger. You should specify the `LastLedgerSequence` parameter on every transaction. Automated processes should use a value of 4 greater than the last validated ledger index to make sure that a transaction is validated or rejected in a predictable and prompt way. -Applications using rippled APIs should explicitly specify a `LastLedgerSequence` when submitting transactions. RippleAPI uses the `maxLedgerVersion` field of [Transaction Instructions](reference-rippleapi.html#transaction-instructions) to specify the `LastLedgerSequence`. RippleAPI automatically provides an appropriate value by default. You can specify `maxLedgerVersion` as `null` to intentionally omit `LastLedgerSequence`, in case you want a transaction that can be executed after an unlimited amount of time. +Applications using `rippled` APIs should explicitly specify a `LastLedgerSequence` when submitting transactions. RippleAPI uses the `maxLedgerVersion` field of [Transaction Instructions](reference-rippleapi.html#transaction-instructions) to specify the `LastLedgerSequence`. RippleAPI automatically provides an appropriate value by default. You can specify `maxLedgerVersion` as `null` to intentionally omit `LastLedgerSequence`, in case you want a transaction that can be executed after an unlimited amount of time. @@ -67,7 +67,7 @@ Applications using rippled APIs should explicitly specify a `LastLedgerSequence` ### Reliable Transactions Submission -Applications submitting transactions should employ the following practices in order to submit reliably even in the event that a process dies or other failure occurs. Application transaction results must be verified so that applications can act on the final, validated results. +Applications submitting transactions should use the following practices to submit reliably even in the event that a process dies or other failure occurs. Application transaction results must be verified so that applications can act on the final, validated results. Submission and verification are two separate procedures which may be implemented using the logic described in this document. @@ -77,7 +77,7 @@ Submission and verification are two separate procedures which may be implemented ### Submission -[Persist](https://en.wikipedia.org/wiki/Persistence_%28computer_science%29) details of the transaction prior to submission, in case of power failure or network failure before submission completes. On restart, the persisted values make it possible to verify the status of the transaction. +[Persist](https://en.wikipedia.org/wiki/Persistence_%28computer_science%29) details of the transaction before submission, in case of power failure or network failure before submission completes. On restart, the persisted values make it possible to verify the status of the transaction. The submission process: @@ -86,7 +86,7 @@ The submission process: 2. Persist the transaction details, saving: - Transaction hash - `LastLedgerSequence` - - Account ID and sequence number + - Sender address and sequence number - Application-specific data, as needed 3. Submit the transaction @@ -94,7 +94,7 @@ The submission process: ### Verification -During normal operation, applications may check the status of submitted transactions by their hashes; or, depending on the API used, receive notifications when transactions have been validated (or failed). This normal operation may be interrupted, for example by network failures or power failures. In case of such interruption applications need to reliably verify the status of transactions which may or may not have been submitted to the network prior to the interruption. +During normal operation, applications may check the status of submitted transactions by their hashes; or, depending on the API used, receive notifications when transactions have been validated (or failed). This normal operation may be interrupted, for example by network failures or power failures. In case of such interruption applications need to reliably verify the status of transactions which may or may not have been submitted to the network before the interruption. On restart, or the determination of a new last validated ledger (pseudocode): @@ -123,7 +123,7 @@ For each persisted transaction without validated result: ## Technical Application -In order to implement the transaction submission and verification best practices, applications need to perform the following actions. +To implement the transaction submission and verification best practices, applications need to do the following: 1. Determine the signing account's next sequence number * Each transaction has an account-specific sequence number. This guarantees the order in which transactions signed by an account are executed and makes it safe to resubmit a transaction without danger of the transaction being applied to the ledger more than once. @@ -136,7 +136,7 @@ In order to implement the transaction submission and verification best practices 5. Determine the final result of a transaction * Final results are an immutable part of the ledger history. -An application's means of performing these actions depends on the API the application uses. An application may use any of the following interfaces: +How the application does these actions depends on the API the application uses. An application may use any of the following interfaces: 1. [`rippled`'s internal APIs](reference-rippled.html) 2. [RippleAPI](reference-rippleapi.html) @@ -188,7 +188,7 @@ Response body: In this example, the account's sequence is **4** (note `"Sequence": 4`, in `"account_data"`) as of the last validated ledger (note `"ledger": "validated"` in the request, and `"validated": "true"` in the response). -If an application were to submit three transactions signed by this account, they would use sequence numbers 4, 5, and 6. In order to submit multiple transactions without waiting for validation of each, an application should keep a running account sequence number. +If an application were to submit three transactions signed by this account, they would use sequence numbers 4, 5, and 6. To submit multiple transactions without waiting for validation of each, an application should keep a running account sequence number. #### Determine the Last Validated Ledger @@ -239,12 +239,12 @@ Response: } ``` -In this example the last validated ledger sequence number is 10268596 (found under `result.state.validated_ledger` in the response). Note also this example indicates a gap in ledger history. The server used here would not be able to provide information about the transactions applied during that gap (ledgers 10256383 through 10256411). If configured to do so, the server will eventually retrieve that portion of the ledger history. +In this example the last validated ledger sequence number is 10268596 (found under `result.state.validated_ledger` in the response). Note also this example indicates a gap in ledger history. The server used here would not be able to provide information about the transactions applied during that gap (ledgers 10256383 through 10256411). If configured to do so, the server eventually retrieves that part of the ledger history. #### Construct the Transaction -`rippled` provides the [sign method](reference-rippled.html#sign) to prepare a transaction for submission. This method requires an account secret, which should only be passed to trusted `rippled` instances. This example issues 10 FOO (a made-up currency) from a gateway to another Ripple account. +`rippled` provides the [sign method](reference-rippled.html#sign) to prepare a transaction for submission. This method requires an account secret, which should only be passed to trusted `rippled` instances. This example issues 10 FOO (a made-up currency) to another Ripple address. Request: @@ -275,7 +275,7 @@ Request: Notice the application specifies the account sequence `"Sequence": 4`, learned from an earlier call to `account_info`, to avoid `tefPAST_SEQ` errors. -Notice also the `LastLedgerSequence` based on the last validated ledger our application learned from `server_state`. The recommendation for backend applications is to use *(last validated ledger sequence + 4)*. Alternately, use a value of *(current ledger + 3)*. If `LastLedgerSequence` is miscalculated and less than the last validated ledger, the transaction will fail with `tefMAX_LEDGER` error. +Notice also the `LastLedgerSequence` based on the last validated ledger our application learned from `server_state`. The recommendation for backend applications is to use *(last validated ledger sequence + 4)*. Alternately, use a value of *(current ledger + 3)*. If `LastLedgerSequence` is miscalculated and less than the last validated ledger, the transaction fails with `tefMAX_LEDGER` error. Response: @@ -412,9 +412,9 @@ Response: } ``` -This example response shows `"validated": true`, indicating the transaction has been included in a validated ledger and therefore the result of the transaction is immutable. Further, the metadata includes `"TransactionResult": "tesSUCCESS"`, indicating the transaction was applied to the ledger. +This example response shows `"validated": true`, indicating the transaction has been included in a validated ledger, so the result of the transaction is immutable. Further, the metadata includes `"TransactionResult": "tesSUCCESS"`, indicating the transaction was applied to the ledger. -If the response does not include `"validated": true`, the result is provisional and subject to change. To retrieve a final result, applications must invoke the `tx` method again, allowing enough time for the network to validate subsequent ledger instances. It may be necessary to wait for the ledger specified in `LastLedgerSequence` to be validated, although if the transaction is included in an earlier validated ledger the result become immutable at that time. +If the response does not include `"validated": true`, the result is provisional and subject to change. To retrieve a final result, applications must invoke the `tx` method again, allowing enough time for the network to validate more ledger instances. It may be necessary to wait for the ledger specified in `LastLedgerSequence` to be validated, although if the transaction is included in an earlier validated ledger the result become immutable at that time. #### Verify Missing Transaction @@ -437,7 +437,7 @@ Applications must handle cases where a call to the [`tx` method](reference-rippl } ``` -The `txnNotFound` result code occurs in cases where the transaction has failed to be included in any ledger. However, it could also occur when a rippled instance does not have a complete ledger history, or if the transaction has not yet propagated to the rippled instance. Applications should make further queries to determine how to react. +The `txnNotFound` result code occurs in cases where the transaction is not included in any ledger. However, it could also occur when a `rippled` instance does not have a complete ledger history, or if the transaction has not yet propagated to the `rippled` instance. Applications should make further queries to determine how to react. The [`server_state` method](reference-rippled.html#server-state) (used earlier to determine the last validated ledger) indicates how complete the ledger history is, under `result.state.complete_ledgers`. @@ -472,11 +472,11 @@ The [`server_state` method](reference-rippled.html#server-state) (used earlier t } ``` -Our example transaction specified `LastLedgerSequence` 10268600, based on the last validated ledger at the time, plus four. So to determine whether our missing transaction has permanently failed, our `rippled` server must have ledgers 10268597 through 10268600. If the server has those validated ledgers in its history, **and** `tx` returns `txnNotFound`, then the transaction has failed and will never be included in any ledger. In this case, application logic may dictate building and submitting a replacement transaction with the same account sequence and updated `LastLedgerSequence`. +Our example transaction specified `LastLedgerSequence` 10268600, based on the last validated ledger at the time, plus four. To determine whether our missing transaction has permanently failed, our `rippled` server must have ledgers 10268597 through 10268600. If the server has those validated ledgers in its history, **and** `tx` returns `txnNotFound`, then the transaction has failed and cannot be included in any future ledger. In this case, application logic may dictate building and submitting a replacement transaction with the same account sequence and updated `LastLedgerSequence`. -The server state may indicate a last validated ledger sequence number less than the specified `LastLedgerSequence`. If so, the `txnNotFound` indicates either (a) the submitted transaction failed to be distributed to the network, or (b) the transaction has been distributed to the network but has not yet been processed. To handle the former case, applications may submit again the same signed transaction. Because the transaction has a unique account sequence number, it will be processed at most once. +The server may report a last validated ledger sequence number less than the specified `LastLedgerSequence`. If so, the `txnNotFound` indicates either (a) the submitted transaction has not been distributed to the network, or (b) the transaction has been distributed to the network but has not yet been processed. To handle the former case, applications may submit again the same signed transaction. Because the transaction has a unique account sequence number, it can be processed at most once. -Finally the server state might indicate one or more gaps in the transaction history. The `completed_ledgers` field shown in the response above indicates that ledgers 10256383 through 10256411 are missing from this rippled instance. Our example transaction can only appear in ledgers 10268597 - 10268600 (based on when it was submitted and `LastLedgerSequence`), so the gap shown here is not relevant. However, if the gap indicated a ledger in that range was missing, then an application would need to query another rippled server (or wait for this one to retrieve the missing ledgers) in order to determine that a `txnNotFound` result is immutable. +Finally the server may show one or more gaps in the transaction history. The `completed_ledgers` field shown in the response above indicates that ledgers 10256383 through 10256411 are missing from this rippled instance. Our example transaction can only appear in ledgers 10268597 - 10268600 (based on when it was submitted and `LastLedgerSequence`), so the gap shown here is not relevant. However, if the gap indicated a ledger in that range was missing, then an application would need to query another rippled server (or wait for this one to retrieve the missing ledgers) to determine that a `txnNotFound` result is immutable. ## Additional Resources diff --git a/content/tutorial-rippleapi-beginners-guide.md b/content/tutorial-rippleapi-beginners-guide.md index 7c3f933ce6..ac253f95e1 100644 --- a/content/tutorial-rippleapi-beginners-guide.md +++ b/content/tutorial-rippleapi-beginners-guide.md @@ -1,6 +1,6 @@ # RippleAPI Beginners Guide # -This tutorial guides you through the basics of building a simple Ripple-connected application using [Node.js](http://nodejs.org/) and [RippleAPI](reference-rippleapi.html), a simple JavaScript API for accessing the Ripple Consensus Ledger. +This tutorial guides you through the basics of building a Ripple-connected application using [Node.js](http://nodejs.org/) and [RippleAPI](reference-rippleapi.html), a JavaScript API for accessing the Ripple Consensus Ledger. The scripts and configuration files used in this guide are [available in the Ripple Dev Portal GitHub Repository](https://github.com/ripple/ripple-dev-portal/tree/master/content/code_samples/rippleapi_quickstart). @@ -29,7 +29,7 @@ nodejs --version ## Use NPM to install RippleAPI and dependencies ## -RippleAPI uses the newest version of JavaScript, ECMAScript 6 (also known as ES2015). In order to use the new features of ECMAScript 6, RippleAPI depends on [Babel-Node](https://babeljs.io) and its ES2015 presets. You can use `npm` to install RippleAPI and these dependencies together. +RippleAPI uses the newest version of JavaScript, ECMAScript 6 (also known as ES2015). To use the new features of ECMAScript 6, RippleAPI depends on [Babel-Node](https://babeljs.io) and its ES2015 presets. You can use `npm` to install RippleAPI and these dependencies together. #### 1. Create a new directory for your project @@ -39,13 +39,13 @@ Create a folder called (for example) `my_ripple_experiment`: mkdir my_ripple_experiment && cd my_ripple_experiment ``` -Optionally, initiate a [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) repository in that directory so you can track changes to your code. +Optionally, start a [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) repository in that directory so you can track changes to your code. ``` git init ``` -Alternatively, you can [create a repo on GitHub](https://help.github.com/articles/create-a-repo/) in order to version and share your work. After setting it up, [clone the repo](https://help.github.com/articles/cloning-a-repository/) to your local machine and `cd` into that directory. +Alternatively, you can [create a repo on GitHub](https://help.github.com/articles/create-a-repo/) to version and share your work. After setting it up, [clone the repo](https://help.github.com/articles/cloning-a-repository/) to your local machine and `cd` into that directory. #### 2. Create a new `package.json` file for your project. @@ -81,7 +81,7 @@ npm WARN ajv@1.4.10 requires a peer of ajv-i18n@0.1.x but none was installed. # First RippleAPI Script ## -This script, `get-account-info.js`, simply fetches information about a hard-coded account. Use it to test that RippleAPI works: +This script, `get-account-info.js`, fetches information about a hard-coded account. Use it to test that RippleAPI works: ``` {% include 'code_samples/rippleapi_quickstart/get-account-info.js' %} @@ -122,7 +122,7 @@ const RippleAPI = require('ripple-lib').RippleAPI; The opening line enables [strict mode](https://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/). This is purely optional, but it helps you avoid some common pitfalls of JavaScript. See also: [Restrictions on Code in Strict Mode](https://msdn.microsoft.com/library/br230269%28v=vs.94%29.aspx#Anchor_1). -The second line imports RippleAPI into the current scope using Node.js's require function. RippleAPI is just one of [the modules `ripple-lib` exports](https://github.com/ripple/ripple-lib/blob/develop/src/index.js). +The second line imports RippleAPI into the current scope using Node.js's require function. RippleAPI is one of [the modules `ripple-lib` exports](https://github.com/ripple/ripple-lib/blob/develop/src/index.js). ### Instantiating the API ### @@ -147,13 +147,13 @@ The one argument to the constructor is an options object, which has [a variety o api.connect().then(() => { ``` -The [connect() method](reference-rippleapi.html#connect) is one of many RippleAPI methods that returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), which is a special kind of JavaScript object. A Promise is designed to perform an asynchronous operation that returns a value later, such as querying the Ripple Consensus Ledger. +The [connect() method](reference-rippleapi.html#connect) is one of many RippleAPI methods that returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), which is a special kind of JavaScript object. A Promise is designed to do an asynchronous operation that returns a value later, such as querying the Ripple Consensus Ledger. When you get a Promise back from some expression (like `api.connect()`), you call the Promise's `then` method and pass in a callback function. Passing a function as an argument is conventional in JavaScript, taking advantage of how JavaScript functions are [first-class objects](https://en.wikipedia.org/wiki/First-class_function). -When a Promise finishes with its asynchronous operations, the Promise runs the callback function you passed it. The return value from the `then` method is another Promise object, so you can "chain" that into another `then` method, or the Promise's `catch` method, which also takes a callback. The callback you provide to `catch` gets called if something goes wrong. +When a Promise finishes with its asynchronous operations, the Promise runs the callback function you passed it. The return value from the `then` method is another Promise object, so you can "chain" that into another `then` method, or the Promise's `catch` method, which also takes a callback. The callback you pass to `catch` gets called if something goes wrong. -Finally, we have more new ECMAScript 6 syntax - an [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). Arrow functions are a shorter way of defining anonymous functions. This is convenient for defining lots of one-off functions as callbacks. The syntax `()=> {...}` is mostly equivalent to `function() {...}`. If you want an anonymous function with one parameter, you can use a syntax like `info => {...}` instead, which is basically just `function(info) {...}` as well. +Finally, we have more new ECMAScript 6 syntax - an [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). Arrow functions are a shorter way of defining anonymous functions. This is convenient for defining lots of one-off functions as callbacks. The syntax `()=> {...}` is mostly equivalent to `function() {...}`. If you want an anonymous function with one parameter, you can use a syntax like `info => {...}` instead, which is almost the same as `function(info) {...}` syntax. ### Custom code ### @@ -171,7 +171,7 @@ Finally, we have more new ECMAScript 6 syntax - an [arrow function](https://deve /* end custom code -------------------------------------- */ ``` -This is the part that really defines what this script does, so this is the part you will probably spend the most time customizing. +This is the part that you change to do whatever you want the script to do. The example code looks up a Ripple account by its address. Try running the code with different addresses to see different results. @@ -191,7 +191,7 @@ The `getAccountInfo` API method returns another Promise, so the line `}).then( i }).catch(console.error); ``` -The remainder of the sample code is mostly more [boilerplate code](reference-rippleapi.html#boilerplate). The first line ends the previous callback function, then chains to another callback to run when it ends. That method disconnects cleanly from the Ripple Consensus Ledger, and has yet another callback which writes to the console when it finishes. If your script waits on [RippleAPI events](reference-rippleapi.html#api-events), do not disconnect until you are done waiting for events. +The rest of the sample code is mostly more [boilerplate code](reference-rippleapi.html#boilerplate). The first line ends the previous callback function, then chains to another callback to run when it ends. That method disconnects cleanly from the Ripple Consensus Ledger, and has yet another callback which writes to the console when it finishes. If your script waits on [RippleAPI events](reference-rippleapi.html#api-events), do not disconnect until you are done waiting for events. The `catch` method ends this Promise chain. The callback provided here runs if any of the Promises or their callback functions encounters an error. In this case, we pass the standard `console.error` function, which writes to the console, instead of defining a custom callback. You could define a smarter callback function here to intelligently catch certain error types. @@ -286,9 +286,8 @@ The file `build/ripple-.js` is a straight export of RippleAPI (w The following HTML file demonstrates basic usage of the browser version of RippleAPI to connect to a public `rippled` server and report information about that server. Instead of using Node.js's "require" syntax, the browser version creates a global variable named `ripple`, which contains the `RippleAPI` class. -To use this example, you must first [build RippleAPI](#build-instructions) and then copy one of the resulting output files to the same folder as this HTML file. (You can use either the minified or full-size version.) Modify the first `