Files
rippled/BinaryFormats.txt
2011-12-06 21:25:44 -08:00

155 lines
5.4 KiB
Plaintext

All signed or hashed objects must have well-defined binary formats at the
byte level. These formats do not have to be the same as the network wire
formats or the forms used for efficient storage or human display. However,
it must always be possible to precisely re-create, byte for byte, any signed
or hashed object. Otherwise, the signatures or hashes cannot be validated.
All 32-byte hashes are the first 32-bytes of a SHA512 hash (in little-endian
format). This is chosen because SHA512 is 33% faster than SHA256 on modern
hardware.
Note that it is not required the objects be stored or transmitted in these
formats. They are only required to be put in these formats when computing or
validating hashes or signatures.
Sadly, Google's protocol buffers are not suitable for the inner portions of
signed or hashed objects.
For signatures, the object is always prefixed with a 4-byte object type.
This prevents a malicious entity from presenting a signed object of one type
as an object of another type, for which the signature would be valid.
Note: Signed blocks that exceed the length in this specification should be
accepted and the extraneous information ignored. Nodes may opt to ignore
objects they consider abusively long (a 1KB transaction, for example).
1) Account ID
An account starts as an ECDSA public key (X,Y), SECP256K1. Private keys are
279 bytes, public keys are normally 65 bytes, signatures are 72 bytes. We
use public keys in compressed form using
EC_KEY_set_conv_form(POINT_CONVERSION_COMPRESS) -- so our public keys are
actually 33 bytes.
Account IDs are based on the compressed public key. Apply SHA512 to the
33-byte public key. Apply RIPEMD160 to the first 256 bits of the result.
The resulting 20-byte value is the account ID.
Keeping with the Bitcoin tradition, unsigned 160-bit and 256-bit integers
(hashes, transaction IDs, account IDs) are sent in little-endian format.
2) Transaction (source/signed format) 145-bytes
Fields:
1) 20-byte destination account
2) 8-byte amount, unsigned BE integer
3) 4-byte source account sequence number, unsigned BE integer
4) 4-byte source ledger index, unsigned BE integer
5) 4-byte arbitrary source tag, unsigned BE integer
6) 33-byte source public key
8) 72-byte prefix 0x54584E00 signature of 73-byte contents of fields 1-6
The transaction ID is the first 256-bits of the SHA512 hash of the 145 byte
signed transaction.
3) Ledger (signed format) - 192 bytes
Fields:
1) 4-byte ledger index, unsigned BE integer
2) 8-byte fees held, unsigned BE integer
3) 32-byte hash of previous ledger
4) 32-byte hash of root of the transaction tree for this ledger
5) 32-byte hash of root of the account tree for this ledger
6) 8-byte closing timestamp
7) Signature: Prefix (0x4C475000) of 116 byte fields 1-6
4) Account status (ledger format)
Fields:
1) 20-byte Account ID
2) 8-byte account balance, unsigned BE integer
3) 4-byte account sequence, unsigned BE integer
5) Non-Leaf Tree Node
Contains 32 hashes, each 20-bytes. They correspond to hashes of the nodes
for the 32 possible values of the *first* 5 bits of the *next* byte of the
hash. By convention, an empty node has a hash of zero.
6) Leaf Node
Contains every item in this node, sorted in order of increasing tags
(Elements that start with a zero byte come first.) In practice, this
will be exactly one item. You'd need a quadrillion entries before two
wound up in the same leaf.
By convention, an empty leaf node has a hash of all zero bytes.
For a transaction, the tag is the transaction ID (hash of the transaction
data). For an account state, the tag is the 20-byte account ID.
Transaction Leaf Node Fields:
1) 32-byte Transaction ID (LE)
2) 2-byte Length, 153 (145+8)
3) 145-byte Transaction in signed format
4) 8-byte fees held, unsigned BE integer
Account State Leaf Node Fields:
1) 32-byte Account ID (20-byte ID zero-extended, in LE format)
2) 2-byte length (32)
3) 32-byte account status in ledger format
7) Propose ledger:
1) 4-byte closing ledger sequence number
2) 4-byte seconds since ledger close time
3) 32-byte previous ledger hash
4) 32-byte current ledger hash
5) Zero or more transaction change objects (optional) each:
32-byte transaction ID
1-byte operation (0=removed, 1=added)
6) 20-byte hanko of signing node
7) 72-byte prefix 0x41564C00 signature of above
8) Contact block
These are used to pass node contact information around the network and are
signed so nodes can prove they are operational.
Fields:
1) 64-byte node public key
2) 4-byte software version
3) 4-byte minimum supported version
4) 8-byte node flags (to be defined)
5) 8-byte timestamp (seconds since 1/1/70)
6) Node Info Block
7) Prefixed (0x4E4F4400) signature of fields 1-6 above.
The node info block consists of one or more node info elements. Each element
consists of a 1-byte element type, a 3-byte element length, and the element
data. Four zero bytes marks the end of the node info block. The following
element types are defined:
0 = IPv4 Contact Information (4-byte address, 2-byte port)
1 = IPv6 Contact Information (16-byte address, 2-byte port)
2 = Node Name
3 = Organization Name
4 = Node Certificate
5 = URL
6 = Admin Email
7 = Node Policy URL
8 = Transitive Trust (20-byte node hanko, 1-byte trust type)
A node *must* ignore unknown element types. Fixed-length element types may
contain more than one value in a single element. For example, you can put
two IP/port combos in a single type 0 element of length 4+12.