Accounts

Protocol.Accounts History

Hide minor edits - Show changes to output

November 14, 2006, at 10:15 PM by ryan - close account
Changed lines 189-190 from:
To request a copy of an account partner's account data for verification, send an @@account_verify_request@@ message, which has no contents.  The immediate reply must contain the complete account data structure of the node receiving the @@account_verify_request@@ as well as a timestamp:
to:
To request a copy of an account partner's account data for verification, send an @@account_verify_request@@ message containing the account ID: 
Changed lines 193-197 from:
  "account_verify": {
    "timestamp": "2006-11-07 02:11:28.401000",
    "account": {
      ...
    }
to:
  "account_verify_request": {
    "account_id": "550e8400-e29b-41d4-a716-446655440000"
Changed lines 199-205 from:
Neither message nor reply must be signed.

[[#
account-history]]
'''Account History'''

To request from an account partner a list of every signed message that has changed the value of an account field over a certain period, send an @@account_history_request@@
:
to:
The immediate reply must contain the complete account data structure of the node receiving the @@account_verify_request@@ as well as a timestamp:
Changed lines 203-205 from:
  "account_history_request": {
    "starting": "2006-01-01 00:00:00.000000",
    "ending": "2006-11-07 02:11:28.401000"
to:
  "account_verify": {
    "timestamp": "2006-11-07 02:11:28.401000",
    "account": {
     
...
    }
Changed lines 212-215 from:
If the "starting" field is omitted, messages from beginning of the account should be included in the reply.  If the "ending" field is omitted, messages up to the present should be included.

The reply is as follows
:
to:
Neither message nor reply must be signed.

[[#
account-history]]
'''Account History'''

To request from an account partner a list of every signed message that has changed
the value of an account field over a certain period, send an @@account_history_request@@:
Changed lines 221-226 from:
  "account_history": [
    (a chronological order of signed messages sent and received over
   this account during the requested period that have changed a piece
    of shared account data, in the format they were originally sent or
    received, including signatures)
  ]
to:
  "account_history_request": {
    "starting": "2006-01-01 00:00:00.000000",
    "ending": "2006-11-07 02:11:28.401000"
  }
Added lines 228-242:
If the "starting" field is omitted, messages from beginning of the account should be included in the reply.  If the "ending" field is omitted, messages up to the present should be included.

The reply is as follows:

[@
{
  "account_history": [
    (a chronological order of signed messages sent and received over
    this account during the requested period that have changed a piece
    of shared account data, in the format they were originally sent or
    received, including signatures)
  ]
}
@]

Added lines 245-260:
[[#closing-an-account]]
'''Closing an Account'''

To close an account, either party may send an @@account_close@@ message containing the ID of the account to be closed:

[@
{
  "account_close": {
    "request_id": 14590,
    "account_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
@]

An affirmative reply indicates assent to close the account.  An error indicates refusal.  Generally an account may only be closed when the balance is zero.  As a precursor to closing an account that is no longer desired, a node would usually set both credit limits to zero, which would only permit transactions that bring the balance closer to zero.

Changed line 73 from:
   ["note": (string explaining request)]
to:
   "note": (string explaining request)  -- optional
Changed line 87 from:
   ["request_id": (integer),]
to:
   "request_id": (integer),   -- only present on responses to account_requests
Changed line 213 from:
   "ending": "2006-11-07 02:11:28.401000",
to:
   "ending": "2006-11-07 02:11:28.401000"
Added line 217:
Added line 191:
[@
Changed lines 200-201 from:
to:
@]
Added line 209:
[@
Changed line 216 from:
to:
@]
Added line 221:
[@
Changed lines 224-227 from:
   (a chronological order of signed messages sent and received over this account during the requested period that have changed a piece of shared account data, in the format they were originally sent or received, including signatures)
to:
   (a chronological order of signed messages sent and received over
    this account during the requested period that have changed a piece
    of shared account data, in the format they were originally sent or
 
received, including signatures)
Changed lines 229-230 from:
)
to:
}
@]

Deleted lines 57-63:
[[#account-data-ownership]]
'''Account Data Ownership'''

While both nodes must store all shared account data, certain fields will conventionally be owned or controlled by one node or the other.  Specifically, each node generally solely owns its own "node_id", "routing_id", "key", and the other node's "limit".  Ownership of all other fields is generally shared.  Other arrangements are possible, though they are not communicated explicitly.  Instead, ownership is negotiated through account messages and their responses.

Ownership decides the semantics of changing the value of an account field.

Changed lines 63-64 from:
An @@account_request@@ is to request a new account, or to request a change in value to fields over which a node does not have sole ownership.  An @@account_request@@ must be signed unless it only contains account fields that are solely owned by the receiving node.  If a node does not feel it is the sole owner of all account fields in an unsigned @@account-request@@ it received, it should reply with a ''Message must be signed'' error.  (Every owner of a field must sign off on changes to it.)  An implementation may decide to simply sign every @@account-request@@.
to:
An @@account_request@@ is to request a new account, or to request a change to one or more account fields that could not be dictated unilaterally by the requesting node.  An @@account_request@@ must be signed unless the request could in other circumstances be imposed unilaterally by the node receiving the request.  Otherwise, the requesting node must indicate that it gives permission to make the requested changes by signing the @@account_request@@, which allows this permission to be verified at a later date.  If a node receives an unsigned message that it feels ought to be signed, it should reply with a ''Message must be signed'' error.  An implementation may decide to simply sign every @@account-request@@.
Changed lines 80-81 from:
The @@account_set@@ message is to confirm a new account, accept the changes requested in an @@account_request@@, or to declare changes to fields over which a node has sole ownership. An @@account_set@@ must always be signed.
to:
The @@account_set@@ message is to confirm a new account, accept the changes requested in an @@account_request@@, or to unilaterally declare changes to account fields where permitted.  While any arrangement may be negotiated between nodes by trial and error, in general, a node may unilaterally dictate values for its own "node_id", "routing_id", and "key", as well as decreases to either node's credit limit.  Credit limit increases would generally require an @@account-request@@, although when it contains an increase to the other node's limit, the request is better understood as an offer.

An @@account_set@@ must always be signed.
Changed lines 147-148 from:
An affirmative reply means the offer is being held for consideration.  If the offer recipient accepts the offer, his node sends back an @@account_set@@ echoing the request ID and the full account data structure in the request, as well as a timestamp which is the official account creation time.
to:
An affirmative reply means the offer has been understood being held for consideration.  If the offer recipient accepts the offer, his node sends back an @@account_set@@ echoing the request ID and the full account data structure in the request, as well as a timestamp which is the official account creation time.
Added lines 151-157:
[[#identification-of-account-partner]]
'''Identification of Account Partner'''

Ripple has no universal mechanism for positively identifying the owner of another node.  The owner of a node receiving a new account request should confirm the identity of the owner of the requesting node before assigning it a non-zero credit limit.  Even if the node ID in the form "node@host.com" of the requesting node is familiar to the request recipient, one must ensure that the transport layer has verified positively by some means that the request actually comes from the correct host and that the host is trustworthy before relying solely on that piece of information.

The requesting node's owner may put secret, personal, or other information that could help the receiving node's owner identify them, such as a signature with a personal signing key, into the "note" field of the @@account_request@@.

Changed lines 167-174 from:
Case-specific errors:

:
''Field change by account_request only'' : Contains path to field that node receiving an @@account_set@@ deems requires an @@account_request@@ to change, ie, that it owns or shares ownership of the field in question.

: ''Field change by account_set only'' : Contains path to field that node receiving an
@@account_request@@ deems requires a @@account_set@@ to change, ie, that it does not own the field in question.  This error should not be used when the message received contains at least one field that does properly require an @@account_request@@ message.

The account messages, combined with the above two errors, allow nodes to negotiate ownership of account data fields when it differs from convention.

to:
[[#account-change-errors]]
'''Account Change Errors'''

The following errors allow nodes
to negotiate between them what are permissible unilateral changes and what aren't in case of disagreement:

: ''Field change by account_request only'' : Contains path to field that node receiving an @@account_set@@ deems requires an
@@account_request@@ to change in the manner requested.

: ''Unilateral declaration preferred'' : Node receiving an @@account_request@@ deems an @@account_set@@ preferable for the requested change.  (Equally valid is to simply accept the request immediately -- perhaps this error is unnecessary?)

Added lines 186-225:
[[#verifying-account-data]]
'''Verifying Account Data'''

To request a copy of an account partner's account data for verification, send an @@account_verify_request@@ message, which has no contents.  The immediate reply must contain the complete account data structure of the node receiving the @@account_verify_request@@ as well as a timestamp:

{
  "account_verify": {
    "timestamp": "2006-11-07 02:11:28.401000",
    "account": {
      ...
    }
  }
}

Neither message nor reply must be signed.

[[#account-history]]
'''Account History'''

To request from an account partner a list of every signed message that has changed the value of an account field over a certain period, send an @@account_history_request@@:

{
  "account_history_request": {
    "starting": "2006-01-01 00:00:00.000000",
    "ending": "2006-11-07 02:11:28.401000",
  }
}

If the "starting" field is omitted, messages from beginning of the account should be included in the reply.  If the "ending" field is omitted, messages up to the present should be included.

The reply is as follows:

{
  "account_history": [
    (a chronological order of signed messages sent and received over this account during the requested period that have changed a piece of shared account data, in the format they were originally sent or received, including signatures)
  ]
)

This account history may be used as an audit to find the source of any data discrepancies between partners.  This same output may also be taken for each account by a node owner from her own node in order to backup account data or move a node to a different host.

Changed lines 7-9 from:
* an account ID,  which serves as a permanent identifier for the account
to:
Required data:
 
* an account
ID, which serves as a permanent identifier for the account
Changed lines 14-15 from:
* a record of past debits and credits
* the current balance
to:
* a balance for the account
Changed lines 18-19 from:
Unless otherwise specified, all account messages must be signed by the sender's authentication key.
to:
Optional data:

* interest rate, as a decimal
* compounding period, in days
* account agreement, possibly including debt-settlement terms/schedule

Example:
[@
{
  "account": {
    "account_id": "550e8400-e29b-41d4-a716-446655440000",
    "unit": "urn:ripple:units:CAD",
    "precision": 4,
    "initiator": {
      "node_id": "rfugger@ripplepay.com",
      "limit": 100.0000,
      "routing_id": "7136976c-251d-4be4-b6e2-74baf4b4a53c",
      "key": [public key info here],
      "balance": -15.50
    },
    "partner": {
      "node_id": "random@example.com",
      "limit": 200.0000,
      "routing_id": "d699c900-b245-4e3d-a586-eb5743fa24af",
      "key": [public key info here]
    },
    "interest_rate": 0.05,
    "compound_period": 0,
    "agreement": "Both parties agree to pay the outstanding balance in cash on demand.",
}
@]

The JSON structure here is only to show how fields will be addressed in account messages, not to dictate how a node must store its data.  The roles of "initiator" node and "partner" node are determined at account creation time, with the node making the initial account offer being deemed the "initiator".  These roles stay constant for the life of the account, allowing either node to its node ID.

The balance field may appear in either the "initiator" or "partner" node object, and gives the balance from that node's perspective (negative means owing, positive means owed).

Custom data fields may be added to an account as long as their meaning is understood by both nodes.

Generally a node will want to keep a record of all messages necessary to calculate the current balance on the account, including transaction receipts and changes to the account.

[[#account-data-ownership]]
'''Account Data Ownership'''

While both nodes must store all shared account data, certain fields will conventionally be owned or controlled by one node or the other.  Specifically, each node generally solely owns its own "node_id", "routing_id", "key", and the other node's "limit".  Ownership of all other fields is generally shared.  Other arrangements are possible, though they are not communicated explicitly.  Instead, ownership is negotiated through account messages and their responses.

Ownership decides the semantics of changing the value of an account field.

[[#account-messages]]
'''Account Messages'''

There are two primary account messages: @@account_request@@ and @@account_set@@.

An @@account_request@@ is to request a new account, or to request a change in value to fields over which a node does not have sole ownership.  An @@account_request@@ must be signed unless it only contains account fields that are solely owned by the receiving node.  If a node does not feel it is the sole owner of all account fields in an unsigned @@account-request@@ it received, it should reply with a ''Message must be signed'' error.  (Every owner of a field must sign off on changes to it.)  An implementation may decide to simply sign every @@account-request@@.

[@
{
  "account_request": {
    "request_id": (integer),
    "account": {
      "account_id": (string),
      (remaining account data structure containing requested field values)
    },
    ["note": (string explaining request)]
  }
}
@]

To avoid overlap, the "initiator" node uses odd request IDs, and the "partner" node uses even request IDs.  Only those account fields that contain new, non-default values, or are to be changed need to be included.

The @@account_set@@ message is to confirm a new account, accept the changes requested in an @@account_request@@, or to declare changes to fields over which a node has sole ownership.  An @@account_set@@ must always be signed.

[@
{
  "account_set": {
    ["request_id": (integer),]
    "timestamp": (string with format "2006-11-01 15:02:48.780000"),
    "account": {
      "account_id": (string),
      (remaining account data structure containing requested field values)
    },
  }
}
@]

The request ID is only necessary when the @@account_set@@ refers to an earlier request.  In that case, the account fields must be identical to those in the earlier @@account-request@@ with the same request ID.

The timestamp establishes the exact time, measured in [[connection time -> Protocol/Host-LevelMessages#connection-time]], that the changes to the account fields take effect.

Account messages, other than at account-creation time, should only alter one account field at a time unless two or more fields must be altered in atomic fashion.

[[#creating-an-account]]
Changed lines 111-112 from:
Accounts are created by one node offering to accept another's IOUs with an @@offer@@ message containing:
to:
Accounts are created by one node offering to accept another's IOUs with a signed @@account_request@@ message containing:

* a request ID
Deleted line 116:
* time of offer
Changed lines 121-194 from:
* the minimum fee offerer will charge for payments through this account
* some explanatory text to the recipient

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

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

* account ID
* current time and date
* its network address
* the minimum fee sender will charge for payments through this account
* its routing information

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

* incorrect account ID
* offer withdrawn

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

In the case that there is an initial balance agreed upon for the account, a payment should be made
  immediately upon account creation to back up that balance with the proper receipts ([[see Payments -> #payments]]).

'''Changing Credit Limits'''

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

* account ID
* current time and date
*
the address of the node whose credit limit is being changed
*
the new credit limit
* a note describing the request

In
the case of wishing to increase one's partner's credit limit, the request is interpreted as an offer.

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

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

If a node wishes
to decrease either limit, it sends a @@limit@@ message, which is implemented immediately upon acknowledgment.  In this case, the request ID field is not required.  A node may not reject a decreased limit.

If a node receives a request to change the same limit as an existing open limit request, the second request should supercede the first.

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

A node may cancel a limit request by responding to a limit acceptance message with a "request withdrawn" error.

'''Changing Routing Information'''

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

* the new set of routing information

For more information on routing information
, see [[Query Routing -> #query-routing]] below.  The routing information messages do not have to be signed.

'''Changing Network ID'''

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

'''Changing Authentication Key'''

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

[[#verify-account]]
'''Verifying Account Data'''

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

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

Especially important
to verify is the balance.  If there are discrepancies, they will have to be worked out between the node owners.  In future it may be possible to compare payments receipt-by-receipt to find the source of the discrepancy.
to:
* any other optional data fields desired for this account

[@
{
  "account_request": {
    "request_id": 1,

    "account": {
      "account_id": "550e8400-e29b-41d4-a716-446655440000",
      "unit": "urn:ripple:units:CAD",
      "precision": 4
,
     "initiator": {
        "node_id": "rfugger@ripplepay.com",
        "routing_id": "7136976c-251d-4be4-b6e2-74baf4b4a53c",
        "key": [key info here]
,
       "balance": -15.50
     },
      "partner": {
        "node_id": "random@example.com",
        "limit": 200,
 
    },
      "interest_rate": 0.05,
      "compound_period": 0,
 
   "agreement": "Both parties agree to pay any outstanding balance in cash on demand."
    },

    "note": "Let's have an account!"
  }
}
@]

An affirmative reply means the offer is being held for consideration.  If the offer recipient accepts
the offer, his node sends back an @@account_set@@ echoing the request ID and the full account data structure in the request, as well as a timestamp which is the official account creation time.

To indicate that the account has been created, the node receiving the @@account_set@@ responds with an affirmative reply.  If the reply is an error, the account is not created.

[[#changing
-account-data]]
'''Changing Account Data'''

To declare a change
to one or more account data fields, a node sends a signed @@account_set@@ message to its account partner.  An affirmative reply by the other node indicates acceptance of those changes.  An error indicates rejection.

To request a change to one or more account data fields, a node sends an @@account_request@@ message, which need not be signed.  An affirmative reply here only indicates that the request has been understood and is being held for approval.  The reply need not contain any data nor be signed. 

Once the
request is approved, the request recipient sends an @@account-set@@ message echoing back the account fields and values and request ID from the @@account-request@@.  An affirmative reply to the @@account_set@@ completes the change.

Case-specific errors:

: ''Field change by account_request only'' : Contains path
to field that node receiving an @@account_set@@ deems requires an @@account_request@@ to change, ie, that it owns or shares ownership of the field in question.

: ''Field change by account_set only
'' : Contains path to field that node receiving an @@account_request@@ deems requires a @@account_set@@ to change, ie, that it does not own the field in question.  This error should not be used when the message received contains at least one field that does properly require an @@account_request@@ message.

The account messages, combined with the above two errors, allow nodes
to negotiate ownership of account data fields when it differs from convention.

[[#adding-new-fields]]
'''Adding New Fields'''

To add a new data field
to an account, use @@account_set@@ or @@account_request@@ as appropriate.  If the other node does not understand the field, it will reply with an error, and the field may not be added.

[[#changing-keys]]
'''Changing Keys'''

An account message declaring or requesting a key change should be signed by the old key.  Subsequent signed messages must be signed by the new key
.
Added lines 1-109:
!! Accounts

[[Protocol/Accounts Work Page]]

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

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

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

'''Creating an Account'''

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

* an account ID
* the offering node's network ID
* the offering node's routing information
* time of offer
* the units of account
* the number of decimal digits with which to keep this account
* the proposed credit limit for node receiving the offer
* an initial balance for the new account
* the minimum fee offerer will charge for payments through this account
* some explanatory text to the recipient

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

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

* account ID
* current time and date
* its network address
* the minimum fee sender will charge for payments through this account
* its routing information

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

* incorrect account ID
* offer withdrawn

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

In the case that there is an initial balance agreed upon for the account, a payment should be made  immediately upon account creation to back up that balance with the proper receipts ([[see Payments -> #payments]]).

'''Changing Credit Limits'''

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

* account ID
* current time and date
* the address of the node whose credit limit is being changed
* the new credit limit
* a note describing the request

In the case of wishing to increase one's partner's credit limit, the request is interpreted as an offer.

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

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

If a node wishes to decrease either limit, it sends a @@limit@@ message, which is implemented immediately upon acknowledgment.  In this case, the request ID field is not required.  A node may not reject a decreased limit.

If a node receives a request to change the same limit as an existing open limit request, the second request should supercede the first.

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

A node may cancel a limit request by responding to a limit acceptance message with a "request withdrawn" error.

'''Changing Routing Information'''

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

* the new set of routing information

For more information on routing information, see [[Query Routing -> #query-routing]] below.  The routing information messages do not have to be signed.

'''Changing Network ID'''

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

'''Changing Authentication Key'''

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

[[#verify-account]]
'''Verifying Account Data'''

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

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

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

'''Payment Messages'''

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

[[Protocol/Accounts Work Page]]