0015 XLS-15d: Concise Transaction Identifier #34
Replies: 8 comments 15 replies
-
Very useful to point eg. with a issued currency HEX code (#30) to a transaction containing memo with more information about the token (@RareData, @nixer89). A change I'd like to propose is to switch from |
Beta Was this translation helpful? Give feedback.
-
This format seems to conflate two different goals: a "compact" encoding for code purposes, and a "compact" encoding for human purposes. Why not use two? Using your example, here's what it would look like for human consumption: xrpl://cti/62090589-9 For the compact 64-bit encoding, useful to machines, I'd recommend 4 bytes for the ledger sequence followed by the 3 low bytes of the sequence number. The last byte can be a CRC8 over the previous 7 bytes, if you're so inclined. |
Beta Was this translation helpful? Give feedback.
-
Referring to transactions to store e.g. a token payload is great, however it will only live for as long as full history is available. Where “live” ledger objects persistent, the transaction history can be lost, hence invalidating the reference? It’s not a major concern, as the standards discussed here and in the NFT thread is focusing on ways to implement NFTs without amending the XRPL – so the outcome will be an agreed upon standard of how to do it, and not a “real” XRPL feature. |
Beta Was this translation helpful? Give feedback.
-
Since the first hex nibble is only affected by the first four bits of ledger hash and the first four bits of transaction hash, it seems there is a risk of a transcription error since it is not a checksum over the entire data. It may make sense to use something like the Luhn algorithm (which is used in credit card numbers) so that any single digit error is caught. |
Beta Was this translation helpful? Give feedback.
-
Alternatively, Bech32 is a little more compact. |
Beta Was this translation helpful? Give feedback.
-
I don't know if that's a very safe assumption. Sure, we're nowhere near that level today, but there's no telling how things may change in the future. |
Beta Was this translation helpful? Give feedback.
-
Having now read this spec and the several comments, I agree that the 64k limitation on transactions per ledger is likely a non-issue today but "feels" problematic nonetheless. Since we're still discussing this, let's weigh the positives of a slightly more complex format: Proposed alternativePart of my goal was to ensure that any tx which has a valid CTI under the original proposal (i.e. has a 64-bit encoding) the resulting encoding under this scheme would also be under 64 bits. In other words, we want to fit the resulting CTI in 64 bits for any currently representable ledger, where the transaction index is less than 65536. In crude ASCII, the proposed format looks like this:
This will fit in 64 Small caveat: we need a simple rule to ensure there is a canonical format (that is, the same tx can't be represented by two CTIs):
Example:Your example was CTI resides in ledger 62084722, has a transaction index of 25, the transaction hash's first nibble is 1 and the ledger hash's first nibble is F. Encoded with my scheme, would produce:
Let's compare the CTIs produced by the two encodings:
DownsideOnce parsed into a 64-bit This downside can be addressed by ensuring that the transaction index is always represented as two bytes. Of course, this makes the "overlong" checker slightly more complex. Still, it may be worth the effort. RepresentationDecimal. I still think hex is, generally, more compact and (imo) easier to parse, but I think decimal is the way to go for the reasons @RichardAH highlights. |
Beta Was this translation helpful? Give feedback.
-
@RichardAH liked the proposed extensions to the format, but he also noticed that with a mild massaging of the fields, my proposal could be backwards-compatible with existing CTIs. He's going to make those changes in the proposed standard. A win, all-around! |
Beta Was this translation helpful? Give feedback.
-
Change Log
This standard was amended on 25th March 2021:
XLS15.1
control byte
to the most significant byte position.Control byte
may be absent in which case assumed to be 0x00 for backwards compatibility.Current Identifiers
Transactions in the XRPL ecosystem are identified using the namespace-biased SHA512-half of their canonical byte-wise serialisation [1] whether or not the transaction has been submitted to consensus.
Ledgers are also identified by hashes. [2] However provided there is a human consensus about validation (sufficient UNL overlap) ledgers may instead be identified by their 4 byte sequence number. [3]
Transactions are recorded in the protocol-defined canonical order within each ledger. [4] This ordering means each transaction has a sequence number within the ledger. This offset is present in the transaction metadata as
TransactionIndex
.[5]It may be useful in a range of applications to be able to uniquely identify a transaction by the point at which it was validated rather than by its explicit contents. Thus for an unvalidated (unsubmitted or locally rejected) transaction this type of identifier would not apply.
New Identifier: Concise Transaction Identifier
At time of the publication we assume for the foreseeable future that there will not be more than 65535 transactions in a given ledger. Therefore we can uniquely identify a txn within a ledger with a 2 byte integer, and we can uniquely identify the ledger by its 4 byte sequence number. Thus a 6 byte number uniquely identifies a validated transaction.
To prevent transcription errors (and to provide some validation for the contents) the first hex nibble of the ledger's canonical hash and the first hex nibble of the transaction's canonical hash are included in byte position 0, bringing the total number of bytes to 7. This is referred to a the checksum byte.
To future-proof this format an additional, optional, 7 bit control byte may be prepended to these 7 bytes. If this control byte is absent then it is assumed to be 0x00 which is referred to as the simple case. This is a change introduced in XLS15.1, and is strictly backwards compatible with existing CTIs.
The control byte (if set) allows the CTI to identify a transaction in:
TransactionIndex
LedgerSequence
In the simple case the CTI fits neatly and unambiguously in a positive signed 64 bit integer. In the advanced case, depending on which options are selected a big number may be required to store and process the CTI.
CTI Format — Simple Case
Must be handled by all implementations.
<first four bits of ledger hash> <first four bits of transaction hash>
<16 bit TransactionIndex>
<32 bit LedgerSequence>
CTI Format — Advanced Case
Required for implementations that need to handle non-mainnet transactions or for "fully future-proofed implementations", otherwise optional.
<reserved 00> <T double-wide txn bit> <L double-wide lgr bit> <four bits of network id>
<first four bits of ledger hash> <first four bits of transaction hash>
simple case
above.T double-wide txn bit
, when1
, doubles the size of theTransactionIndex
field.L double-wide lgr bit
, when1
, doubles the size of theLedgerSequence
field.Taken together the two double-wide bits inform the parsing application how to proceed:
Case 1: Normal Field Sizes
TL = 00
<16 bit TransactionIndex>
<32 bit LedgerSequence>
Case 2: Double wide LedgerSequence
TL = 01
<16 bit TransactionIndex>
<64 bit LedgerSequence>
Case 3: Double-wide TransactionIndex
TL = 10
<32 bit TransactionIndex>
<32 bit LedgerSequence>
Case 4: Double-wide TransactionIndex and LedgerSequence
TL = 11
<32 bit TransactionIndex>
<64 bit LedgerSequence>
Network IDs
Canonical Presentation
To prevent copy-paste errors and non-canonical CTIs, presentation of CTIs to end users must be in decimal without leading zeros. The only allowable characters in a presented CTI are
[0-9]
.In the case of an advanced CTI the smallest possible way to describe the transaction is always the Canonical CTI. Thus if
double-wide
bits are set but the high bytes of those fields are0x00
then this is a non-canonical and therefore an invalid CTI. Any implementation that handlesadvanced case
CTIs must identify this.Examples—Simple Case
This randomly selected transaction: 1C0FA22BBF5D0A8A7A105EB7D0AD7A2532863AA48584493D4BC45741AEDC4826
1
F
Thus this transaction in CTI format encodes to
67835576823535218
F1001903B35672
xrpl://cti/67835576823535218
Another randomly selected transaction AE1C4AD620251CA97C320052A5B9755CD002B5FBDBECC9A49F088FD58B71A44E
43347185130237277
You can resolve these CTIs right now: cti-resolver
CTI Reference Implementations—Simple Case
In C:
In JS:
RH Note: Advanced case (XLS15.1) examples and reference implementations to be added shortly
Beta Was this translation helpful? Give feedback.
All reactions