Protocol01

Protocol.Protocol01 History

Hide minor edits - Show changes to output

April 11, 2012, at 09:18 PM by 24.67.80.198 -
Changed line 324 from:
Ripple uses the Metropolis-Hastings algorithm for routing, as described in Clarke and Sandberg's presentation [[Routing in the Dark -> http://www.math.chalmers.se/~ossa/defcon13/vegas1_print.pdf]] (PDF). 
to:
Ripple uses the Metropolis-Hastings algorithm for routing, as described in Clarke and Sandberg's presentation [[Routing in the Dark -> https://freenetproject.org/papers/vegas1_dc.pdf]] (PDF). 
Changed lines 37-39 from:
  * make "on-demand", "payable at end of month", "payable in 90 days", etc. suffixes on regular units all into different units
  * "amount" field may include payment dates, or any other information necessary to do conversions
  * units definition must give programmatic instructions to do addition/subtraction of amounts in the same units, and conversion to other units (present value calculation -- defacto interest)
to:
  * "on-demand", "payable at end of month", "payable in 90 days", etc. as suffixes on regular units become different different units, stored on separate accounts
  * units definition must show how to do conversion
to other units (present value calculation = defacto interest)
Changed lines 40-42 from:
  * account contracts in account creation messages, including units definition
  * how does this affect the concept of an account "balance"?
to:
  * put account contracts in account creation messages, including units definition
  * have a units-udpate message that can hold custom fields for sharing units state (such as current interest rate)?
Changed lines 110-111 from:
* the minimum fee for payments in each direction (see Fees)
to:
Deleted lines 186-189:
'''Changing Minimum Fee'''

Send a signed @@fee-change@@ message containing the new minimum fee.

Changed lines 13-14 from:
to:
* Stanislav Mazhara
Deleted lines 27-29:
* allow nodes to reveal location of connections to prove no cheating on location swaps
* per-hop fee-based routing spaces?
* weight location swap calculations by accounts' credit range to put more emphasis on high-capacity accounts?
Changed lines 30-32 from:
* link-state routing?
* interest rate field on accounts
  * allow for progressively-increasing interest on higher balance amounts, eg, 0% on first $20, 5% on next $980, 8% thereafter.
to:
* link-state routing!
  * introduce a host-level connection for transmitting routing data, timing/heartbeat messages
Changed lines 36-43 from:
to:
* generalized (time-value) units
  * make "on-demand", "payable at end of month", "payable in 90 days", etc. suffixes on regular units all into different units
  * "amount" field may include payment dates, or any other information necessary to do conversions
  * units definition must give programmatic instructions to do addition/subtraction of amounts in the same units, and conversion to other units (present value calculation -- defacto interest)
    * node software may take plugins for custom units
  * account contracts in account creation messages, including units definition
  * how does this affect the concept of an account "balance"?

October 17, 2006, at 06:25 PM by ryan - payment after account creation on initial balances, took out limit-reject
Added lines 143-144:
In the case that there is an initial balance agreed upon for the account, a payment should be made  immediately upon account creation to back up that balance with the proper receipts ([[see Payments -> #payments]]).
Deleted lines 160-161:
If a @@limit-reject@@ is received with the same account ID and reference to the request ID, then the credit change has been rejected.  The rejecting node may of course propose a different limit it considers appropriate by sending its own limit-request message anew.
October 16, 2006, at 05:37 PM by ryan - change limit semantics a bit
Changed lines 145-146 from:
If a node wishes to change its partner's or its own credit limit, it sends a @@limit@@ message containing:
to:
If a node wishes to increase its partner's or its own credit limit, it sends a @@limit-request@@ message containing:
Deleted line 147:
* request ID
Changed lines 153-158 from:
The change is considered pending until a @@limit-accept@@ containing the same information is received back.  If a @@limit-reject@@ is received with the same account ID and request ID, then the credit change has been rejected.  The rejecting node may of course propose a different limit it considers appropriate by sending its own limit message anew.

In the case of decreasing either limit
, the limit message is considered as simply informative, and should be implemented immediately, with the limit-accept being sent back immediately.  A node may not reject a decreased limit.

In the case of increasing either
limit, the message is interpreted either as a request or an offer and the limit-confirm or -reject may be delayed while the partner considers
to:
In the case of wishing to increase one's partner's credit limit, the request is interpreted as an offer.

The change
is considered pending until the requesting node receives back a @@limit@@ message containing the same information as the @@limit-request@@, plus:

* a reference to the ID
of the original @@limit-request@@ message

If a @@limit-reject@@ is received with the same account ID and reference to the request ID
, then the credit change has been rejected.  The rejecting node may of course propose a different limit it considers appropriate by sending its own limit-request message anew.

If
a node wishes to decrease either limit, it sends a @@limit@@ message, which is implemented immediately upon acknowledgment.  In this case, the request ID field is not requiredA node may not reject a decreased limit.
Changed lines 167-168 from:
A node may cancel a limit request by replying to a limit-accept with a "request withdrawn" error.
to:
A node may cancel a limit request by responding to a limit acceptance message with a "request withdrawn" error.
Deleted line 34:
   * can be implemented as multiple accounts (or sub-accounts) with different interest rates and limits. The protocol will automatically use the lowest interest rate that has available credit.
Deleted line 24:
  * ? automatically when limits and balance zero
Changed lines 5-7 from:
%center%''by Ryan Fugger''\\
%center%
''with contributions by Brandyn Webb, Evgeni Pandurski, and Matthew Toseland''
to:
%center%''by Ryan Fugger''

'''Contributors'''

*
Brandyn Webb
* Evgeni Pandurski
* Matthew Toseland
* Jiri Baum
October 15, 2006, at 07:41 AM by jiri_at_baum_com_au - progressive interest as multiple (sub-)accounts
Added line 30:
   * can be implemented as multiple accounts (or sub-accounts) with different interest rates and limits. The protocol will automatically use the lowest interest rate that has available credit.
October 15, 2006, at 07:05 AM by jiri_at_baum_com_au - automatic account close; recipient can decline out-of-bounds request
Added line 19:
  * ? automatically when limits and balance zero
Added line 31:
  * recipient can accept or decline
Changed lines 29-32 from:
to:
* out-of-bounds request flag on payments (for gifts, donations, etc.)
  * if account exists between payer and recipient, allow payment to move balance outside existing credit limits
  * if no account exists between payer and recipient, create an account with credit limits of zero (reflecting the fact that no trust exists), and an initial out-of-bounds balance reflecting the payment

Added line 112:
* an initial balance for the new account
Changed lines 26-29 from:
to:
* link-state routing?
* interest rate field on accounts
  * allow for progressively-increasing interest on higher balance amounts, eg, 0% on first $20, 5% on next $980, 8% thereafter.

Changed lines 25-28 from:
* ponder advertisement-based closest-direction routing as alternative to MH
 
* attenuated bloom filters?
 
* advertise link capacity as well?
to:
* alternative forking formula: minimize [sum over all forks(query amount * distance to target)] * # of forks
Changed lines 24-28 from:
to:
* express time limit in real time instead of hops?
* ponder advertisement-based closest-direction routing as alternative to MH
  * attenuated bloom filters?
  * advertise link capacity as well?

Added lines 348-351:
The penalty deadline is the time after which the promising node may begin charging a penalty to its partner for having to hold credit it could be using for payment.  The penalty is charged continuously at the daily rate specified.  Intermediaries should always set a shorter deadline and higher penalty rate on promises out than they have received on promises in, to ensure that they are compensated for overdue @@receipts@@.  This provides incentive for the recipient to ensure quick completion or cancellation of each promise path, without requiring hard-and-fast deadlines to come into play so soon that minor delays spawn major disputes.

Nodes should only accept promises for paths in a single swarm for any given payment.

Changed lines 363-364 from:
The recipient can cancel the transaction at any time by informing the payer and releasing its neighbours from their promises with a @@path-cancel@@.  The payer can cancel the transaction by informing the recipient that it can release its neighbours from their promises.  Released promises should be propagated back down each payment path to free up those funds for other payments.
to:
The recipient's receipt deadline to the payer should be well before the penalty deadline on any promise received.  Therefore, the recipient should wait until it has received promises equal to the entire payment amount before sending back any promises-received to the payer.

The recipient can cancel the transaction at any time by sending the payer a @@payment-cancel@@ and releasing its neighbours from their promises with a @@path-cancel@@ (see [[Cancelling Unneeded Paths -> #cancelling-paths]]).  The payer can cancel the transaction by sending the recipient a @@payment-cancel@@, informing it
that it can release its neighbours from their promises.  Released promises should be propagated back down each payment path to free up those funds for other payments.
Changed lines 399-400 from:
A node may release a neighbour from all or part of its promise at any time with a signed @@promise-release@@ message:
to:
A node may release a neighbour from all or part of its promise at any time with a signed @@path-cancel@@ message:
June 12, 2006, at 01:43 AM by ryan - new bidirectional query/response scheme to replace query/path-available
Changed line 19 from:
* specify error codes
to:
* error codes
Changed lines 22-29 from:
* separate routing spaces for:
  * convertible
accounts
  * zero-fee account pairs
  * sub
-0.1% fee pairs
  * sub-1.0% fee pairs
* path-cancel messages to release amounts frozen in path-available
* weight location swap calculations by
accounts' credit range to put more emphasis on high-capacity accounts
to:
* per-hop fee-based routing spaces?
* weight location swap calculations by
accounts' credit range to put more emphasis on high-capacity accounts?
Added line 36:
  * Changing Minimum Fee
Changed lines 42-43 from:
  * Path Queries
  * Available Paths
to:
  * Path Queries & Responses
Changed lines 46-47 from:
  * Making Promises (Commit-Request
to:
  * Making Promises (Commit-Request)
  * Cancelling Unneeded Paths
Added line 69:
[[#connection-time]]
Changed lines 92-93 from:
to:
* the minimum fee for payments in each direction (see Fees)
Added line 107:
* the minimum fee offerer will charge for payments through this account
Added line 117:
* the minimum fee sender will charge for payments through this account
Added lines 166-169:
'''Changing Minimum Fee'''

Send a signed @@fee-change@@ message containing the new minimum fee.

Changed line 193 from:
* Initiating payment between the payer and recipient nodes
to:
* Initializing payment between the payer and recipient nodes
Deleted line 204:
* time of request
Changed lines 211-216 from:
The authorization number may be used to pre-authorize payments, so the node can automatically make payments when it receives a request.  The request-payment message may also be authorized by signing it with a certain key, contained in the node owner's smart card, for example, for point-of-sale scenarios.

'''Initiating Payment'''

The payer node contacts recipient node and communicates
the following in an @@payment-init@@ message:
to:
The authorization number field may be used to contain a single-use password to pre-authorize payments, so the node can automatically make payments when it receives a request containing a password from a pre-determined list that it holds.  The payment-request message may also be authorized by signing it with a certain key, contained in the node owner's smart card, for example, for point-of-sale scenarios.

'''Initializing Payment'''

The payer node contacts recipient node and communicates the following in a
@@payment-init@@ message:
Changed line 222 from:
* payer's routing information (optional?)
to:
* payer's routing information
Changed lines 225-226 from:
Transaction units allow the payer to mask the true units of the payment by inventing custom units.  However, this will hinder intermediaries' ability to properly conduct zero-fee path searched.  To guarantee zero-fee paths only, transaction units must be recognized by at least some of the intermediaries.  See [[Path Queries -> #path-queries]].
to:
Transaction units allow the payer to mask the true units of the payment by inventing custom units.  However, this will hinder intermediaries' ability to properly conduct zero-fee path searches.  To guarantee overall fee limits on paths, transaction units must be recognizable to the intermediaries.  See [[Path Queries -> #path-queries]].
Changed line 233 from:
* number of transaction units that will consist the entire payment
to:
* payment amount in transaction units
Changed lines 241-242 from:
Otherwise the payer rejects the payment initiation with an error code.
to:
Otherwise the recipient rejects the payment initiation with an error code.
Changed lines 244-247 from:
'''Path Queries'''

The payer sends out @@path-query@@ messages to one or more of their account partners, which they in turn pass on to one or more of their partners as described in [[Query Routing -> #query-routing]].  A path-query message consists of:
to:
'''Path Queries & Responses'''

The payer and recipient send out @@path-query@@ messages to one or more account partners, which they in turn pass on to one or more of their partners as described in [[Query Routing -> #query-routing]].  A path-query message consists of:
Changed lines 249-251 from:
* query ID
* subquery ID
* credit available along this sub-query path so far, in transaction units
to:
* swarm ID
* path ID
* direction of query, forward or backward, depending on whether query originates at payer or recipient
* transaction units
* credit available along this
path so far, in transaction units
Changed lines 255-256 from:
* the transaction units
* credit available along path so far, in
account units for that account (defines a conversion rate from transaction to account units)
to:
* credit available along path so far, in account units for that account (defines a conversion rate from transaction units to account units)
Changed lines 257-261 from:
* the remaining visited-nodes limit
* the original proximity-aware hop limit
* the remaining proximity-aware hop limit
* the closest distance to the target so far on this sub-query
* a bloom filter containing aliases for each of the nodes visited by this subquery
to:
* the time this available credit guarantee will expire, measured in connection time between sender and recipient
* promise penalty deadline (forward: maximum offered; backward: minimum required)
* promise daily penalty rate (forward: maximum offered; backward: minimum required)
* promise final deadline (forward: maximum offered; backward: minimum required)
* the remaining hop limit for the query
* a bloom filter containing aliases for each of the locations visited on this paths
Changed lines 264-282 from:

The subquery ID is to distinguish between forked subpaths of the query.  The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  The visited-nodes limit is a cap on the nodes visited for this query ID.  The proximity-aware hop limit is only decremented when the subquery moves away from its target.  Whenever the subquery gets closer to its target, the hop limit is reset to its original setting.  The bloom filter of visited nodes is for detecting loops.

If the payer wishes to guarantee a per-hop fee limit of zero, it must specify transaction units that are known to most if not all of
the intermediaries, so they can manage exchange rate differences between them.  Otherwise these might become de facto fees.

A node that receives a query can accept it, which needs only an empty affirmative reply, or reject it by replying with an error code.
  See [[Query Routing -> #query-routing]] below for how nodes decide where to pass a query.  For each neighbour that it is passing the query on to, the node receiving a query should:

* replace account ID of previous step with account ID of next step
* calculate the desired conversion rate from transaction units to account units for the account with that neighbour, based on
the conversion rate of the incoming query
* reduce
the “credit available along the path” if the account with that neighbour has insufficient available credit
* decrement the remaining visited-nodes limit and assign that neighbour a proportion of it
* decrement or reset
the hop limit
* put an alias it can remember into the visited-nodes bloom filter

[[#available-paths]]
'''Available Paths'''

The payment recipient also participates in the path-finding process.  If the payer has revealed some or all of his routing information during payment initiation, the recipient may immediately begin issuing @@path-available@@ messages.  Otherwise, he must wait until he receives a query to begin issuing them.  Path available messages contain
:
to:
* the accumulated fee limit for this query (as a percentage of the query amount)

Final payment will be made using
the paths found by queries within a single swarm.  Therefore, queries within a single swarm may not reserve the same credit.  Queries within different swarms, but with the same payment ID, may reserve the same credit.  Queries with different payment IDs may not reserve the same credit.  When a query forks in two separate directions, it splits into two different paths, but each maintain the same swarm ID.  To avoid overlap, payer-initiated (forward) queries should use even-numbered swarm IDs, and recipient-initiated (backward) queries odd-numbered swarm IDs.  See [[Query Routing -> #query-routing]]. 

The payer sends out "forward" queries, and
the recipient sends out "backward" queries, refering to the direction the payment will ultimately take.  If fees are permitted, the backward queries are more precise:  the payment amount is generally interpreted as the amount to be received by the recipient (Paypal notwithstanding), and the backward queries begin by specifying this amount and accumulate fees as they propagate towards the payer.  Forward queries that permit fees must begin with an estimate of the payment amount including intermediary fees, which would generally be too high and result in too much credit being reserved.  However, forward queries play an important role as signposts towards the payer for the more-precise backward queries.

The transaction units allow
the payer and recipient to recognize what percentage of the payment is actually being paid and received down a given path, regardless of fees or varying conversion rates between account units along the path.  For example, suppose node A is paying node C $100 through intermediary node B.  A's account with B may be in Euros, and B's account with C may be in Pounds.  Before paying 82 Euros to B, A must know how many dollars that represents to recipient C.  Intermediaries that do not recognize the transaction units cannot enforce overall fee limits on queries.

The account ID changes with each step the query is forwarded along, and lets the query recipient know which account with the sender is intended as part of the path, if there is more than one.  The amount in account units is the amount that is to be reserved on that account for this query's payment path.  It also defines a conversion rate between account units and transaction units that can be used to calculate whether or not the full query amount can be passed on to a single neighbour, and what proportion to pass on to various neighbours otherwise.  This conversion rate is also used in subsequent payment messages.

The target location is used by each intermediary to route the query.  Generally the target for forward queries is the recipient's location, and the target for backward queries is the payer's location, but this is not strictly required.  Either payer or recipient may direct the other to route their queries to a different target location, and then ensure that the node with this target location receives a query from the opposite direction to point back to the correct target.

The credit guarantee expiry time gives a deadline for the next phase of the payment to occur.  If this time limit is reached, the credit held for this path will be released and made available to other payments.  Each intermediary should subtract from this time before passing it on to give themselves a small buffer in which to process messages from the next payment phase.  The time is given in the connection time between each of the intermediaries, so each one must convert if the time on the incoming account is not in sync with the time on the outgoing account.  See [[Connection Time -> #connection-time]].

The promise penalty deadline, penalty rate, and final deadline refer to fields in the @@promise@@ message in the next payment phase.  In the forward query, they represent maximum bounds for those fields, and in the backward query, minimum bounds.  The times are again given in connection time, and the penalty rate is a daily percentage.

The hop limit is the maximum number of hops for all queries spawned from the one received, including forks.  When a query forks in several different directions, the hop limit must be divided up amongst them.

The bloom filter containing aliases of the locations already visited is to prevent loops -- no location should occur twice in the same path.  Nodes can use any alias they want as long as it is unique among potential intermediaries with high probability and they remember it to compare against incoming queries with the same payment and swarm IDs.

The per-hop fee limit is a limit on the percentage fee charged per hop in the path.  The accumulated fee limit is an overall limit to the fees on this query.  This can only be enforced if intermediaries recognize the transaction units.

When the query reaches the opposing payment endpoint, or creates a loop or otherwise hits a dead end, the node receiving the query message returns a @@path-response@@ message
:
Changed lines 289-320 from:
* path ID
* subpath ID
* ID of the account between the message sender and recipient that will form part of the path
* credit currently available for this payment on this account, in account units
* credit currently available for this payment on this account, in transaction units (defines conversion rate to transaction units)
* the time this available credit guarantee will expire
* minimum promise time-to-penalty
* minimum required promise life
* the target's routing information (optional)
* the remaining visited-nodes limit (optional)
* the original proximity-aware hop limit (optional)
* the remaining proximity-aware hop limit (optional)
* the closest distance to the target so far on this sub-query (optional)
* a bloom filter containing aliases for each of the nodes visited by this subpath
* per-hop fee limit

The optional entries do not apply when following a query path back to the payer. 

The list of accounts in the path is to allow the payer to determine if two paths overlap and if so, what the actual total credit available along the two paths is.  Nodes may add dummy accounts to obfuscate the number of hops between payer and recipient or the recipient's identity.  The transaction alias for an account might be the payment ID appended to the account ID, hashed.

Path-available messages are routed just like queries (see [[Query Routing -> #query-routing]] below), except they are headed in the other direction.  They also act as an available credit guarantee for a certain period of time.  If no promise message is received by then, the frozen credit can be released.  For each neighbour it is passing a path-available message on to, a node should:

* replace account ID of previous step with account ID of next step
* calculate a conversion rate between transaction units and account units for the account with that neighbour, based on the conversion rate of the incoming path-available message
* change “credit available for this payment" if appropriate
* decrease the time this available credit guarantee will expire to allow enough time for a received promise to be passed on to the next node in the path without its guarantee expiring
* increase the "minimum promise time-to-penalty" to ensure that it incurs no penalty without being able to recoup the amount
* increase the “minimum promise life” to give it time to process the receipt if the deadline is near (see Making Promises and Finalizing Payment below)
* decrement the remaining visited-nodes limit and assign that neighbour a proportion of it
* decrement or reset the hop limit
* put an alias it can remember into the visited-nodes bloom filter

to:
* swarm ID
* list of path IDs with corresponding available amounts in transaction units
* path ID of query to which this message is a response
* expiry time for these paths
* unused hop limit

These path-responses are propagated back to the query originator in the following fashion:  When an intermediary receives a path-response, it checks whether the available amounts equal the amount on the query to which it is a response.  If the sum of the path amounts is less than the original query, it sends out new secondary queries for the remaining amounts, if possible.  (Multiple queries are permitted on the same accounts, but each must have a different path ID as described in [[Query Routing -> #query-routing]].)  Unused hop limit may be used for this purpose.  Credit amounts held for the outgoing query should be reduced to reflect the amounts in the path-response.

If the path amounts equal the original query amount, if there is no unused hop limit, or if there are no directions remaining to query, it waits until it has received responses to all its queries, and then packages the nonzero paths together into a new query response.  The new expiry time is the soonest expiry time of any of the path-responses.  The unused hop limit is the total unused hop limit from all the responses that hasn't been used in a secondary query fork.

[[#fees]]
Changed lines 302-303 from:
Fees charged may be integrated as a percentage into conversion rates between units.  There is no provision for flat fees at the moment.
to:
Fees charged may be integrated as a percentage into conversion rates between units.  There is no provision for flat fees at the moment.  Minimum fees for any payment through an account are shared with account partners as part of the account data.
Changed lines 309-310 from:
Each node has a location, which is a decimal number between 0 and 1 representing a position on the boundary of a circle.  The distance between any two locations is defined as the distance along the boundary of the circle between their locations:
to:
Each node partitions its accounts into separate routing classes such that obligations are convertible between any accounts within a class (in other words, an incoming payment on any account might be routed out along any other account in its routing class).  Each routing class is then given a location, which is a decimal number between 0 and 1 representing a position on the boundary of a circle.  The distance between any two locations is defined as the distance along the boundary of the circle between their locations:
Changed lines 319-328 from:
A query (and path-available messages) is routed in the direction of the neighbour with the location the closest to the query's target.  If that direction does not have enough credit to satisfy the entire query, the query is split by forking off new queries with new sub-IDs in the second-, third-, and fourth-best directions, and so on until either the full query amount is satisfied or there are no more available directions

The same credit should not be reported as available for queries with the same query/path ID.  The same credit may be reported as available for multiple queries with the same payment ID.  The goal is
to find the entire payment amount through the web found by queries with the same query ID.

When a path-query reaches the payment recipient or a node that has seen a path-available message for the same payment ID, a path-available message is sent back along its path to the payer carrying the amount of credit available on that subpath (equal to the smaller of the available credit on the path-query and the path-available).

Note that with Metropolis-Hastings routing there is no requirement for nodes to report their own exact location as the routing target of messages from transaction partners.  They may report slightly inexact locations for privacy reasons, or
the location of a neighbour, or an average of a group of neighbours to route the message through them.  This requires informing those neighbours ahead of time that the message is coming, by sending a @@path-query@@ or @@path-available@@ as the case may be.

Nodes might also consider such things as past records
of success in finding paths through various neighbours, connection latency, desirability of holding or spending certain obligations, exchange rates offered, network resources available with each neighbour, etc.  Fee-charging nodes have a profit motive to quickly find a relatively low-fee path that will appeal to the payer.
to:
A @@path-query@@ is routed first in directions path-queries in the opposite direction were received for the same payment ID.  From among these directions, the neighbour with the location closest to the query's target location is chosen first.  If there is not enough credit, as determined by available credit specified on the opposing query received from that direction, to fulfill the entire query, new queries with new path IDs are forked off in subsequent directions which have received opposing queries.  Path IDs must be unique within a swarm.  Once directions having received opposing path-queries are used up, all the accounts in the routing class may be considered on the basis of distance to the target location, using available credit as determined by the account balances and limits.

Remember that credit amounts reported as available on queries must be held for that path and made unavailable for other payments until they time out.  Only other swarms from the same payment may access amounts held.

At all times, per-hop fee limits must be obeyed.  If a node would charge more than
the per-hop fee limit, it must respond as though it were a dead end.  An account with a minimum fee on through payments higher than the per-hop fee limit on the query should therefore be ignored for the purposes of routing that query.

Note that with Metropolis-Hastings routing there is no requirement for nodes to report their own exact location as the routing target
of messages from transaction partners.  They may report slightly inexact locations for privacy reasons, or the location of a neighbour, or an average of a group of neighbours to route the message through them.  This requires informing those neighbours ahead of time that the message is coming, by sending a @@path-query@@.
Deleted lines 328-334:
[[#path-found]]
'''Once a Path is Found'''

When a node sees a path-query and a path-available with the same payment ID, a path has been found.  The node that discovered the connection should immediately pass the path available message in the direction from which it received the path-query.  Units-of-work restrictions can be ignored on these messages.  It should also continue routing queries and path-available messages as usual, since further paths may be necessary to complete the entire payment, or may offer a lower price for the payer.

The payer analyzes path-available messages it receives to build a set of paths with potentially enough available credit to complete the payment.

Changed lines 331-332 from:
When the payer has found payment paths with enough combined available credit to complete the payment, it sends a @@promise message@@ to the first node on each path, representing its commitment to redeem a valid receipt that can be authenticated with the promise's authentication key up to the amount of IOUs indicated on the receipt, if presented before the stated deadline.  A promise serves to hold credit for the payment.
to:
When the payer has found payment paths with enough combined available credit to complete the payment, it sends a @@promise message@@ to the first node on each path, representing its commitment to redeem a valid receipt that can be authenticated with the promise's authentication key up to the amount of credit indicated on the receipt, if presented before the stated deadline.  A promise renews the credit held for each path and gives a new deadline for the expiry of these holds.
Changed lines 334-335 from:
* path ID (a chain of promises defines a path)
to:
* swarm ID
* path ID
Changed lines 338-341 from:
* amount to be held for payment, in account units, according to conversion rate defined by neighbour in path-available message
* promise time-to-penalty
* daily penalty rate if receipt or promise-release not received within time-to-penalty
* promise deadline, after which promise expires
to:
* amount to be held for payment, in account units, according to conversion rate defined by neighbour in @@path-query@@ message
* promise penalty deadline
*
daily penalty rate if receipt or path-cancel not received before the penalty deadline
*
promise final deadline, after which promise expires
Deleted line 343:
* the transaction alias for each account in the path, in order
Changed lines 346-358 from:
At each step, the promise message is authenticated to the next node by the passing node's host's authentication key.  This serves to establish the integrity and non-repudiability of the promise.

Each node passes the promise message on to
the next node in the path as indicated by the transaction alias after its own on the promise message.  Before passing it on, each node that receives a promise should:

* calculate the amount held for payment in account units on the next account in the path according * to the conversion rate stated in the path-available message received on that account
* reduce the amount to be held for payment in transaction units if there is insufficient credit on the next account in the path
* shorten the time-to-penalty to what it indicated on the path-available message
* optionally increase the daily penalty rate
* shorten the deadline according to the promise life it indicated on the path-available message
* remove the previous account alias

The path-available message referred to above is the most recent path-available message received with the same path forward to the payment recipient as the promise message, as determined by the list of transaction aliases
.
to:
Each node passes the promise message on to the next node in the path, as determined by @@path-response@@s received in the previous phase.  At each step, the promise message is signed to the next node by the passing node's authentication key.  This serves to establish the integrity and non-repudiability of the promise.
Changed lines 359-360 from:
The recipient can cancel the transaction at any time by informing the payer and releasing its neighbours from their promises.  The payer can cancel the transaction by informing the recipient that it can release its neighbours from their promises.  Released promises should be propagated back down each payment path to free up those funds for other payments.
to:
The recipient can cancel the transaction at any time by informing the payer and releasing its neighbours from their promises with a @@path-cancel@@.  The payer can cancel the transaction by informing the recipient that it can release its neighbours from their promises.  Released promises should be propagated back down each payment path to free up those funds for other payments.
Changed lines 369-380 from:
to:
[[#cancelling-paths]]
'''Cancelling Unneeded Paths'''

The payer and recipient should send a @@path-cancel@@ down each path they know they will not need:

* payment ID
* swarm ID
* path ID

When passing a @@path-cancel@@ before having returned a @@path-response@@, intermediaries should fork the @@path-cancel@@ just as they did the @@path-query@@ with the same identifiers.

May 29, 2006, at 12:00 AM by ryan - put in matthew's routing scheme
Changed lines 6-7 from:
%center%''with contributions by Evgeni Pandurski and Brandyn Webb''
to:
%center%''with contributions by Brandyn Webb, Evgeni Pandurski, and Matthew Toseland''
Changed lines 22-31 from:
* Hop-limit counter that decrements every time a query gets closer to its target (measured by MH distance)
* routing:
  * fork only when full amount can't go down one path; prefer best routes regardless of amounts
  * separate routing spaces for:
    * convertible
accounts
   * zero-fee account pairs
    * sub-0.1% fee pairs
    * sub-1.0% fee pairs
* payer option to specify actual payment units in queries - needed for guaranteed zero-fee paths

to:
* separate routing spaces for:
  * convertible accounts
  * zero-fee account pairs
  * sub-0.1% fee pairs
  * sub-1.0% fee pairs
* path-cancel messages to release amounts frozen in
path-available
* weight location swap calculations by accounts' credit range to put more emphasis on high-capacity
accounts
Changed lines 217-218 from:
* number of transaction units that will consist the entire payment
to:
* transaction units
* payment amount in transaction units
Changed lines 222-223 from:
Transaction units are integer units invented for the purposes of the transaction to mask the true nature (amount & units) of the transaction from intermediaries.  The number of transaction units consisting the entire payment as declared in the payment-init message defines the conversion rate between transaction units and actual units of payment.  A simple convention is to make one transaction unit equal one cent, although any conversion rate that allows the entire amount to be flexibly divided into integer transaction-unit amounts for payment down multiple paths is acceptable.
to:
Transaction units allow the payer to mask the true units of the payment by inventing custom units.  However, this will hinder intermediaries' ability to properly conduct zero-fee path searched.  To guarantee zero-fee paths only, transaction units must be recognized by at least some of the intermediaries.  See [[Path Queries -> #path-queries]].
Added line 229:
* transaction units
Added line 240:
[[#path-queries]]
Changed lines 243-244 from:
The payer sends out @@path-query@@ messages to one or more of their account partners, which they in turn pass on to one or more of their partners as they deem appropriate – see [[Query Routing -> #query-routing]].  A path-query message consists of:
to:
The payer sends out @@path-query@@ messages to one or more of their account partners, which they in turn pass on to one or more of their partners as described in [[Query Routing -> #query-routing]].  A path-query message consists of:
Changed lines 246-248 from:
* credit available along query path so far, in transaction units
to:
* query ID
* subquery ID
* credit available along this sub-
query path so far, in transaction units
Added line 250:
* the transaction units
Changed lines 253-256 from:
* units of work remaining on this query

The credit available along
the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead -- nodes should never pass a query with negative units of work.  Units of work may be ignored for path-available messages along established paths.  See [[Once a Path is Found -> #path-found]] below.
to:
* the remaining visited-nodes limit
* the original proximity-aware hop limit
*
the remaining proximity-aware hop limit
* the closest distance to
the target so far on this sub-query
* a bloom filter containing aliases for each
of the nodes visited by this subquery
* the per-hop fee limit for this query (as a percentage of the query amount)

The subquery ID is
to distinguish between forked subpaths of the query.  The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  The visited-nodes limit is a cap on the nodes visited for this query ID.  The proximity-aware hop limit is only decremented when the subquery moves away from its target.  Whenever the subquery gets closer to its target, the hop limit is reset to its original setting.  The bloom filter of visited nodes is for detecting loops.

If the payer wishes to guarantee a per-hop fee limit of zero, it must specify transaction units that are known to most if not all of the intermediaries, so they can manage exchange rate differences between them.  Otherwise these might become de facto fees
.
Changed lines 269-271 from:
* decrement the total units of work by one
* assign that neighbour a proportion of the remaining units of work available for that query

to:
* decrement the remaining visited-nodes limit and assign that neighbour a proportion of it
* decrement or reset the hop limit
* put an alias it can remember into the visited-nodes bloom filter

Added lines 279-280:
* path ID
* subpath ID
Changed lines 282-284 from:
* credit currently available for this payment on this account, in account units for this step
to:
* credit currently available for this payment on this account, in account units
* credit currently available for this payment on this account, in transaction units (defines conversion rate to transaction units)
* the time this available credit guarantee will expire
Changed lines 287-294 from:
* the target's routing information (if available)
* work units remaining
* for each account/connection along which this message has been passed:
  * a transaction-unique alias
(each account must use the same alias for every message with the same payment ID)
  * credit currently available for this transaction, in transaction units, on the account on which the node will accept payment

This last entry, along with credit available on this account, defines a conversion rate between transaction units and account units on the current account.

to:
* the target's routing information (optional)
* the remaining visited-nodes limit (optional)
* the original proximity-aware hop limit (optional)
* the remaining proximity-aware hop limit
(optional)
* the closest distance to
the target so far on this sub-query (optional)
* a bloom filter containing aliases for each of the nodes visited by this subpath
* per-hop fee limit

The optional entries do not apply when following a query path back to the payer.

Changed lines 299-300 from:
Path-available messages are routed just like queries (see [[Query Routing -> #query-routing]] below), except they are headed in the other direction.  Queries received from the other direction with the same payment ID will naturally give very important routing hints!  For each neighbour it is passing a path-available message on to, a node should:
to:
Path-available messages are routed just like queries (see [[Query Routing -> #query-routing]] below), except they are headed in the other direction.  They also act as an available credit guarantee for a certain period of time.  If no promise message is received by then, the frozen credit can be released.  For each neighbour it is passing a path-available message on to, a node should:
Added line 304:
* decrease the time this available credit guarantee will expire to allow enough time for a received promise to be passed on to the next node in the path without its guarantee expiring
Changed lines 307-315 from:
* stamp the account's transaction alias for this payment on the message
* stamp the credit available on this account for this transaction
* decrement the total units of work by one
* assign that neighbour a proportion of the remaining units of work available for that query

If a node receives a path-available that already has its transaction-unique alias stamped on it, it should reject it to avoid loops in the payment path.

Nodes must store who passed them queries for a given payment ID.  Nodes must also store the aliases of the neighbours that passed path-available messages in case that path is selected for the next phase of the transaction, Making Promises, as well as conversion rates between account units and transaction units, minimum promise time-to-penalty and promise life.

to:
* decrement the remaining visited-nodes limit and assign that neighbour a proportion of it
* decrement or reset the hop limit
* put an alias it can remember into the visited-nodes bloom filter

Added lines 330-335:
A query (and path-available messages) is routed in the direction of the neighbour with the location the closest to the query's target.  If that direction does not have enough credit to satisfy the entire query, the query is split by forking off new queries with new sub-IDs in the second-, third-, and fourth-best directions, and so on until either the full query amount is satisfied or there are no more available directions. 

The same credit should not be reported as available for queries with the same query/path ID.  The same credit may be reported as available for multiple queries with the same payment ID.  The goal is to find the entire payment amount through the web found by queries with the same query ID.

When a path-query reaches the payment recipient or a node that has seen a path-available message for the same payment ID, a path-available message is sent back along its path to the payer carrying the amount of credit available on that subpath (equal to the smaller of the available credit on the path-query and the path-available).

Deleted line 17:
* limited query floods at one or both ends?
Deleted lines 19-20:
* query speed/cost flag
  * requires accounts to specify lowest fee charged on through-payments
Changed lines 23-31 from:
to:
* routing:
  * fork only when full amount can't go down one path; prefer best routes regardless of amounts
  * separate routing spaces for:
    * convertible accounts
    * zero-fee account pairs
    * sub-0.1% fee pairs
    * sub-1.0% fee pairs
* payer option to specify actual payment units in queries - needed for guaranteed zero-fee paths

Changed lines 25-26 from:
to:
* Hop-limit counter that decrements every time a query gets closer to its target (measured by MH distance)
Changed lines 24-25 from:
to:
* allow nodes to reveal location of connections to prove no cheating on location swaps
Changed lines 470-471 from:
to one of its neighbours, chosen randomly (except in the case of the last hop, where neighbours who are currently swapping should be avoided).  That neighbour passes it on randomly, decrementing the TTL by one.  When a node receives a @@swap-init@@ with a hop limit of one, it has been selected as a potential swap partner.  If the swap partner is not currently participating in another swap, it responds with a @@swap-accept@@, containing:
to:
to one of its neighbours, chosen randomly.  That neighbour passes it on randomly, decrementing the TTL by one.  When a node receives a @@swap-init@@ with a hop limit of one, it has been selected as a potential swap partner.  If the swap partner is not currently participating in another swap, it responds with a @@swap-accept@@, containing:
Deleted lines 461-462:
The two nodes participating in a swap should send out a @@swapping@@ message to each neighbour to indicate that they are not available for swaps.  This @@swapping@@ state lasts until a @@routing-change@@ message is received.  (This message would contain the same location if a swap ultimately didn't occur.)
Changed lines 477-478 from:
This is passed back to the swap initiator along the path followed by the @@swap-init@@.  If the swap partner is currently participating in a swap, then it sends back a @@swap-reject@@ instead, containing the swap ID.
to:
This is passed back to the swap initiator along the path followed by the @@swap-init@@.  If the swap partner is currently participating in a swap, then it replies with a @@swap-reject@@, and the previous intermediary tries another direction.
Deleted line 20:
* separate fees from payment amount - they mask the fraction of the promise actually being redeemed by the receipt.
Deleted line 45:
  * Premix Routing
Deleted lines 17-20:
* Metropolis-Hastings location-swapping
  * swap mediated by disinterested third party?
  * optional to allow neighbours to ensure honest swapping by revealing neighbours' locations?
* [[interest]]
Deleted line 20:
* make premix routing tunnels bidirectional
Deleted line 21:
* take out premix routing
Changed lines 23-24 from:
* limiting messages per unit time per account
to:
  * requires accounts to specify lowest fee charged on through-payments
* mechanism to limit messages per unit time per connection

Changed lines 301-302 from:
Each node has a location, which is a decimal number between -1 and 1 representing a position on the boundary of a circle.  The distance between any two nodes is defined as the distance along the boundary of the circle between their locations. Each node regularly swaps locations with other randomly-chosen nodes in a systematic way to minimize the product of the distances to its neighbours.  Thus a node's location comes to be close in a certain sense to the location of its neighbours.  Path-finding messages can then be routed by passing them to those neighbours with locations closest to the target location.
to:
Each node has a location, which is a decimal number between 0 and 1 representing a position on the boundary of a circle.  The distance between any two locations is defined as the distance along the boundary of the circle between their locations:

[@
d(x, y) = min(abs(x - y), 1 - abs(x - y))
@]

Each node regularly swaps locations with other randomly-chosen nodes in a systematic way to minimize the product of the distances to its neighbours.  Thus a node's location comes to be close in a certain sense to the location of its neighbours.  Path-finding messages can then be routed by passing them to those neighbours with locations closest to the target location.
Changed lines 311-312 from:
Nodes might also consider such things as past records of success in finding paths through various neighbours, connection latency, desirability of holding or spending certain obligations, exchange rates offered, number of queries sent to each neighbour, etc.
to:
Note that with Metropolis-Hastings routing there is no requirement for nodes to report their own exact location as the routing target of messages from transaction partners.  They may report slightly inexact locations for privacy reasons, or the location of a neighbour, or an average of a group of neighbours to route the message through them.  This requires informing those neighbours ahead of time that the message is coming, by sending a @@path-query@@ or @@path-available@@ as the case may be.

Nodes might also consider such things as past records of success in finding paths through various neighbours, connection latency, desirability of holding or spending certain obligations, exchange rates offered, network resources available with each neighbour, etc.  Fee-charging nodes have a profit motive to quickly find a relatively low-fee path that will appeal to the payer
.
Deleted lines 316-344:

'''Premix Routing'''

To prevent neighbours from discovering the source or destination of one's transactions, nodes may build tunnels away from themselves for sending and receiving transactions.  To build a tunnel, a node would send out a @@build-tunnel@@ message with:

* tunnel ID
* account ID to use for tunnel
* minimum desired forward available credit for tunnel, in account units with neighbour receiving this message
* minimum desired backward available credit for tunnel
* a public key to encrypt messages back down the tunnel
* TTL = number of hops to end of tunnel

Each node receiving a build-tunnel message decrements the TTL by one and passes it on to an appropriate neighbour.  If no appropriate neighbour exists for the tunnel, it responds with an error.  Each node in the tunnel must store the accounts that it is using for each particular tunnel ID.

The node receiving the build-tunnel message with TTL zero is the end of the tunnel.  It sends a @@tunnel-status@@ message back down the tunnel to the tunneling node:

* tunnel ID
* public key for encrypting messages up the tunnel
* encrypted by public key from build-tunnel message:
  * routing information of tunnel endpoint
  * random salt, so tunnel intermediaries cannot discover the endpoint by encrypting known locations

Whenever the tunnel endpoint's routing information changes, it must send another tunnel-status back down the tunnel to keep the tunneling node informed of its location.

Now the tunneling node can use the tunnel endpoint as a proxy for routing transactions.  To send path-queries or path-available messages down the tunnel in either direction, the tunneling node or the endpoint places the tunnel ID in the spot of the routing information.  On outgoing routed messages, the true routing destination can be encrypted (with a salt) for the tunnel endpoint. 

Tunnel hops count against units of work on the query -- when receiving payment, the tunneling node may use this to send a path-available message to the tunnel endpoint and have it stop there awaiting queries, in the case where the payer's routing information isn't known.

Added lines 460-510:
For Metropolis-Hastings routing to work, locations must be continually shuffled around as the network changes to maintain the property that each node's location is close to its neighbours'.  The general mechanism is that described in Clarke and Sandberg's presentation [[Routing in the Dark -> http://www.math.chalmers.se/~ossa/defcon13/vegas1_print.pdf]] (PDF):  A node wishing to swap finds another node in the network by random walk.  If the product of the two nodes' distances to their neighbours would be lower after swapping locations, then the swap occurs.  If it would be higher, then the swap occurs with probability A/B, where A is the product of distances to their neighbours before the swap, and B is what the product of distances to their neighbours would be after the swap. 

To accomplish this in a distributed setting, first, a node must decide that it wishes to swap.  Nodes should routinely initiate swaps, perhaps once a day, in order to maintain desirable overall network state, but the specific swapping strategy is up to each node.

The two nodes participating in a swap should send out a @@swapping@@ message to each neighbour to indicate that they are not available for swaps.  This @@swapping@@ state lasts until a @@routing-change@@ message is received.  (This message would contain the same location if a swap ultimately didn't occur.)

The swap initiator sends out a @@swap-init@@ message containing:

* a swap ID
* the hash of its location
* the hash of the base-10 logarithm of the current product of distances to its neighbours
* the hash of a random number P between 0 and 1, for determining whether to swap in case the distances are not lower
* a hop limit (ie, TTL)

to one of its neighbours, chosen randomly (except in the case of the last hop, where neighbours who are currently swapping should be avoided).  That neighbour passes it on randomly, decrementing the TTL by one.  When a node receives a @@swap-init@@ with a hop limit of one, it has been selected as a potential swap partner.  If the swap partner is not currently participating in another swap, it responds with a @@swap-accept@@, containing:

* the swap ID
* its location
* the hash of the logarithm of the current product of distances to its neighbours
* "above" or "below", how to interpret P against the probability of a swap

This is passed back to the swap initiator along the path followed by the @@swap-init@@.  If the swap partner is currently participating in a swap, then it sends back a @@swap-reject@@ instead, containing the swap ID.

When the swap initiator receives a @@swap-accept@@, it sends back a @@swap-initiator-info@@:

* swap ID
* its location
* the hash of what the logarithm of the product of distances to its neighbours would be after the swap

Note that if the swap partners happen to be neighbours, then care must be taken to change both their locations when calculating this last number.  The swap partner replies with a @@swap-partner-info@@:

* swap ID
* the actual logarithm of the product of distances to its neighbours
* what the actual logarithm of the product of distances to its neighbours would be after the swap

Now the swap initiator has all the information to determine whether the swap should occur or not.  Let log(A/B) be the sum of pre-swap distance logarithms minus the sum of the post-swap distance logarithms.  If log(A/B) is positive, or if log(P) is above/below (as specified in the @@swap-accept@@) a negative log(A/B), then the swap should occur. 

If the swap should occur, the swap initiator sends a @@swap-ready@@ containing values that the swap partner can verify against the prior hashes:

* swap ID
* the actual logarithm of the product of distances to its neighbours
* what the actual logarithm of the product of distances to its neighbours would be after the swap
* the value of P

If the swap should not occur, the swap initiator sends a @@swap-cancel@@ containing the same information.

When the swap partner receives the @@swap-ready@@, it replies with a @@swap-commit@@ containing the swap ID, and informs its neighbours of the its new location.  When the swap initiator receives the swap commit, it does the same.

Note that every swap messages passes along a chain of nodes, each of whom can see every message and check if there is cheating.  Of course, any intermediary could substitute any numbers it wanted, which is a potential security hole if someone wanted to actively subvert the routing system -- although I can't imagine an effective attack at the moment.  The initiator and partner can cheat in calculating their distance products and in so doing sway the probability of a swap occurring, however, there is no reason to do so since it is much simpler to simply invent a new desired location and report a swap that never happened.  Nodes should not do this, as it could degrade the routing scheme.  Future versions of the protocol may have to guard against this explicitly, at the cost of revealing the local topology of the network.

Nodes may decide to weight the importance of each connection differently in computing the distance product by giving them coefficients.  This is fine as long as it is applied consistently to pre-swap and post-swap distance product computations.
Changed lines 27-30 from:
to:
* take out premix routing
* query speed/cost flag
* limiting messages per unit time per account

Added lines 28-61:
'''Summary'''

* Network Structure
  * Messaging Semantics
  * Connection Time
* Accounts
  * Creating an Account
  * Changing Credit Limits
  * Changing Routing Information
  * Changing Network ID
  * Changing Authentication Key
  * Verifying Account Data
  * Payment Messages
* Payments
  * Requesting Payment
  * Initiating Payment
  * Path Queries
  * Available Paths
  * Fees
  * Query Routing
  * Premix Routing
  * Once a Path is Found
  * Making Promises (Commit-Request
  * Finalizing the Payment
  * Redeeming Promises (Commit)
  * Releasing Promises (Rollback)
  * Promise Penalties and Expiry
* Appendices
  * Timing Disputes
  * Other Disputes
  * Credit/Reputation Requests
  * Units of Account
  * Location Swapping

Changed lines 30-31 from:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow searching for paths in the network, and sending and tracking of obligations between the two parties through the passing of messages.  Payers must also establish messaging connections to the recipients of their payments.  The nature of those connections depends on the particular message transport being used.  Right now, there is a tentative [[binding to XMPP -> Main/XMPP binding]].
to:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow searching for paths in the network, and sending and tracking of obligations between the two parties through the passing of messages.  Payers must also be able to establish messaging connections to the recipients of their payments.  The nature of those connections depends on the particular message transport system being used.  Right now, there is a tentative [[binding to XMPP -> Main/XMPP binding]].
May 08, 2006, at 07:01 PM by ryan - need to separate fees from payment amount!
Changed lines 26-27 from:
to:
* separate fees from payment amount - they mask the fraction of the promise actually being redeemed by the receipt.
May 08, 2006, at 06:37 PM by ryan - more detail on conflicting limit requests
Changed lines 108-111 from:
If a node receives a credit-change message for an account on which it already has an open limit request that it has sent, it should reply with an error: "limit request ID xxx already open".  [Error codes to be defined...]

A node may cancel a limit request without informing the other node.  If a limit-accept subsequently arrives for that request, the requesting
node would then reply with a "request withdrawn" error.
to:
If a node receives a request to change the same limit as an existing open limit request, the second request should supercede the first.

If a node receives a
request to change to same limit as an open limit request that ''it has sent'', it should reply with an error: "conflicting limit request ID xxx already open".  [Error codes to be defined...]

A
node may cancel a limit request by replying to a limit-accept with a "request withdrawn" error.
Added lines 110-111:
A node may cancel a limit request without informing the other node.  If a limit-accept subsequently arrives for that request, the requesting node would then reply with a "request withdrawn" error.
Changed lines 99-100 from:
* the new credit limit.
to:
* the new credit limit
* a note describing the request
May 08, 2006, at 06:14 PM by ryan - connection time sent by connection acceptor, echoed back
Changed lines 39-40 from:
When a messaging connection between two Ripple nodes is established, the connection initiator must send a @@time@@ message, consisting of its current time, UTC.  The node receiving the time message responds with its own time message in reply, indicating that it agrees to use the other node's time as the official time for that connection.  If it disagrees, it replies with an error and sends its own time message.  If that time message is rejected, the connection is closed.  There is little reason to disagree with someone's time at the start of a connection, unless you have oustanding open transactions with the other node that are time-sensitive. 
to:
When a messaging connection between two Ripple nodes is established, the node accepting the conection must send a @@time@@ message, consisting of its current time, UTC.  The node receiving the time message echoes back its own time message in reply, indicating that it agrees to use the other node's time as the official time for that connection.  If it disagrees, it replies with an error and sends its own time message.  If that time message is rejected, the connection is closed.  There is little reason to disagree with someone's time at the start of a connection, unless you have oustanding open transactions with the other node that are time-sensitive. 
Changed lines 43-45 from:
Repeated time messages can be used to discover connection latency.

to:
Time messages can be used to discover connection latency.

Changed lines 25-26 from:
to:
* make premix routing tunnels bidirectional
Added line 341:
* payment ID
Changed lines 154-155 from:
A node wishing to receive a payment from another node may initiate contact with the potential payer node by sending a @@request-payment@@ message to his node's network ID:
to:
A node wishing to receive a payment from another node may initiate contact with the potential payer node by sending a @@payment-request@@ message to his node's network ID:
Changed lines 164-165 from:
The payment request may be followed by an @@initiate-payment@@ message from the potential payer, or ignored.
to:
The payment request may be followed by an @@payment-init@@ message from the potential payer, or ignored.
Changed lines 170-171 from:
The payer node contacts recipient node and communicates the following in an @@initiate-payment@@ message:
to:
The payer node contacts recipient node and communicates the following in an @@payment-init@@ message:
Changed lines 179-182 from:
Transaction units are integer units invented for the purposes of the transaction to mask the true nature (amount & units) of the transaction from intermediaries.  The number of transaction units consisting the entire payment as declared in the initiate-payment message defines the conversion rate between transaction units and actual units of payment.  A simple convention is to make one transaction unit equal one cent, although any conversion rate that allows the entire amount to be flexibly divided into integer transaction-unit amounts for payment down multiple paths is acceptable.

The recipient may accept the payment initiation with an @@accept-payment@@:
to:
Transaction units are integer units invented for the purposes of the transaction to mask the true nature (amount & units) of the transaction from intermediaries.  The number of transaction units consisting the entire payment as declared in the payment-init message defines the conversion rate between transaction units and actual units of payment.  A simple convention is to make one transaction unit equal one cent, although any conversion rate that allows the entire amount to be flexibly divided into integer transaction-unit amounts for payment down multiple paths is acceptable.

The recipient may accept the payment initiation with an @@payment-accept@@:
Changed lines 24-25 from:
to:
* specify error codes
Changed lines 92-93 from:
If a node wishes to change its partner's or its own credit limit, it sends a @@credit-change@@ message containing:
to:
If a node wishes to change its partner's or its own credit limit, it sends a @@limit@@ message containing:
Changed lines 100-107 from:
The change is considered pending until a @@credit-change-accept@@ containing the same information is received back.  If a @@credit-change-reject@@ is received with the same account ID and request ID, then the credit change has been rejected.  The rejecting node may of course propose a different limit it considers appropriate by sending its own credit-change message anew.

In the case of decreasing either limit, the credit-change message is considered as simply informative, and should be implemented immediately, with the credit-change-accept being sent back immediately.  A node may not reject a decreased limit.

In the case of increasing either limit, the message is interpreted either as a request or an offer and the credit-change-confirm may be delayed while the partner considers. 

If a node receives a credit-change message for an account on which it already has an open credit-change request that it has sent, it should reply with an error: "credit change request ID xxx already open".  [Error codes to be defined...]
to:
The change is considered pending until a @@limit-accept@@ containing the same information is received back.  If a @@limit-reject@@ is received with the same account ID and request ID, then the credit change has been rejected.  The rejecting node may of course propose a different limit it considers appropriate by sending its own limit message anew.

In the case of decreasing either limit, the limit message is considered as simply informative, and should be implemented immediately, with the limit-accept being sent back immediately.  A node may not reject a decreased limit.

In the case of increasing either limit, the message is interpreted either as a request or an offer and the limit-confirm or -reject may be delayed while the partner considers. 

If a node receives a credit-change message for an account on which it already has an open limit request that it has sent, it should reply with an error: "limit request ID xxx already open".  [Error codes to be defined...]
Changed lines 23-24 from:
to:
* close account
Changed lines 98-101 from:
The change is considered pending until a @@credit-change-accept@@ containing the same information is received back.  If a @@credit-change-reject@@ is received with the same account ID and request ID, then the credit change has been rejected.

In the case of decreasing either limit, the credit-change message is considered as simply informative, and should be implemented immediately, with
the affirmative reply containing the credit-change-confirm.
to:
The change is considered pending until a @@credit-change-accept@@ containing the same information is received back.  If a @@credit-change-reject@@ is received with the same account ID and request ID, then the credit change has been rejected.  The rejecting node may of course propose a different limit it considers appropriate by sending its own credit-change message anew.

In
the case of decreasing either limit, the credit-change message is considered as simply informative, and should be implemented immediately, with the credit-change-accept being sent back immediately.  A node may not reject a decreased limit.
Changed lines 104-107 from:
no change occurs until the partner sends back another credit-change message confirming the new limit or specifying a lower limit than the one proposed.  If another credit-change message addressing the limit in question is sent by the node who proposed the original change, the original message is to be disregarded. 

In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect
.  In case of doubt, the other node's account state can be retrieved using a @@verify-account@@ query, described in [[Verifying Account Data -> #verify-account]] below.
to:
If a node receives a credit-change message for an account on which it already has an open credit-change request that it has sent, it should reply with an error: "credit change request ID xxx already open".  [Error codes to be defined...]
Added lines 28-33:
'''Messaging Semantics'''

Each Ripple message has an ID unique for the node-to-node connection, and must be immediately responded to by either a reply or an error with the same ID upon receipt.  This serves to establish that the message was received and either understood or malformed or otherwise inappropriate as detailed by an error code and message.

Nodes need not wait for the reply or error to send another message.

Added line 93:
* request ID
Changed lines 98-101 from:
In the case of decreasing either limit, the change is implemented immediately, as soon as the affirmative reply is received

In
the case of increasing either limit, the message is interpreted either as a request or an offer and no change occurs until the partner sends back another credit-change message confirming the new limit or specifying a lower limit than the one proposed.  If another credit-change message addressing the limit in question is sent by the node who proposed the original change, the original message is to be disregarded. 
to:
The change is considered pending until a @@credit-change-accept@@ containing the same information is received back.  If a @@credit-change-reject@@ is received with the same account ID and request ID, then the credit change has been rejected.

In the case of decreasing either limit, the credit-change message is considered as simply informative, and should be implemented immediately, with the affirmative reply containing the credit-change-confirm.

In the case of increasing either limit, the message is interpreted either as a request or an offer and the credit-change-confirm may be delayed while the partner considers. 

no change occurs until the partner sends back another credit-change message confirming the new limit or specifying a lower limit than the one proposed.  If another credit-change message addressing the limit in question is sent by the node who proposed the original change, the original message is to be disregarded. 
Changed line 18 from:
* Metropolis-Hastings routing
to:
* Metropolis-Hastings location-swapping
Deleted lines 20-21:
* premix routing
  * tunnels a random distance away for sending and receiving transactions to hide payer and recipient ID from statistical analysis by neighbours
Changed lines 198-199 from:
The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead -- nodes should never pass a query with units of work zero.  Units of work may be ignored for path-available messages along established paths.  See [[Once a Path is Found -> #path-found]] below.
to:
The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead -- nodes should never pass a query with negative units of work.  Units of work may be ignored for path-available messages along established paths.  See [[Once a Path is Found -> #path-found]] below.
Changed lines 203-204 from:
* calculate the desired conversion rate from transaction units to account units for the * * * account with that neighbour, based on the conversion rate of the incoming query
* reduce
the “credit available along the path” if the account with that neighbour has * * * * insufficient available credit
to:
* calculate the desired conversion rate from transaction units to account units for the account with that neighbour, based on the conversion rate of the incoming query
* reduce
the “credit available along the path” if the account with that neighbour has insufficient available credit
Added lines 261-289:

'''Premix Routing'''

To prevent neighbours from discovering the source or destination of one's transactions, nodes may build tunnels away from themselves for sending and receiving transactions.  To build a tunnel, a node would send out a @@build-tunnel@@ message with:

* tunnel ID
* account ID to use for tunnel
* minimum desired forward available credit for tunnel, in account units with neighbour receiving this message
* minimum desired backward available credit for tunnel
* a public key to encrypt messages back down the tunnel
* TTL = number of hops to end of tunnel

Each node receiving a build-tunnel message decrements the TTL by one and passes it on to an appropriate neighbour.  If no appropriate neighbour exists for the tunnel, it responds with an error.  Each node in the tunnel must store the accounts that it is using for each particular tunnel ID.

The node receiving the build-tunnel message with TTL zero is the end of the tunnel.  It sends a @@tunnel-status@@ message back down the tunnel to the tunneling node:

* tunnel ID
* public key for encrypting messages up the tunnel
* encrypted by public key from build-tunnel message:
  * routing information of tunnel endpoint
  * random salt, so tunnel intermediaries cannot discover the endpoint by encrypting known locations

Whenever the tunnel endpoint's routing information changes, it must send another tunnel-status back down the tunnel to keep the tunneling node informed of its location.

Now the tunneling node can use the tunnel endpoint as a proxy for routing transactions.  To send path-queries or path-available messages down the tunnel in either direction, the tunneling node or the endpoint places the tunnel ID in the spot of the routing information.  On outgoing routed messages, the true routing destination can be encrypted (with a salt) for the tunnel endpoint. 

Tunnel hops count against units of work on the query -- when receiving payment, the tunneling node may use this to send a path-available message to the tunnel endpoint and have it stop there awaiting queries, in the case where the payer's routing information isn't known.

Changed lines 426-431 from:
Other types of units may be useful for credit/reputation checks, although not for payment.  For example, a satisfied customer may give a merchant one unit of "satisfied customer" credit for each successful transaction with her.  Then a prospective customer could learn about that merchant's reputation by doing a credit check against "satisfied customer" units.
to:
Other types of units may be useful for credit/reputation checks, although not for payment.  For example, a satisfied customer may give a merchant one unit of "satisfied customer" credit for each successful transaction with her.  Then a prospective customer could learn about that merchant's reputation by doing a credit check against "satisfied customer" units.


[[#location-swapping]]
'''Location Swapping'''

Changed lines 251-265 from:
''*** Change to Metropolis-Hastings ***''

Every node assigns itself a set of keywords which serve to locate it in the network
.  Most keywords should be chosen so they are shared with several neighbours, although nodes are free to select keywords to identify them uniquely.  Geographic names are ideal for routing keywords as they provide a natural hierarchy: country, province/state, city, etc.

Nodes should advertise
their keywords to their neighbours with @@keyword-advertisement@@ messages.  Nodes can also advertise their distance to other keywords using this same message type:

* keyword
* number of hops to keyword

Nodes are not obliged
to pass on keyword advertisements, and may pass on advertisements to selected neighbours.  Generally, nodes will want to pass on keyword advertisements that give new information about a shorter path to a certain keyword that has been relatively popular in past queries.

Nodes that receive too many advertisements in a certain time period from a certain neighbour should reply with the appropriate error code.

To route path queries (and path-available messages), nodes should make use of the keyword advertisements they have received, as well as past records of success in finding paths through various neighbours.  Nodes might also consider such things as neighbours' connection latency, desirability of holding or spending certain IOUs
, exchange rates offered, number of queries sent to each neighbour, etc.
to:
Ripple uses the Metropolis-Hastings algorithm for routing, as described in Clarke and Sandberg's presentation [[Routing in the Dark -> http://www.math.chalmers.se/~ossa/defcon13/vegas1_print.pdf]] (PDF). 

Each node has a location, which is a decimal number between -1 and 1 representing a position on the boundary of a circle.  The distance between any two nodes is defined as the distance along the boundary of the circle between
their locations.  Each node regularly swaps locations with other randomly-chosen nodes in a systematic way to minimize the product of the distances to its neighbours.  Thus a node's location comes to be close in a certain sense to the location of its neighbours.  Path-finding messages can then be routed by passing them to those neighbours with locations closest to the target location.

See below for a [[specification of location-swapping -> #location-swapping]].

Nodes might also consider such things as past records of success in finding paths through various neighbours, connection latency, desirability of holding or spending certain obligations,
exchange rates offered, number of queries sent to each neighbour, etc.
Deleted line 17:
* heartbeat messages to maintain agreement on current time?
Changed line 289 from:
* the transaction alias for each node in the path, in order
to:
* the transaction alias for each account in the path, in order
Changed lines 301-302 from:
* remove its own alias from the list of intermediaries
to:
* remove the previous account alias
Changed lines 29-31 from:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of obligations between the two parties.  The nature of those connections depends on the particular message transport being usedRight now, there is a tentative [[binding to XMPP -> Main/XMPP binding]].

to:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow searching for paths in the network, and sending and tracking of obligations between the two parties through the passing of messagesPayers must also establish messaging connections to the recipients of their payments.  The nature of those connections depends on the particular message transport being used.  Right now, there is a tentative [[binding to XMPP -> Main/XMPP binding]].

'''Connection Time'''

When a messaging connection between two Ripple nodes is established, the connection initiator must send a @@time@@ message, consisting of its current time, UTC.  The node receiving the time message responds with its own time message in reply, indicating that it agrees to use the other node's time as the official time for that connection.  If it disagrees, it replies with an error and sends its own time message.  If that time message is rejected, the connection is closed.  There is little reason to disagree with someone's time at the start of a connection, unless you have oustanding open transactions with the other node that are time-sensitive. 

During the course of the connection, either node may send a time message to the other to verify the time.  If at any point the two nodes fail to agree on the current time, the connection should be closed.

Repeated time messages can be used to discover connection latency.


Changed line 43 from:
* each node's routing data (see Query Routing)
to:
* each node's routing information (see Query Routing)
Changed line 160 from:
* payer's routing information (optional, may be a partial set)
to:
* payer's routing information (optional?)
Changed line 214 from:
  * a unique alias (each account must use the same alias for every message with the same payment ID)
to:
  * a transaction-unique alias (each account must use the same alias for every message with the same payment ID)
Changed lines 219-220 from:
The list of accounts in the path is to allow the payer to determine if two paths overlap and if so, what the actual total credit available along the two paths is.  Nodes may add dummy accounts to obfuscate the number of hops between payer and recipient, or to
to:
The list of accounts in the path is to allow the payer to determine if two paths overlap and if so, what the actual total credit available along the two paths is.  Nodes may add dummy accounts to obfuscate the number of hops between payer and recipient or the recipient's identity.  The transaction alias for an account might be the payment ID appended to the account ID, hashed.
Changed lines 228-229 from:
* stamp its unique alias for this payment ID on the message
* stamp the credit available for this transaction on the account on which it will be accepting payment
to:
* stamp the account's transaction alias for this payment on the message
* stamp the credit available on this account for this transaction
Added lines 244-245:
''*** Change to Metropolis-Hastings ***''
Changed line 18 from:
* heartbeat messages?
to:
* heartbeat messages to maintain agreement on current time?
Changed lines 22-25 from:
* payer can volunteer payment up the chain if recipient sends copy of signed receipt to payer
* interest
  * keep separate balance on account for each rate

to:
* premix routing
  * tunnels a random distance away for sending and receiving transactions
to hide payer and recipient ID from statistical analysis by neighbours
* [[interest]]
* limited query floods at one or both ends?

Changed lines 213-216 from:
* for each node that has passed along the message:
* a unique alias (each node must use the same alias for every message with the same payment ID)
* credit currently available for this transaction, in transaction units, on the account on which the node will accept payment
to:
* for each account/connection along which this message has been passed:
  * a unique alias (each account must use the same alias for every message with the same payment ID)
  * credit currently available for this transaction, in transaction units, on the account on which the node will accept payment
Added lines 219-220:
The list of accounts in the path is to allow the payer to determine if two paths overlap and if so, what the actual total credit available along the two paths is.  Nodes may add dummy accounts to obfuscate the number of hops between payer and recipient, or to
Changed lines 320-321 from:
When a node accepts a receipt, it must stamp the amount to be redeemed in account units, sign the receipt with its authentication key, and reply by sending the signed receipt back to the node that it accepted the receipt from.  This creates an undeniable record that the promise has been redeemed.  The sum of signed receipts from each partner to an account equals the account balance.  The original receipt is passed down the chain unchanged.
to:
When a node accepts a receipt, it must stamp the amount to be redeemed in account units, sign the receipt with its authentication key, and reply by sending the signed receipt back to the node from which it accepted the receipt.  This creates an undeniable record that the promise has been redeemed.  The sum of signed receipts from each partner to an account equals the account balance.  The original receipt is passed down the chain unchanged.

The payer may optionally volunteer payment forward up a path without delay, as long as she has received a copy of the receipt signed by the recipient, which is her proof-of-payment.  She can do this by appending the amount to be redeemed in account units to the receipt, signing it, and passing it forward.  Any intermediary receiving such a volunteered payment may in turn volunteer it forward to the next node up the chain.  This capability serves to speed up the finalization of the transaction, minimizing uncertainty and the time that credit must be held frozen
.
Changed lines 10-11 from:
The eventual goal is to define a protocol ethemnabling nodes on the Ripple network to make and maintain mutual-credit accounts between , and use the network of these accounts for making credit payments by finding paths to the payment recipient and passing credits/IOUs down those paths.  Also specified is a method of making credit/reputation check requests based on paths through the Ripple network.
to:
The eventual goal is to define the Ripple network with a protocol enabling nodes to make and maintain mutual-credit accounts between them, and use the network of these accounts for making payments by finding paths to the payment recipient and passing obligations down those paths.  Nodes should also be able to verify another's reputation by checking the available credit through the network to the target node.
Changed lines 14-16 from:
This document outlines in an abstract way the types of messages that need to be passed between nodes and the data contained in those messages.  It also addresses bindings to network protocols and possible message formats.

to:
This document outlines in an abstract way the types of messages that need to be passed between nodes and the data contained in those messages.

'''To Do'''

* heartbeat messages?
* Metropolis-Hastings routing
  * swap mediated by disinterested third party?
  * optional to allow neighbours to ensure honest swapping by revealing neighbours' locations?
* payer can volunteer payment up the chain if recipient sends copy of signed receipt to payer
* interest
  * keep separate balance on account for each rate

Changed lines 28-30 from:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of IOUs between the two parties.  The nature of those connections and the message transport between them is defined by a particular transport binding.  Right now, there is a [[binding to XMPP -> Main/XMPP binding]].

to:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of obligations between the two parties.  The nature of those connections depends on the particular message transport being used.  Right now, there is a tentative [[binding to XMPP -> Main/XMPP binding]].

Changed line 42 from:
* each node's routing keywords (see Query Routing)
to:
* each node's routing data (see Query Routing)
Changed lines 230-231 from:
Query Routing
to:
'''Query Routing'''
Changed line 177 from:
* credit available along path so far, in account units for that account (defines a * * * * * conversion rate from transaction to account units)
to:
* credit available along path so far, in account units for that account (defines a conversion rate from transaction to account units)
Changed lines 10-11 from:
The eventual goal is to define a protocol enabling nodes on the Ripple network to make and maintain mutual-credit accounts between them, and use the network of these accounts for making credit payments by finding paths to the payment recipient and passing credits/IOUs down those paths.  Also specified is a method of making credit/reputation check requests based on paths through the Ripple network.
to:
The eventual goal is to define a protocol ethemnabling nodes on the Ripple network to make and maintain mutual-credit accounts between , and use the network of these accounts for making credit payments by finding paths to the payment recipient and passing credits/IOUs down those paths.  Also specified is a method of making credit/reputation check requests based on paths through the Ripple network.
Changed lines 181-182 from:
The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead -- nodes should never pass a query with units of work zero.
to:
The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead -- nodes should never pass a query with units of work zero.  Units of work may be ignored for path-available messages along established paths.  See [[Once a Path is Found -> #path-found]] below.
Changed lines 191-192 from:
If the payer has revealed some or all of his routing information during payment initiation, the recipient may immediately begin issuing @@path-available@@ messages.  Otherwise, he must wait until he receives a query to begin issuing them.  Path available messages contain:
to:
[[#available-paths]]
'''Available Paths'''

The payment recipient also participates in the path-finding process. 
If the payer has revealed some or all of his routing information during payment initiation, the recipient may immediately begin issuing @@path-available@@ messages.  Otherwise, he must wait until he receives a query to begin issuing them.  Path available messages contain:
Changed lines 209-220 from:
Path-available messages are routed just like queries (see Query Routing below), except they are headed in the other direction.  Queries received with the same payment ID will naturally give very important routing hints!  For each neighbour it is passing a path-available message on to, a node should:

replace account ID of previous step with
account ID of next step
calculate a conversion rate between transaction units and account units for the account with that neighbour, based on the conversion rate of the incoming path-available message
change “credit available for this payment" if appropriate
increase the "minimum promise time-to-penalty" to ensure that it incurs no penalty without being able
to recoup the amount
increase the “minimum promise life” to give it time
to process the receipt if the deadline is near (see Making Promises and Finalizing Payment below)
stamp its unique alias for this payment ID on the message
stamp the credit available for this transaction on the account on which it will be accepting payment
decrement
the total units of work by one
assign
that neighbour a proportion of the remaining units of work available for that query
to:
Path-available messages are routed just like queries (see [[Query Routing -> #query-routing]] below), except they are headed in the other direction.  Queries received from the other direction with the same payment ID will naturally give very important routing hints!  For each neighbour it is passing a path-available message on to, a node should:

* replace
account ID of previous step with account ID of next step
* calculate a conversion rate between transaction units and account units for
the account with that neighbour, based on the conversion rate of the incoming path-available message
* change “credit available for this payment" if appropriate
* increase the "minimum promise time-
to-penalty" to ensure that it incurs no penalty without being able to recoup the amount
* increase
the “minimum promise life” to give it time to process the receipt if the deadline is near (see Making Promises and Finalizing Payment below)
* stamp its unique alias for this payment ID on the message
* stamp
the credit available for this transaction on the account on which it will be accepting payment
* decrement the total units of work by one
*
assign that neighbour a proportion of the remaining units of work available for that query
Changed lines 223-226 from:
Nodes must store who passed them queries for a given payment ID.  Nodes must also store the aliases of the neighbours that passed path-available messages in case that path is selected for the next phase of the transaction, Making Promises, as well as conversion rates between account units and transaction units, minimum promise time-to-penatly and promise life.

Fees
to:
Nodes must store who passed them queries for a given payment ID.  Nodes must also store the aliases of the neighbours that passed path-available messages in case that path is selected for the next phase of the transaction, Making Promises, as well as conversion rates between account units and transaction units, minimum promise time-to-penalty and promise life.

'''Fees'''
Changed lines 234-238 from:
Nodes should advertise their keywords to their neighbours with keyword-advertisement messages.  Nodes can also advertise their distance to other keywords using this same message type:

keyword
number of hops to keyword
to:
Nodes should advertise their keywords to their neighbours with @@keyword-advertisement@@ messages.  Nodes can also advertise their distance to other keywords using this same message type:

* keyword
* number of hops to keyword
Changed lines 247-250 from:
Once a Path is Found

When a node sees a path-query and a path-available with the same payment ID, a path has been found.  The node that discovered the connection should immediately pass the path available message in the direction from which it received the path-query.  It should also continue routing queries and path-available messages as usual, since further paths may be necessary to complete the entire payment, or may offer a lower price for the payer.
to:
[[#path-found]]
'''
Once a Path is Found'''

When a node sees a path-query and a path-available with the same payment ID, a path has been found.  The node that discovered the connection should immediately pass the path available message in the direction from which it received the path-query.  Units-of-work restrictions can be ignored on these messages.  It should also continue routing queries and path-available messages as usual, since further paths may be necessary to complete the entire payment, or may offer a lower price for the payer.
Changed lines 254-270 from:
Making Promises (Commit-Request)

When the payer has found payment paths with enough combined available credit to complete the payment, it sends a promise message to the first node on each path, representing its commitment to redeem a valid receipt that can be authenticated with the promise's authentication key up to the amount of IOUs indicated on the receipt, if presented before the stated deadline.  A promise serves to hold credit for the payment.

payment ID
path ID (a chain of promises defines a path)
amount to be held for payment, in transaction units
ID of account to be made part of path by this promise being passed
amount to be held for payment, in account units, according to conversion rate defined by neighbour in path-available message
promise time-to-penalty
daily penalty rate if receipt or promise-release not received within time-to-penalty
promise deadline, after which promise expires
the payer's receipt authentication key for this payment path
the recipient's receipt authentication key for this payment path
the transaction alias for each node in the path, in order
a timestamp to indicate the time the promise came into effect.
to:
'''Making Promises (Commit-Request)'''

When the payer has found payment paths with enough combined available credit to complete the payment, it sends a @@promise message@@ to the first node on each path, representing its commitment to redeem a valid receipt that can be authenticated with the promise's authentication key up to the amount of IOUs indicated on the receipt, if presented before the stated deadline.  A promise serves to hold credit for the payment.

* payment ID
* path ID (a chain of promises defines a path)
* amount to be held for payment, in transaction units
* ID of account to be made part of path by this promise being passed
* amount to be held for payment, in account units, according to conversion rate defined by neighbour in path-available message
* promise time-to-penalty
* daily penalty rate if receipt or promise-release not received within time-to-penalty
* promise deadline, after which promise expires
* the payer's receipt authentication key for this payment path
* the recipient's receipt authentication key for this payment path
* the transaction alias for each node in the path, in order
* a timestamp to indicate the time the promise came into effect.
Changed lines 275-283 from:
calculate the amount held for payment in account units on the next account in the path according to the conversion rate stated in the path-available message received on that account
reduce the amount to be held for payment in transaction units if there is insufficient credit on the next account in the path
shorten the time-to-penalty to what it indicated on the path-available message
optionally increase the daily penalty rate
shorten the deadline according to the promise life it indicated on the path-available message
remove its own alias from the list of intermediaries

The path-available message referred to above is the most recent path-available message received with the same path forward to the payment recipient, as determined by the list of transaction aliases.
to:
* calculate the amount held for payment in account units on the next account in the path according * to the conversion rate stated in the path-available message received on that account
* reduce the amount to be held for payment in transaction units if there is insufficient credit on the next account in the path
* shorten the time-to-penalty to what it indicated on the path-available message
* optionally increase the daily penalty rate
* shorten the deadline according to the promise life it indicated on the path-available message
* remove its own alias from the list of intermediaries

The path-available message referred to above is the most recent path-available message received with the same path forward to the payment recipient as the promise message, as determined by the list of transaction aliases.
Changed lines 285-293 from:
Finalizing the Payment

The recipient sends the payer promise-received messages, each indicating that a promise has been received:

received promise's path ID
final amount of promise in transaction units
recipient's deadline for accepting the receipt for this path
timestamp indicating current time
to:
'''Finalizing the Payment'''

The recipient sends the payer @@promise-received@@ messages, each indicating that a promise has been received:

* received promise's path ID
* final amount of promise in transaction units
* recipient's deadline for accepting the receipt for this path
* timestamp indicating current time
Changed lines 296-301 from:
When the payer receives promise-received messages equal to or exceeding the amount of the payment, he generates receipts matching the promises received by the recipient, – one receipt per promise/path --  authenticates them individually with each path's authentication key, and sends them each to the recipient:

payment ID
path ID
amount for this path in transaction units
to:
When the payer receives promise-received messages equal to or exceeding the amount of the payment, he generates @@receipt@@ messages matching the promises received by the recipient, –- one receipt per promise/path --  authenticates them individually with each path's authentication key, and sends them each to the recipient:

* payment ID
* path ID
* amount for this path in transaction units
Changed lines 305-306 from:
Redeeming Promises (Commit)
to:
'''Redeeming Promises (Commit)'''
Changed lines 313-321 from:
Releasing Promises (Rollback)

A node may release a neighbour from all or part of its promise at any time with a signed promise-release message:

payment ID
path ID
amount to release, in transaction units
error/reason code
to:
'''Releasing Promises (Rollback)'''

A node may release a neighbour from all or part of its promise at any time with a signed @@promise-release@@ message:

* payment ID
* path ID
* amount to release, in transaction units
* error/reason code
Changed lines 324-325 from:
Promise Penalties and Expiry
to:
'''Promise Penalties and Expiry'''
Changed lines 328-332 from:
Penalties are collected by issuing a payment-request to the offending node, containing the following special fields:

penalty – payment ID
penalty – path ID
to:
Penalties are collected by issuing a @@payment-request@@ to the offending node, containing the following special fields:

* penalty – payment ID
* penalty – path ID
Changed lines 335-340 from:
If any promise's final deadline for accepting receipts passes, the issuing node should issue a promise-expired notification, containing:

payment ID
path ID
timestamp
to:
If any promise's final deadline for accepting receipts passes, the issuing node should issue a @@promise-expired@@ notification, containing:

* payment ID
* path ID
* timestamp
Changed lines 343-347 from:
Any node can fulfill an expired promise if it wishes and has available credit.  Any node can request that an expired promise be fulfilled by sending a promise-renew request:

payment ID
promise ID
to:
Any node can fulfill an expired promise if it wishes and has available credit.  Any node can request that an expired promise be fulfilled by sending a @@promise-renew@@ request:

* payment ID
* promise ID
Changed lines 350-351 from:
Timing Disputes
to:

!! Appendices

'''Timing
Disputes'''
Changed lines 361-362 from:
Other Disputes
to:
'''Other Disputes'''
Changed lines 372-373 from:
Credit/Reputation Requests
to:
'''Credit/Reputation Requests'''
Changed lines 377-382 from:
Appendices

Units of Account

National currencies and other value units can be identified by arbitrary strings, although this should be standardized across the Ripple network to avoid duplicate IDsA natural ID for a national currency is its three-letter code.  Other standard units should be ounces of gold, grams of gold, hours, joules, and kilowatt-hours.
to:
'''Units of Account'''

National currencies and other value units can be identified by arbitrary strings.  A natural ID for a national currency is its three-letter codeOther standard units should include ounces of gold, grams of gold, hours, joules, and kilowatt-hours.  Since units of payment will have to be communicated between payer and recipient, it is important that unit codes be standardized.
Changed lines 12-13 from:
For background on Ripple, see [[Money as IOUs in Social Trust Networks & A Proposal for a Decentralized Currency Network Protocol -> http://ripple.sourceforge.net/decentralizedcurrency.pdf]].
to:
For background on Ripple, see [[Money as IOUs in Social Trust Networks & A Proposal for a Decentralized Currency Network Protocol -> http://ripple.sourceforge.net/decentralizedcurrency.pdf]] (PDF).
Changed lines 17-18 from:
!!! Network Structure
to:
!! Network Structure
Changed lines 22-23 from:
!!! Accounts
to:
!! Accounts
Changed lines 40-41 from:
Accounts are created by one node offering to accept another's IOUs with an ''offer'' message containing:
to:
Accounts are created by one node offering to accept another's IOUs with an @@offer@@ message containing:
Changed lines 53-54 from:
If the offer recipient accepts the offer, his node sends back an ''offer-accept'' message:
to:
If the offer recipient accepts the offer, his node sends back an @@offer-accept@@ message:
Changed lines 65-66 from:
Otherwise it sends an ''offer-reject'' message. 
to:
Otherwise it sends an @@offer-reject@@ message. 
Changed lines 69-70 from:
If a node wishes to change its partner's or its own credit limit, it sends a ''credit-change'' message containing:
to:
If a node wishes to change its partner's or its own credit limit, it sends a @@credit-change@@ message containing:
Changed lines 80-81 from:
In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a ''verify-account'' query, described in [[Verifying Account Data -> #verify-account]] below.
to:
In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a @@verify-account@@ query, described in [[Verifying Account Data -> #verify-account]] below.
Changed lines 84-85 from:
If a node's routing information changes, it must send a ''routing-change'' message to its neighbours:
to:
If a node's routing information changes, it must send a @@routing-change@@ message to its neighbours:
Changed lines 92-93 from:
To change network ID, a node must send a signed ''id-change'' message containing the new network ID.  After the reply to this message, the receiving node must send all Ripple messages to the new ID.
to:
To change network ID, a node must send a signed @@id-change@@ message containing the new network ID.  After the reply to this message, the receiving node must send all Ripple messages to the new ID.
Changed lines 96-97 from:
Send a signed ''key-change'' message containing the new key.  (Perhaps this should contain a revocation message for the old key?)
to:
Send a signed @@key-change@@ message containing the new key.  (Perhaps this should contain a revocation message for the old key?)
Changed lines 101-102 from:
Send a ''verify-account'' message to which the reply contains:
to:
Send a @@verify-account@@ message to which the reply contains:
Changed lines 115-116 from:
!!! Payments
to:
!! Payments
Changed lines 121-152 from:
Initiating payment between the payer and recipient nodes
Path discovery, consisting of query messages sent out by the payer, and path-available message sent out by the recipient
Making promises, where the payer propagates promises to redeem the payment receipt for IOUs forward down each payment path
Finalizing the payment, where a receipt created by the payer is propagated back down the path by the recipient, and is redeemed for IOUs at each step.

Requesting Payment

A node wishing to receive a payment from another node may initiate contact with the potential payer node by sending a request-payment message to his node's network ID:

unique ID for the payment
amount
units
time of request
payment recipient's node's network address
authorization number (optional)
an explanatory note

The payment request may be followed by an initiate-payment message from the potential payer, or ignored.

The authorization number may be used to pre-authorize payments, so the node can automatically make payments when it receives a request.  The request-payment message may also be authorized by signing it with a certain key, contained in the node owner's smart card, for example.

Initiating Payment

The payer node contacts recipient
node and communicates the following in an initiate-payment message:

unique ID for the
payment
amount to be paid to recipient
units of
payment
number of transaction units that will consist the entire payment
payer's routing information (optional, may be a partial set)
some
explanatory text to the recipient
to:
* Initiating payment between the payer and recipient nodes
* Path discovery, consisting of query messages sent out by the payer, and path-available message sent out by the recipient
* Making promises, where the payer propagates promises to redeem the payment receipt for IOUs forward down each payment path
* Finalizing the payment, where a receipt created by the payer is propagated back down the path by the recipient, and is redeemed for IOUs at each step.

'''Requesting Payment'''

A node wishing to receive a payment from another node may initiate contact with the potential payer node by sending a @@request-payment@@ message to his node's network ID:

* unique ID for the payment
* amount
* units
* time of request
* payment recipient's node's network address
* authorization number (optional)
* an explanatory note

The payment request may be followed by an @@initiate-payment@@ message from the potential payer, or ignored.

The authorization number may be used to pre-authorize payments, so the node can automatically make payments when it receives a request.  The request-payment message may also be authorized by signing it with a certain key, contained in the node owner's smart card, for example, for point-of-sale scenarios.

'''Initiating Payment'''

The payer
node contacts recipient node and communicates the following in an @@initiate-payment@@ message:

* unique ID for the
payment
* amount to be paid to recipient
* units of
payment
* number of transaction units that will consist the entire payment
* payer's routing information (optional, may be a partial set)
*
some explanatory text to the recipient
Changed lines 155-167 from:
The recipient may accept the payment initiation with an accept-payment:

payment ID
amount to be paid to recipient
units of payment
number of transaction units that will consist the entire payment
payer's explanatory text echoed back
recipient's routing information
recipient's authentication key for payment (used to sign receipts)
public-key certificate establishing recipient's identity to the payer

This must be signed by the recipient's identifying certificate key, whose certificate may be authorized by an authority recognized by the payer and which identifies the recipient in a way acceptable to the payer.  This message serves as evidence that the recipient participated in the transaction.  The explanatory text can contain the reason for the payment.  It can be used to connect the recipient's signature on receipts to the recipient (see Finalizing Payment.)
to:
The recipient may accept the payment initiation with an @@accept-payment@@:

* payment ID
* amount to be paid to recipient
* units of payment
* number of transaction units that will consist the entire payment
* payer's explanatory text echoed back
* recipient's routing information
* recipient's authentication key for payment (used to sign receipts)
* public-key certificate establishing recipient's identity to the payer

This must be signed by the recipient's identifying certificate key, whose certificate may be authorized by an authority recognized by the payer and which identifies the recipient in a way acceptable to the payer.  This message serves as evidence that the recipient participated in the transaction.  The explanatory text can contain the reason for the payment.  It can be used to connect the recipient's signature on receipts to the recipient (see [[Finalizing Payment -> #finalizing-payment]].)
Changed lines 170-184 from:
Path Queries

The payer sends out path queries to one or more of their account partners, which they in turn pass on to one or more of their partners as they deem appropriate – see Query Routing.  A path-query message consists of:

payment ID
credit available along query path so far, in transaction units
ID for the account between message sender and recipient that will form part of the path
credit available along path so far, in account units for that account (defines a conversion rate from transaction to account units)
the target's routing information
units of work remaining on this query

The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead.

A node that receives a query can accept it, which needs only an empty affirmative reply, or reject it by replying with an error code.  See Query Routing below for how nodes decide where to pass a query.  For each neighbour that it is passing the query on to, the node receiving a query should:

to:
'''Path Queries'''

The payer sends out @@path-query@@ messages to one or more of their account partners, which they in turn pass on to one or more of their partners as they deem appropriate – see [[Query Routing -> #query-routing]].  A path-query message consists of:

* payment ID
* credit available along query path so far, in transaction units
* ID for the account between message sender and recipient that will form part of the path
* credit available along path so far, in account units for that account (defines a * * * * * conversion rate from transaction to account units)
* the target's routing information
* units of work remaining on this query

The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead -- nodes should never pass a query with units of work zero.

A node that receives a query can accept it, which needs only an empty affirmative reply, or reject it by replying with an error code.  See [[Query Routing -> #query-routing]] below for how nodes decide where to pass a query.  For each neighbour that it is passing the query on to, the node receiving a query should:

* replace account ID of previous step with account ID of next step
* calculate the desired conversion rate from transaction units to account units for the * * * account with that neighbour, based on the conversion rate of the incoming query
* reduce the “credit available along the path” if the account with that neighbour has * * * * insufficient available credit
* decrement the total units of work by one
* assign that neighbour a proportion of the remaining units of work available for that query

If the payer has revealed some or all of his routing information during payment initiation, the recipient may immediately begin issuing @@path-available@@ messages.  Otherwise, he must wait until he receives a query to begin issuing them.  Path available messages contain:

* payment ID
* ID of the account between the message sender and recipient that will form part of the path
* credit currently available for this payment on this account, in account units for this step
* minimum promise time-to-penalty
* minimum required promise life
* the target's routing information (if available)
* work units remaining
* for each node that has passed along the message:
* a unique alias (each node must use the same alias for every message with the same payment ID)
* credit currently available for this transaction, in transaction units, on the account on which the node will accept payment

This last entry, along with credit available on this account, defines a conversion rate between transaction units and account units on the current account.

Path-available messages are routed just like queries (see Query Routing below), except they are headed in the other direction.  Queries received with the same payment ID will naturally give very important routing hints!  For each neighbour it is passing a path-available message on to, a node should:

Changed lines 209-210 from:
calculate the desired conversion rate from transaction units to account units for the account with that neighbour, based on the conversion rate of the incoming query
reduce the
“credit available along the path” if the account with that neighbour has insufficient available credit
to:
calculate a conversion rate between transaction units and account units for the account with that neighbour, based on the conversion rate of the incoming path-available message
change
“credit available for this payment" if appropriate
increase
the "minimum promise time-to-penalty" to ensure that it incurs no penalty without being able to recoup the amount
increase the “minimum promise life” to give it time to process the receipt if the deadline is near (see Making Promises and Finalizing Payment below)
stamp its unique alias for this payment ID on the message
stamp the credit available for this transaction on the account on which it will be accepting payment
Deleted lines 217-243:
If the payer has revealed some or all of his routing information during payment initiation, the recipient may immediately begin issuing path-available messages.  Otherwise, he must wait until he receives a query to begin issuing them.  Path available messages contain:

payment ID
ID of the account between the message sender and recipient that will form part of the path
credit currently available for this payment on this account, in account units for this step
minimum promise time-to-penalty
minimum required promise life
the target's routing information (if available)
work units remaining
for each node that has passed along the message:
a unique alias (each node must use the same alias for every message with the same payment ID)
credit currently available for this transaction, in transaction units, on the account on which the node will accept payment

This last entry, along with credit available on this account, defines a conversion rate between transaction units and account units on the current account.

Path-available messages are routed just like queries (see Query Routing below), except they are headed in the other direction.  Queries received with the same payment ID will naturally give very important routing hints!  For each neighbour it is passing a path-available message on to, a node should:

replace account ID of previous step with account ID of next step
calculate a conversion rate between transaction units and account units for the account with that neighbour, based on the conversion rate of the incoming path-available message
change “credit available for this payment" if appropriate
increase the "minimum promise time-to-penalty" to ensure that it incurs no penalty without being able to recoup the amount
increase the “minimum promise life” to give it time to process the receipt if the deadline is near (see Making Promises and Finalizing Payment below)
stamp its unique alias for this payment ID on the message
stamp the credit available for this transaction on the account on which it will be accepting payment
decrement the total units of work by one
assign that neighbour a proportion of the remaining units of work available for that query

Added line 280:
[[#finalizing-payment]]
Changed lines 90-97 from:
Changing Network ID

To change network ID, a node must send a signed id-change message containing the new network ID.  After the reply to this message, the receiving node must send all Ripple messages to the new ID.

Changing Authentication Key

Send a signed key-change message containing the new key.  (Perhaps this should contain a revocation message for the old key?)
to:
'''Changing Network ID'''

To change network ID, a node must send a signed ''id-change'' message containing the new network ID.  After the reply to this message, the receiving node must send all Ripple messages to the new ID.

'''Changing Authentication Key'''

Send a signed ''key-change'' message containing the new key.  (Perhaps this should contain a revocation message for the old key?)
Changed lines 99-107 from:
Verifying Account Data

Send a verify-account message to which the reply contains:

account balance
units of account
credit limit for each node
routing information for each node
to:
'''Verifying Account Data'''

Send a ''verify-account'' message to which the reply contains:

* account balance
* units of account
* credit limit for each node
* routing information for each node
Changed lines 110-116 from:
Payment Messages

Several payment messages are also sent over account channels.  See the next section for details.


Payments
to:
'''Payment Messages'''

Several payment messages are also sent over account channels.  See the [[next section -> #payments]] for details.

[[#payments]]
!!!
Payments
Changed lines 80-89 from:
In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a ''verify-account'' query, described in [[Verifying Account Data -> #verfiy-account]] below.

Changing Routing Information

If a node
's routing information changes, it must send a routing-change message to its neighbours:

the new set of routing information

For more information on routing information, see Query Routing below.  The routing information messages do not have to be signed.
to:
In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a ''verify-account'' query, described in [[Verifying Account Data -> #verify-account]] below.

'''Changing Routing Information'''

If a node's routing information
changes, it must send a ''routing-change'' message to its neighbours:

* the new set of routing information

For more information on routing information, see [[Query Routing -> #query-routing]] below.  The routing information messages do not have to be signed.
Added line 226:
[[#query-routing]]
Changed lines 5-6 from:
%center%''by Ryan Fugger''
to:
%center%''by Ryan Fugger''\\
Changed lines 8-9 from:
Goal
to:
'''Goal'''
Changed lines 12-13 from:
For background on Ripple, see Money as IOUs in Social Trust Networks & A Proposal for a Decentralized Currency Network Protocol at http://ripple.sourceforge.net/decentralizedcurrency.pdf.
to:
For background on Ripple, see [[Money as IOUs in Social Trust Networks & A Proposal for a Decentralized Currency Network Protocol -> http://ripple.sourceforge.net/decentralizedcurrency.pdf]].
Changed lines 17-23 from:
Network Structure

The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of IOUs between the two parties.


Accounts
to:
!!! Network Structure

The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of IOUs between the two parties.  The nature of those connections and the message transport between them is defined by a particular transport binding.  Right now, there is a [[binding to XMPP -> Main/XMPP binding]].


!!!
Accounts
Changed lines 26-35 from:
an account ID,  which serves as a permanent identifier for the account
each node's ID
the unit of account (see Units of Account)
the number of decimal digits with which to keep this account
a credit limit for each node
a record of past debits and credits
the current balance
each node's routing keywords (see Query Routing)
an authentication key for each node (see Authentication Keys)
to:
* an account ID,  which serves as a permanent identifier for the account
* each node's ID
* the unit of account (see Units of Account)
* the number of decimal digits with which to keep this account
* a credit limit for each node
* a record of past debits and credits
* the current balance
* each node's routing keywords (see Query Routing)
* an authentication key for each node (see Authentication Keys)
Changed lines 38-50 from:
Creating an Account

Accounts are created by one node offering to accept another's IOUs with an offer message containing:

an account ID
the offering node's network ID
the offering node's routing information
time of offer
the units of account
the number of decimal digits with which to keep this account
the proposed credit limit for node receiving the offer
some explanatory text to the recipient
to:
'''Creating an Account'''

Accounts are created by one node offering to accept another's IOUs with an ''offer'' message containing:

* an account ID
* the offering node's network ID
* the offering node's routing information
* time of offer
* the units of account
* the number of decimal digits with which to keep this account
* the proposed credit limit for node receiving the offer
* some explanatory text to the recipient
Changed lines 53-59 from:
If the offer recipient accepts the offer, his node sends back an offer-accept message:

account ID
current time and date
its network address
its routing information
to:
If the offer recipient accepts the offer, his node sends back an ''offer-accept'' message:

* account ID
* current time and date
* its network address
* its routing information
Changed lines 62-75 from:
 incorrect account ID
offer withdrawn

Otherwise it sends an offer-reject message. 

Changing Credit Limits

If a node wishes to change its partner's or its own credit limit, it sends a credit-change message containing:

account ID
current time and date
the address of the node whose credit limit is being changed
the new credit limit.
to:
* incorrect account ID
* offer withdrawn

Otherwise it sends an ''offer-reject'' message. 

'''Changing Credit Limits'''

If a node wishes to change its partner's or its own credit limit, it sends a ''credit-change'' message containing:

* account ID
* current time and date
* the address of the node whose credit limit is being changed
* the new credit limit.
Changed lines 80-81 from:
In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a verify-account query, described in Verifying Account Data below.
to:
In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a ''verify-account'' query, described in [[Verifying Account Data -> #verfiy-account]] below.
Added line 98:
[[#verify-account]]
Changed lines 1-5 from:
%center%'+Ripple Application Protocol+'

%center%''Preliminary Design Outline''
%center%''version 4
''
to:
!! %center%Ripple Application Protocol

%center%''Design Outline''
Added line 6:
Deleted lines 8-13:
'''To Do'''

* how to send messages to offline nodes - JEP-0079 Advanced Message Processing, JEP-0091 Delayed Delivery
* network latency discovery - JEP-0090 Entity Time
* date and time - JEP-0082 Date & Time Profiles

Changed lines 20-68 from:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of IOUs between the two parties.  Each Ripple node is an XMPP client connected to a server on an XMPP network.  The server provides the following:

node identifiers
node presence
contact list storage
node-to-node message transport
connection-level authentication and encryption
end-to-end message signing and encryption

See http://xmpp.org/ for detailed XMPP protocol specifications.

Node Identifiers

A node ID may be any legal Jabber ID, for example user@example.com or user@example.com/resource. 

Node Presence

Nodes with permission may subscribe to another node's presence, allowing nodes to know when their neighbours are online.

Contact List Storage

XMPP servers store a roster of contacts for each user which specifies node IDs, presence subscription information, contact names, and grouping of contacts.  Ripple clients may wish to group all Ripple neighbours together in one group.

Connection account data may be stored while a node is offline using XMPP extension specification JEP-0049: Private XML Storage if it is available.  Care must be taken when storing authentication keys.

Node-to-Node Message Transport

XMPP is designed to be a transport for XML messages, which makes XML a natural fit for Ripple messages, although another textual format would also work.  Ripple messages could be carried within an XMPP <iq/> stanza.  Messages would be contained in an IQ "set", and responses in IQ "result" (affirmative) or "error" (negative) stanza, containing a <query/> element in the "jabber:iq:ripple" namespace.  The <query/> element will contain the Ripple message itself.

The section "IQ semantics" of RFC 3920 (XMPP Core) describes how IQ messages provide reliable delivery by requiring a response to each query.  A Ripple node may resend any query or response if it is not certain it has been delivered.  Nodes should disregard multiple messages with the same id.

XMPP lacks proper message framing, and as such servers must parse every message in its entirety which may bog down under heavy loads.  As Ripple message volume increases -- path-finding in a large network may generate a lot of messages - XMPP messaging could be used to negotiate a direct P2P connection between nodes, as is done in JEPs 0176, 0177, and 0179.

Connection-Level Authentication and Encryption

XMPP ensures authentication of clients to servers and servers to each other using SASL.  XMPP connections support TLS encryption.

End-to-End Message Signing and Encryption

Still not finalized, JEP-0116 is the latest specification for end-to-end security of XMPP messages.  This capability is very important for Ripple.

Service Discovery

Ripple nodes should advertise themselves as such in response to service discovery queries (JEP-0030) by returning

<identity category="automation" type="ripple"/>
<feature var="jabber:iq:ripple"/>


to:
The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of IOUs between the two parties.

Added lines 1-426:
%center%'+Ripple Application Protocol+'

%center%''Preliminary Design Outline''
%center%''version 4''

%center%''by Ryan Fugger''
%center%''with contributions by Evgeni Pandurski and Brandyn Webb''

'''To Do'''

* how to send messages to offline nodes - JEP-0079 Advanced Message Processing, JEP-0091 Delayed Delivery
* network latency discovery - JEP-0090 Entity Time
* date and time - JEP-0082 Date & Time Profiles

Goal

The eventual goal is to define a protocol enabling nodes on the Ripple network to make and maintain mutual-credit accounts between them, and use the network of these accounts for making credit payments by finding paths to the payment recipient and passing credits/IOUs down those paths.  Also specified is a method of making credit/reputation check requests based on paths through the Ripple network.

For background on Ripple, see Money as IOUs in Social Trust Networks & A Proposal for a Decentralized Currency Network Protocol at http://ripple.sourceforge.net/decentralizedcurrency.pdf.

This document outlines in an abstract way the types of messages that need to be passed between nodes and the data contained in those messages.  It also addresses bindings to network protocols and possible message formats.


Network Structure

The Ripple network consists of user agents, or nodes, connected pairwise by abstract mutual-credit accounts which allow tracking of IOUs between the two parties.  Each Ripple node is an XMPP client connected to a server on an XMPP network.  The server provides the following:

node identifiers
node presence
contact list storage
node-to-node message transport
connection-level authentication and encryption
end-to-end message signing and encryption

See http://xmpp.org/ for detailed XMPP protocol specifications.

Node Identifiers

A node ID may be any legal Jabber ID, for example user@example.com or user@example.com/resource. 

Node Presence

Nodes with permission may subscribe to another node's presence, allowing nodes to know when their neighbours are online.

Contact List Storage

XMPP servers store a roster of contacts for each user which specifies node IDs, presence subscription information, contact names, and grouping of contacts.  Ripple clients may wish to group all Ripple neighbours together in one group.

Connection account data may be stored while a node is offline using XMPP extension specification JEP-0049: Private XML Storage if it is available.  Care must be taken when storing authentication keys.

Node-to-Node Message Transport

XMPP is designed to be a transport for XML messages, which makes XML a natural fit for Ripple messages, although another textual format would also work.  Ripple messages could be carried within an XMPP <iq/> stanza.  Messages would be contained in an IQ "set", and responses in IQ "result" (affirmative) or "error" (negative) stanza, containing a <query/> element in the "jabber:iq:ripple" namespace.  The <query/> element will contain the Ripple message itself.

The section "IQ semantics" of RFC 3920 (XMPP Core) describes how IQ messages provide reliable delivery by requiring a response to each query.  A Ripple node may resend any query or response if it is not certain it has been delivered.  Nodes should disregard multiple messages with the same id.

XMPP lacks proper message framing, and as such servers must parse every message in its entirety which may bog down under heavy loads.  As Ripple message volume increases -- path-finding in a large network may generate a lot of messages - XMPP messaging could be used to negotiate a direct P2P connection between nodes, as is done in JEPs 0176, 0177, and 0179.

Connection-Level Authentication and Encryption

XMPP ensures authentication of clients to servers and servers to each other using SASL.  XMPP connections support TLS encryption.

End-to-End Message Signing and Encryption

Still not finalized, JEP-0116 is the latest specification for end-to-end security of XMPP messages.  This capability is very important for Ripple.

Service Discovery

Ripple nodes should advertise themselves as such in response to service discovery queries (JEP-0030) by returning

<identity category="automation" type="ripple"/>
<feature var="jabber:iq:ripple"/>


Accounts

An account is a mutual-credit connection between two nodes defined by the following data, a copy of which is kept by the node of each account partner.

an account ID,  which serves as a permanent identifier for the account
each node's ID
the unit of account (see Units of Account)
the number of decimal digits with which to keep this account
a credit limit for each node
a record of past debits and credits
the current balance
each node's routing keywords (see Query Routing)
an authentication key for each node (see Authentication Keys)

Unless otherwise specified, all account messages must be signed by the sender's authentication key.

Creating an Account

Accounts are created by one node offering to accept another's IOUs with an offer message containing:

an account ID
the offering node's network ID
the offering node's routing information
time of offer
the units of account
the number of decimal digits with which to keep this account
the proposed credit limit for node receiving the offer
some explanatory text to the recipient

As with every message not requiring any immediate reply of data, the node receiving an offer replies with the affirmative result containing no data.

If the offer recipient accepts the offer, his node sends back an offer-accept message:

account ID
current time and date
its network address
its routing information

To indicate that the account has been created, the node receiving the offer-accept responds with the affirmative reply.  The reply may also be the negative error with one of the following error codes indicating why the account has not been created:

 incorrect account ID
offer withdrawn

Otherwise it sends an offer-reject message. 

Changing Credit Limits

If a node wishes to change its partner's or its own credit limit, it sends a credit-change message containing:

account ID
current time and date
the address of the node whose credit limit is being changed
the new credit limit.

In the case of decreasing either limit, the change is implemented immediately, as soon as the affirmative reply is received. 

In the case of increasing either limit, the message is interpreted either as a request or an offer and no change occurs until the partner sends back another credit-change message confirming the new limit or specifying a lower limit than the one proposed.  If another credit-change message addressing the limit in question is sent by the node who proposed the original change, the original message is to be disregarded. 

In the case where both nodes happen to send messages proposing to change the same limit simultaneously, the lower of the two proposals comes into effect.  In case of doubt, the other node's account state can be retrieved using a verify-account query, described in Verifying Account Data below.

Changing Routing Information

If a node's routing information changes, it must send a routing-change message to its neighbours:

the new set of routing information

For more information on routing information, see Query Routing below.  The routing information messages do not have to be signed.

Changing Network ID

To change network ID, a node must send a signed id-change message containing the new network ID.  After the reply to this message, the receiving node must send all Ripple messages to the new ID.

Changing Authentication Key

Send a signed key-change message containing the new key.  (Perhaps this should contain a revocation message for the old key?)

Verifying Account Data

Send a verify-account message to which the reply contains:

account balance
units of account
credit limit for each node
routing information for each node

Especially important to verify is the balance.  If there are discrepancies, they will have to be worked out between the node owners.  In future it may be possible to compare payments receipt-by-receipt to find the source of the discrepancy.

Payment Messages

Several payment messages are also sent over account channels.  See the next section for details.


Payments

To allow payments between two nodes that don't share an account, Ripple finds a path of account-connected intermediaries between the payer and recipient, and propagates IOUs along the path.

There are four stages to the payment process:

Initiating payment between the payer and recipient nodes
Path discovery, consisting of query messages sent out by the payer, and path-available message sent out by the recipient
Making promises, where the payer propagates promises to redeem the payment receipt for IOUs forward down each payment path
Finalizing the payment, where a receipt created by the payer is propagated back down the path by the recipient, and is redeemed for IOUs at each step.

Requesting Payment

A node wishing to receive a payment from another node may initiate contact with the potential payer node by sending a request-payment message to his node's network ID:

unique ID for the payment
amount
units
time of request
payment recipient's node's network address
authorization number (optional)
an explanatory note

The payment request may be followed by an initiate-payment message from the potential payer, or ignored.

The authorization number may be used to pre-authorize payments, so the node can automatically make payments when it receives a request.  The request-payment message may also be authorized by signing it with a certain key, contained in the node owner's smart card, for example.

Initiating Payment

The payer node contacts recipient node and communicates the following in an initiate-payment message:

unique ID for the payment
amount to be paid to recipient
units of payment
number of transaction units that will consist the entire payment
payer's routing information (optional, may be a partial set)
some explanatory text to the recipient

Transaction units are integer units invented for the purposes of the transaction to mask the true nature (amount & units) of the transaction from intermediaries.  The number of transaction units consisting the entire payment as declared in the initiate-payment message defines the conversion rate between transaction units and actual units of payment.  A simple convention is to make one transaction unit equal one cent, although any conversion rate that allows the entire amount to be flexibly divided into integer transaction-unit amounts for payment down multiple paths is acceptable.

The recipient may accept the payment initiation with an accept-payment:

payment ID
amount to be paid to recipient
units of payment
number of transaction units that will consist the entire payment
payer's explanatory text echoed back
recipient's routing information
recipient's authentication key for payment (used to sign receipts)
public-key certificate establishing recipient's identity to the payer

This must be signed by the recipient's identifying certificate key, whose certificate may be authorized by an authority recognized by the payer and which identifies the recipient in a way acceptable to the payer.  This message serves as evidence that the recipient participated in the transaction.  The explanatory text can contain the reason for the payment.  It can be used to connect the recipient's signature on receipts to the recipient (see Finalizing Payment.)

Otherwise the payer rejects the payment initiation with an error code.

Path Queries

The payer sends out path queries to one or more of their account partners, which they in turn pass on to one or more of their partners as they deem appropriate – see Query Routing.  A path-query message consists of:

payment ID
credit available along query path so far, in transaction units
ID for the account between message sender and recipient that will form part of the path
credit available along path so far, in account units for that account (defines a conversion rate from transaction to account units)
the target's routing information
units of work remaining on this query

The credit available along the path so far is to help route the query by preferring accounts that have that amount of available credit.  Units of work is how queries are given a finite lifetime.  Each unit of work represents one query message being passed from one neighbour to another.  When a query is received from one neighbour and subsequently sent to several other neighbours, the units of work must be divided up amongst the subqueries, and each number decremented by one.  When units of work reaches zero, the query may be considered dead.

A node that receives a query can accept it, which needs only an empty affirmative reply, or reject it by replying with an error code.  See Query Routing below for how nodes decide where to pass a query.  For each neighbour that it is passing the query on to, the node receiving a query should:

replace account ID of previous step with account ID of next step
calculate the desired conversion rate from transaction units to account units for the account with that neighbour, based on the conversion rate of the incoming query
reduce the “credit available along the path” if the account with that neighbour has insufficient available credit
decrement the total units of work by one
assign that neighbour a proportion of the remaining units of work available for that query

If the payer has revealed some or all of his routing information during payment initiation, the recipient may immediately begin issuing path-available messages.  Otherwise, he must wait until he receives a query to begin issuing them.  Path available messages contain:

payment ID
ID of the account between the message sender and recipient that will form part of the path
credit currently available for this payment on this account, in account units for this step
minimum promise time-to-penalty
minimum required promise life
the target's routing information (if available)
work units remaining
for each node that has passed along the message:
a unique alias (each node must use the same alias for every message with the same payment ID)
credit currently available for this transaction, in transaction units, on the account on which the node will accept payment

This last entry, along with credit available on this account, defines a conversion rate between transaction units and account units on the current account.

Path-available messages are routed just like queries (see Query Routing below), except they are headed in the other direction.  Queries received with the same payment ID will naturally give very important routing hints!  For each neighbour it is passing a path-available message on to, a node should:

replace account ID of previous step with account ID of next step
calculate a conversion rate between transaction units and account units for the account with that neighbour, based on the conversion rate of the incoming path-available message
change “credit available for this payment" if appropriate
increase the "minimum promise time-to-penalty" to ensure that it incurs no penalty without being able to recoup the amount
increase the “minimum promise life” to give it time to process the receipt if the deadline is near (see Making Promises and Finalizing Payment below)
stamp its unique alias for this payment ID on the message
stamp the credit available for this transaction on the account on which it will be accepting payment
decrement the total units of work by one
assign that neighbour a proportion of the remaining units of work available for that query

If a node receives a path-available that already has its transaction-unique alias stamped on it, it should reject it to avoid loops in the payment path.

Nodes must store who passed them queries for a given payment ID.  Nodes must also store the aliases of the neighbours that passed path-available messages in case that path is selected for the next phase of the transaction, Making Promises, as well as conversion rates between account units and transaction units, minimum promise time-to-penatly and promise life.

Fees

Fees charged may be integrated as a percentage into conversion rates between units.  There is no provision for flat fees at the moment.

Query Routing

Every node assigns itself a set of keywords which serve to locate it in the network.  Most keywords should be chosen so they are shared with several neighbours, although nodes are free to select keywords to identify them uniquely.  Geographic names are ideal for routing keywords as they provide a natural hierarchy: country, province/state, city, etc.

Nodes should advertise their keywords to their neighbours with keyword-advertisement messages.  Nodes can also advertise their distance to other keywords using this same message type:

keyword
number of hops to keyword

Nodes are not obliged to pass on keyword advertisements, and may pass on advertisements to selected neighbours.  Generally, nodes will want to pass on keyword advertisements that give new information about a shorter path to a certain keyword that has been relatively popular in past queries.

Nodes that receive too many advertisements in a certain time period from a certain neighbour should reply with the appropriate error code.

To route path queries (and path-available messages), nodes should make use of the keyword advertisements they have received, as well as past records of success in finding paths through various neighbours.  Nodes might also consider such things as neighbours' connection latency, desirability of holding or spending certain IOUs, exchange rates offered, number of queries sent to each neighbour, etc.

The performance of path-finding will be critical to the success of Ripple, and therefore the protocol should be as flexible as possible in terms of its ability to incorporate new and diverse methods of path-finding.

Once a Path is Found

When a node sees a path-query and a path-available with the same payment ID, a path has been found.  The node that discovered the connection should immediately pass the path available message in the direction from which it received the path-query.  It should also continue routing queries and path-available messages as usual, since further paths may be necessary to complete the entire payment, or may offer a lower price for the payer.

The payer analyzes path-available messages it receives to build a set of paths with potentially enough available credit to complete the payment.

Making Promises (Commit-Request)

When the payer has found payment paths with enough combined available credit to complete the payment, it sends a promise message to the first node on each path, representing its commitment to redeem a valid receipt that can be authenticated with the promise's authentication key up to the amount of IOUs indicated on the receipt, if presented before the stated deadline.  A promise serves to hold credit for the payment.

payment ID
path ID (a chain of promises defines a path)
amount to be held for payment, in transaction units
ID of account to be made part of path by this promise being passed
amount to be held for payment, in account units, according to conversion rate defined by neighbour in path-available message
promise time-to-penalty
daily penalty rate if receipt or promise-release not received within time-to-penalty
promise deadline, after which promise expires
the payer's receipt authentication key for this payment path
the recipient's receipt authentication key for this payment path
the transaction alias for each node in the path, in order
a timestamp to indicate the time the promise came into effect.

At each step, the promise message is authenticated to the next node by the passing node's host's authentication key.  This serves to establish the integrity and non-repudiability of the promise.

Each node passes the promise message on to the next node in the path as indicated by the transaction alias after its own on the promise message.  Before passing it on, each node that receives a promise should:

calculate the amount held for payment in account units on the next account in the path according to the conversion rate stated in the path-available message received on that account
reduce the amount to be held for payment in transaction units if there is insufficient credit on the next account in the path
shorten the time-to-penalty to what it indicated on the path-available message
optionally increase the daily penalty rate
shorten the deadline according to the promise life it indicated on the path-available message
remove its own alias from the list of intermediaries

The path-available message referred to above is the most recent path-available message received with the same path forward to the payment recipient, as determined by the list of transaction aliases.

Finalizing the Payment

The recipient sends the payer promise-received messages, each indicating that a promise has been received:

received promise's path ID
final amount of promise in transaction units
recipient's deadline for accepting the receipt for this path
timestamp indicating current time

The recipient can cancel the transaction at any time by informing the payer and releasing its neighbours from their promises.  The payer can cancel the transaction by informing the recipient that it can release its neighbours from their promises.  Released promises should be propagated back down each payment path to free up those funds for other payments.

When the payer receives promise-received messages equal to or exceeding the amount of the payment, he generates receipts matching the promises received by the recipient, – one receipt per promise/path --  authenticates them individually with each path's authentication key, and sends them each to the recipient:

payment ID
path ID
amount for this path in transaction units

The collection of receipts signed by the payer represents the value of the payment, and once they are given to the recipient, the recipient is considered to have been paid.  If any of the receipts does not match its promise (eg, one of the amounts is wrong) or is otherwise invalid (to be rigorously defined), the amount of that receipt is not considered to have been paid until a valid receipt is issued.  The recipient must reply with an error code when receiving an invalid receipt.


Redeeming Promises (Commit)

Once the recipient has the receipts for a payment, and has verified the payer's signature on each of them, she must sign each of them with her authentication key for the payment to establish that she has accepted it from the payer.  This validates the receipt so that it will be acceptable to the payment intermediaries.  This recipient-signed receipt must then be passed back to the payer as proof-of-payment.

Then the recipient redeems each receipt by passing a receipt message to each of its neighbours that has promised to redeem a receipt.  Each neighbour in turn passes the receipt back along the path to the payer.  At each step, an outstanding promise is redeemed for the promised IOUs by adjusting the account balance according to the conversion rate between transaction and account units given by the promise.

When a node accepts a receipt, it must stamp the amount to be redeemed in account units, sign the receipt with its authentication key, and reply by sending the signed receipt back to the node that it accepted the receipt from.  This creates an undeniable record that the promise has been redeemed.  The sum of signed receipts from each partner to an account equals the account balance.  The original receipt is passed down the chain unchanged.

Releasing Promises (Rollback)

A node may release a neighbour from all or part of its promise at any time with a signed promise-release message:

payment ID
path ID
amount to release, in transaction units
error/reason code

If an intermediary node is at any time released from its promise, it should immediately release the preceding node in the path from its related promise to free up available credit.  Failure to release promises in a timely fashion will result in penalty fees being assessed according to the time-to-penalty and daily penalty rate thereafter. 

Promise Penalties and Expiry

A promise has two deadlines:  a penalty deadline and a final deadline.  After the first, penalty, deadline, the promise issuer may begin penalizing the promise holder for failing to provide either a receipt or a promise-release.  Penalties are charged at the daily rate stated on the promise applied to the full amount of the promise.  The penalty grows continually applied to fractions of days since the penalty deadline, not just in chunks every 24 hours.

Penalties are collected by issuing a payment-request to the offending node, containing the following special fields:

penalty – payment ID
penalty – path ID

The offending node may automatically pay the fine when requested, or hold the payment request for approval by the human being who owns the node.  Penalties continue to accrue even though a fine may be paid, until a receipt or promise-release is produced, or until the promise's second, final, deadline is reached.

If any promise's final deadline for accepting receipts passes, the issuing node should issue a promise-expired notification, containing:

payment ID
path ID
timestamp

Then, it may issue a promise-release back down the chain, triggering a wave of promise-releases back to the payer.

Any node can fulfill an expired promise if it wishes and has available credit.  Any node can request that an expired promise be fulfilled by sending a promise-renew request:

payment ID
promise ID

This may cause a chain of such requests to be passed back to the payer.  If accepted, the promise should be reissued with a new deadline, and the receipt can then be presented safely for redemption.  There is no way to enforce promise renewal.

Timing Disputes

Neighbouring nodes should accept receipts and promise-releases received soon after deadlines with no penalty if doing so causes them no loss further down the chain.  If two neighbours can not cooperate in this fashion due to high latency on their connection and a refusal to extend long deadlines to each other, then they cannot continue being neighbours.

Timing disputes between payer and recipient are slightly different, since they have no presumed trust between them.  There may be a dispute about whether a receipt sent to the recipient by the payer reached the recipient before the recipient's deadline.  The payer may suspect that the recipient used the receipt to collect payment from the path intermediaries, but is refusing to acknowledge that fact.  Ultimately, this type of dispute is resolved by the payer waiting to see if a payer-signed receipt comes back down the payment path before the final deadline.  If so, that receipt provides proof-of-payment, regardless whether the payer met the deadline for passing the receipt to the payment recipient.

For greater accountability in either case, a third party timing authority could timestamp and relay messages to provide a definitive message time.  This capability could be integrated in the future.

Other Disputes

Generally, the receipts should propagate in an orderly fashion back to the payer.  But it is possible that an intermediary node goes offline during this redemption phase and remains offline until after the redemption deadlines have passed.  In this case, the intermediary directly after the offline node may get stuck with the receipt and thus an undeserved burden of payment.  This intermediary will rightly blame the node that went offline, who is a trusted associate, and request that he take responsibility for the loss.  To do this, the node that went offline can reissue his promise and accept the receipt.  This allows him to continue attempting to renew promises back to the payer and recoup his loss.  The node with the receipt and the node that went offline must negotiate a workable settlement in any case.  This negotiation may become part of a future Ripple protocol.

It would be good etiquette for a node that is stuck with a receipt and unable to communicate with the next node up the chain to make an effort to contact the owner of that node, by email for example, ahead of the deadline to give her warning that her node is down and that she will be expected to cover any loss incurred by her node being unavailable.

Reputable node hosts may offer insurance against such downtime losses if they are due to a server failure, power outage, etc.  One can imagine the possibility of dumb fall-back nodes that could perform minimal operations in case the primary node went down.

A neighbour that fails to acknowledge a receipt and then fails to take responsibility for any loss incurred should not remain a neighbour for long.


Credit/Reputation Requests

A node may wish to check how much another node can pay it without actually receiving payment, as a means of checking that node's credit or reputation.  This can be accomplished by using the payment process, but by indicating that transaction is a credit check and not a payment, so that no credit is actually held and no actual payments are prevented by it.  The total value of promises received is the result of the credit check.


Appendices

Units of Account

National currencies and other value units can be identified by arbitrary strings, although this should be standardized across the Ripple network to avoid duplicate IDs.  A natural ID for a national currency is its three-letter code.  Other standard units should be ounces of gold, grams of gold, hours, joules, and kilowatt-hours.

Other types of units may be useful for credit/reputation checks, although not for payment.  For example, a satisfied customer may give a merchant one unit of "satisfied customer" credit for each successful transaction with her.  Then a prospective customer could learn about that merchant's reputation by doing a credit check against "satisfied customer" units.