Ripple Distributed Protocol v0.5

Protocol.Protocol05 History

Hide minor edits - Show changes to output

Changed line 69 from:
* '''Node''' - an address in the credit network that can send and/or receive payment.
to:
* '''Node''' - an address in the credit network that can send and/or receive payment.  Nodes are exchange hubs that transmit value between their incoming and outgoing lines of credit.
Changed line 73 from:
* '''Line of credit''' - a credit relationship between two nodes.
to:
* '''Line of credit''' - a credit relationship between two nodes in which one node offers to accept the other's IOUs up to a certain limit, enabling value to flow in one direction between the two nodes.
Added lines 109-110:

The Ripple credit network consists of nodes and lines of credit between them, forming a directed graph of potential value flow.  A node is represents an exchange hub that can transmit value from any of its incoming lines of credit to any of its outgoing lines of credit.  In general, a Ripple user will have multiple nodes.  Arbitrary exchanges between a user's connections can be accomplished by assigning a separate node for each connection and a line of credit for each exchange that the user wishes to perform.
Changed lines 421-423 from:
Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU need only be sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account.  If an IOU is a consequence of a routed transaction, the @@transaction_key_id@@ must be included.
to:
Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU is only sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account. 

If an IOU is a consequence of a routed transaction, the @@transaction_key_id@@ must be included.  In this case, the IOU is merely indicating agreement that the corresponding @@Promise@@ has been committed.
Changed line 707 from:
Commit is generated by the recipient and used to trigger promises back through the intermediaries to the payer.  A promise holder redeems the promise its holds with its neighbour by sending a Commit message with the same @@commit_key_id@@ as the Promise, and with its @@commit_token@@ signed in @@commit_signature@@ by the transaction's @@commit_key@@, before the promise's expiry.
to:
Commit is generated by the recipient and used to trigger promises back through the intermediaries to the payer.  A promise holder redeems the promise its holds with its neighbour by sending a Commit message with the same @@commit_key_id@@ as the Promise, and with its @@commit_key_id@@ signed in @@commit_signature@@ by the transaction's @@commit_key@@, before the promise's expiry.
Added lines 363-364:

TODO: Maybe allow extra keys for signing some types of messages (like Credit?) to enable servers only partial control over a node (can't issue any extra credit, for example)?  Maybe a different key for broadcast messages than for neighbour messages?
Changed line 395 from:
@@linked_line_of_credit_id@@ indicates another line of credit that is to have a shared balance with this line of credit, in order that the two lines of credit form a single mutual credit account.  The linked line of credit does not have to be between the same two nodes, but it must have the same unitsThis would be used if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | @@Credit@@]] below.
to:
Lines of credit only transfer value in one direction, with the node initiating the connection accepting value from the node receiving the connection invitation.  Two lines of credit can be linked together to form a single bidirectional mutual credit account with a single balance, by setting @@linked_line_of_credit_id@@ when the second line of credit is createdThe linked line of credit does not have to be between the same two nodes, but it must have the same units.  This would happen if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | @@Credit@@]] below.
Changed lines 534-538 from:
   optional uint32 chunk_id = 4 [default = 0];
   optional string limit = 5;
    optional string exchange_rate = 6 [default = '1'];
    optional bytes exchange_rate_key_id = 7;
    optional bytes atomicity_fee_set_key_id = 8;
to:
   message CreditChunk {
      required uint32 chunk_id = 1;
        optional string amount = 2;
       optional string exchange_rate = 3 [default = '1'];
 
     optional bytes exchange_rate_key_id = 4;
        optional bytes atomicity_fee_set_key_id = 5;
    }
    repeated CreditChunk chunks = 4
;
Changed lines 547-552 from:
A node may advertise multiple "chunks" on the same line of credit, in order to, for example, offer a better exchange rate for a portion of credit available in order motivate its use.  Exchange rates are set at either end unilaterally, so both partners need not agree on chunks.  When multiple chunks are advertised, @@chunk_id@@ must be used to distinguish between them.  A missing @@chunk_id@@ refers to chunk 0, the default chunk for that line of credit.

@@limit@@ indicates the maximum value of obligations the source node is willing to accept from (@@IN@@) or emit to (@@OUT@@)
the partner node, in the units of that line of credit.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If @@limit@@ is missing, it is assumed the node will process unlimited transfers on this line of credit.

Limits set by each partner do not have to agree.  When they do not, the lower of the two limits
prevails.
to:
A node may advertise multiple "chunks" on the same line of credit, in order to, for example, offer a better exchange rate for a portion of credit available in order motivate its use.  Exchange rates are set at either end unilaterally, so both partners need not agree on chunks.

@@amount@@ indicates the maximum value of obligations the source node is willing
to accept from (@@IN@@) or emit to (@@OUT@@) the partner node, at the corresponding exchange rate.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If @@amount@@ is missing, it is assumed the node will process unlimited transfers on this line of credit.

Credit amounts set by each partner do not have to agree.  When they do not, the lower of the two amounts
prevails.
Changed line 567 from:
For efficiency, nodes may not wish to advertise the exact account limits, but rather some other lower number that will accomodate enough transactions to be useful, but will not need frequent updating.  This behaviour should generate fewer broadcast messages.  Payers can still potentially get approval for larger transactions by making [[#credit_check | Credit Checks]] prior to initiating payment.
to:
For efficiency, nodes may not wish to advertise the exact credit limits, but rather some other lower number that will accomodate enough transactions to be useful, but will not need frequent updating.  This behaviour should generate fewer broadcast messages.  Payers can still potentially get approval for larger transactions by making [[#credit_check | Credit Checks]] prior to initiating payment.
Changed lines 382-383 from:
   required precision = 3;
    required scale = 4;
to:
   required uint32 precision = 3;
    required uint32 scale = 4;
Changed lines 522-523 from:
TODO: Remove in_*/out_* field coupling here and just define a line of credit as a one-directional flow?  (Would need extra field for incoming/outgoing -- atomicity fee would only apply to incoming.)
to:
TODO:
- Advertise precision
/scale of LoC?
Changed lines 529-536 from:
   optional uint32 chunk_id = 3 [default = 0];
    optional string in_limit = 4;
    optional string out_limit = 5;
    optional string in_rate = 6 [default = '1'];
 
   optional string out_rate = 7 [default = '1'];
   optional bytes in_rate_key_id = 8;
 
   optional bytes out_rate_key_id = 9;
 
   optional bytes atomicity_fee_set_key_id = 10;
to:
   enum Direction = {
       IN = 0;
        OUT = 1;
    }
    required Direction direction = 3;
    optional uint32 chunk_id
= 4 [default = 0];
    optional string limit = 5;
    optional string exchange_rate = 6 [default = '1'];
    optional bytes exchange_rate_key_id = 7;
    optional bytes atomicity_fee_set_key_id = 8
;
Changed lines 542-543 from:
Broadcast credit advertisement.  Signed by @@from@@ address.  For a line of credit to be valid for use in transactions, both partner nodes must broadcast corresponding credit advertisements.
to:
Broadcast credit advertisement.  Signed by @@from@@ address.  For a line of credit to be valid for use in transactions, both partner nodes must broadcast corresponding credit advertisements.  One partner advertises the @@IN@@ direction, the other advertises the @@OUT@@ direction.
Changed lines 546-549 from:
@@in_limit@@ and @@out_limit@@ indicate the maximum value of obligations the node given by @@source_address@@ is willing to accept from and emit to, respectively, the node given by @@partner_address@@, in the units of that line of credit.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If either limit is missing, it is assumed the node will process unlimited transfers in that direction.  To accept no transfers in a particular direction, the appropriate limit must be explicitly set to zero.

Limits set by each partner for a given direction (one partner's @@in_limit@@ corresponds to the other's @@out_limit@@) do not have to agree.  When they do not, the lower of the two limits is used
.
to:
@@limit@@ indicates the maximum value of obligations the source node is willing to accept from (@@IN@@) or emit to (@@OUT@@) the partner node, in the units of that line of credit.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If @@limit@@ is missing, it is assumed the node will process unlimited transfers on this line of credit.

Limits set by each partner do not have to agree.  When they do not
, the lower of the two limits prevails.
Changed line 555 from:
* IM (incoming multiplier) = in rate * atomicity fee
to:
* IM (incoming multiplier) = IN rate * atomicity fee
Changed line 557 from:
* OM (outgoing multiplier) = out rate
to:
* OM (outgoing multiplier) = OUT rate
Changed lines 560-563 from:
Here, the incoming multiplier is calculated by multiplying @@in_rate@@ (or the rate corresponding to @@in_rate_key_id@@) with the atomicity fee.  Similarly outgoing multiplier is calculated from @@out_rate@@ or @@out_rate_key_id@@.  The atomicity fees are selected from the Atomicity Fee Set corresponding to @@atomicity_fee_set_key_id@@, for the appropriate atomicity mode.

By indicating an
@@in_limit@@, the node is offering to exchange incoming values on that line of credit into outgoing values on any of the node's lines of credit with an @@out_limit@@.  A node cannot indicate that it is unwilling to make certain of these exchanges.  Instead, multiple nodes must be used to limit exchanges between one user's accounts.
to:
Here, IN rate is calculated by multiplying @@exchange_rate@@ and the rate corresponding to @@exchange_rate_key_id@@, if given, for the IN node.  Similarly OUT rate is calculated from the @@OUT@@ node's @@exchange_rate@@ and rate from @@exchange_rate_key_id@@.  The atomicity fees are selected from the Atomicity Fee Set corresponding to @@atomicity_fee_set_key_id@@, for the appropriate atomicity mode, and only apply to the @@IN@@ node.

A node
is a conceptual entity that performs exchanges between all of its incoming lines of credit and all of its outgoing lines of credit.  To indicate that some some exchanges are not performed, use multiple nodes.
Added line 576:
   required string amount = 2;
Deleted line 577:
   required string amount = 2;
Added lines 522-523:
TODO: Remove in_*/out_* field coupling here and just define a line of credit as a one-directional flow?  (Would need extra field for incoming/outgoing -- atomicity fee would only apply to incoming.)
Changed line 557 from:
Here, the in rate calculated by multiplying @@in_rate@@ and the rate corresponding to @@in_rate_key_id@@, if given.  Similarly out rate is calculated from @@out_rate@@ and @@out_rate_key_id@@.  The atomicity fees are selected from the Atomicity Fee Set corresponding to @@atomicity_fee_set_key_id@@, for the appropriate atomicity mode.
to:
Here, the incoming multiplier is calculated by multiplying @@in_rate@@ (or the rate corresponding to @@in_rate_key_id@@) with the atomicity fee.  Similarly outgoing multiplier is calculated from @@out_rate@@ or @@out_rate_key_id@@.  The atomicity fees are selected from the Atomicity Fee Set corresponding to @@atomicity_fee_set_key_id@@, for the appropriate atomicity mode.
May 12, 2011, at 06:25 PM by Ryan - Remove transaction_key_id from Commit.
Changed lines 620-621 from:
Sent by either payer or recipient to the other payment endpoint to initiate or request payment, respectively.  To request payment, the recipient specifies a @@request_id@@, but no @@transaction_key_id@@.  To initiate payment, the payer specifies a @@transaction_key_id@@, and the @@request_id@@ if it is sending the payment in response to a request from the recipient.  @@transaction_key_id@@ is the canonical hash of a key the payer will use to authenticate its messages to intermediaries when necessary during the transaction.
to:
Sent by either payer or recipient to the other payment endpoint to initiate or request payment, respectively.  To request payment, the recipient specifies a @@request_id@@, but no @@transaction_key_id@@.  To initiate payment, the payer specifies a @@transaction_key_id@@, and the @@request_id@@ if it is sending the payment in response to a request from the recipient.  @@transaction_key_id@@ is the canonical hash of a key the payer will use to authenticate its messages to intermediaries when necessary during the transaction, and must be unique.
Changed lines 643-644 from:
@@commit_key_id@@ must be the canonical hash of @@commit_key@@, which is used by the recipient to sign the Commit message.
to:
@@commit_key_id@@ must be the canonical hash of @@commit_key@@, which is used by the recipient to sign the Commit message, and must be unique.
Changed lines 692-696 from:
   message CommitToken {
        required bytes transaction_key_id = 1;
        required bytes commit_key_id = 2;
    }
    required CommitToken commit_token
= 1;
to:
   required bytes commit_key_id = 1;
Changed line 697 from:
Commit is generated by the recipient and used to trigger promises back through the intermediaries to the payer.  A promise holder redeems the promise its holds with its neighbour by sending a Commit message with the same @@transaction_key_id@@ and @@commit_key_id@@ as the Promise, and with its @@commit_token@@ signed in @@commit_signature@@ by the transaction's @@commit_key@@, before the promise's expiry.
to:
Commit is generated by the recipient and used to trigger promises back through the intermediaries to the payer.  A promise holder redeems the promise its holds with its neighbour by sending a Commit message with the same @@commit_key_id@@ as the Promise, and with its @@commit_token@@ signed in @@commit_signature@@ by the transaction's @@commit_key@@, before the promise's expiry.
May 12, 2011, at 06:20 PM by Ryan - Fix tabs.
Changed lines 190-211 from:
TIME = 0;
RELAY = 1;
INVENTORY
= 2;
INVENTORY_REQUEST = 3;
NODE = 10;
CONNECT
= 11;
IOU = 12;
KEY_CERTIFICATE = 20
;
KEY_REVOCATION = 21;
EXCHANGE_RATE = 22;
ATOMICITY
_FEE_SET = 23;
CREDIT = 24;
CREDIT_CHECK = 30
;
PAYMENT_INIT = 31;
PAYMENT_ACCEPT = 32;
PROMISE
= 33;
PROMISE_RELEASE = 34;
COMMIT = 35
;
PROMISE_RENEW = 36;
STATUS_QUERY = 40;
STATUS
= 41;
ERROR = 100;
to:
    TIME = 0;
    RELAY = 1;
    INVENTORY = 2;
    INVENTORY_REQUEST = 3;
    NODE = 10;
    CONNECT = 11;
    IOU = 12;
    KEY_CERTIFICATE = 20;
   KEY_REVOCATION = 21;
    EXCHANGE_RATE = 22;
    ATOMICITY_FEE_SET = 23;
    CREDIT = 24;
    CREDIT_CHECK = 30;
    PAYMENT_INIT = 31;
    PAYMENT_ACCEPT = 32;
    PROMISE = 33;
    PROMISE_RELEASE = 34;
    COMMIT = 35;
    PROMISE_RENEW = 36;
    STATUS_QUERY = 40;
    STATUS = 41;
   
ERROR = 100;
Changed lines 382-383 from:
required precision = 3;
required scale = 4;
to:
    required precision = 3;
   required scale = 4;
Changed line 435 from:
required bytes key_id = 1;
to:
   required bytes key_id = 1;
Changed lines 437-440 from:
optional double valid_from = 3;
optional double valid_until = 4;
optional bytes revocation_hash = 5;
optional
bytes supersedes_key_id = 6;
to:
    optional double valid_from = 3;
    optional double valid_until = 4;
    optional bytes revocation_hash = 5;
   
optional bytes supersedes_key_id = 6;
Changed lines 457-461 from:
required KeyCertificate revocation_key = 2;
required bytes salt = 3;
optional string reason = 4;
optional double compromised_since
= 5;
optional KeyCertificate replacement_key = 6;
to:
    required KeyCertificate revocation_key = 2;
    required bytes salt = 3;
   optional string reason = 4;
    optional double compromised_since = 5;
   
optional KeyCertificate replacement_key = 6;
Changed line 502 from:
BARE = 0;
to:
   BARE = 0;
Changed lines 506-512 from:
required bytes atomicity_fee_set_key_id = 1;
message AtomicityFee {
required AtomicityMode atomicity_mode = 1;
optional string atomicity_rate = 2 [default = "1"];
optional string
atomicity_flat_fee = 3 [default = "0"];
}
repeated
AtomicityFee atomicity_fees = 2;
to:
    required bytes atomicity_fee_set_key_id = 1;
    message AtomicityFee {
 
      required AtomicityMode atomicity_mode = 1;
       optional string atomicity_rate = 2 [default = "1"];
       optional string atomicity_flat_fee = 3 [default = "0"];
    }
   
repeated AtomicityFee atomicity_fees = 2;
Changed lines 529-530 from:
optional string in_rate = 6 [default = '1'];
optional string out_rate = 7 [default = '1'];
to:
    optional string in_rate = 6 [default = '1'];
   optional string out_rate = 7 [default = '1'];
Changed line 533 from:
optional bytes atomicity_fee_set_key_id = 10;
to:
   optional bytes atomicity_fee_set_key_id = 10;
Changed line 616 from:
optional bytes data = 7;
to:
   optional bytes data = 7;
Changed lines 633-634 from:
required bytes commit_key_id = 2;
required PublicKey commit_key = 3;
to:
    required bytes commit_key_id = 2;
   required PublicKey commit_key = 3;
Changed line 636 from:
optional string commit_url = 5;
to:
   optional string commit_url = 5;
Changed lines 656-657 from:
required bytes commit_key_id = 3;
required PublicKey commit_key = 4;
to:
    required bytes commit_key_id = 3;
   required PublicKey commit_key = 4;
Changed line 662 from:
optional commit_url = 9;
to:
   optional commit_url = 9;
Changed line 694 from:
required bytes commit_key_id = 2;
to:
       required bytes commit_key_id = 2;
Changed line 714 from:
This behaviour is difficult or impossible to verify or enforce, therefore @@BARE@@ atomicity mode is only appropriate for use within a cooperating group of servers.
to:
This behaviour is difficult or impossible to verify or enforce, therefore @@BARE@@ atomicity mode is only appropriate for use within a cooperating group of servers.  Even within a group of cooperating servers, a server outage could cause a transaction to permanently stall partially-committed if committing it would now cause an unacceptable credit limit overage.
Deleted lines 49-50:
* [[#promise_accept | Promise Accept]]
* [[#commit_ready | Commit Ready]]
May 12, 2011, at 03:32 AM by Ryan - Rewrite to allow for registry extension, and other improvements.
Changed lines 3-4 from:
A protocol for establishing mutual credit accounts between users on different hosts, and conducting multi-hop transactions through the resulting credit network.
to:
A protocol for establishing mutual credit accounts between users on different servers, and transmitting value through the resulting credit network in real-time.
Changed lines 8-10 from:
1. [[#definitions | Definitions]]

2. [[#transport | Transport]]
to:
0. [[#definitions | Definitions]]
* [[#terms | Terms]]
* [[#cryptographic_algorithms | Cryptographic Algorithms]]

1. [[#introduction | Introduction]]

2. [[#message_transport | Message
Transport]]
Added lines 19-21:
* [[#time_format | Time Format]]
* [[#public_key_format | Public Key Format]]
* [[#identifiers | Identifiers]]
Deleted lines 23-24:
* [[#public_key_format | Public Key Format]]
* [[#unique_ids | Unique IDs]]
Deleted line 28:
* [[#node | Node]]
Added line 33:
* [[#node-account | Node]]
Changed lines 37-38 from:
6. [[#routing_messages | Routing Messages]]
* [[#credit | Credit]]
to:
6. [[#broadcast_messages | Broadcast Messages]]
* [[#key_certificate | Key Certificate]]
* [[#key_revocation | Key Revocation]]
* [[#node-broadcast | Node (Broadcast)
]]
Added lines 42-45:
* [[#atomicity_fee_set | Atomicity Fee Set]]
* [[#credit | Credit]]

7. [[#transaction_messages | Transaction Messages]]
Deleted lines 46-47:

7. [[#transaction_messages | Transaction Messages]]
Added line 50:
* [[#promise_accept | Promise Accept]]
Changed lines 62-63 from:
!! 1. Definitions
to:
!! 0. Definitions

[[#terms]]
!!! Terms

Changed lines 69-70 from:
* '''Data network''' - the network of data connections that serves to pass messages between host machines; the internet.
to:
* '''Data network''' - the network of data connections that serves to pass messages between different servers
Changed lines 73-74 from:
* '''Server''' - the protocol software, an instance of that software running on a host machine, or the host itself running the software.
to:
* '''Server''' - an software program speaking the Ripple protocol running on a host machine, or the host itself running the software.  A server hosts one or more nodes.
Changed lines 76-88 from:
  * not quite the same as the higher-level term '''mutual credit account''', which is a credit relationship between two ''users'', each of which may control multiple nodes, consisting of either one or two lines of credit, depending on the routing needs.


[[#transport]]
!! 2. Transport

Ripple messages are passed over TCP connections, secured by [[http://en.wikipedia.org/wiki/Transport_Layer_Security | TLS]].  Connected Ripple hosts are considered peers in that they can each pass the same set of messages to each other, as opposed to client and server, where one sends requests and the other responds.  For efficiency, connections should preferably be long-lasting, rather than set up for each message and then closed immediately.

Messages and their responses are passed asynchronously, meaning that multiple requests may be sent by one host on the same connection before any potential responses to those requests are received back, and the responses may come in any order, so that the responding server may take advantage of its parallel processing capabilities.  Hosts may open multiple TCP connections with each other if [[http://document-program.blogspot.com/2009/11/105-exploring-head-of-line-blocking.html | head-of-line blocking]] becomes a bottleneck for messages on a single connection (or for any other reason).

''In the future, [[http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol | SCTP]] has many desirable features as a Ripple transport layer, once it becomes more commonplace and easy to use in various networking frameworks and hosting arrangements.''


to:
* '''Mutual credit account''' - a credit relationship between two ''users'', each of which may control multiple nodes, consisting of either one or two lines of credit between their nodes, depending on the routing needs.


[[#cryptographic_algorithms]]
!!! Cryptographic Algorithms

* '''SHA-256''' - Hash function defined at http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
* '''RSA''' - public key cryptography scheme defined at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
* '''RSASSA-PSS''' - public key signature scheme defined at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
* '''RSAES-OAEP''' - public key encryption scheme defined at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
  * '''MGF1''' - mask generation function defined at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
* '''AES-256''' - secret key encryption scheme defined at http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
* '''TLS''' - protocol for securing TCP connections, defined at http://tools.ietf.org/html/rfc5246


[[#introduction]]
!! 1. Introduction

Ripple is a protocol for transmitting value through a credit network formed by mutual credit accounts between "nodes".  The protocol consists of several parts:

* a message transport mechanism for passing messages directly between servers
* a message tunnelling mechanism for sending messages indirectly between servers
* a broadcast mechanism for distributing messages across the entire network
* a basic public key infrastructure (PKI)
* a mechanism for establishing and managing mutual credit accounts between nodes
* a path-discovery mechanism for discovering paths through the credit network that can send payment from a selected payer node to a selected recipient node
* a transaction mechanism for committing payments over paths through the credit network

Ripple servers can pass messages directly to each other over TCP connections, secured by TLS.  Messages can also be encrypted to a node on an unknown server and relayed there via one or more intermediaries using the Relay message.  Broadcast messages are passed across the data network between servers: the @@Inventory@@ message notifies a neighbouring server of pending broadcast messages, which it may then request using an @@InventoryRequest@@.

Ripple makes heavy use of public key cryptography, and public keys are used to identify nodes, transactions, and other entities in the network.  To distribute and manage these keys, Ripple has a basic public key infrastructure consisting of @@KeyCertificate@@ and @@KeyRevocation@@ messages.

Ripple servers can declare the existence of nodes to other servers, and then establish lines of credit with nodes on other servers.  They can then pass and request IOUs over established lines of credit.

Servers can then broadcast details of their nodes' lines of credit across the network so they can be used in multi-hop transactions in which a series of connected of nodes, called a path or chain of intermediaries, is asked to pass forward IOUs on specific lines of credit simultaneously in order to transfer value between two nodes that may not have a line of credit between them.

Multi-hop transactions use a two-phase commit protocol.  The originating node, called the payer, determines a suitable path through the credit network connecting it and the destination node, called the recipient.  The payer informs the recipient of the payment.  If the recipient approves, the payer begins a two-phase commit by sending a commit-ready message called a @@Promise@@ to the first node(s) on the path, who in turn send their own promises to the next node(s), until all promises reach the recipient, who then, in concert with the payer, creates a cryptographic @@Commit@@ message that can be used to trigger IOU passing by redeeming promises backwards down the path from recipient to payer.

At every step, the protocol ensures that messages committing entities to particular actions are signed by their identifying public keys, so they may be later held to those commitments.


[[#message_transport]]
!! 2. Message Transport

Ripple messages are passed over TCP connections, secured by TLS.  Connected Ripple servers are considered peers in that they can each pass the same set of messages to each other, as opposed to client and server, where one sends requests and the other responds.  For efficiency, connections should preferably be long-lasting, rather than set up for each message and then closed immediately.

Messages and their responses are passed asynchronously, meaning that multiple requests may be sent by one server on the same connection before any potential responses to those requests are received back, and the responses may come in any order, so that the responding server may take advantage of its parallel processing capabilities.  Servers may open multiple TCP connections with each other if [[http://document-program.blogspot.com/2009/11/105-exploring-head-of-line-blocking.html | head-of-line blocking]] becomes a bottleneck for messages on a single connection (or for any other reason).

TODO: Define default port for Ripple servers.

''In the future, [[http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol | SCTP]] has desirable features as a Ripple transport layer, once it becomes more commonplace and easy to use in various networking frameworks and hosting arrangements.''


Changed lines 159-160 from:
Each @@MSG@@ message must be replied to with zero or more a @@ANS@@ messages with the same @@Message Number@@ containing any content in direct response to the @@MSG@@, followed by an empty @@OK@@ frame, also with the same @@Message Number@@, indicating an end to that message exchange.  For example, any error messages resulting from a @@MSG@@ request would go in an @@ANS@@ response.  Each @@ANS@@ message must be completely transmitted before another @@ANS@@ or @@OK@@ in the same message exchange is begun.  Multiple message exchanges can be open simultaneously on the same connection.  BEEP and SPDY prescribe even-numbered messages for the connection initiator and odd-numbered messages for the listener, but here either host may use any number, as long as it has not already been used for a message that has not been replied to.
to:
Each @@MSG@@ message must be replied to with zero or more a @@ANS@@ messages with the same @@Message Number@@ containing any content in direct response to the @@MSG@@, followed by an empty @@OK@@ frame, also with the same @@Message Number@@, indicating an end to that message exchange.  For example, any error messages resulting from a @@MSG@@ request would go in an @@ANS@@ response.  Each @@ANS@@ message must be completely transmitted before another @@ANS@@ or @@OK@@ in the same message exchange is begun.  Multiple message exchanges can be open simultaneously on the same connection.  BEEP and SPDY prescribe even-numbered messages for the connection initiator and odd-numbered messages for the listener, but here either server may use any number, as long as it has not already been used for a message that has not been replied to.
Changed lines 167-168 from:
Ripple messages are defined using Google's [[ http://code.google.com/apis/protocolbuffers/ | Protocol Buffers ]] mechanism.
to:
Ripple messages are defined using Google's [[ http://code.google.com/apis/protocolbuffers/ | Protocol Buffers ]] mechanism.  Fields of type @@bytes@@ are given in network byte order.
Added lines 180-181:
TODO: Add hop-limit or valid-until for routing broadcasts?
Added lines 191-215:
enum MessageType {
TIME = 0;
RELAY = 1;
INVENTORY = 2;
INVENTORY_REQUEST = 3;
NODE = 10;
CONNECT = 11;
IOU = 12;
KEY_CERTIFICATE = 20;
KEY_REVOCATION = 21;
EXCHANGE_RATE = 22;
ATOMICITY_FEE_SET = 23;
CREDIT = 24;
CREDIT_CHECK = 30;
PAYMENT_INIT = 31;
PAYMENT_ACCEPT = 32;
PROMISE = 33;
PROMISE_RELEASE = 34;
COMMIT = 35;
PROMISE_RENEW = 36;
STATUS_QUERY = 40;
STATUS = 41;
ERROR = 100;
}

Deleted lines 216-236:
   enum MessageType {
        TIME = 0;
        RELAY = 1;
        NODE = 2;
        INVENTORY = 3;
        INVENTORY_REQUEST = 4;
        CONNECT = 10;
        IOU = 11;
        CREDIT = 20;
        EXCHANGE_RATE = 21;
        CREDIT_CHECK = 22;
        PAYMENT_INIT = 30;
        PAYMENT_ACCEPT = 31;
        PROMISE = 32;
        COMMIT_READY = 33;
        PROMISE_RELEASE = 34;
        COMMIT = 35;
        STATUS_QUERY = 40;
        STATUS = 41;
        ERROR = 50;
    }
Changed line 221 from:
   optional bytes to = 5;
to:
   optional bytes to_key_id = 5;
Changed line 223 from:
   optional bytes from = 7;
to:
   optional bytes from_key_id = 7;
Changed lines 228-235 from:
@@version@@ is the Ripple protocol version this message is to be interpreted under.  This document's protocol version is @@0.5@@.  @@time@@ is given in number of seconds since Jan. 1, 1970 (ie, unix time).  @@message_id@@ is to identify broadcast messages, so a host needn't receive the same message repeatedly.

@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | @@Nodes@@ message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains and ports, eg, ''user@host.com:1234''.  Since one user may have multiple nodes, when directing a message to a user rather than to a specific node, such as when creating a line of credit or initiating a payment, use an alias.  You should get a return message back with @@from@@ set to the appropriate node you should be addressing, as well as @@from_alias@@ set to the alias of the user you sent the initial message to.  If this message is signed, it can then be used to provably link the alias to the node.


[[#signatures]]
!!! Signatures
to:
@@version@@ is the Ripple protocol version this message is to be interpreted under.  This document's protocol version is @@0.5@@.  @@message_id@@ is to identify different broadcast messages from a particular source, so a server needn't receive the same message repeatedly.

@@
to_key_id@@ and @@from_key_id@@ are key-associated IDs for network entities.  (See [[#identifiers | Identifiers]] below.@@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify server domains and ports, eg, ''user@host.com:1234''.  Since one user may have multiple nodes, when directing a message to a user rather than to a specific node, such as when creating a line of credit or initiating a payment, use an alias.  You should get a return message back with @@from@@ set to the appropriate node you should be addressing, as well as @@from_alias@@ set to the alias of the user you sent the initial message to.  If this message is signed, it can then be used to provably link the alias to the node.


[[#time_format]]
!!! Time Format

Times are given as 64-bit floating point values (ie, Protocol Buffer @@double@@ fields) which represent
the number of seconds since the Unix epoch at midnight, Jan. 1, 1970, UTC.


[[#public_key_format]]
!!! Public Key Format
Changed lines 243-245 from:
message Signature {
    optional bytes signer = 1;
    required bytes signature = 2
;
to:
message PublicKey {
    required bytes modulus = 1;
Changed lines 248-255 from:
@@signature@@ is a [[ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf | PKCS#1 v2.1]] RSASSA-PSS signature with SHA256 as the hash function.

@@signer@@ is the address of the signing node if the signature is generated by its communication key, or canonical hash of the key used if not, and may be omitted if there is only a single signer who is already identified in the message.


[[#encrypted_messages]]
!!! Encrypted Messages

to:
Ripple uses RSA keys of any length @@modulus@@ with a fixed exponent of 65537.

The canonical hash identifier of a key is the result of SHA-256 applied to the modulus.


[[#identifiers]]
!!! Identifiers

There are two types
of identifiers:

1. Entities associated with a public key are identified by the canonical hash of the key.  Fields containing such identifiers usually end in @@key_id@@
.

2. Entities not associated with a public key are identified by a 16-byte [[http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID]] generated by any method (Protocol Buffers @@bytes@@), or an integer (Protocol Buffers @@uint32@@ or @@uint64@@).  Fields containing such identifiers usually end in @@id@@.


[[#signatures]]
!!! Signatures

Changed lines 267-270 from:
message EncryptedMessage {
    required bytes recipient = 1;
    required bytes encrypted_key = 3;
    required bytes ciphertext = 4
;
to:
message Signature {
    optional bytes signer_key_id = 1;
    required bytes signature = 2;
Changed lines 273-280 from:
@@recipient@@ is a node address (hash of node's signing key).

To encrypt a @@RippleMessage@@ to the recipient, the sender encrypts a symmetric AES256 encryption key, using [[ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf | PKCS#1 v2.1]] RSAES-OAEP with MGF1/SHA256, and then uses that key to encrypt the message to the @@ciphertext@@ field using AES256 encryption.


[[#public_key_format]]
!!! Public Key Format

to:
@@signature@@ is a RSASSA-PSS signature with SHA-256 as the hash function.

@@signer_key_id@@ is the hash-identifier of the signing key, and may be omitted where it is already given by the context.


[[#encrypted_messages]]
!!! Encrypted Messages
Changed lines 282-283 from:
message PublicKey {
    required bytes modulus = 1;
to:
message EncryptedMessage {
    required bytes recipient_key_id = 1;
    required bytes encrypted_key = 2;
    required bytes ciphertext = 3
;
Changed lines 289-297 from:
Ripple uses RSA keys of any length with a fixed exponent of 65537.  @@modulus@@ is big-endian.


[[#unique_ids]]
!!! Unique IDs

Unless otherwise specified, unique identifiers are 16-byte [[http://en.wikipedia.org/wiki/Universally_unique_identifier | UUIDs]], generated by any method.  Usually these fields have names ending in
@@_id@@.

to:
@@recipient_key_id@@ is a node address (hash of node's signing key).

To encrypt a
@@RippleMessage@@ to the recipient, the sender encrypts a symmetric AES-256 encryption key, using RSAES-OAEP with MGF1 as the mask generation function and SHA-256 as the hash function, and then uses that key to encrypt the message to the @@ciphertext@@ field using AES-256 encryption in CTR (counter) mode with an IV (initial value) of all zero bytes.

Changed lines 297-299 from:
Decimal numbers (ie, monetary amounts), are encoded as Protocol Buffer ASCII/UTF-8 strings to avoid rounding error introduced by binary encoding.

to:
Decimal numbers (ie, monetary amounts), are encoded as Protocol Buffer ASCII/UTF-8 strings to avoid rounding error introduced by binary encoding.  A period '.' is used as the decimal separator, and negative numbers are prefixed with '-'.

When rounding is necessary, the [[http://en.wikipedia.org/wiki/Rounding#Round_half_to_even | round half to even]] method must be used
.

Changed lines 308-314 from:
@@Time@@ has no message body.

Allows hosts to discover what time the other thinks it is (before transmission delay).  A peer can send a @@Time@@ message at any time during the connection.  The other peer should respond immediately with its own @@Time@@ message.

The
actual time is contained in the header.

to:
Allows connected servers to discover what time the other thinks it is (before transmission delay), so they can compensate appropriately when performing time-sensitive actions involving the other server.

A server can send a Time message at any time during the connection.  The other server should respond immediately with its own Time message.

Time has no message body. 
The actual time is contained in the header.

Changed lines 325-330 from:
Message encrypted to destination node to pass on to @@message.recipient@@.  Encrypted message may be another @@Relay@@.  Broadcast messages should not be tunneled using @@Relay@@.


[[#node]]
!!! Node
to:
Message encrypted to destination node to pass on to @@message.recipient@@.  Encrypted message may be another Relay.  Broadcast messages should not be tunneled using Relay.


[[#inventory]]
!!! Inventory
Changed lines 332-340 from:
message Node {
    required PublicKey identity_key = 1;
    required double identity_key_expiry = 2;
    required PublicKey communication_key = 3;
    required double communication_key_expiry = 4;
    optional bytes old_address = 5;
    optional string host = 6;
    optional string transaction_fee = 7;
    optional string commit_archive_url = 8
;
to:
message InventoryItem {
    required bytes source = 1;
    required bytes message_id = 2;
    required MessageType type = 3;
Added lines 337-340:

message Inventory {
    repeated InventoryItem items = 1;
}
Changed lines 343-360 from:
Broadcast advertisement describing a node.  The node's address is given in the @@from@@ field of the header.

@@address@@ is the RIPEMD160 hash
of the node's @@identity_key@@ structure, used to identify the node in message headers and elsewhere@@identity_key@@ is only used to sign @@Node@@ messages establishing a communication key.  @@communication_key@@ is then used for signing and encryption of other messages.  The reason for this setup is to facilitate medium-term cycling of communication keys without requiring a change of address.  Thus the identity key can be very large and communication keys can be smaller, yielding smaller more efficient signatures.  Old communication keys should be kept around for a period after cycling in case messages arrive that still use them.

@@old_address@@ is used to indicate that this is a change of identity key for this node.  If a node receives a @@Node@@ message with its own address in the @@old_address@@ field, and it wishes to transfer itself to the sending host, it should sign the @@Node@@ message for the new address and pass it back to the new address for broadcast.  If a node receives a @@Node@@ message with one of its line of credit partner addresses in the @@old_address@@ field, the line of credit moves to being with the new node address.

The message is signed by @@identity_key@@, as well as the previous identity key for @@old_address@@, if the node is being renamed. 

@@host@@ is the host[:port] server address for the node.  This allows any node to send messages directly to this node, in particular [[#status_query | status queries]].  For privacy reasons, this is not required.

@@transaction_fee@@ is where a node can indicate that it charges a flat fee for through-transactions.  Fee is given in node base units -- see [[#credit | Credit message]] below.

@@commit_archive_url@@ is a URL of the form "http://host.com/commit/%s", so that when "%s" is substituted with a canonical form transaction ID such as "5e025939-6ab8-4563-87b2-7e90f87a84f8", it returns a commit token for that transaction, timestamped and signed by by @@identity_key@@.  Nodes publishing a @@commit_archive_url@@ should also publish their @@host@@, so commit messages can be submitted to them directly.


[[#inventory]]
!!! Inventory

to:
Broadcast to let neighbouring servers know about new [[#broadcast_messages | broadcast messages]].  Another server would be considered a neighbour if one of its nodes is given a credit limit by one of a server's local nodes

When two servers first become neighbours, the server sending the initial [[#connect | Connect message]] should also send the first Inventory message.  Then the other server need only send an Inventory containing @@message_id@@s the initiating server doesn't already have
.


[[#inventory_request]]
!!! Inventory Request

Changed lines 352-360 from:
message InventoryItem {
    required bytes source = 1;
    required bytes message_id = 2;
    enum BroadcastMessageType {
        NODE = 1;
        CREDIT = 2;
        EXCHANGE_RATE = 3;
    }
    required BroadcastMessageType type = 3;
to:
message InventoryRequest {
    repeated InventoryItem items = 1;   
Deleted lines 354-357:

message Inventory {
    repeated InventoryItem items = 1;
}
Changed lines 357-362 from:
Broadcast to let neighbouring hosts know about new broadcast message IDs.  @@source@@ is included with each message ID so another node cannot block full propagation of a broadcast message by simply propagating a message with a similar ID.  (Broadcast messages must be signed by the communication key cryptographically linked to the source address.)  It may also help determine whether the receiving node is interested in the item.


[[#inventory_request]]
!!! Inventory Request

to:
Request to receive the listed broadcast messages.  The requested messages should then be sent individually as separate messages.


[[#account_messages]]
!! 5. Account Messages

[[#
node-account]]
!!! Node

Changed lines 367-368 from:
message InventoryRequest {
    repeated InventoryItem items = 1;  
to:
message Node {
    optional string host = 1;
Changed lines 372-377 from:
Request to receive the listed broadcast messages.


[[#account_messages]]
!! 5. Account Messages

to:
Let another server know about a node that wishes to establish a line of credit with one of its nodes.  The node's identifying key is given by @@from_key_id@@ in the header, and this message must be signed by that key.

@@host@@ identifies the domain and port of the node's server, eg, ''host.com:1234'', if the node wants other nodes to be able to communicate with it directly.  If @@host@@ is given, this message should be broadcast after the first line of credit is established.  This message cannot be relayed unless @@host@@ is given, since the receiver would have no way of knowing where to address the reply.

Changed lines 384-390 from:
    optional string units = 3;
    optional string credit_offered = 4;
    optional string iou_offered = 5;
    repeated bytes commit_arbiters = 6;
    optional string note = 7;
    optional bytes proof_of_id = 8;
    optional bytes old_address = 9;
to:
required precision = 3;
required scale = 4;
    optional string units = 5;
    optional string credit_offered = 6;
    optional string iou_offered = 7;
    optional string note = 8;
    optional bytes proof_of_id = 9;
    optional bytes old_node_id = 10;
Changed lines 399-400 from:
@@commit_arbiters@@ identifies nodes which the sending node agrees will be authoritative on the existence of transaction commit message at particular times, in case of disagreement between the two partner nodes.  See [[#promise | @@Promise@@]] below.  Only nodes publishing a @@commit_archive_url@@ should be listed.
to:
Nodes must agree on how numeric amount values for the line of credit will be stored, so each can maintain identical records of the account.  @@precision@@ specifies the maximum total number of digits in any amount, and @@scale@@ specifies the maximum digits after the decimal point.  Connect messages from both partners must contain the same @@precision@@ and @@scale@@ values.  Amounts refering to this account must be be rounded to the agreed precision and scale when being considered.

In particular, messages refering to this line of credit may contain values that go beyond the precision and scale specified, and these values must be rounded when being considered
.
Changed lines 405-407 from:
To move a line of credit to a different node, send another @@Connect@@ message with the existing @@line_of_credit_id@@ from the new node address, and put the old node address into @@old_address@@.  Sign the message with both node keys.

to:
To move a line of credit to a different node, send another @@Connect@@ message with the existing @@line_of_credit_id@@ from the new node address, and put the old node ID into @@old_node_id@@.  Sign the message with both node keys.

Changed line 416 from:
   optional bytes transaction_id = 4;
to:
   optional bytes transaction_key_id = 4;
Changed lines 421-422 from:
Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU need only be sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account.  If an IOU is a consequence of a routed transaction, the @@transaction_id@@ must be included.
to:
Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU need only be sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account.  If an IOU is a consequence of a routed transaction, the @@transaction_key_id@@ must be included.
Changed lines 427-431 from:
!! 6. Routing Messages

[[#credit]]
!!! Credit

to:
!! 6. Broadcast Messages

All broadcast messages must be signed by their source's identifying key.


[[#key_certificate]]
!!! Key Certificate

Changed lines 436-448 from:
message Credit {
    required bytes partner_address = 1;
 
  required bytes line_of_credit_id = 2;
    optional bytes chunk_id = 3;
    optional string in_limit = 4;
    optional string out_limit = 5;
    optional string in_rate = 6;
    optional string out_rate = 7;
    optional bytes in_rate_id = 8;
    optional bytes out_rate_id = 9;
    optional string in_rate_modifier = 10;
    optional string out_rate_modifier = 11;
    optional double expiry = 12
;
to:
message KeyCertificate {
required bytes key_id = 1;
 
  required PublicKey key = 2;
optional double valid
_from = 3;
optional double valid_until = 4;
optional bytes revocation_hash = 5;
optional bytes supersedes_key_id = 6;
Changed lines 446-468 from:
Broadcast credit advertisement.  Signed by @@from@@ addressFor a line of credit to be valid for use in transactions, both partner nodes must broadcast corresponding credit advertisements.

A node may advertise multiple "chunks" on the same line of credit, in order to, for example, offer
a better exchange rate for a portion of credit available in order motivate its use.  Exchange rates are set at either end unilaterally, so both partners need not agree on chunks.  When multiple chunks are advertised, @@chunk_id@@ must be used to distinguish between them.  A missing @@chunk_id@@ refers to the default chunk for that line of credit.

@@in_limit@@ and @@out_limit@@ indicate the maximum value of obligations the node given by @@source_address@@ is willing to accept from and emit to, respectively, the node given by @@partner_address@@, in the units of that line of credit.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If either limit is missing, it is assumed the node will process unlimited transfers in that direction.

Each node has a conceptual base unit, which line-of-credit (LoC) values can be converted to and from using the advertised @@in_rate@@ and @@out_rate@@ multipliers, given as decimal values, not percentages:

* incoming LoC amount * @@in_rate@@ = amount in node units
* amount in node units * @@out_rate@@ = outgoing LoC amount

By indicating an @@in_limit@@, the node is offering to exchange incoming values on that line of credit into outgoing values on any of the node's lines of credit with an @@out_limit@@.  A node cannot indicate that it is unwilling to make certain of these exchanges.  Instead, multiple nodes must be used.

Instead of advertising numeric exchange rates, nodes may reference independently-broadcast exchange rates using @@in_rate_id@@ and @@out_rate_id@@.  (See [[#exchange_rate | @@ExchangeRate@@]] below.)  Nodes may modify these independently-broadcast rates using @@in_rate_modifier@@ and @@out_rate_modifier@@, which give values to be added to broadcast rates to determine the node's exchange rates for that line of credit.

Advertised credit and exchange rates are informational only and not binding.

For efficiency, nodes may not wish to advertise the exact account limits, but rather some other lower number that will accomodate enough transactions to be useful, but will not need frequent updating.  This behaviour should generate fewer broadcast messages.  Payers can still potentially get approval for larger transactions by making [[#credit_check | Credit Checks]] prior to initiating payment.


[[#exchange_rate]]
!!! Exchange Rate

to:
Announces a public key and its validity period@@key_id@@ must be the key's canonical hash.  @@revocation_hash@@ is the SHA-256 hash of the concatenation of this key's modulus, the revocation key's modulus, and a secret salt, used to validate a [[#key_revocation | Key Revocation]].

If
a previously-announced key ID is given in @@supersedes_key_id@@, the present key is intended to replace the previous key as the identifier for the entity identified by the previous key's ID.  During the period that both certificates are valid, both key IDs are acceptable identifiers for the entity.

Must be signed by the given key, and the key
that it supersedes, if any.


[[#key_revocation]]
!!! Key Revocation

Changed lines 457-463 from:
message ExchangeRate {
    required bytes rate_id = 1;
    required string rate = 2;
    optional string in_units = 3;
    optional string out_units = 4;
    optional string description = 5;
    optional double valid_until
= 6;
to:
message KeyRevocation {
    required bytes revoked_key_id = 1;
required KeyCertificate revocation_key = 2;
required bytes salt = 3;
optional string reason = 4;
optional double compromised_since = 5;
optional KeyCertificate replacement_key = 6;
Changed lines 467-472 from:
Signed by @@from@@ address.


[[#credit_check]]
!!! Credit Check

to:
Used in an emergency to revoke a compromised key using a secret revocation key.  For example, if a node's private identity key is compromised and used to move the node to another host with a new identity key, a revocation of the old key indicating that it was compromised prior to the move would notify its partners that the new identity is not legitimate and to halt all dealings until the situation is sorted out.

To be eligible for revocation, a [[#public_key_format | @@PublicKey@@]] must contain a @@revocation_hash@@ value.  To be valid, a @@KeyRevocation@@'s revoked key modulus, revocation key modulus, and salt, concatenated together and SHA-256'd must equal the @@revocation_hash@@ of the revoked key.

The purpose of the @@salt@@ is to prevent discovery of which other keys use the same revocation key, once a @@KeyRevocation@@ has been issued. 

Must be signed by the revocation key.


[[#node-broadcast]]
!!! Node (Broadcast)

[[#node-account | Node messages]] may also be broadcast.  The broadcast form is identical to the local form used when creating lines of credit.  A broadcast Node message is distinguishable from a local Node message, and its meaning the sending server wishes to use the node to connect to a node on the receiving server, by the fact that it is announced by an Inventory message, and received in response to an InventoryRequest.


[[#exchange_rate]]
!!! Exchange Rate

Changed lines 486-490 from:
message Transfer {
    required bytes line_of_credit_id = 1;
    optional bytes chunk_id = 3;
    required string amount = 2;
    optional EncryptedMessage onion_forward = 4;
to:
message ExchangeRate {
    required bytes rate_key_id = 1;
    required string rate = 2;
    optional string in_units = 3;
    optional string out_units = 4;
    optional string description = 5;
    optional double valid_until = 6
;
Changed lines 494-500 from:

message Exchange {
    repeated Transfer in
_transfers = 1;
    repeated Transfer out
_transfers = 2;
 
  optional bool wait_for_merge = 3;
    optional string forward_to_node = 4;
    optional bytes forward_to_host = 5
;
to:
@]

Signed by the key whose ID is @@rate
_key_id@@.


[[#atomicity_fee_set]]
!!! Atomicity Fee Set

[@
enum AtomicityMode = {
BARE = 0
;
Changed lines 507-515 from:
message CreditCheck {
    required bytes check_id = 1;
    required bytes checker_key = 2;
    optional EncryptedMessage exchange_onion = 3;
    message CheckResponse {
        required bytes node_address = 1;
        required bool transaction_possible = 2;
    }
    repeated EncryptedMessage responses = 4
;
to:
message AtomicityFeeSet {
required bytes atomicity_fee_set_key_id = 1;
message AtomicityFee {
required AtomicityMode atomicity_mode = 1
;
optional string atomicity_rate = 2 [default = "1"];
optional string atomicity_flat_fee = 3 [default = "0"];
}
repeated AtomicityFee atomicity_fees = 2
;
Changed lines 518-535 from:
Used to inquire from one or more nodes whether a particular transaction is possible at the moment.  @@exchange_onion@@ contains an @@Exchange@@ structure, encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  @@chunk_id@@s are specified when desired credit has previously been advertised as a non-default chunk.  Each outgoing @@Transfer@@ structure may contain a further @@Exchange@@, encrypted to the next intermediary node in the transaction.  

The response to a credit check is a boolean @@transaction_possible@@, which indicates whether the the node is willing to perform the requested exchange at the moment.  Responses must be encrypted against @@checker_key@@, appended to @@responses@@, and @@onion_forward@@ copied to @@exchange_onion@@ for each branch going forward.  An affirmative response is no guarantee of credit availability, just a relatively up-to-date credit advertisement.

When a propagating credit check branches and then merges again, only one branch needs to carry responses from the branch point and before, and only one branch needs to contain @@Exchange@@ queries for the merge point node and beyond.  When a node receives a credit check with no @@exchange_onion@@, it should expect a further credit check message with the same @@check_id@@ that does contain an @@exchange_onion@@.  @@wait_for_merge@@ indicates to a node to wait for all branches to arrive and concatenate all responses before forwarding them on.

@@forward_to_node@@ indicates that the receiving node should add its response, and, after waiting for merge, if requested, forward the credit check to a particular node.  This allows checking only a portion of a potential transaction flow subgraph.  @@forward_to_host@@ allows the credit check to be forwarded directly, but if it is missing, or connection to the destination hosts fails, the credit check should be forwarded over the credit network using @@Relay@@.


[[#transaction_messages]]
!! 7. Transaction Messages

[[#payment_request]]
!!! Payment Request

[[#payment_init]]
!!! Payment Init

to:
Allows nodes to define a set of conversion factors and flat fees to be applied to incoming transactions on a line of credit, depending on the type of atomicity offered by the transaction.  This document only defines a single atomicity mode @@BARE@@, but extensions can define others that may allow for less intermediary risk and therefore lower fees.  See [[#credit | Credit message]] below for how the atomicity rate and flat fee are applied.


[[#credit]]
!!! Credit

Changed lines 525-530 from:
message PaymentInit {
    required bytes transaction_id = 1;
    required string amount = 2;
    optional string units = 3;
   optional string memo = 4;
 
   optional bytes proof_of_id = 5;
to:
message Credit {
    required bytes partner_node_key_id = 1;
    required bytes line_of_credit_id = 2;
    optional uint32 chunk_id = 3 [default = 0];
    optional string in_limit = 4;
    optional string out_limit =
5;
optional string in_rate = 6 [default = '1'];
optional string out_rate = 7 [default = '1'];
    optional bytes in_rate_key_id = 8;
    optional bytes out_rate_key_id = 9;
optional bytes atomicity_fee_set_key_id = 10
;
Changed lines 539-550 from:
Sent by payer to recipient (or vice-versa for payment request with negative amount), signed by sender.  Amount is given in recipient node base units.

@@units@@ is an optional string that can be used to indicate the payer's understanding that the payment amount is being valued by the recipient in some external unit of account.  By filling out this field, the payer is asking for the recipient node to reject the payment if it does not recognize the @@units@@ value as the base unit of account for the recipient node, to help prevent misunderstandings.

If @@amount@@ is negative, the message is interpreted as a request for
the receiving node to send an equal but positive-valued payment to the sender.

@@proof_of_id@@ may be used to link the sending node to a human identity.  The mechanism is left unspecified here.


[[#payment_accept]]
!!! Payment Accept

to:
Broadcast credit advertisement.  Signed by @@from@@ address.  For a line of credit to be valid for use in transactions, both partner nodes must broadcast corresponding credit advertisements.

A node may advertise multiple "chunks" on the same line of credit, in order to, for example, offer a better exchange rate for a portion of credit available in order motivate its use.  Exchange rates are set at either end unilaterally, so both partners need not agree on chunks.  When multiple chunks are advertised, @@chunk_id@@ must be used to distinguish between them.  A missing @@chunk_id@@ refers to chunk 0, the default chunk for that line of credit.

@@in_limit@@ and @@out_limit@@ indicate
the maximum value of obligations the node given by @@source_address@@ is willing to accept from and emit to, respectively, the node given by @@partner_address@@, in the units of that line of credit.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If either limit is missing, it is assumed the node will process unlimited transfers in that direction.  To accept no transfers in a particular direction, the appropriate limit must be explicitly set to zero.

Limits set by each partner for a given direction (one partner's @@in_limit@@ corresponds to the other's @@out_limit@@) do not have to agree.  When they do not, the lower of the two limits is used.

Each node has a conceptual base unit, which line-of-credit (LoC) values can be converted to and from:

* incoming LoC amount * IM - IFF = incoming amount in node units
* amount in node units * OM - OFF = outgoing LoC amount

* IM (incoming multiplier) = in rate * atomicity fee
* IFF (incoming flat fee) = atomicity flat fee
* OM (outgoing multiplier) = out rate
* OFF (outgoing flat fee) = 0 (may be modified by extensions)

Here, the in rate calculated by multiplying @@in_rate@@ and the rate corresponding to @@in_rate_key_id@@, if given.  Similarly out rate is calculated from @@out_rate@@ and @@out_rate_key_id@@.  The atomicity fees are selected from the Atomicity Fee Set corresponding to @@atomicity_fee_set_key_id@@, for the appropriate atomicity mode.

By indicating an @@in_limit@@, the node is offering to exchange incoming values on that line of credit into outgoing values on any of the node's lines of credit with an @@out_limit@@.  A node cannot indicate that it is unwilling to make certain of these exchanges.  Instead, multiple nodes must be used to limit exchanges between one user's accounts.

For efficiency, nodes may not wish to advertise the exact account limits, but rather some other lower number that will accomodate enough transactions to be useful, but will not need frequent updating.  This behaviour should generate fewer broadcast messages.  Payers can still potentially get approval for larger transactions by making [[#credit_check | Credit Checks]] prior to initiating payment.


[[#transaction_messages]]
!! 7. Transaction Messages

[[#credit_check]]
!!! Credit Check

Changed lines 571-575 from:
message PaymentAccept {
    required bytes payment_init = 1;
    required bytes recipient_commit_key = 2;
    optional string commit_url = 3;
    optional bytes proof_of_id = 4;
to:
message Transfer {
    required bytes line_of_credit_id = 1;
    optional uint32 chunk_id = 3;
    required string amount = 2;
    optional EncryptedMessage onion_forward = 4;
Added lines 577-595:

message Exchange {
    repeated Transfer in_transfers = 1;
    repeated Transfer out_transfers = 2;
    optional bool wait_for_merge = 3;
    optional bytes forward_to_node_key_id = 4;
    optional string forward_to_host = 5;
}

message CreditCheck {
    required bytes check_id = 1;
    required PublicKey checker_key = 2;
    optional EncryptedMessage exchange_onion = 3;
    message CheckResponse {
        required bytes node_key_id = 1;
        required bool transaction_possible = 2;
    }
    repeated EncryptedMessage responses = 4;
}
Changed lines 598-607 from:
Returned by recipient in response to a payment init, if it chooses to accept the paymentMust be signed by recipient. 

@@payment_init@@ is a copy of
the payment init.  A recipient that does not understand units should strip the @@units@@ field from the payment init if it was set, otherwise it is acknowledging that the payment is being received in the stated units.

@@recipient_commit_key@@ will be used by the recipient to sign the commit message.  @@commit_url@@ is a URL where the commit message will be made available once it has been prepared. 


[[#promise]]
!!! Promise

to:
Used to inquire from one or more nodes whether a particular transaction is possible at the moment@@exchange_onion@@ contains an @@Exchange@@ structure, encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  @@chunk_id@@s are specified when desired credit has previously been advertised as a non-default chunk.  Each outgoing @@Transfer@@ structure may contain a further @@Exchange@@, encrypted to the next intermediary node in the transaction.

The response to a credit check is a boolean @@transaction_possible@@, which indicates whether the the node is willing to perform the requested exchange at the moment.  Responses must be encrypted against @@checker_key@@, appended to @@responses@@, and @@onion_forward@@ copied to @@exchange_onion@@ for each branch going forward.  An affirmative response is no guarantee of credit availability, just a relatively up-to-date credit advertisement.

When a propagating credit check branches and then merges again, only one branch needs to carry responses from the branch point and before, and only one branch needs to contain @@Exchange@@ queries for the merge point node and beyond.  When a node receives a credit check with no @@exchange_onion@@, it should expect a further credit check message with the same @@check_id@@ that does contain an @@exchange_onion@@.  @@wait_for_merge@@ indicates to a node to wait for all branches to arrive and concatenate all responses before forwarding them on.

@@forward_to_node_key_id@@ indicates that the receiving node should add its response, and, after waiting for merge, if requested, forward the credit check to a particular node, generally the node performing the credit check.  @@forward_to_host@@ allows the credit check to be forwarded directly, but if it is missing, or connection to the destination hosts fails, the credit check should be forwarded over the credit network using @@Relay@@.


[[#payment_init]]
!!! Payment Init

Changed lines 611-613 from:
message Promise {
    required bytes transaction_id = 1;
    required bytes line_of_credit_id = 2;
to:
message PaymentInit {
    optional bytes request_id = 1;
    optional bytes transaction_key_id = 2;
Changed lines 615-620 from:
   required double expiry = 4;
    required bytes payer_commit_key = 5;
    required bytes recipient_commit_key = 6;
    optional bytes exchange_onion = 7;
    optional string commit_url = 8;
    repeated bytes commit_arbiters = 9
;
to:
   optional string units = 4;
    optional string memo = 5;
    optional bytes proof_of_id = 6;
optional bytes data = 7;
Changed lines 622-631 from:
A signed promise to pass forward an [[#iou | @@IOU@@]] of value @@amount@@ on the specified line of credit when shown a commit message with the given @@transaction_id@@, and signed by the @@payer_commit_key@@ and @@recipient_commit_key@@ before the @@expiry@@ time.

@@exchange_onion@@ consists of @@Exchange@@ structures (defined in [[#credit_check | @@CreditCheck@@]] above), and defines the lines of credit and exchanges to carry obligations to the recipient.  @@forward_to_node@@ and @@forward_to_host@@ are not used here.

If any of the nodes identified
in @@commit_arbiters@@ declares, by timestamping, signing, and making available a valid commit message at its @@commit_archive_url@@, that a valid commit message existed at a time before promise @@expiry@@, then the promisor must pass forward an IOU to fulfill the promise.  Generally, the commit message for a transaction would just be presented to the promisor before promise expiry, and the promisor would immediately pass the required IOU.  @@commit_arbiters@@ gives the promisee a mechanism to have the promise fulfilled in case the promisor is non-responsive in the period before the promise expires.


[[#commit_ready]]
!!! Commit Ready

to:
Sent by either payer or recipient to the other payment endpoint to initiate or request payment, respectively.  To request payment, the recipient specifies a @@request_id@@, but no @@transaction_key_id@@.  To initiate payment, the payer specifies a @@transaction_key_id@@, and the @@request_id@@ if it is sending the payment in response to a request from the recipient.  @@transaction_key_id@@ is the canonical hash of a key the payer will use to authenticate its messages to intermediaries when necessary during the transaction.

@@amount@@ is given
in recipient node base units.  @@units@@ is an optional string that can be used to indicate the payer's understanding that the payment amount is being valued by the recipient in some external unit of account.  By filling out this field, the payer is asking for the recipient node to reject the payment if the given @@units@@ value is not the correct base unit of account for the recipient node, to help prevent misunderstandings.

@@proof_of_id@@ may be used to link the sending node to a human identity.  The mechanism is left unspecified here
.  @@data@@ may contain arbitrary data which may be used, for example, to embed further payment instructions to the recipient using another protocol.


[[#payment_accept]]
!!! Payment Accept

Changed lines 633-634 from:
message CommitReady {
    required bytes transaction_id = 1;
to:
message PaymentAccept {
    required bytes transaction_key_id = 1;
required bytes commit_key_id = 2;
required PublicKey commit_key = 3;
    required PaymentInit payment_init = 4;
optional string commit_url = 5;
    optional bytes proof_of_id = 6
;
Changed lines 643-648 from:
The recipient passes this to the payer when it has received enough promises to commit the transaction.


[[#promise_release]]
!!! Promise Release

to:
Returned by the recipient in response to a payment init, if it chooses to accept the payment.  Must be signed by the recipient.  The PaymentAccept combined with the Commit will form proof of payment for the payer.

@@commit_key_id@@ must be the canonical hash of @@commit_key@@, which is used by the recipient to sign the Commit message.

@@payment_init@@ is a copy of the payment init.  A recipient that does not understand units should strip the @@units@@ field from the payment init if it was set, otherwise it is acknowledging that the payment is being received in the stated units. 

@@commit_url@@ is where the recipient will publish the Commit message if and when it is generated.

[[#promise]]
!!! Promise

Changed lines 655-657 from:
message PromiseRelease {
    required bytes transaction_id = 1;
    required bytes line_of_credit_id = 2;
to:
message Promise {
    required bytes transaction_key_id = 1;
    required PublicKey transaction_key = 2;
required bytes commit_key_id = 3;
required PublicKey commit_key = 4;
    required bytes line_of_credit_id = 5;
    required string amount = 6;
    required double expiry = 7;
    optional bytes exchange_onion = 8;
optional commit_url = 9
;
Changed lines 668-673 from:
The promisee may release the promisor of its promise by sending a @@PromiseRelease@@.  Must be signed.


[[#commit]]
!!!
Commit
to:
TODO: Ensure promises are valid long enough to have a chance of committing the transaction?
* payer specifies minimum promise time
* nodes advertise their max promise time

A signed promise to pass forward an [[#iou | IOU]] of value @@amount@@ on the specified line of credit when shown a
Commit message with the given @@transaction_key_id@@, signed by the @@commit_key@@ before the @@expiry@@ time.  @@commit_key_id@@ is included so there is no question as to its value, since it may be used to identify the Commit in atomicity extensions.

@@exchange_onion@@ consists of Exchange structures (defined in [[#credit_check | CreditCheck]] above), and defines the lines of credit and exchanges to carry obligations to the recipient.  @@forward_to_node@@ and @@forward_to_host@@ are not used here.


[[#promise_release]]
!!! Promise Release

Changed lines 681-688 from:
message Commit {
    message CommitToken {
       required bytes transaction_id = 1;
        required double time = 2;
    }
    required CommitToken commit_token = 1;
    required Signature payer_signature = 2;
    optional Signature recipient_signature = 3
;
to:
message PromiseRelease {
    required bytes transaction_key_id = 1;
Deleted lines 683-691:

message TimestampedCommit {
    required Commit commit_message = 1;
    message TimestampedSignature {
        required double timestamp = 1;
        required Signature signature = 2;
    }
    repeated TimestampedSignature = 2;
}
Changed lines 686-693 from:
@@commit_token@@ contains a @@CommitToken@@ signed by both the @@payer_commit_key@@ and @@recipient_commit_key@@ defined in the promise phase.

@@TimestampedCommit@@ is for third-party authorities to indicate they were aware of a commit message at a certain time.  The commit message body, including token and both payer and recipient signatures, is concatenated with a timestamp and then signed.  @@TimestampedCommit@@ messages are made available at nodes' @@commit_archive_url@@s.


[[#status_query]]
!!! Status Query

to:
A promise holder may release the promisor of its promise by sending a @@PromiseRelease@@.  Must be signed by the promise holder.


[[#commit]]
!!! Commit

Changed lines 693-694 from:
message StatusQuery {
    required bytes transaction_id = 1;
to:
message Commit {
    message CommitToken {
       required bytes transaction_key_id = 1;
required bytes commit_key_id = 2;
    }
    required CommitToken commit_token = 1;
    required Signature commit_signature = 2
;
Changed lines 703-708 from:
The payer uses this to request information about the current state of the transaction from another participantMust be signed by the @@payer_commit_key@@ for the transaction.


[[#status]]
!!!
Status
to:
Commit is generated by the recipient and used to trigger promises back through the intermediaries to the payerA promise holder redeems the promise its holds with its neighbour by sending a Commit message with the same @@transaction_key_id@@ and @@commit_key_id@@ as the Promise, and with its @@commit_token@@ signed in @@commit_signature@@ by the transaction's @@commit_key@@, before the promise's expiry.

In @@BARE@@ atomicity mode, the only mode described here, there is no authority to enforce the acknowledgement of Commit messages on promisors if they are unable or unwilling to do so by promise expiry time.  Therefore each promise holder takes a risk in handling the Commit message: it is bound by its own promise to pass an IOU forward, but it may not be able to use the Commit to redeem a promise that it holds.

To help propagate the Commit in case of an intermediary server outage, the recipient should publish the Commit at the @@commit_url@@ specified in the Promises.

@@BARE@@ atomicity mode requires voluntary cooperation from servers to work: 

* A node that receives a Commit, either from a neighbour or from the @@commit_url@@, must pass IOUs forward to redeem all promises it has issued for that transaction that have not expired or been released.
* A node that has received all its IOUs for a transaction must redeem all unreleased promises it has issued, even if they have expired.
* A node should attempt to redeem any unreleased expired promises it holds by passing the Commit message to the promise issuer(s), even when it causes a line of credit balance to surpass its credit limit.  It may, however, decide not to do this if the amount over limit would be unacceptable.
* Payers must honour unreleased expired promises, even if the Commit message is late.

This behaviour is difficult or impossible to verify or enforce, therefore @@BARE@@ atomicity mode is only appropriate for use within a cooperating group of servers.


[[#status_query]]
!!!
Status Query
Changed line 723 from:
message Status {
to:
message StatusQuery {
Added lines 725-736:
}
@]

The payer uses this to request information about the current state of the transaction from another participant.  Must be signed by the @@transaction_key@@.


[[#status]]
!!! Status

[@
message Status {
    required bytes transaction_id = 1;
Added lines 773-774:

* Connect: precision/scale too high/low.
April 11, 2011, at 04:52 AM by Ryan - ans/ok instead of rpy/err.
Changed lines 79-83 from:
Since TCP is a byte-stream protocol, Ripple messages must be framed to preserve message boundaries.  Each frame is defined by:

 +
------+-----+---+-------------------------+
 | Type | Ver | M |    Length (24 bits)    |
 +------+-----+---+-------------------------+
to:
Since TCP is a byte-stream protocol, Ripple messages must be framed to preserve message boundaries.  Ripple's framing semantics are inspired by the [[http://www.rfc-editor.org/rfc/rfc3080.txt | BEEP]] and [[http://www.chromium.org/spdy/spdy-protocol | SPDY]] protocols.  Each frame is defined by:

 +
-----+------+---+-------------------------+
 | Ver | Type | M |    Length (24 bits)    |
 +-----+------+---+-------------------------+
Added line 87:
 |                  ...                    |
Changed lines 90-95 from:
* @@Type@@ (4 bits) - type of frame
  * 0000 = @@MSG@@ (message)
  * 0001 =
@@RPY@@ (reply)
  * 0010 = @@ERR@@ (error)
* @@Ver@@ (3 bits) - frame version
  * 000 = frame version 0
to:
* @@Ver@@ (4 bits) - frame encoding version
  * 0000 = frame version 0, this specification
*
@@Type@@ (3 bits) - message type
  * 000 = @@MSG@@ (message)
  * 001 = @@ANS@@ (answer)
  * 010 = @@OK@@ (ok)
Changed line 98 from:
  * 1 = more content coming in further frames
to:
  * 1 = more data for this message coming in further frames
Changed lines 100-101 from:
  * max permitted value is for this protocol version is 1048576
* @@Message Number@@ - identifier to associate messages with reply/error responses
to:
  * max permitted value for this protocol version is 1048576
* @@Message Number@@ - identifier to associate messages with responses
Added lines 104-107:
Each message can be broken up into multiple frames, so high-priority messages do not need to wait in line while long low-priority messages are being transferred, but rather can be sent in between frames of long messages.  Therefore it is recommended to break messages into relatively short frames that can be transferred nearly instantaneously.

Each @@MSG@@ message must be replied to with zero or more a @@ANS@@ messages with the same @@Message Number@@ containing any content in direct response to the @@MSG@@, followed by an empty @@OK@@ frame, also with the same @@Message Number@@, indicating an end to that message exchange.  For example, any error messages resulting from a @@MSG@@ request would go in an @@ANS@@ response.  Each @@ANS@@ message must be completely transmitted before another @@ANS@@ or @@OK@@ in the same message exchange is begun.  Multiple message exchanges can be open simultaneously on the same connection.  BEEP and SPDY prescribe even-numbered messages for the connection initiator and odd-numbered messages for the listener, but here either host may use any number, as long as it has not already been used for a message that has not been replied to.

Changed lines 110-118 from:
The general semantics is inspired by the [[http://www.rfc-editor.org/rfc/rfc3080.txt | BEEP specification]].  Each message can be broken up into multiple frames, so high-priority messages do not need to wait in line while long low-priority messages are being transferred, but rather can be sent in between frames of long messages.  Therefore it is recommended to break messages into relatively short frames that can be transferred nearly instantaneously.

Each @@MSG@@ frame must be replied to with either a @@RPY@@ or @@ERR@@ frame with the same @@Message Number@@.  An empty @@RPY@@ indicates the message was understood and accepted.  An @@ERR@@ frame indicates a problem, and should include an [[#error_messages | error message]] if possible.  BEEP prescribes even-numbered messages for the connection initiator and odd-numbered messages for the other host, but here either host may use any number, as long as it has not already been used for a message that has not been replied to.

The concept of BEEP channels has been excluded because their function, to enable multiple independently-flow-controlled streams of data on the same connection, is somewhat crippled by TCP's in-order requirement for the overall connection, and much the same thing can be accomplished by interleaving chunked message frames.  For multiple truly independent streams between two hosts in Ripple, simply open multiple TCP connections.

Another reference describing a somewhat similar style of framing is the [[http://www.chromium.org/spdy/spdy-protocol | SPDY protocol]].

to:
Changed lines 237-238 from:
Allows hosts to discover what time the other thinks it is (before transmission delay).  A peer can send a @@Time@@ message at any time during the connection.  The other peer should reply immediately with its own @@Time@@ message.
to:
Allows hosts to discover what time the other thinks it is (before transmission delay).  A peer can send a @@Time@@ message at any time during the connection.  The other peer should respond immediately with its own @@Time@@ message.
Changed lines 341-342 from:
Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  Must be signed by sender.  The receiving node would reply with another @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.
to:
Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  Must be signed by sender.  The receiving node would eventually send back its own @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.
Changed line 510 from:
Returned by recipient in reply to a payment init, if it chooses to accept the payment.  Must be signed by recipient. 
to:
Returned by recipient in response to a payment init, if it chooses to accept the payment.  Must be signed by recipient. 
Changed line 278 from:
@@old_address@@ is used to indicate that this is a change of identity key for this node.  If a node receives a @@Node@@ message with its own address in the @@old_address@@ field, and it wishes to move to the sending host, it should sign the @@Node@@ message for the new address and pass it back to the new address for broadcast.  If a node receives a @@Node@@ message with one of its line of credit partner addresses in the @@old_address@@ field, the line of credit moves to being with the new node address.
to:
@@old_address@@ is used to indicate that this is a change of identity key for this node.  If a node receives a @@Node@@ message with its own address in the @@old_address@@ field, and it wishes to transfer itself to the sending host, it should sign the @@Node@@ message for the new address and pass it back to the new address for broadcast.  If a node receives a @@Node@@ message with one of its line of credit partner addresses in the @@old_address@@ field, the line of credit moves to being with the new node address.
April 09, 2011, at 05:04 PM by Ryan - more detail on renaming/moving node
Changed lines 278-280 from:
@@old_address@@ is used to indicate that this is a change of identity key for this node.

Message is signed by
@@identity_key@@, as well as the previous identity key for @@old_address@@, if the node is being renamed.
to:
@@old_address@@ is used to indicate that this is a change of identity key for this node.  If a node receives a @@Node@@ message with its own address in the @@old_address@@ field, and it wishes to move to the sending host, it should sign the @@Node@@ message for the new address and pass it back to the new address for broadcast.  If a node receives a @@Node@@ message with one of its line of credit partner addresses in the @@old_address@@ field, the line of credit moves to being with the new node address.

The message is signed by @@identity_key@@, as well as the previous identity key for @@old_address@@, if the node is being renamed. 
April 08, 2011, at 12:47 AM by Ryan - Shorter frame header
Changed lines 81-92 from:
|| border=0
||!Bytes ||!Length ||!Field ||
||1
      ||1       ||@@frame_type@@ | @@frame_version@@ | @@more@@ ||
||2
-5    ||4      ||@@msgno@@ ||
||6
-9    ||4      ||@@size@@ ||
||10
-?  ||?      ||@@content@@ ||

* @@frame_type@@ (4 bits)
- type of frame
  * 0000 = MSG
  * 0001 = RPY
  * 0010 = ERR
* @@frame_version@@ (3
bits)
to:
 +------+-----+---+-------------------------+
 
| Type | Ver | M |    Length (24 bits)    |
 +
------+-----+---+-------------------------+
 | 
      Message Number (32 bits)       |
 +------------------------------------------+
 |                  Data                    |
 +------------------------------------------+

* @@Type@@ (4
bits) - type of frame
  * 0000 = @@MSG@@ (message)
  * 0001 = @@RPY@@ (reply)
  * 0010 = @@ERR@@ (error)
* @@Ver@@ (3 bits) - frame version
Changed line 95 from:
* @@more@@ (1 bit) - allows messages to span multiple framess
to:
* @@M@@ (1 bit) - continuation flag
Changed lines 98-103 from:
* @@msgno@@ - number to connect messages with replies; each new message must have a unique value among open messages on the connection (ie, those with no completed response yet).
* @@size@@ - number of bytes in @@content@@
* @@content@@ - message bytes

The general semantics of these basic fields is much the same as in the [[http://www
.rfc-editor.org/rfc/rfc3080.txt | BEEP specification]].  In particular, each @@MSG@@ frame must be replied to with either a @@RPY@@ or @@ERR@@ frame with the same @@msgno@@.  An empty @@RPY@@ indicates the message was understood and accepted.  An @@ERR@@ frame indicates a problem, and should include an [[#error_messages | error message]] if possible.  The connection initiator uses only even-numbered message numbers, and the other host uses odd numbers.
to:
* @@Length@@ - number of bytes in @@Data@@
  * max permitted value is for this protocol version is 1048576
* @@Message Number@@ - identifier to associate messages with reply/error responses
* @@Data@@ - contains the actual Ripple message

@@Length@@ and @@Message Number@@ are in network byte order.  The overall size of each frame is @@Length@@ + 8 bytes.

The general semantics is inspired by the [[http://www.rfc-editor.org/rfc/rfc3080.txt | BEEP specification]].  Each message can be broken up into multiple frames, so high-priority messages do not need to wait in line while long low-priority messages are being transferred, but rather can be sent in between frames of long messages.  Therefore it is recommended to break messages into relatively short frames that can be transferred nearly instantaneously.

Each @@MSG@@ frame must be replied to with either a @@RPY@@ or @@ERR@@ frame with the same @@Message Number@@.  An empty @@RPY@@ indicates the message was understood and accepted.  An @@ERR@@ frame indicates a problem, and should include an [[#error_messages | error message]] if possible.  BEEP prescribes even-numbered messages for the connection initiator and odd-numbered messages for the other host, but here either host may use any number, as long as it has not already been used for a message that has not been replied to
.
Added lines 110-111:

Another reference describing a somewhat similar style of framing is the [[http://www.chromium.org/spdy/spdy-protocol | SPDY protocol]].
April 04, 2011, at 12:14 PM by Ryan - Moving a line of credit to different node
Added line 332:
   optional bytes old_address = 9;
Changed lines 336-337 from:
Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  The receiving node would reply with another @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.
to:
Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  Must be signed by sender.  The receiving node would reply with another @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.
Changed line 344 from:
Must be signed by sender.
to:
To move a line of credit to a different node, send another @@Connect@@ message with the existing @@line_of_credit_id@@ from the new node address, and put the old node address into @@old_address@@.  Sign the message with both node keys.
April 04, 2011, at 05:48 AM by Ryan - frame version
Changed line 83 from:
||1      ||1      ||@@type@@ | @@more@@ | [reserved] ||
to:
||1      ||1      ||@@frame_type@@ | @@frame_version@@ | @@more@@ ||
Changed line 88 from:
* @@type@@ (4 bits) - type of frame
to:
* @@frame_type@@ (4 bits) - type of frame
Changed lines 92-94 from:
* @@more@@ (1 bit) - whether this is the last chunk for this message
to:
* @@frame_version@@ (3 bits)
  * 000 = frame version 0
* @@more@@ (1 bit) - allows messages to span multiple framess
Changed lines 96-97 from:
  * 1 = more frames coming
* @@[reserved]@@ (3 bits)
to:
  * 1 = more content coming in further frames
April 04, 2011, at 04:18 AM by Ryan - More on framing and aliases
Changed lines 86-87 from:
||10-?  ||?      ||@@body@@ ||
to:
||10-?  ||?      ||@@content@@ ||
Changed lines 93-94 from:
  * 0 = last chunk
  * 1 = more chunks
coming
to:
  * 0 = last frame for this message
  * 1 = more frames coming
Changed lines 97-102 from:
* @@size@@ - number of bytes in @@body@@
* @@payload@@ - message bytes

The general semantics of these basic fields is much the same as in the [[http://www.rfc-editor.org/rfc/rfc3080.txt | BEEP specification]].

to:
* @@size@@ - number of bytes in @@content@@
* @@content@@ - message bytes

The general semantics of these basic fields is much the same as in the [[http://www.rfc-editor.org/rfc/rfc3080.txt | BEEP specification]].  In particular, each @@MSG@@ frame must be replied to with either a @@RPY@@ or @@ERR@@ frame with the same @@msgno@@.  An empty @@RPY@@ indicates the message was understood and accepted.  An @@ERR@@ frame indicates a problem, and should include an [[#error_messages | error message]] if possible.  The connection initiator uses only even-numbered message numbers, and the other host uses odd numbers.

The concept of BEEP channels has been excluded because their function, to enable multiple independently-flow-controlled streams of data on the same connection, is somewhat crippled by TCP's in-order requirement for the overall connection, and much the same thing can be accomplished by interleaving chunked message frames.  For multiple truly independent streams between two hosts in Ripple, simply open multiple TCP connections
.

Changed line 165 from:
@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | @@Nodes@@ message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains and ports, eg, ''user@host.com:1234''.
to:
@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | @@Nodes@@ message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains and ports, eg, ''user@host.com:1234''.  Since one user may have multiple nodes, when directing a message to a user rather than to a specific node, such as when creating a line of credit or initiating a payment, use an alias.  You should get a return message back with @@from@@ set to the appropriate node you should be addressing, as well as @@from_alias@@ set to the alias of the user you sent the initial message to.  If this message is signed, it can then be used to provably link the alias to the node.
April 04, 2011, at 03:12 AM by Ryan - Proof of work for any message; negative amounts as requests.
Changed lines 108-109 from:
Each Ripple message consists of a @@Header@@ followed by another message of the type indicated in the header, and optional signatures.
to:
Each Ripple message consists of a @@Header@@ followed by another message of the type indicated in the header, and optional signatures and proof of work.
Added line 115:
   optional bytes proof_of_work = 4;
Changed lines 119-121 from:
Signatures are to validate the header and body sections; any other signatures and instructions are not signed.

to:
Signatures are to validate the header and body sections; any other signatures and @@proof_of_work@@ are not signed.

@@proof_of_work@@ is a string of bytes that causes the SHA256 hash of the entire message to be below a certain acceptability threshold (ie, with at least a certain number of zeroes at the start).  This number is meant to be reasonably difficult to calculate in order to prevent spamming of certain types of messages.  Any server can require that some types of messages come with a proof of work attached.  If a server receives a message with insufficient proof of work, it should indicate in an error the proof of work threshold required for that message
.

Changed line 166 from:
[[#signatures]]Ripple uses RSA keys of any length, although 2048 bits or more is recommended, with a fixed exponent of 65537.
to:
[[#signatures]]
Changed lines 259-260 from:
   optional bytes proof_of_work = 8;
    optional string commit_archive_url = 9
;
to:
   optional string commit_archive_url = 8;
Deleted lines 274-275:
@@proof_of_work@@ is a string of bytes that, when concatenated to the end of @@address@@ || @@time@@ and hashed with SHA256, gives a result below a certain acceptability threshold (ie, with at least a certain number of zeroes at the start).  This number is meant to be reasonably difficult to calculate, to prevent someone from spamming the network with millions of nodes.  If a host receives a @@NodeInfo@@ segment with what it considers insufficient proof of work, it should reply with an error indicating the required proof-of-work threshold.
Changed lines 338-339 from:
@@proof_of_id@@ may be used to associate the sending node with a human identity, by way of, for example, a GPG key and signature of @@line_of_credit_id@@.  This mechanism is left unspecified here.
to:
@@proof_of_id@@ may be used to associate the sending node with a human identity, by way of, for example, a password, or a GPG key and signature of @@line_of_credit_id@@.  This mechanism is left unspecified here.
Changed lines 358-360 from:
to:
If @@amount@@ is negative, the message is interpreted as a request for that amount IOU to be sent by the other partner.

Changed lines 411-414 from:
   optional double valid_until = 3;
to:
   optional string in_units = 3;
    optional string out_units = 4;
    optional string description = 5;
    optional double valid_until = 6
;
Changed lines 418-420 from:
Signed by @@from@@ address. 

to:
Signed by @@from@@ address.

Added lines 464-466:
[[#payment_request]]
!!! Payment Request

Added line 476:
   optional bytes proof_of_id = 5;
Changed lines 480-481 from:
Sent by payer to recipient.  Amount is given in recipient node base units.
to:
Sent by payer to recipient (or vice-versa for payment request with negative amount), signed by sender.  Amount is given in recipient node base units.
Added lines 484-488:
If @@amount@@ is negative, the message is interpreted as a request for the receiving node to send an equal but positive-valued payment to the sender.

@@proof_of_id@@ may be used to link the sending node to a human identity.  The mechanism is left unspecified here.

Changed line 497 from:
   optional bytes recipient_proof_of_id = 4;
to:
   optional bytes proof_of_id = 4;
Changed lines 507-509 from:
@@recipient_proof_of_id@@ may be used to link the receiving node to a human identity.  The mechanism is left unspecified here.

to:
Changed line 520 from:
   optional string commit_message_url = 8;
to:
   optional string commit_url = 8;
Changed lines 525-526 from:
A promise to pass forward an [[#iou | @@IOU@@]] of value @@amount@@ on the specified line of credit when shown a commit message with the given @@transaction_id@@, and signed by the @@payer_commit_key@@ and @@recipient_commit_key@@ before the @@expiry@@ time. 
to:
A signed promise to pass forward an [[#iou | @@IOU@@]] of value @@amount@@ on the specified line of credit when shown a commit message with the given @@transaction_id@@, and signed by the @@payer_commit_key@@ and @@recipient_commit_key@@ before the @@expiry@@ time. 
Changed line 554 from:
The promisee may release the promisor of its promise by sending a @@PromiseRelease@@.
to:
The promisee may release the promisor of its promise by sending a @@PromiseRelease@@.  Must be signed.
April 02, 2011, at 04:11 PM by Ryan - How commit arbiters work
Changed line 24 from:
* [[#nodes | Nodes]]
to:
* [[#node | Node]]
Added line 237:
   required hop_limit = 2;
Added line 257:
   optional string commit_archive_url = 9;
Added lines 267-268:
Message is signed by @@identity_key@@, as well as the previous identity key for @@old_address@@, if the node is being renamed.
Changed lines 273-277 from:
@@proof_of_work@@ is a string of bytes that, when concatenated to the end of @@address@@ and hashed with SHA256, gives a result below a certain acceptability threshold (ie, with at least a certain number of zeroes at the start).  This number is meant to be reasonably difficult to calculate, to prevent someone from spamming the network with millions of nodes.  If a host receives a @@NodeInfo@@ segment with what it considers insufficient proof of work, it should reply with an error indicating the required proof-of-work threshold.

Message is signed by @@identity_key@@, and the previous identity key for @@old_address@@, if the node is being renamed.

to:
@@proof_of_work@@ is a string of bytes that, when concatenated to the end of @@address@@ || @@time@@ and hashed with SHA256, gives a result below a certain acceptability threshold (ie, with at least a certain number of zeroes at the start).  This number is meant to be reasonably difficult to calculate, to prevent someone from spamming the network with millions of nodes.  If a host receives a @@NodeInfo@@ segment with what it considers insufficient proof of work, it should reply with an error indicating the required proof-of-work threshold.

@@commit_archive_url@@ is a URL of the form "http://host.com/commit/%s", so that when "%s" is substituted with a canonical form transaction ID such as "5e025939-6ab8-4563-87b2-7e90f87a84f8", it returns a commit token for that transaction, timestamped and signed by by @@identity_key@@.  Nodes publishing a @@commit_archive_url@@ should also publish their @@host@@, so commit messages can be submitted to them directly.

Changed lines 336-337 from:
@@commit_arbiters@@ identifies third parties (eg, by public key) which the sending node agrees will be authoritative on the existence of transaction commit message at particular times, in case of disagreement between the two partner nodesSee [[#promise | @@Promise@@]] below.
to:
@@commit_arbiters@@ identifies nodes which the sending node agrees will be authoritative on the existence of transaction commit message at particular times, in case of disagreement between the two partner nodes.  See [[#promise | @@Promise@@]] belowOnly nodes publishing a @@commit_archive_url@@ should be listed.
Changed lines 517-519 from:
If any of the entities identified in @@commit_arbiters@@ declares, presumably by timestamping and signing, that a valid commit message existed at a time before promise @@expiry@@, then the promisor must pass forward an IOU to fulfill the promise.  Generally, the commit message for a transaction would just be presented to the promisor before promise expiry, and the promisor would immediately pass the required IOU.  @@commit_arbiters@@ gives the promisee a mechanism to have the promise fulfilled in case the promisor in non-responsive in the period before the promise expires.

to:
If any of the nodes identified in @@commit_arbiters@@ declares, by timestamping, signing, and making available a valid commit message at its @@commit_archive_url@@, that a valid commit message existed at a time before promise @@expiry@@, then the promisor must pass forward an IOU to fulfill the promise.  Generally, the commit message for a transaction would just be presented to the promisor before promise expiry, and the promisor would immediately pass the required IOU.  @@commit_arbiters@@ gives the promisee a mechanism to have the promise fulfilled in case the promisor is non-responsive in the period before the promise expires.

Added lines 558-566:

message TimestampedCommit {
    required Commit commit_message = 1;
    message TimestampedSignature {
        required double timestamp = 1;
        required Signature signature = 2;
    }
    repeated TimestampedSignature = 2;
}
Added lines 570-571:

@@TimestampedCommit@@ is for third-party authorities to indicate they were aware of a commit message at a certain time.  The commit message body, including token and both payer and recipient signatures, is concatenated with a timestamp and then signed.  @@TimestampedCommit@@ messages are made available at nodes' @@commit_archive_url@@s.
April 02, 2011, at 05:28 AM by Ryan - RippleMessage structure to contain header, body, signatures
Changed line 15 from:
* [[#signed_messages | Signed Messages]]
to:
* [[#signatures | Signatures]]
Changed lines 17-18 from:
* [[#public_key_formats | Public Key Formats]]
  * [[# rsa_key_format | RSA
Key Format]]
to:
* [[#public_key_format | Public Key Format]]
Changed lines 25-26 from:
* [[#node_request | Node Request]]
to:
* [[#inventory | Inventory]]
* [[#inventory_request | Inventory
Request]]
Changed lines 88-91 from:
* @@type@@ (4 bits) - type of message
  * 0000 = message
  * 0001 = reply
  * 0010 = error
to:
* @@type@@ (4 bits) - type of frame
  * 0000 = MSG
  * 0001 = RPY
  * 0010 = ERR
Changed lines 95-96 from:
* [reserved] (3 bits)
* @@msgno@@ - number to connect messages with replies/errors; each new message must have a unique value among open messages on the connection (ie, those with no reply or error response yet).
to:
* @@[reserved]@@ (3 bits)
* @@msgno@@ - number to connect messages with replies; each new message must have a unique value among open messages on the connection (ie, those with no completed response yet).
Changed lines 108-111 from:

[[#header]]
!!!
Header
to:
Each Ripple message consists of a @@Header@@ followed by another message of the type indicated in the header, and optional signatures.
Added lines 111-124:
message RippleMessage {
    required Header header = 1;
    optional bytes body = 2;
    repeated Signature signatures = 3;
}
@]

Signatures are to validate the header and body sections; any other signatures and instructions are not signed.


[[#header]]
!!! Header

[@
Changed lines 129-130 from:
       NODES = 2;
        NODE_REQUEST = 3;
to:
       NODE = 2;
        INVENTORY = 3;
        INVENTORY_REQUEST = 4
;
Changed lines 149-153 from:
   optional bytes to = 3;
    optional string to_alias = 4;
    optional bytes from = 5;
    optional string from_alias = 6;
    required double time = 7;
to:
   required double time = 3;
    optional bytes message_id = 4;
    optional bytes to = 5;
    optional string to_alias = 6;
    optional bytes from = 7;
    optional string from_alias = 8
;
Changed lines 158-167 from:
@@version@@ is the Ripple protocol version this message is to be interpreted under.

@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | @@Nodes@@ message]] below.)
  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains, eg, ''user@host.com''.

@@time@@ is given in number of seconds since Jan. 1, 1970 (ie, unix time).


[[#signed_messages]]
!!! Signed Messages

to:
@@version@@ is the Ripple protocol version this message is to be interpreted under.  This document's protocol version is @@0.5@@.  @@time@@ is given in number of seconds since Jan. 1, 1970 (ie, unix time).  @@message_id@@ is to identify broadcast messages, so a host needn't receive the same message repeatedly.

@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | @@Nodes@@ message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains and ports, eg, ''user@host.com:1234''.


[[#signatures]]Ripple uses RSA keys of any length, although 2048 bits or more is recommended, with a fixed exponent of 65537.
!!! Signatures

Changed lines 167-178 from:
message SignedMessage {
    required bytes message = 1;
    message Signature {
        optional bytes signer = 1;
        enum HashAlgorithm {
            SHA256 = 0;
        }
        required HashAlgorithm hash_algorithm = 2;
        required bytes hash = 3;
        required bytes signature = 4;
    }
    repeated Signature signatures
= 2;
to:
message Signature {
    optional bytes signer = 1;
    required bytes signature = 2;
Changed lines 173-177 from:
@@signer@@ is the canonical hash of the signing key, and may be omitted if the signer is already identified in the message.

For simplicity of implementation, only one hashing algorithm is supported initially.  SHA256 was chosen because it is ubiquitous
and should remain resilient to attack for quite some time.

to:
@@signature@@ is a [[ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf | PKCS#1 v2.1]] RSASSA-PSS signature with SHA256 as the hash function.

@@
signer@@ is the address of the signing node if the signature is generated by its communication key, or canonical hash of the key used if not, and may be omitted if there is only a single signer who is already identified in the message.

Deleted lines 183-186:
   enum Cipher {
        AES256 = 0;
    }
    required Cipher cipher = 2;
Changed lines 191-198 from:
To encrypt a message to the recipient, the sender encrypts a symmetric encryption key for the @@cipher@@ algorithm, and then uses that key to encrypt the message to the @@ciphertext@@ field.

For simplicity of implementation, only one cipher algorithm is supported initially
.  AES256 was chosen because it is ubiquitous, strong, and fast.


[[#public_key_formats]]
!!! Public Key Formats

to:
To encrypt a @@RippleMessage@@ to the recipient, the sender encrypts a symmetric AES256 encryption key, using [[ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf | PKCS#1 v2.1]] RSAES-OAEP with MGF1/SHA256, and then uses that key to encrypt the message to the @@ciphertext@@ field using AES256 encryption.


[[#public_key_format]]
!!! Public Key Format

Changed lines 199-203 from:
   enum KeyFormat {
       RSA = 0;
    }
    required KeyFormat key_format = 1;
    required bytes key = 2
;
to:
   required bytes modulus = 1;
Changed lines 203-219 from:
@@key@@ contains a specific byte sequence particular to the selected key format.

The protocol provides for various key formats and public
-key cryptography algorithms to be used, but for simplicity of implementation, only one is supported initially.  RSA was chosen because it is ubiquitous (vs. elliptic curve algorithms) and is quick for signature verification, as well as flexible key size and hash algorithm for signatures (vs. DSA).

[[#rsa_key_format]]
!!!! RSA Key Format

[@
message RSAKey {
    required bytes modulus = 1;
    required bytes exponent = 2;
}
@]

Goes in the @@PublicKey.key@@ field.  Both @@modulus@@ and @@exponent@@ are big-endian integers
.

to:
Ripple uses RSA keys of any length with a fixed exponent of 65537.  @@modulus@@ is big-endian.

Changed lines 224-229 from:
[@
message Time {
    required Header header = 1;
}
@]

to:
@@Time@@ has no message body.
Changed lines 236-237 from:
   required Header header = 1;
    required EncryptedMessage message = 2
;
to:
   required EncryptedMessage message = 1;
Changed lines 240-245 from:
Message encrypted to destination node, pass it on.  Encrypted message may be another @@Relay@@.


[[#nodes]]
!!! Nodes

to:
Message encrypted to destination node to pass on to @@message.recipient@@.  Encrypted message may be another @@Relay@@.  Broadcast messages should not be tunneled using @@Relay@@.


[[#node]]
!!! Node

Changed lines 247-256 from:
message Nodes {
    required Header header = 1;
    message NodeInfo {
        required bytes address = 0;
        required PublicKey signing_key = 1;
        optional PublicKey encryption_key = 2;
        optional string host = 3;
       optional bytes proof_of_work = 4;
    }
    repeated NodeInfo nodes = 2
;
to:
message Node {
    required PublicKey identity_key = 1;
    required double identity_key_expiry = 2;
    required PublicKey communication_key = 3;
    required double communication_key_expiry = 4;
    optional bytes old_address = 5;
    optional string host = 6;
    optional string transaction_fee = 7;
    optional bytes proof_of_work = 8;
Changed lines 259-262 from:
Node advertisement.  @@address@@ is the RIPEMD160 hash of the node's signing key.  If the encryption key is omitted, the signing key should be used to encrypt messages to this node.

RIPEMD160 was chosen because it is ubiquitous, its output
is shorter than SHA256, which is useful if node addresses are communicated outside protocol messages, and probably stronger than SHA1.
to:
Broadcast advertisement describing a node.  The node's address is given in the @@from@@ field of the header.

@@address@@
is the RIPEMD160 hash of the node's @@identity_key@@ structure, used to identify the node in message headers and elsewhere.  @@identity_key@@ is only used to sign @@Node@@ messages establishing a communication key.  @@communication_key@@ is then used for signing and encryption of other messages.  The reason for this setup is to facilitate medium-term cycling of communication keys without requiring a change of address.  Thus the identity key can be very large and communication keys can be smaller, yielding smaller more efficient signatures.  Old communication keys should be kept around for a period after cycling in case messages arrive that still use them.

@@old_address@@ is used to indicate that this is a change of identity key for this node.

@@host@@ is the host[:port] server address for the node.  This allows any node to send messages directly to this node, in particular [[#status_query | status queries]].  For privacy reasons, this is not required.

@@transaction_fee@@ is where a node can indicate that it charges a flat fee for through-transactions.  Fee is given in node base units -- see [[#credit | Credit message]] below
.
Changed lines 271-274 from:

[[#node
_request]]
!!! Node Request

to:
Message is signed by @@identity_key@@, and the previous identity key for @@old_address@@, if the node is being renamed.


[[#inventory]]
!!! Inventory

Changed lines 278-280 from:
message NodeRequest {
    required Header header = 1;
    repeated bytes addresses = 2;
to:
message InventoryItem {
    required bytes source = 1;
    required bytes message_id = 2;
    enum BroadcastMessageType {
        NODE = 1;
        CREDIT = 2;
        EXCHANGE_RATE = 3;
    }
    required BroadcastMessageType type = 3
;
Added lines 288-291:

message Inventory {
    repeated InventoryItem items = 1;
}
Changed lines 294-302 from:
Request info about one or more nodes.  Reply is a @@Nodes@@ message.


[[#account_messages]]
!! 5. Account Messages

[[#connect]]
!!! Connect

to:
Broadcast to let neighbouring hosts know about new broadcast message IDs.  @@source@@ is included with each message ID so another node cannot block full propagation of a broadcast message by simply propagating a message with a similar ID.  (Broadcast messages must be signed by the communication key cryptographically linked to the source address.)  It may also help determine whether the receiving node is interested in the item.


[[#inventory_request]]
!!! Inventory Request

Changed lines 301-310 from:
message Connect {
    required Header header = 1;
    required bytes line_of_credit_id = 2;
    optional bytes linked_line_of_credit_id = 3;
    optional string units = 4;
    optional string credit_offered = 5;
    optional string iou_offered = 6;
    repeated bytes commit_arbiters = 7;
    optional string note = 8;
    optional bytes proof_of_id = 9;
to:
message InventoryRequest {
    repeated InventoryItem items = 1;   
Changed lines 306-317 from:
Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  The receiving node would reply with another @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.

@@linked_line_of_credit_id@@ indicates another line of credit that is to have a shared balance with this line of credit, in order that the two lines of credit form a single mutual credit account.  The linked line of credit does not have to be between the same two nodes, but it must have the same units.  This would be used if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | @@Credit@@]] below.

@@commit_arbiters@@ identifies third parties (eg, by public key) which the sending node agrees will be authoritative on the existence of transaction commit message at particular times, in case of disagreement between the two partner nodes.  See [[#promise | @@Promise@@]] below.

@@proof_of_id@@ may be used to associate the sending node with a human identity, by way of, for example, a GPG key and signature of @@line_of_credit_id@@.  This mechanism is left unspecified here.


[[#iou]]
!!! IOU

to:
Request to receive the listed broadcast messages.


[[#account_messages]]
!! 5. Account Messages

[[#connect]]
!!!
Connect
Changed lines 316-322 from:
message IOU {
    required Header header = 1;
    required bytes iou_id = 2;
    required bytes line_of_credit_id = 3;
    required string amount = 4;
    optional bytes transaction_id = 5;
    optional string memo = 6;
to:
message Connect {
    required bytes line_of_credit_id = 1;
    optional bytes linked_line_of_credit_id = 2;
    optional string units = 3;
    optional string credit_offered = 4;
    optional string iou_offered = 5;
    repeated bytes commit_arbiters = 6;
    optional string note = 7;
    optional bytes proof_of_id = 8
;
Changed lines 328-336 from:
Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU need only be sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account.  If an IOU is a consequence of a routed transaction, the @@transaction_id@@ must be included.


[[#routing_messages]]
!! 6. Routing Messages

[[#
credit]]
!!!
Credit
to:
Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  The receiving node would reply with another @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.

@@linked_line_of_credit_id@@ indicates another line of credit that is to have a shared balance with this line of
credit, in order that the two lines of credit form a single mutual credit account.  The linked line of credit does not have to be between the same two nodes, but it must have the same units.  This would be used if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | @@Credit@@]] below.

@@commit_arbiters@@ identifies third parties (eg, by public key) which the sending node agrees will be authoritative on the existence of transaction commit message at particular times, in case of disagreement between the two partner nodes.  See [[#promise | @@Promise@@]] below.

@@proof_of_id@@ may be used to associate the sending node with a human identity, by way of, for example, a GPG key and signature of @@line_of_credit_id@@.  This mechanism is left unspecified here.

Must be signed by sender.


[[#iou]]
!!! IOU

Added lines 343-361:
message IOU {
    required bytes iou_id = 1;
    required bytes line_of_credit_id = 2;
    required string amount = 3;
    optional bytes transaction_id = 4;
    optional string memo = 5;
}
@]

Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU need only be sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account.  If an IOU is a consequence of a routed transaction, the @@transaction_id@@ must be included.


[[#routing_messages]]
!! 6. Routing Messages

[[#credit]]
!!! Credit

[@
Changed lines 363-385 from:
   required Header header = 1;
    message NodeCredit {
        required bytes source_address = 1;
        message CreditChunk {
 
          required bytes partner_address = 1;
 
          required bytes line_of_credit_id = 2;
 
          optional bytes chunk_id = 3;
 
          optional string in_limit = 4;
            optional string out_limit = 5;
            optional string in_rate = 6;
            optional string out_rate = 7;
            optional bytes in_rate_id = 8;
            optional bytes out_rate_id = 9;
            optional string in_rate_modifier = 10;
            optional string out_rate_modifier = 11;
            optional double expiry = 12;
        }
        repeated bytes lines_of_credit = 2;
        optional string transaction_fee = 3;
        optional string host_port = 4;
        optional int32 hop_limit = 5;
    }
    repeated NodeCredit nodes = 2
;
to:
   required bytes partner_address = 1;
    required bytes line_of_credit_id = 2;
    optional bytes chunk_id = 3;
    optional string in_limit = 4;
    optional string out_limit = 5;
    optional string in_rate = 6;
 
  optional string out_rate = 7;
    optional bytes in_rate_id = 8;
 
  optional bytes out_rate_id = 9;
    optional string in_rate_modifier = 10;
 
  optional string out_rate_modifier = 11;
    optional double expiry = 12;
Changed lines 378-381 from:
Broadcast credit advertisement for one or more nodes.  For a line of credit to be valid for use in transactions, it must be advertised and signed by both partner nodes.

A node may advertise multiple @@CreditChunk@@s on the same line of credit, in order to, for example, offer a better exchange rate for a portion of credit available in order motivate its use.  Both partners need not agree on chunks.  When multiple chunks are advertised, @@chunk_id@@ must be used to distinguish between them.  A missing @@chunk_id@@ refers to the default chunk for that line of credit.
to:
Broadcast credit advertisement.  Signed by @@from@@ address.  For a line of credit to be valid for use in transactions, both partner nodes must broadcast corresponding credit advertisements.

A node may advertise multiple "chunks" on the same line of credit, in order to, for example, offer a better exchange rate for a portion of credit available in order motivate its use.  Exchange rates are set at either end unilaterally, so both partners need not agree on chunks.  When multiple chunks are advertised, @@chunk_id@@ must be used to distinguish between them.  A missing @@chunk_id@@ refers to the default chunk for that line of credit.
Changed lines 393-394 from:
Advertised exchange rates are non-binding.
to:
Advertised credit and exchange rates are informational only and not binding.
Changed lines 403-407 from:
   required Header header = 1;
    required bytes rate_id = 2;
    required bytes source_address = 3;
    required string rate = 4;
    optional double valid_until = 5
;
to:
   required bytes rate_id = 1;
    required string rate = 2;
    optional double valid_until = 3;
Changed lines 409-411 from:
@@source_address@@ is a node whose key must sign every exchange rate message.

to:
Signed by @@from@@ address.

Changed lines 432-435 from:
   required Header header = 1;
    required bytes check_id = 2;
    required bytes checker_key = 3;
    optional EncryptedMessage exchange_onion = 4
;
to:
   required bytes check_id = 1;
    required bytes checker_key = 2;
    optional EncryptedMessage exchange_onion = 3;
Changed line 439 from:
   repeated EncryptedMessage responses = 5;
to:
   repeated EncryptedMessage responses = 4;
Changed lines 460-464 from:
   required Header header = 1;
    required bytes transaction_id = 2;
    required string amount = 3;
    optional string units = 4;
    optional string memo = 5
;
to:
   required bytes transaction_id = 1;
    required string amount = 2;
    optional string units = 3;
    optional string memo = 4;
Changed lines 476-480 from:
   required Header header = 1;
    required bytes payment_init = 2;
    required bytes recipient_commit_key = 3;
    optional string commit_url = 4;
    optional bytes recipient_proof_of_id = 5
;
to:
   required bytes payment_init = 1;
    required bytes recipient_commit_key = 2;
    optional string commit_url = 3;
    optional bytes recipient_proof_of_id = 4;
Changed lines 497-506 from:
   required Header header = 1;
    required bytes transaction_id = 2;
    required bytes line_of_credit_id = 3;
    required string amount = 4;
    required double expiry = 5;
    required bytes payer_commit_key = 6;
    required bytes recipient_commit_key = 7;
    optional bytes exchange_onion = 8;
    optional string commit_message_url = 9;
    repeated bytes commit_arbiters = 10
;
to:
   required bytes transaction_id = 1;
    required bytes line_of_credit_id = 2;
    required string amount = 3;
    required double expiry = 4;
    required bytes payer_commit_key = 5;
    required bytes recipient_commit_key = 6;
    optional bytes exchange_onion = 7;
    optional string commit_message_url = 8;
    repeated bytes commit_arbiters = 9;
Changed lines 521-522 from:
   required Header header = 1;
    required bytes transaction_id = 2
;
to:
   required bytes transaction_id = 1;
Changed lines 533-535 from:
   required Header header = 1;
    required bytes transaction_id = 2;
    required bytes line_of_credit_id = 3
;
to:
   required bytes transaction_id = 1;
    required bytes line_of_credit_id = 2;
Deleted line 545:
   required Header header = 1;
Changed lines 550-552 from:
   required SignedMessage commit_token = 2;
to:
   required CommitToken commit_token = 1;
    required Signature payer_signature = 2;
    optional Signature recipient_signature = 3
;
Changed lines 564-565 from:
   required Header header = 1;
    required bytes transaction_id = 2
;
to:
   required bytes transaction_id = 1;
Changed lines 576-577 from:
   required Header header = 1;
    required bytes transaction_id = 2
;
to:
   required bytes transaction_id = 1;
Changed line 593 from:
   repeated StatusChunk chunks = 3;
to:
   repeated StatusChunk chunks = 2;
Deleted line 605:
   required Header header = 1;
Changed lines 609-610 from:
   optional ErrorCode code = 2;
    optional string message = 3;
to:
   optional ErrorCode code = 1;
    optional string message = 2;
Added line 132:
       ERROR = 50;
March 28, 2011, at 11:26 AM by Ryan - error messages
Added lines 47-50:
8. [[#error_messages | Error Messages]]
* [[#error | Error]]

Changed lines 117-131 from:
       ...  // TODO: Fill the rest out.
to:
       NODES = 2;
        NODE_REQUEST = 3;
        CONNECT = 10;
        IOU = 11;
        CREDIT = 20;
        EXCHANGE_RATE = 21;
        CREDIT_CHECK = 22;
        PAYMENT_INIT = 30;
        PAYMENT_ACCEPT = 31;
        PROMISE = 32;
        COMMIT_READY = 33;
        PROMISE_RELEASE = 34;
        COMMIT = 35;
        STATUS_QUERY = 40;
        STATUS = 41;
Changed lines 604-605 from:
           COMMIT_RECEIVED = 7;
            COMMIT_SENT = 8;
to:
           COMMIT_RECEIVED = 10;
            COMMIT_SENT = 11;
Added lines 613-629:

[[#error_messages]]
!! 8. Error Messages

[[#error]]
!!! Error

[@
message Error {
    required Header header = 1;
    enum ErrorCode {
        // TODO: List all error codes here.
    }
    optional ErrorCode code = 2;
    optional string message = 3;
}
@]
Deleted lines 404-405:

TODO: How to determine if exchange_onion is encrypted or not?  Maybe just required encryption...
Changed line 52 from:
* '''data network''' - the network of data connections that serves to pass messages between host machines; the internet.
to:
* '''Data network''' - the network of data connections that serves to pass messages between host machines; the internet.
Changed lines 127-128 from:
@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | Nodes message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains, eg, ''user@host.com''.
to:
@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | @@Nodes@@ message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains, eg, ''user@host.com''.
Changed lines 151-152 from:
@@signer@@ is the canonical hash of the signing key, and may be omitted if it is obvious who the signer is.
to:
@@signer@@ is the canonical hash of the signing key, and may be omitted if the signer is already identified in the message.
Changed line 301 from:
   repeated bytes arbiter_keys = 7;
to:
   repeated bytes commit_arbiters = 7;
Changed lines 309-310 from:
@@linked_line_of_credit_id@@ indicates another line of credit that is to have a shared balance with this line of credit, in order that the two lines of credit form a single mutual credit account.  The linked line of credit does not have to be between the same two nodes, but it must have the same units.  This would be used if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | Credit]] below.
to:
@@linked_line_of_credit_id@@ indicates another line of credit that is to have a shared balance with this line of credit, in order that the two lines of credit form a single mutual credit account.  The linked line of credit does not have to be between the same two nodes, but it must have the same units.  This would be used if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | @@Credit@@]] below.

@@commit_arbiters@@ identifies third parties (eg, by public key) which the sending node agrees will be authoritative on the existence of transaction commit message at particular times, in case of disagreement between the two partner nodes.  See [[#promise | @@Promise@@
]] below.
Added line 356:
           optional double expiry = 12;
Changed lines 380-381 from:
Instead of advertising numeric exchange rates, nodes may reference independently-broadcast exchange rates using @@in_rate_id@@ and @@out_rate_id@@.  (See [[#exchange_rate | Exchange Rate]] below.)  Nodes may modify these independently-broadcast rates using @@in_rate_modifier@@ and @@out_rate_modifier@@, which give values to be added to broadcast rates to determine the node's exchange rates for that line of credit.
to:
Instead of advertising numeric exchange rates, nodes may reference independently-broadcast exchange rates using @@in_rate_id@@ and @@out_rate_id@@.  (See [[#exchange_rate | @@ExchangeRate@@]] below.)  Nodes may modify these independently-broadcast rates using @@in_rate_modifier@@ and @@out_rate_modifier@@, which give values to be added to broadcast rates to determine the node's exchange rates for that line of credit.
Added lines 406-407:
TODO: How to determine if exchange_onion is encrypted or not?  Maybe just required encryption...
Added lines 409-423:
message Transfer {
    required bytes line_of_credit_id = 1;
    optional bytes chunk_id = 3;
    required string amount = 2;
    optional EncryptedMessage onion_forward = 4;
}

message Exchange {
    repeated Transfer in_transfers = 1;
    repeated Transfer out_transfers = 2;
    optional bool wait_for_merge = 3;
    optional string forward_to_node = 4;
    optional bytes forward_to_host = 5;
}

Changed lines 427-439 from:
   optional bytes checker_key = 3;
    message CheckLOC {
           required bytes line_of_credit_id = 1;
 
          required string amount = 2;
            optional bytes chunk_id = 3
            optional bytes next_query = 4;
        }
    message CheckNodeQuery {
        repeated CheckLOC in_locs = 1;
        repeated CheckLOC out_locs = 2;
        optional bool wait_for_merge = 3;
        optional string forward_to_node = 4;
        optional bytes forward_to_host = 5
;
to:
   required bytes checker_key = 3;
    optional EncryptedMessage exchange_onion = 4;
    message CheckResponse {
        required bytes node_address = 1;
        required bool transaction_possible = 2;
Changed lines 433-438 from:
   optional bytes node_query = 4;
    message CheckNodeResponse {
        required bytes node_address = 1;
        required bool transaction_possible = 2;
    }
    repeated bytes node_
responses = 5;
to:
   repeated EncryptedMessage responses = 5;
Changed lines 437-442 from:
Used to inquire from one or more nodes whether a particular transaction is possible at the moment.  @@node_query@@ contains a @@CheckNodeQuery@@ structure, possibly encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  Chunk IDs are included when desired credit has previously been advertised as a non-default chunk.  Each outgoing line of credit structure may contain a further @@CheckNodeQuery@@, possibly encrypted, for the next intermediary node in the transaction. 

The response to a credit check is a boolean @@transaction_possible@@, which indicates whether the the node is willing to perform the requested exchange at the moment.  Responses should be encrypted against @@checker_key@@ when it is present, appended to @@node_responses@@, and @@next_query@@ made @@node_query for each branch going forward.  An affirmative response is no guarantee of credit availability, just a relatively up-to-date credit advertisement.

When a propagating credit check branches and then merges again, only one branch needs to carry responses from the branch point and before, and only one branch needs to contain queries for the merge point node and beyond.  When a node receives a credit check with no @@node_query@@, it should expect a further credit check message with the same @@check_id@@ that does contain a @@node_query@@.  @@wait_for_merge@@ indicates to a node to wait for all branches to arrive and concatenate all responses before forwarding them on.
to:
Used to inquire from one or more nodes whether a particular transaction is possible at the moment.  @@exchange_onion@@ contains an @@Exchange@@ structure, encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  @@chunk_id@@s are specified when desired credit has previously been advertised as a non-default chunk.  Each outgoing @@Transfer@@ structure may contain a further @@Exchange@@, encrypted to the next intermediary node in the transaction. 

The response to a credit check is a boolean @@transaction_possible@@, which indicates whether the the node is willing to perform the requested exchange at the moment.  Responses must be encrypted against @@checker_key@@, appended to @@responses@@, and @@onion_forward@@ copied to @@exchange_onion@@ for each branch going forward.  An affirmative response is no guarantee of credit availability, just a relatively up-to-date credit advertisement.

When a propagating credit check branches and then merges again, only one branch needs to carry responses from the branch point and before, and only one branch needs to contain @@Exchange@@ queries for the merge point node and beyond.  When a node receives a credit check with no @@exchange_onion@@, it should expect a further credit check message with the same @@check_id@@ that does contain an @@exchange_onion@@.  @@wait_for_merge@@ indicates to a node to wait for all branches to arrive and concatenate all responses before forwarding them on.
Changed lines 491-493 from:
''TODO''

to:
[@
message Promise {
    required Header header = 1;
    required bytes transaction_id = 2;
    required bytes line_of_credit_id = 3;
    required string amount = 4;
    required double expiry = 5;
    required bytes payer_commit_key = 6;
    required bytes recipient_commit_key = 7;
    optional bytes exchange_onion = 8;
    optional string commit_message_url = 9;
    repeated bytes commit_arbiters = 10;
}
@]

A promise to pass forward an [[#iou | @@IOU@@]] of value @@amount@@ on the specified line of credit when shown a commit message with the given @@transaction_id@@, and signed by the @@payer_commit_key@@ and @@recipient_commit_key@@ before the @@expiry@@ time. 

@@exchange_onion@@ consists of @@Exchange@@ structures (defined in [[#credit_check | @@CreditCheck@@]] above), and defines the lines of credit and exchanges to carry obligations to the recipient.  @@forward_to_node@@ and @@forward_to_host@@ are not used here.

If any of the entities identified in @@commit_arbiters@@ declares, presumably by timestamping and signing, that a valid commit message existed at a time before promise @@expiry@@, then the promisor must pass forward an IOU to fulfill the promise.  Generally, the commit message for a transaction would just be presented to the promisor before promise expiry, and the promisor would immediately pass the required IOU.  @@commit_arbiters@@ gives the promisee a mechanism to have the promise fulfilled in case the promisor in non-responsive in the period before the promise expires.


Changed lines 516-518 from:
''TODO''

to:
[@
message CommitReady {
    required Header header = 1;
    required bytes transaction_id = 2;
}
@]

The recipient passes this to the payer when it has received enough promises to commit the transaction.


Changed lines 529-531 from:
''TODO''

to:
[@
message PromiseRelease {
    required Header header = 1;
    required bytes transaction_id = 2;
    required bytes line_of_credit_id = 3;
}
@]

The promisee may release the promisor of its promise by sending a @@PromiseRelease@@.


Changed lines 543-545 from:
''TODO''

to:
[@
message Commit {
    required Header header = 1;
    message CommitToken {
        required bytes transaction_id = 1;
        required double time = 2;
    }
    required SignedMessage commit_token = 2;
}
@]

@@commit_token@@ contains a @@CommitToken@@ signed by both the @@payer_commit_key@@ and @@recipient_commit_key@@ defined in the promise phase.


Changed lines 560-562 from:
''TODO''

to:
[@
message StatusQuery {
    required Header header = 1;
    required bytes transaction_id = 2;
}
@]

The payer uses this to request information about the current state of the transaction from another participant.  Must be signed by the @@payer_commit_key@@ for the transaction.


Changed lines 573-595 from:
''TODO''
to:
[@
message Status {
    required Header header = 1;
    required bytes transaction_id = 2;
    message StatusChunk {
        required bytes line_of_credit_id = 1;
        optional bytes chunk_id = 2;
        enum StatusCode {
            AWAITING_PROMISE = 0;
            PROMISE_RECEIVED = 1;
            PROMISE_RECEIVED_REJECTED = 2;
            PROMISE_SENT = 3;
            PROMISE_SENT_REJECTED = 4;
            PROMISE_RELEASED = 5;
            PROMISE_EXPIRED = 6;
            COMMIT_RECEIVED = 7;
            COMMIT_SENT = 8;
        }
        repeated StatusCode codes = 3;
    }
    repeated StatusChunk chunks = 3;
}
@]
Changed lines 320-326 from:
   required bytes iou_id = 2;[[#]]
!!!

''TODO''


to:
   required bytes iou_id = 2;
Changed lines 6-7 from:
!!Contents
to:
!! Contents
Changed line 18 from:
    * [[# rsa_key_format | RSA Key Format]]
to:
  * [[# rsa_key_format | RSA Key Format]]
Changed lines 11-14 from:

3. [[#framing | Framing]]

4. [[#message_format | Message Format]]
to:
* [[#framing | Framing]]

3. [[#message_format | Message Format]]
Changed lines 17-21 from:

5. [[#public_key_formats | Public Key Formats]]
* [[# rsa_key_format | RSA Key Format]]

6. [[#core_messages | Core Messages]]
to:
* [[#public_key_formats | Public Key Formats]]
    * [[# rsa_key_format | RSA Key Format]]
* [[#unique_ids | Unique IDs]]
* [[#decimal_numbers | Decimal Numbers]]

4
. [[#core_messages | Core Messages]]
Changed line 28 from:
7. [[#account_messages | Account Messages]]
to:
5. [[#account_messages | Account Messages]]
Changed lines 30-31 from:

8. [[#routing_messages | Routing Messages]]
to:
* [[#iou | IOU]]

6
. [[#routing_messages | Routing Messages]]
Changed lines 37-38 from:
9. [[#transaction_messages | Transaction Messages]]
to:
7. [[#transaction_messages | Transaction Messages]]
* [[#payment_init | Payment Init]]
* [[#payment_accept | Payment Accept]]
* [[#promise | Promise]]
* [[#commit_ready | Commit Ready]]
* [[#promise_release | Promise Release]]
* [[#commit | Commit]]
* [[#status_query | Status Query]]
* [[#status | Status
]]
Changed lines 50-53 from:
* '''Credit Network''' - the abstract network of financial trust connections over which payments are routed in Ripple.
  * also '''Trust Network''', '''Payment Network'''
* '''Data Network''' - the network of data connections that serves to pass messages between host machines; the internet.
to:
* '''Credit network''' - the abstract network of financial trust connections over which payments are routed in Ripple.
  * also '''trust network''', '''payment network'''
* '''data network''' - the network of data connections that serves to pass messages between host machines; the internet.
Changed line 55 from:
  * also '''Address'''
to:
  * also '''address'''
Changed lines 73-74 from:
!! 3. Framing
to:
!!! Framing
Changed lines 100-101 from:
!! 4. Message Format
to:
!! 3. Message Format
Changed lines 179-180 from:
!! 5. Public Key Formats
to:
!!! Public Key Formats
Changed lines 196-197 from:
!!! RSA Key Format
to:
!!!! RSA Key Format
Added lines 208-219:
[[#unique_ids]]
!!! Unique IDs

Unless otherwise specified, unique identifiers are 16-byte [[http://en.wikipedia.org/wiki/Universally_unique_identifier | UUIDs]], generated by any method.  Usually these fields have names ending in @@_id@@.


[[#decimal_numbers]]
!!! Decimal Numbers

Decimal numbers (ie, monetary amounts), are encoded as Protocol Buffer ASCII/UTF-8 strings to avoid rounding error introduced by binary encoding.

Changed lines 221-222 from:
!! 6. Core Messages
to:
!! 4. Core Messages
Changed lines 288-289 from:
!! 7. Account Messages
to:
!! 5. Account Messages
Added line 303:
   optional bytes proof_of_id = 9;
Changed lines 311-317 from:

[[#routing_messages]]
!! 8. Routing Messages

[[#credit]]
!!! Credit

to:
@@proof_of_id@@ may be used to associate the sending node with a human identity, by way of, for example, a GPG key and signature of @@line_of_credit_id@@.  This mechanism is left unspecified here.


[[#iou]]
!!! IOU

Changed line 318 from:
message Credit {
to:
message IOU {
Added lines 320-345:
   required bytes iou_id = 2;[[#]]
!!!

''TODO''



    required bytes line_of_credit_id = 3;
    required string amount = 4;
    optional bytes transaction_id = 5;
    optional string memo = 6;
}
@]

Signed by sender, indicates change in a line of credit's mutual credit account balance by @@amount@@, in favour of the receiving partner.  When a mutual credit account comprises two lines of credit, an IOU need only be sent on one of them.  An IOU with the same ID must only be recognized once on the same mutual credit account.  If an IOU is a consequence of a routed transaction, the @@transaction_id@@ must be included.


[[#routing_messages]]
!! 6. Routing Messages

[[#credit]]
!!! Credit

[@
message Credit {
    required Header header = 1;
Changed line 348 from:
       message LineOfCredit {
to:
       message CreditChunk {
Changed lines 351-358 from:
           optional string in_limit = 3;
            optional string out_limit = 4;
            optional string in_rate = 5;
            optional string out_rate = 6;
            optional bytes in_rate_id = 7;
            optional bytes out_rate_id = 8;
            optional string in_rate_modifier = 9;
            optional string out_rate_modifier = 10;
to:
           optional bytes chunk_id = 3;
            optional string in_limit = 4;
            optional string out_limit = 5;
            optional string in_rate = 6;
            optional string out_rate = 7;
            optional bytes in_rate_id = 8;
            optional bytes out_rate_id = 9;
            optional string in_rate_modifier = 10;
            optional string out_rate_modifier = 11
;
Added lines 372-373:
A node may advertise multiple @@CreditChunk@@s on the same line of credit, in order to, for example, offer a better exchange rate for a portion of credit available in order motivate its use.  Both partners need not agree on chunks.  When multiple chunks are advertised, @@chunk_id@@ must be used to distinguish between them.  A missing @@chunk_id@@ refers to the default chunk for that line of credit.
Changed lines 417-418 from:
           optional bytes next_query = 3;
to:
           optional bytes chunk_id = 3
           optional bytes next_query = 4;
Changed lines 436-437 from:
Used to inquire from one or more nodes whether a particular transaction is possible at the moment.  @@node_query@@ contains a @@CheckNodeQuery@@ structure, possibly encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  Each outgoing line of credit structure may contain a further @@CheckNodeQuery@@, possibly encrypted, for the next intermediary node in the transaction. 
to:
Used to inquire from one or more nodes whether a particular transaction is possible at the moment.  @@node_query@@ contains a @@CheckNodeQuery@@ structure, possibly encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  Chunk IDs are included when desired credit has previously been advertised as a non-default chunk.  Each outgoing line of credit structure may contain a further @@CheckNodeQuery@@, possibly encrypted, for the next intermediary node in the transaction. 
Changed lines 446-448 from:
!! 9. Transaction Messages

''TODO''
to:
!! 7. Transaction Messages

[[#payment_init]]
!!! Payment Init

[@
message PaymentInit {
    required Header header = 1;
    required bytes transaction_id = 2;
    required string amount = 3;
    optional string units = 4;
    optional string memo = 5;
}
@]

Sent by payer to recipient.  Amount is given in recipient node base units.

@@units@@ is an optional string that can be used to indicate the payer's understanding that the payment amount is being valued by the recipient in some external unit of account.  By filling out this field, the payer is asking for the recipient node to reject the payment if it does not recognize the @@units@@ value as the base unit of account for the recipient node, to help prevent misunderstandings.

[[#payment_accept]]
!!! Payment Accept

[@
message PaymentAccept {
    required Header header = 1;
    required bytes payment_init = 2;
    required bytes recipient_commit_key = 3;
    optional string commit_url = 4;
    optional bytes recipient_proof_of_id = 5;
}
@]

Returned by recipient in reply to a payment init, if it chooses to accept the payment.  Must be signed by recipient. 

@@payment_init@@ is a copy of the payment init.  A recipient that does not understand units should strip the @@units@@ field from the payment init if it was set, otherwise it is acknowledging that the payment is being received in the stated units.

@@recipient_commit_key@@ will be used by the recipient to sign the commit message.  @@commit_url@@ is a URL where the commit message will be made available once it has been prepared. 

@@recipient_proof_of_id@@ may be used to link the receiving node to a human identity.  The mechanism is left unspecified here.


[[#promise]]
!!! Promise

''TODO''


[[#commit_ready]]
!!! Commit Ready

''TODO''


[[#promise_release]]
!!! Promise Release

''TODO''


[[#commit]]
!!! Commit

''TODO''


[[#status_query]]
!!! Status Query

''TODO''


[[#status]]
!!! Status

''TODO''

Added lines 2-3:

A protocol for establishing mutual credit accounts between users on different hosts, and conducting multi-hop transactions through the resulting credit network.
March 27, 2011, at 11:46 PM by Ryan - definitions
Changed lines 39-45 from:
''TODO''

* Node
* Line of credit
* Mutual credit account
* Host
* Server
to:
* '''Credit Network''' - the abstract network of financial trust connections over which payments are routed in Ripple.
  * also '''Trust Network''', '''Payment Network'''
* '''Data Network''' - the network of data connections that serves to pass messages between host machines; the internet.

* '''Node''' - an address in the credit network that can send and/or receive payment.
  * also '''Address'''
* '''Server''' - the protocol software, an instance of that software running on a host machine, or the host itself running the software.

* '''Line of credit''' - a credit relationship between two nodes.
  * not quite the same as the higher-level term '''mutual credit account''', which is a credit relationship between two ''users'', each of which may control multiple nodes, consisting of either one or two lines of credit, depending on the routing needs.
March 27, 2011, at 11:28 PM by Ryan - Credit check
Changed lines 32-33 from:
to:
* [[#credit_check | Credit Check]]
Changed lines 338-387 from:
''TODO''
to:
[@
message ExchangeRate {
    required Header header = 1;
    required bytes rate_id = 2;
    required bytes source_address = 3;
    required string rate = 4;
    optional double valid_until = 5;
}
@]

@@source_address@@ is a node whose key must sign every exchange rate message.


[[#credit_check]]
!!! Credit Check

[@
message CreditCheck {
    required Header header = 1;
    required bytes check_id = 2;
    optional bytes checker_key = 3;
    message CheckLOC {
            required bytes line_of_credit_id = 1;
            required string amount = 2;
            optional bytes next_query = 3;
        }
    message CheckNodeQuery {
        repeated CheckLOC in_locs = 1;
        repeated CheckLOC out_locs = 2;
        optional bool wait_for_merge = 3;
        optional string forward_to_node = 4;
        optional bytes forward_to_host = 5;
    }
    optional bytes node_query = 4;
    message CheckNodeResponse {
        required bytes node_address = 1;
        required bool transaction_possible = 2;
    }
    repeated bytes node_responses = 5;
}
@]

Used to inquire from one or more nodes whether a particular transaction is possible at the moment.  @@node_query@@ contains a @@CheckNodeQuery@@ structure, possibly encrypted to the receiving node, containing the set of incoming and outgoing lines of credit and amounts on each representing that node's part in the transaction.  Each outgoing line of credit structure may contain a further @@CheckNodeQuery@@, possibly encrypted, for the next intermediary node in the transaction. 

The response to a credit check is a boolean @@transaction_possible@@, which indicates whether the the node is willing to perform the requested exchange at the moment.  Responses should be encrypted against @@checker_key@@ when it is present, appended to @@node_responses@@, and @@next_query@@ made @@node_query for each branch going forward.  An affirmative response is no guarantee of credit availability, just a relatively up-to-date credit advertisement.

When a propagating credit check branches and then merges again, only one branch needs to carry responses from the branch point and before, and only one branch needs to contain queries for the merge point node and beyond.  When a node receives a credit check with no @@node_query@@, it should expect a further credit check message with the same @@check_id@@ that does contain a @@node_query@@.  @@wait_for_merge@@ indicates to a node to wait for all branches to arrive and concatenate all responses before forwarding them on.

@@forward_to_node@@ indicates that the receiving node should add its response, and, after waiting for merge, if requested, forward the credit check to a particular node.  This allows checking only a portion of a potential transaction flow subgraph.  @@forward_to_host@@ allows the credit check to be forwarded directly, but if it is missing, or connection to the destination hosts fails, the credit check should be forwarded over the credit network using @@Relay@@.

Changed lines 3-4 from:
!! Transport
to:
[[#contents]]
!!Contents

1. [[#definitions | Definitions]]

2. [[#transport | Transport]]

3. [[#framing | Framing]]

4. [[#message_format | Message Format]]
* [[#header | Header]]
* [[#signed_messages | Signed Messages]]
* [[#encrypted_messages | Encrypted Messages]]

5. [[#public_key_formats | Public Key Formats]]
* [[# rsa_key_format | RSA Key Format]]

6. [[#core_messages | Core Messages]]
* [[#time | Time]]
* [[#relay | Relay]]
* [[#nodes | Nodes]]
* [[#node_request | Node Request]]

7. [[#account_messages | Account Messages]]
* [[#connect | Connect]]

8. [[#routing_messages | Routing Messages]]
* [[#credit | Credit]]
* [[#exchange_rate | Exchange Rate]]

9. [[#transaction_messages | Transaction Messages]]

[[#definitions]]
!! 1. Definitions

''TODO''

* Node
* Line of credit
* Mutual credit account
* Host
* Server


[[#transport]]
!! 2. Transport

Changed lines 57-58 from:
!! Framing
to:
[[#framing]]
!! 3. Framing
Changed lines 84-85 from:
!! Message Format
to:
[[#message_format]]
!! 4. Message Format
Added line 90:
[[#header]]
Added line 117:
[[#signed_messages]]
Added line 141:
[[#encrypted_messages]]
Changed lines 163-164 from:
!! Public Key Formats
to:
[[#public_key_formats]]
!! 5. Public Key Formats
Added line 180:
[[#rsa_key_format]]
Changed lines 193-194 from:
!! Core Messages
to:
[[#core_messages]]
!! 6. Core Messages

[[#time]]
Added line 210:
[[#relay]]
Changed lines 230-233 from:
       required bytes address = 1;
        required PublicKey signing_key = 2;
        optional PublicKey encryption_key = 3;
        optional string host = 4;
to:
       required bytes address = 0;
        required PublicKey signing_key = 1;
        optional PublicKey encryption_key = 2;
        optional string host = 3;
        optional bytes proof_of_work
= 4;
Changed lines 244-247 from:
to:
@@proof_of_work@@ is a string of bytes that, when concatenated to the end of @@address@@ and hashed with SHA256, gives a result below a certain acceptability threshold (ie, with at least a certain number of zeroes at the start).  This number is meant to be reasonably difficult to calculate, to prevent someone from spamming the network with millions of nodes.  If a host receives a @@NodeInfo@@ segment with what it considers insufficient proof of work, it should reply with an error indicating the required proof-of-work threshold.


[[#node_request]]
Changed lines 260-261 from:
!! Account Messages
to:
[[#account_messages]]
!! 7. Account Messages

[[#connect]]
!!! Connect

[@
message Connect {
    required Header header = 1;
    required bytes line_of_credit_id = 2;
    optional bytes linked_line_of_credit_id = 3;
    optional string units = 4;
    optional string credit_offered = 5;
    optional string iou_offered = 6;
    repeated bytes arbiter_keys = 7;
    optional string note = 8;
}
@]

Indicates a desire for the sending node to connect and register a line of credit with the receiving node.  The receiving node would reply with another @@Connect@@ message to indicate its reciprocal willingness to maintain the line of credit.

@@linked_line_of_credit_id@@ indicates another line of credit that is to have a shared balance with this line of credit, in order that the two lines of credit form a single mutual credit account.  The linked line of credit does not have to be between the same two nodes, but it must have the same units.  This would be used if one or both partners wished to process incoming transactions on a different node than outgoing transactions, in order have a different set of exchanges for incoming and outgoing accounts, which can't be done with a single node.  See [[#credit | Credit]] below.


[[#routing_messages]]
!! 8. Routing Messages

[[#credit]]
!!! Credit

[@
message Credit {
    required Header header = 1;
    message NodeCredit {
        required bytes source_address = 1;
        message LineOfCredit {
            required bytes partner_address = 1;
            required bytes line_of_credit_id = 2;
            optional string in_limit = 3;
            optional string out_limit = 4;
            optional string in_rate = 5;
            optional string out_rate = 6;
            optional bytes in_rate_id = 7;
            optional bytes out_rate_id = 8;
            optional string in_rate_modifier = 9;
            optional string out_rate_modifier = 10;
        }
        repeated bytes lines_of_credit = 2;
        optional string transaction_fee = 3;
        optional string host_port = 4;
        optional int32 hop_limit = 5;
    }
    repeated NodeCredit nodes = 2;
}
@]

Broadcast credit advertisement for one or more nodes.  For a line of credit to be valid for use in transactions, it must be advertised and signed by both partner nodes.

@@in_limit@@ and @@out_limit@@ indicate the maximum value of obligations the node given by @@source_address@@ is willing to accept from and emit to, respectively, the node given by @@partner_address@@, in the units of that line of credit.  Notice that no balance is advertised, meaning that the advertised limits must take into account any non-zero balance between the partner nodes.  If either limit is missing, it is assumed the node will process unlimited transfers in that direction.

Each node has a conceptual base unit, which line-of-credit (LoC) values can be converted to and from using the advertised @@in_rate@@ and @@out_rate@@ multipliers, given as decimal values, not percentages:

* incoming LoC amount * @@in_rate@@ = amount in node units
* amount in node units * @@out_rate@@ = outgoing LoC amount

By indicating an @@in_limit@@, the node is offering to exchange incoming values on that line of credit into outgoing values on any of the node's lines of credit with an @@out_limit@@.  A node cannot indicate that it is unwilling to make certain of these exchanges.  Instead, multiple nodes must be used.

Instead of advertising numeric exchange rates, nodes may reference independently-broadcast exchange rates using @@in_rate_id@@ and @@out_rate_id@@.  (See [[#exchange_rate | Exchange Rate]] below.)  Nodes may modify these independently-broadcast rates using @@in_rate_modifier@@ and @@out_rate_modifier@@, which give values to be added to broadcast rates to determine the node's exchange rates for that line of credit.

Advertised exchange rates are non-binding.

For efficiency, nodes may not wish to advertise the exact account limits, but rather some other lower number that will accomodate enough transactions to be useful, but will not need frequent updating.  This behaviour should generate fewer broadcast messages.  Payers can still potentially get approval for larger transactions by making [[#credit_check | Credit Checks]] prior to initiating payment.


[[#exchange_rate]]
!!! Exchange Rate

Changed lines 339-343 from:
!! Routing Messages

''TODO''

!!
Transaction Messages
to:
[[#transaction_messages]]
!! 9. Transaction Messages
March 24, 2011, at 08:08 AM by Ryan - pretty title
Added lines 1-2:
(:title Ripple Distributed Protocol v0.5:)
March 23, 2011, at 05:01 PM by Ryan - More RSA justification; no destination needed for Relay if EncryptedMessage is used.
Changed lines 125-126 from:
The protocol provides for various key formats and public-key cryptography algorithms to be used, but for simplicity of implementation, only one is supported initially.  RSA was chosen because it is ubiquitous and is quick for signature verification.
to:
The protocol provides for various key formats and public-key cryptography algorithms to be used, but for simplicity of implementation, only one is supported initially.  RSA was chosen because it is ubiquitous (vs. elliptic curve algorithms) and is quick for signature verification, as well as flexible key size and hash algorithm for signatures (vs. DSA).
Changed lines 159-160 from:
   optional bytes destination_node = 2;
    required bytes encrypted_message = 3
;
to:
   required EncryptedMessage message = 2;
March 23, 2011, at 10:00 AM by Ryan - Add anchor for Nodes message.
Changed lines 62-63 from:
@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#node | Node message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains, eg, ''user@host.com''.
to:
@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#nodes | Nodes message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains, eg, ''user@host.com''.
Added line 167:
[[#nodes]]
March 23, 2011, at 09:42 AM by Ryan - Core messages
Added lines 1-209:
!! Transport

Ripple messages are passed over TCP connections, secured by [[http://en.wikipedia.org/wiki/Transport_Layer_Security | TLS]].  Connected Ripple hosts are considered peers in that they can each pass the same set of messages to each other, as opposed to client and server, where one sends requests and the other responds.  For efficiency, connections should preferably be long-lasting, rather than set up for each message and then closed immediately.

Messages and their responses are passed asynchronously, meaning that multiple requests may be sent by one host on the same connection before any potential responses to those requests are received back, and the responses may come in any order, so that the responding server may take advantage of its parallel processing capabilities.  Hosts may open multiple TCP connections with each other if [[http://document-program.blogspot.com/2009/11/105-exploring-head-of-line-blocking.html | head-of-line blocking]] becomes a bottleneck for messages on a single connection (or for any other reason).

''In the future, [[http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol | SCTP]] has many desirable features as a Ripple transport layer, once it becomes more commonplace and easy to use in various networking frameworks and hosting arrangements.''


!! Framing

Since TCP is a byte-stream protocol, Ripple messages must be framed to preserve message boundaries.  Each frame is defined by:

|| border=0
||!Bytes ||!Length ||!Field ||
||1      ||1      ||@@type@@ | @@more@@ | [reserved] ||
||2-5    ||4      ||@@msgno@@ ||
||6-9    ||4      ||@@size@@ ||
||10-?  ||?      ||@@body@@ ||

* @@type@@ (4 bits) - type of message
  * 0000 = message
  * 0001 = reply
  * 0010 = error
* @@more@@ (1 bit) - whether this is the last chunk for this message
  * 0 = last chunk
  * 1 = more chunks coming
* [reserved] (3 bits)
* @@msgno@@ - number to connect messages with replies/errors; each new message must have a unique value among open messages on the connection (ie, those with no reply or error response yet).
* @@size@@ - number of bytes in @@body@@
* @@payload@@ - message bytes

The general semantics of these basic fields is much the same as in the [[http://www.rfc-editor.org/rfc/rfc3080.txt | BEEP specification]].


!! Message Format

Ripple messages are defined using Google's [[ http://code.google.com/apis/protocolbuffers/ | Protocol Buffers ]] mechanism.


!!! Header

[@
message Header {
    enum MessageType {
        TIME = 0;
        RELAY = 1;
        ...  // TODO: Fill the rest out.
    }
    required MessageType type = 1;
    required string version = 2;
    optional bytes to = 3;
    optional string to_alias = 4;
    optional bytes from = 5;
    optional string from_alias = 6;
    required double time = 7;
}
@]

@@version@@ is the Ripple protocol version this message is to be interpreted under.

@@to@@ and @@from@@ are node addresses, which are hashes of node public keys.  (See [[#node | Node message]] below.)  @@to_alias@@ and @@from_alias@@ are human-readable node aliases that also specify host domains, eg, ''user@host.com''.

@@time@@ is given in number of seconds since Jan. 1, 1970 (ie, unix time).


!!! Signed Messages

[@
message SignedMessage {
    required bytes message = 1;
    message Signature {
        optional bytes signer = 1;
        enum HashAlgorithm {
            SHA256 = 0;
        }
        required HashAlgorithm hash_algorithm = 2;
        required bytes hash = 3;
        required bytes signature = 4;
    }
    repeated Signature signatures = 2;
}
@]

@@signer@@ is the canonical hash of the signing key, and may be omitted if it is obvious who the signer is.

For simplicity of implementation, only one hashing algorithm is supported initially.  SHA256 was chosen because it is ubiquitous and should remain resilient to attack for quite some time.


!!! Encrypted Messages

[@
message EncryptedMessage {
    required bytes recipient = 1;
    enum Cipher {
        AES256 = 0;
    }
    required Cipher cipher = 2;
    required bytes encrypted_key = 3;
    required bytes ciphertext = 4;
}
@]

@@recipient@@ is a node address (hash of node's signing key).

To encrypt a message to the recipient, the sender encrypts a symmetric encryption key for the @@cipher@@ algorithm, and then uses that key to encrypt the message to the @@ciphertext@@ field.

For simplicity of implementation, only one cipher algorithm is supported initially.  AES256 was chosen because it is ubiquitous, strong, and fast.


!! Public Key Formats

[@
message PublicKey {
    enum KeyFormat {
        RSA = 0;
    }
    required KeyFormat key_format = 1;
    required bytes key = 2;
}
@]

@@key@@ contains a specific byte sequence particular to the selected key format. 

The protocol provides for various key formats and public-key cryptography algorithms to be used, but for simplicity of implementation, only one is supported initially.  RSA was chosen because it is ubiquitous and is quick for signature verification.

!!! RSA Key Format

[@
message RSAKey {
    required bytes modulus = 1;
    required bytes exponent = 2;
}
@]

Goes in the @@PublicKey.key@@ field.  Both @@modulus@@ and @@exponent@@ are big-endian integers.


!! Core Messages

!!! Time

[@
message Time {
    required Header header = 1;
}
@]

Allows hosts to discover what time the other thinks it is (before transmission delay).  A peer can send a @@Time@@ message at any time during the connection.  The other peer should reply immediately with its own @@Time@@ message.

The actual time is contained in the header.


!!! Relay

[@
message Relay {
    required Header header = 1;
    optional bytes destination_node = 2;
    required bytes encrypted_message = 3;
}
@]

Message encrypted to destination node, pass it on.  Encrypted message may be another @@Relay@@.


!!! Nodes

[@
message Nodes {
    required Header header = 1;
    message NodeInfo {
        required bytes address = 1;
        required PublicKey signing_key = 2;
        optional PublicKey encryption_key = 3;
        optional string host = 4;
    }
    repeated NodeInfo nodes = 2;
}
@]

Node advertisement.  @@address@@ is the RIPEMD160 hash of the node's signing key.  If the encryption key is omitted, the signing key should be used to encrypt messages to this node.

RIPEMD160 was chosen because it is ubiquitous, its output is shorter than SHA256, which is useful if node addresses are communicated outside protocol messages, and probably stronger than SHA1.


!!! Node Request

[@
message NodeRequest {
    required Header header = 1;
    repeated bytes addresses = 2;
}
@]

Request info about one or more nodes.  Reply is a @@Nodes@@ message.


!! Account Messages

''TODO''

!! Routing Messages

''TODO''

!! Transaction Messages

''TODO''