Account

Protocol.Account History

Hide minor edits - Show changes to output

June 14, 2007, at 08:36 PM by ryan - added entry-id to account-entry
Added line 292:
       "entry-id": (decimal),
Added line 299:
* @@entry-id@@ is to distinguish between the entries on this account (in case an entry gets sent twice, etc.).  Account initiator must use only odd entry-ids, partner must use only evens.
June 14, 2007, at 08:29 PM by ryan - added account-id field to account-entry
Added line 291:
       "account-id": (string),
June 14, 2007, at 07:57 PM by ryan - removed balance from account-entry -- new balance may not be knowable w/ simultaneous entries
Deleted line 292:
       "balance": (decimal),
Deleted line 298:
* @@balance@@ is the new account balance
May 18, 2007, at 06:01 PM by ryan - moved account core stuff over from payment transaction page
Changed lines 3-11 from:
!!Ripple Mutual Credit Accounts

Ripple mutual credit accounts are electronically-kept accounts between two Ripple nodes.  Both nodes keep a copy of the account data, and both share responsibility for maintaining it. 

A mutual credit account can underlie a
Ripple connection by specifying its @@account-id@@ as the @@external-id@@ in the @@payment-account-request@@ that creates the Ripple connection.  Thus, creating a Ripple connection with an underlying mutual-credit account is a two-step process: (1) create the mutual credit account, (2) create the Ripple connection.  The @@unit@@ and @@initiator@@ and @@partner@@ @@node-id@@s fields for the Ripple connection must match those in the mutual credit account.


'''Account Data Structure'''

to:
[[AccountWorkPage]]

!! Account Core

Ripple nodes may connect when one or both accept the other's obligations as valuable.  Connected nodes are said to be neighbours.  A ''neighbour connection'' is a relationship defined by an agreement to participate in
Ripple transactions as neighbours, and does not refer to the messaging connection that may exist from time to time between the neighbouring nodes' hosts, and over which the neighbour relationship takes place.

The Ripple Payment Protocol involves nodes issuing and accepting obligations of a certain value to
and from their neighbours, but doesn't specify how these obligations are recorded or what the terms or limits of these obligations are.  Neighbours must agree on an accounting system that will approve potential transactions and record the balance of committed transactions between them.  One such system is the Ripple Account Protocol.

A neighbour connection consists of nothing other than one or more accounts between the neighbours.  The minimal set of data that must be known by two neighbouring nodes in order to participate in Ripple payments is:

* a Ripple ID for each node
* an account ID
* the unit of account
* an authentication key for each node

The JSON data structure for these core account fields is:

Changed lines 24-26 from:
       "unit": (URI),
        "balance": (decimal),
       "initiator": {
to:
       "account-type": (string),
"unit": (URI),
"initiator": {
Changed lines 28-29 from:
           "key": (public key data structure),
           ("limit": (decimal))
to:
    "key": (public key data structure)
},
"partner": {
   "node-id": (Ripple ID),
    "key": (public key data structure)
Deleted lines 33-41:
       "partner": {
            "node-id": (Ripple ID),
            "key": (public key data structure)
            ("limit": (decimal))
        },
        "precision": (integer),
        "interest-rate": (decimal),
        "last-interest": (date/time),
        "agreement": (string)
Changed lines 38-40 from:

Account Request

to:
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 change its node ID. 

[[Account types are described below -> #account-types]].  Different account types will have various other fields in addition to the core fields listed above.

[[#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 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 63-66 from:


Account Set

to:
@]

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 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 85-89 from:

Nodes may directly set their own keys and reduce their own limits using @@account-set@@.  Other modifications require an @@account-request@@ to obtain the other node's approval.  @@Balance@@ and @@last-interest@@ may only be modified by @@account-entry@@ below.  A change to the interest rate should be followed immediately by an @@account-entry@@ settling the outstanding interest at the former rate, with an identical timestamp as the @@account-set@@ that changed the interest rate.


Account Entry
to:
@]

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

[[#establishing-an-account]]
'''Establishing an Account'''

Accounts are established by a signed @@account-request@@ message sent between potential or existing neighbours containing the basic information for the account:

* a request ID
* an account ID
* the offering node's network ID
* the units of account

Example:
[@
Changed lines 106-109 from:
   "type": "account-entry",
    "to": (string),
    "from": (string),
    "time": (date/time),
to:
   "type": "account-request",
    "to": "random",
    "from": "rfugger",
    "request-id": 1,
    "
time": "2007-04-01 15:53:41.537449",
Changed lines 112-114 from:
       "amount": (decimal),
        ("interest": (decimal),)
       "balance": (decimal),
to:
       "account": {
            "account-id": "550e8400-e29b-41d4-a716-446655440000",
            "unit": "urn:ripple:units:CAD"
,
            "external-id": "120489",
            "initiator": {
                "node-id": "rfugger@ripplepay.com",
            "key": (...),
            },
            "partner": {
                "node-id": "random@example.com",
            }
        },
        "note": "Let's have an account!"
Changed lines 127-135 from:

* @@amount@@ is amount that @@from@@ node's balance is decreased (ie, @@from@@ pays to @@to@@)
* @@interest@@ is interest accumulated since @@last-interest@@ date, also given as amount that @@from@@ node's balance is decreased.  If this field is included, @@last-interest@@ is set to the entry @@time@@.
* @@balance@@ is the new account balance
* all amounts must be given to the number of decimal places specified in account @@precision@@


Account Verify Request

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.

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.

[[#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 message signed with a personal signing key, into the @@note@@ field of the @@account-request@@.

[[#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.  An affirmative reply here only indicates that the request has been understood and is being held for approval. 

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.

[[#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?)

[[#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.

[[#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 containing the account ID: 

Example:
[@
Changed lines 176-182 from:
    "type": "account-verify-request",
   
"to": (string),
    "from": (string),
    "request-id": (integer),
    "body": {
        "account-id": (string)
 
  }
to:
  "account-verify-request": {
   
"account-id": "550e8400-e29b-41d4-a716-446655440000"
  }
Changed lines 180-183 from:


Account Verify

to:
@]

The immediate reply must contain the complete account data structure of the node receiving the @@account-verify-request@@ as well as a timestamp:

Example:
[@
Changed lines 187-194 from:
    "type": "account-verify",
   
"to": (string),
   "from": (string),
    "request-id": (integer),
    "time": (date/time),
    "body": {
        "account": {
     
      (...)
to:
  "account-verify": {
   
"timestamp": "2006-11-07 02:11:28.401000",
    "account": {
      (...)
Added line 192:
  }
Changed lines 194-197 from:


Account History Request

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@@:

Example:
[@
Changed lines 206-214 from:
    "type": "account-history-request",
   
"to": (string),
   "from": (string),
    "request-id"
: (integer),
    "body": {
        "account-id": (string),
        "start": (date/time),
        "end": (date/time)
 
  }
to:
  "account-history-request": {
   
"starting": "2006-01-01 00:00:00.000000",
    "ending": "2006-11-07 02:11:28.401000"
  }
Changed lines 211-214 from:


Account History

to:
@]

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:

[@
Changed lines 219-228 from:
    "type": "account-history",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "body": [
        (
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": [
    (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 226-229 from:


Account Close

to:
@]

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.

[[#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:

Example:
[@
Changed lines 238-244 from:
    "type": "account-close",
    "to": (string),
   
"from": (string),
    "request-id": (integer),
    "body": {
        "account-id": (string)
 
  }
to:
  "account-close": {
   
"request-id": 14590,
    "account-id": "550e8400-e29b-41d4-a716-446655440000"
  }
Added lines 243-319:
@]

An affirmative reply indicates assent to close the account.  An error indicates refusal.


[[#account-types]]
!! Account Types

!!! Ripple Mutual Credit Account

Ripple mutual credit accounts are electronically-kept accounts between two Ripple nodes.  Both nodes keep a copy of the account data, and both share responsibility for maintaining it. 

'''Account Data Structure'''

[@
{
    "account": {
        "account-id": (string),
        "account-type": "ripple-mutual",
        "unit": (URI),
        "balance": (decimal),
        "initiator": {
            "node-id": (Ripple ID),
            "key": (public key data structure),
            ("limit": (decimal))
        },
        "partner": {
            "node-id": (Ripple ID),
            "key": (public key data structure)
            ("limit": (decimal))
        },
        "precision": (integer),
        "interest-rate": (decimal),
        "last-interest": (date/time),
        "agreement": (string)
    }
}
@]

Nodes may directly set their own keys and reduce their own limits using @@account-set@@.  Other modifications require an @@account-request@@ to obtain the other node's approval.  @@Balance@@ and @@last-interest@@ may only be modified by @@account-entry@@ below.  A change to the interest rate should be followed immediately by an @@account-entry@@ settling the outstanding interest at the former rate, with an identical timestamp as the @@account-set@@ that changed the interest rate.

[@
{
    "type": "account-entry",
    "to": (string),
    "from": (string),
    "time": (date/time),
    "body": {
        "amount": (decimal),
        ("interest": (decimal),)
        "balance": (decimal),
    }
}
@]

* @@amount@@ is amount that @@from@@ node's balance is decreased (ie, @@from@@ pays to @@to@@)
* @@interest@@ is interest accumulated since @@last-interest@@ date, also given as amount that @@from@@ node's balance is decreased.  If this field is included, @@last-interest@@ is set to the entry @@time@@.
* @@balance@@ is the new account balance
* all amounts must be given to the number of decimal places specified in account @@precision@@

An @@account-entry@@ must be sent when a promise is redeemed with a receipt in the payment transaction.


!!! External Account

Extra field: @@"external-id": (string)@@

Example: bank account, where one partner (the bank) handles all the accounting in a pre-existing external mechanism.


!!! i-WAT Account

[[See the i-WAT page -> http://www.media-art-online.org/iwat/]].

Keys are i-WAT keys, Ripple transactions are completed using i-WAT value transfers. 

[[AccountWorkPage]]
Added lines 1-2:
Subprotocol name: @@ripple-account@@.
Added lines 1-159:
!!Ripple Mutual Credit Accounts

Ripple mutual credit accounts are electronically-kept accounts between two Ripple nodes.  Both nodes keep a copy of the account data, and both share responsibility for maintaining it. 

A mutual credit account can underlie a Ripple connection by specifying its @@account-id@@ as the @@external-id@@ in the @@payment-account-request@@ that creates the Ripple connection.  Thus, creating a Ripple connection with an underlying mutual-credit account is a two-step process: (1) create the mutual credit account, (2) create the Ripple connection.  The @@unit@@ and @@initiator@@ and @@partner@@ @@node-id@@s fields for the Ripple connection must match those in the mutual credit account.


'''Account Data Structure'''

[@
{
    "account": {
        "account-id": (string),
        "unit": (URI),
        "balance": (decimal),
        "initiator": {
            "node-id": (Ripple ID),
            "key": (public key data structure),
            ("limit": (decimal))
        },
        "partner": {
            "node-id": (Ripple ID),
            "key": (public key data structure)
            ("limit": (decimal))
        },
        "precision": (integer),
        "interest-rate": (decimal),
        "last-interest": (date/time),
        "agreement": (string)
    }
}
@]


Account Request

{
    "type": "account-request",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "body": {
        "account": {
            "account-id": (string),
            (remaining account data structure containing requested field values)
        },
        ("note": (string))
    }
}


Account Set

{
    "type": "account-set",
    "to": (string),
    "from": (string),
    ("request-id": (integer),)
    "time": (date/time string),
    "body": {
        "account": {
            "account-id": (string),
            (remaining account data structure containing requested field values)
        },
    }
}

Nodes may directly set their own keys and reduce their own limits using @@account-set@@.  Other modifications require an @@account-request@@ to obtain the other node's approval.  @@Balance@@ and @@last-interest@@ may only be modified by @@account-entry@@ below.  A change to the interest rate should be followed immediately by an @@account-entry@@ settling the outstanding interest at the former rate, with an identical timestamp as the @@account-set@@ that changed the interest rate.


Account Entry
{
    "type": "account-entry",
    "to": (string),
    "from": (string),
    "time": (date/time),
    "body": {
        "amount": (decimal),
        ("interest": (decimal),)
        "balance": (decimal),
    }
}

* @@amount@@ is amount that @@from@@ node's balance is decreased (ie, @@from@@ pays to @@to@@)
* @@interest@@ is interest accumulated since @@last-interest@@ date, also given as amount that @@from@@ node's balance is decreased.  If this field is included, @@last-interest@@ is set to the entry @@time@@.
* @@balance@@ is the new account balance
* all amounts must be given to the number of decimal places specified in account @@precision@@


Account Verify Request

{
    "type": "account-verify-request",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "body": {
        "account-id": (string)
    }
}


Account Verify

{
    "type": "account-verify",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "time": (date/time),
    "body": {
        "account": {
            (...)
    }
}


Account History Request

{
    "type": "account-history-request",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "body": {
        "account-id": (string),
        "start": (date/time),
        "end": (date/time)
    }
}


Account History

{
    "type": "account-history",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "body": [
        (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)
    ]
}


Account Close

{
    "type": "account-close",
    "to": (string),
    "from": (string),
    "request-id": (integer),
    "body": {
        "account-id": (string)
    }
}