Core

Protocol.Core History

Hide minor edits - Show changes to output

Added line 115:
[[#transport]]
Changed lines 29-30 from:
   ("from": "rfugger",
    "to": "otheruser",)
to:
   "from": "rfugger@ripplepay.com",
    "to": "otheruser@otherhost.com:2338",
Changed lines 39-41 from:
The @@from@@ and @@to@@ fields contain node names on the sending and receiving host, respectively.  These fields are omitted for host-to-host messages.  The @@request-id@@ field is used to pair up requests and replies.  Request IDs must be unique among open requests between two hosts.  The @@time@@ field contains the UTC time according to the sending host's clock.  It is only used in certain subprotocols, particularly Payments and Accounts.  The @@body@@ field is not used for every message type.

to:
The @@from@@ and @@to@@ fields contain node names on the sending and receiving host, respectively.  For host-to-host messages, these fields contain hostnames (with optional ports), without node IDs.  This allows hosts to know each other's hostnames, and also provides, for signed messages, a record of sender and recipient.

The @@request-id@@ field is used to pair up requests and replies.  Request IDs must be unique among open requests between two hosts.  The @@time@@ field contains the UTC time according to the sending host's clock.  It is only used in certain subprotocols, particularly Payments and Accounts.  The @@body@@ field is not used for every message type.

Deleted lines 11-21:
[[#binding-to-a-transport-layer]]
'''Binding to a Message Transport Layer'''

A Ripple transport layer binding must specify the following:

* how hosts open and close connections to each other
* how the connection is secured
* how connected hosts send messages to each other
* how Ripple messaging semantics are implemented (see [[Messaging Semantics -> #messaging-semantics]] below).
* how two hosts ensure they are both using the same version of this protocol

Added lines 123-180:

!!!Transport

'''Host Connections'''

Ripple hosts connect to each other by TCP.  (Need to specify a standard port for hosts to listen on.)  TCP connections are meant to be persistent, but may be closed by either host at any time.

Hosts may open multiple connections with each other.


'''Connection Security'''

After @@time@@ and possibly @@host-status@@ messages have been exchanged, the initiating host starts TLS on the connection.


'''Node Identification'''

Nodes are identified in standard ''node@host.com'' email-address style.  For nonstandard ports, use ''node@host.com:xxxx'', where xxxx is the port the host is listening on for Ripple connections.


'''Host Messages'''

Host messages are sent in [[BEEP -> http://www.rfc-editor.org/rfc/rfc3080.txt]]-style frames as follows:

[@
(type) (version) (msgno) (more) (size)(CRLF)
(content)
END(CRLF)
@]

where

[@
(type)    = MSG | RPY | ERR
(version) = (string)
(msgno)  = 0..2147483647
(more)    = . | *
(size)    = (integer)
@]

Message types @@MSG@@, @@RPY@@, and @@ERR@@ correspond to the Ripple message types @@message@@, @@reply@@, and @@error@@. 

The @@version@@ indicates the Ripple protocol version. 

The @@msgno@@ must be unique among @@MSG@@-type messages in the connection that have not yet received a complete response.  For @@RPY@@ and @@ERR@@ types, @@msgno@@ must be identical to the original @@MSG@@.  The host that initiated the connection must use only even-numbered @@msgno@@s and the host that received the connection must use only odd-numbered @@msgno@@s.

If @@more@@ is "*", it signifies there are more frames in the message; if it is ".", this is the final frame.  This allows a host to chunk messages into discrete bits in order to interleave messages on the same connection.  If the connection is dropped before the final frame is received and acknowledged, the message must be disregarded.

@@size@@ is the number of content bytes between, but not including, the @@CRLF@@ at the end of the header line, and the @@END@@ at the end of the frame.

Channels from the BEEP specification are omitted because Ripple interleaving message frames seems to accomplish much the same thing.  The @@seqno@@ field from BEEP is omitted here because TCP already does its own byte-counting at a lower level.


'''Errors'''

If a received frame is not in the correct format, the association must be immediately closed.

Added lines 1-123:
!! Ripple Core Protocol

[[Protocol/Core Work Page]]

The following is common to all Ripple subprotocols.

[[#messaging]]
!!! Messaging

The Ripple network consists of software agents called ''nodes'' connected together pairwise where one or both accept the other's obligations as valuable.  These abstract connections are manifested over messaging connections between hosts, each of which may host multiple nodes. 

[[#binding-to-a-transport-layer]]
'''Binding to a Message Transport Layer'''

A Ripple transport layer binding must specify the following:

* how hosts open and close connections to each other
* how the connection is secured
* how connected hosts send messages to each other
* how Ripple messaging semantics are implemented (see [[Messaging Semantics -> #messaging-semantics]] below).
* how two hosts ensure they are both using the same version of this protocol

[[#messaging-semantics]]
'''Messaging Semantics'''

A message transport layer must distinguish between three message types: @@message@@, @@reply@@, and @@error@@.  Each Ripple @@message@@ has a unique ID within the host-level connection, and must be immediately responded to by either a @@reply@@ or an @@error@@ with the same ID upon receipt.  This serves to establish that the message was received and was either understood (@@reply@@), or deemed somehow malformed or otherwise inappropriate as detailed by an error code and message (@@error@@).  The ID may consist of one or more fields.

Replies and errors may carry any data that a regular message may carry.  In addition, error messages must carry an error code.

In general, nodes need not wait for the reply or error to send another message.

[[#message-syntax]]
'''Message Syntax'''

Ripple messages carried within the transport layer are in [[JSON textual format -> http://json.org/]].  For example:

[@
{
    "type": "account-request",
    ("from": "rfugger",
    "to": "otheruser",)
    ("request-id": (integer),)
    ("time": "2007-03-30 14:10:03.112000",)
    ("body": (message body goes here))
}
@]

The indentation and line breaks are for readability in this document only.  The actual messages themselves do not have significant whitespace other than described in the [[JSON specification -> http://www.ietf.org/rfc/rfc4627.txt]].

The @@from@@ and @@to@@ fields contain node names on the sending and receiving host, respectively.  These fields are omitted for host-to-host messages.  The @@request-id@@ field is used to pair up requests and replies.  Request IDs must be unique among open requests between two hosts.  The @@time@@ field contains the UTC time according to the sending host's clock.  It is only used in certain subprotocols, particularly Payments and Accounts.  The @@body@@ field is not used for every message type.


!!! Host Messages

Certain messages are sent to a host, rather than to an individual node on a host.

[[#keeping-time]]
'''Keeping Time'''

The timestamp put on a Ripple message by the sending host is interpreted by the receiving host as the time the corresponding event occurred, so it is important that:

* the two hosts' clocks are reasonably in sync
* the network latency is reasonable

To allow two hosts to verify these two conditions at the beginning of a connection, and at any other time there is uncertainty (such as a long delay between timestamped messages), they may use a @@time@@ message:

[@
{
    "type": "time",
    (request-id: 24223,)
    "time": "2007-03-30 14:10:03.112000"
}
@]

@@request-id@@ is only used if the message is in reply to a @@time-request@@.  An affirmative reply to this message indicates the receiving host's approval of the sending host's local clock and network latency of the connection.  An error reply containing a @@time-request@@ message indicates that the another time message should be sent.  After three consecutive time errors, the connection should be closed after all open transactions are completed.

To request a @@time@@ message from another host, for example, when timestamped non-@@time@@ messages are arriving at off-times, send a @@time-request@@:

[@
{
    "type": "time-request",
    "request-id": (4485093)
}
@]

The host receiving a @@time-request@@ must give an affirmative reply followed immediately by a @@time@@ message with the same @@request-id@@ as the request.  This may trigger a time error and subsequent @@time@@ messages and possibly a closed connection. 

Ping may also be used to detect network latency.  Ripple hosts should accept pings.

This section presumes both hosts are making every effort to be honest about their timekeeping.  Cheating is addressed elsewhere.  Timekeeping issues such as clock differences between hosts, network latency, and cheating may be addressed in the future by allowing hosts to negotiate a third-party timestamping authority as an intermediary for their Ripple messaging.


[[#host-status]]
'''Host Status'''

At any time they are connected, a host may request another for the status of its protocol support by sending a @@host-status-request@@ message with no body:

[@
{
    "type": "host-status-request"
}
@]

The host receiving such a message must reply immediately with a @@host-status@@ message containing a list of protocol versions and subprotocols of each that it understands.

[@
{
    "type": "host-status",
    "body": [
        {
            "version": "1",
            "subprotocols": [
                "ripple-payment",
                "ripple-routing",
                "ripple-channel",
                "ripple-account",
            ]
        }
    ]
}
@]

[[Protocol/Core Work Page]]