Skip to content

Commit 488608a

Browse files
committed
lint
1 parent a00dead commit 488608a

File tree

3 files changed

+336
-169
lines changed

3 files changed

+336
-169
lines changed
Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# Quickstart
2-
## Improved Concise Transaction Identifier (CTID)
1+
# Quickstart
2+
3+
## Improved Concise Transaction Identifier (CTID)
34

45
CTIDs are composed of 16 hex nibbles, and begin with a `C`.
56

@@ -9,55 +10,63 @@ CXXXXXXXYYYYZZZZ
910

1011
The identifier is divided into three fields.
1112

12-
Char Offset | Field | Size (bits) |Explanation
13-
-|-----|------|---------
14-
0 | C| 4 | Lead-in (ignore)
15-
1-7 | XXXXXXX | 28 | Ledger Sequence
16-
8-11 | YYYY | 16 | Transaction index (offset) within that ledger
17-
12-16 | ZZZZ | 16 | Network ID.
13+
| Char Offset | Field | Size (bits) | Explanation |
14+
| ----------- | ------- | ----------- | --------------------------------------------- |
15+
| 0 | C | 4 | Lead-in (ignore) |
16+
| 1-7 | XXXXXXX | 28 | Ledger Sequence |
17+
| 8-11 | YYYY | 16 | Transaction index (offset) within that ledger |
18+
| 12-16 | ZZZZ | 16 | Network ID. |
1819

1920
Reference implementations are available for several languages. Click below to dive in.
2021

21-
Language | Implementation
22-
-|-
23-
Javascript | [ctid.js](https://github.com/XRPLF/ctid/blob/main/ctid.js)
24-
Typescript | [ctid.ts](https://github.com/XRPLF/ctid/blob/main/ctid.ts)
25-
C++ | [ctid.cpp](https://github.com/XRPLF/ctid/blob/main/ctid.cpp)
26-
Python 3| [ctid.py](https://github.com/XRPLF/ctid/blob/main/ctid.py)
27-
PHP 5|[ctid.php](https://github.com/XRPLF/ctid/blob/main/ctid.php)
28-
22+
| Language | Implementation |
23+
| ---------- | ------------------------------------------------------------ |
24+
| Javascript | [ctid.js](https://github.com/XRPLF/ctid/blob/main/ctid.js) |
25+
| Typescript | [ctid.ts](https://github.com/XRPLF/ctid/blob/main/ctid.ts) |
26+
| C++ | [ctid.cpp](https://github.com/XRPLF/ctid/blob/main/ctid.cpp) |
27+
| Python 3 | [ctid.py](https://github.com/XRPLF/ctid/blob/main/ctid.py) |
28+
| PHP 5 | [ctid.php](https://github.com/XRPLF/ctid/blob/main/ctid.php) |
2929

3030
### Function prototypes (pseudocode)
31+
3132
In this repo there are several reference implementations available for various languages but they all use the same function model.
33+
3234
```js
3335
function encodeCTID (
3436
ledger_seq : number,
3537
txn_index : number,
3638
network_id : number) -> string;
3739
```
40+
3841
```js
39-
function decodeCTID (ctid : string or number) -> {
42+
function decodeCTID (ctid : string or number) -> {
4043
ledger_seq : number,
4144
txn_index : number,
4245
network_id : number };
4346
```
4447

4548
### Mainnet example
49+
4650
[This transaction](https://livenet.xrpl.org/transactions/D42BE7DF63B4C12E5B56B4EFAD8CBB096171399D93353A8A61F61066160DFE5E/raw) encodes in the following way:
51+
4752
```js
4853
encodeCTID(
4954
77727448, // ledger sequence number the txn appeared in
50-
54, // `TransactionIndex` as per metadata
51-
0) // Network ID of mainnet is 0
52-
'C4A206D800360000'
55+
54, // `TransactionIndex` as per metadata
56+
0,
57+
); // Network ID of mainnet is 0
58+
("C4A206D800360000");
5359
```
5460

5561
### Hooks testnet v3 example
62+
5663
[This transaction](https://hooks-testnet-v3-explorer.xrpl-labs.com/tx/C4E284010276F8457C4BF96D0C534B7383087680C159F9B8C18D5EE876F7EFE7) encodes in the following way:
64+
5765
```js
5866
encodeCTID(
5967
428986, // ledger sequence number the txn appeared in
60-
0, // `TransactionIndex` as per metadata
61-
21338) // Network ID of hooks v3 is 21338
62-
'C0068BBA0000535A'
68+
0, // `TransactionIndex` as per metadata
69+
21338,
70+
); // Network ID of hooks v3 is 21338
71+
("C0068BBA0000535A");
6372
```
Lines changed: 171 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,200 @@
11
const encodeCTID = (ledger_seq, txn_index, network_id) => {
2-
if (typeof(ledger_seq) != 'number')
2+
if (typeof ledger_seq != "number")
33
throw new Error("ledger_seq must be a number.");
4-
if (ledger_seq > 0xFFFFFFF || ledger_seq < 0)
5-
throw new Error("ledger_seq must not be greater than 268435455 or less than 0.");
4+
if (ledger_seq > 0xfffffff || ledger_seq < 0)
5+
throw new Error(
6+
"ledger_seq must not be greater than 268435455 or less than 0.",
7+
);
68

7-
if (typeof(txn_index) != 'number')
9+
if (typeof txn_index != "number")
810
throw new Error("txn_index must be a number.");
9-
if (txn_index > 0xFFFF || txn_index < 0)
11+
if (txn_index > 0xffff || txn_index < 0)
1012
throw new Error("txn_index must not be greater than 65535 or less than 0.");
1113

12-
if (typeof(network_id) != 'number')
14+
if (typeof network_id != "number")
1315
throw new Error("network_id must be a number.");
14-
if (network_id > 0xFFFF || network_id < 0)
15-
throw new Error("network_id must not be greater than 65535 or less than 0.");
16-
17-
return ((BigInt(0xC0000000) +
18-
(BigInt(ledger_seq)) << 32n) +
19-
(BigInt(txn_index) << 16n) +
20-
BigInt(network_id)).toString(16).toUpperCase();
16+
if (network_id > 0xffff || network_id < 0)
17+
throw new Error(
18+
"network_id must not be greater than 65535 or less than 0.",
19+
);
20+
21+
return (
22+
((BigInt(0xc0000000) + BigInt(ledger_seq)) << 32n) +
23+
(BigInt(txn_index) << 16n) +
24+
BigInt(network_id)
25+
)
26+
.toString(16)
27+
.toUpperCase();
2128
};
2229

23-
2430
const decodeCTID = (ctid) => {
2531
let ctidValue;
26-
if (typeof(ctid) === 'string')
27-
{
32+
if (typeof ctid === "string") {
2833
if (!/^[0-9A-F]+$/.test(ctid))
2934
throw new Error("ctid must be a hexadecimal string or BigInt");
3035

3136
if (ctid.length !== 16)
3237
throw new Error("ctid must be exactly 16 nibbles and start with a C");
3338

34-
ctidValue = BigInt('0x' + ctid);
35-
}
36-
else if (typeof(ctid) === 'bigint')
37-
ctidValue = ctid;
38-
else
39-
throw new Error("ctid must be a hexadecimal string or BigInt");
39+
ctidValue = BigInt("0x" + ctid);
40+
} else if (typeof ctid === "bigint") ctidValue = ctid;
41+
else throw new Error("ctid must be a hexadecimal string or BigInt");
4042

41-
if (ctidValue > 0xFFFFFFFFFFFFFFFFn ||
42-
(ctidValue & 0xF000000000000000n) != 0xC000000000000000n)
43+
if (
44+
ctidValue > 0xffffffffffffffffn ||
45+
(ctidValue & 0xf000000000000000n) != 0xc000000000000000n
46+
)
4347
throw new Error("ctid must be exactly 16 nibbles and start with a C");
4448

45-
const ledger_seq = Number((ctidValue >> 32n) & 0xFFFFFFFn);
46-
const txn_index = Number((ctidValue >> 16n) & 0xFFFFn);
47-
const network_id = Number(ctidValue & 0xFFFFn);
49+
const ledger_seq = Number((ctidValue >> 32n) & 0xfffffffn);
50+
const txn_index = Number((ctidValue >> 16n) & 0xffffn);
51+
const network_id = Number(ctidValue & 0xffffn);
4852
return {
4953
ledger_seq,
5054
txn_index,
51-
network_id
55+
network_id,
5256
};
5357
};
5458

5559
// NOTE TO DEVELOPER:
5660
// you only need the two functions above, below are test cases for nodejs, if you want them.
57-
if (typeof(window) === 'undefined' && typeof(process) === 'object')
58-
{
59-
console.log("Running test cases...");
60-
// Test cases For encodeCTID
61-
const assert = require('assert');
62-
63-
// Test case 1: Valid input values
64-
assert.equal(encodeCTID(0xFFFFFFF, 0xFFFF, 0xFFFF), "CFFFFFFFFFFFFFFF");
65-
assert.equal(encodeCTID(0, 0, 0), "C000000000000000");
66-
assert.equal(encodeCTID(1, 2, 3), "C000000100020003");
67-
assert.equal(encodeCTID(13249191, 12911, 49221), "C0CA2AA7326FC045");
68-
69-
// Test case 2: ledger_seq greater than 0xFFFFFFF
70-
assert.throws(() => encodeCTID(0x10000000, 0xFFFF, 0xFFFF), /ledger_seq must not be greater than 268435455 or less than 0./);
71-
assert.throws(() => encodeCTID(-1, 0xFFFF, 0xFFFF), /ledger_seq must not be greater than 268435455 or less than 0./);
72-
73-
// Test case 3: txn_index greater than 0xFFFF
74-
assert.throws(() => encodeCTID(0xFFFFFFF, 0x10000, 0xFFFF), /txn_index must not be greater than 65535 or less than 0./);
75-
assert.throws(() => encodeCTID(0xFFFFFFF, -1, 0xFFFF), /txn_index must not be greater than 65535 or less than 0./);
76-
77-
// Test case 4: network_id greater than 0xFFFF
78-
assert.throws(() => encodeCTID(0xFFFFFFF, 0xFFFF, 0x10000), /network_id must not be greater than 65535 or less than 0./);
79-
assert.throws(() => encodeCTID(0xFFFFFFF, 0xFFFF, -1), /network_id must not be greater than 65535 or less than 0./);
80-
81-
// Test cases For decodeCTID
82-
83-
// Test case 5: Valid input values
84-
assert.deepEqual(decodeCTID("CFFFFFFFFFFFFFFF"), { ledger_seq: 0xFFFFFFF, txn_index: 0xFFFF, network_id: 0xFFFF });
85-
assert.deepEqual(decodeCTID("C000000000000000"), { ledger_seq: 0, txn_index: 0, network_id: 0 });
86-
assert.deepEqual(decodeCTID("C000000100020003"), { ledger_seq:1, txn_index: 2, network_id: 3 });
87-
assert.deepEqual(decodeCTID("C0CA2AA7326FC045"), { ledger_seq:13249191, txn_index: 12911, network_id: 49221 });
88-
89-
// Test case 6: ctid not a string or big int
90-
assert.throws(() => decodeCTID(0xCFF), /ctid must be a hexadecimal string or BigInt/);
91-
92-
// Test case 7: ctid not a hexadecimal string
93-
assert.throws(() => decodeCTID("C003FFFFFFFFFFFG"), /ctid must be a hexadecimal string or BigInt/);
94-
95-
// Test case 8: ctid not exactly 16 nibbles
96-
assert.throws(() => decodeCTID("C003FFFFFFFFFFF"), /ctid must be exactly 16 nibbles and start with a C/);
97-
98-
// Test case 9: ctid too large to be a valid CTID value
99-
assert.throws(() => decodeCTID("CFFFFFFFFFFFFFFFF"), /ctid must be exactly 16 nibbles and start with a C/);
100-
101-
// Test case 10: ctid doesn't start with a C nibble
102-
assert.throws(() => decodeCTID("FFFFFFFFFFFFFFFF"), /ctid must be exactly 16 nibbles and start with a C/);
103-
104-
// the same tests again but using bigint instead of string
105-
//
106-
107-
// Test case 11: Valid input values
108-
assert.deepEqual(decodeCTID(0xCFFFFFFFFFFFFFFFn), { ledger_seq: 0xFFFFFFF, txn_index: 0xFFFF, network_id: 0xFFFF });
109-
assert.deepEqual(decodeCTID(0xC000000000000000n), { ledger_seq: 0, txn_index: 0, network_id: 0 });
110-
assert.deepEqual(decodeCTID(0xC000000100020003n), { ledger_seq:1, txn_index: 2, network_id: 3 });
111-
assert.deepEqual(decodeCTID(0xC0CA2AA7326FC045n), { ledger_seq:13249191, txn_index: 12911, network_id: 49221 });
112-
113-
// Test case 12: ctid not exactly 16 nibbles
114-
assert.throws(() => decodeCTID(0xC003FFFFFFFFFFFn), /ctid must be exactly 16 nibbles and start with a C/);
115-
116-
// Test case 13: ctid too large to be a valid CTID value
117-
assert.throws(() => decodeCTID(0xCFFFFFFFFFFFFFFFFn), /ctid must be exactly 16 nibbles and start with a C/);
118-
119-
// Test case 14: ctid doesn't start with a C nibble
120-
assert.throws(() => decodeCTID(0xFFFFFFFFFFFFFFFFn), /ctid must be exactly 16 nibbles and start with a C/);
121-
122-
console.log("Done.");
61+
if (typeof window === "undefined" && typeof process === "object") {
62+
console.log("Running test cases...");
63+
// Test cases For encodeCTID
64+
const assert = require("assert");
65+
66+
// Test case 1: Valid input values
67+
assert.equal(encodeCTID(0xfffffff, 0xffff, 0xffff), "CFFFFFFFFFFFFFFF");
68+
assert.equal(encodeCTID(0, 0, 0), "C000000000000000");
69+
assert.equal(encodeCTID(1, 2, 3), "C000000100020003");
70+
assert.equal(encodeCTID(13249191, 12911, 49221), "C0CA2AA7326FC045");
71+
72+
// Test case 2: ledger_seq greater than 0xFFFFFFF
73+
assert.throws(
74+
() => encodeCTID(0x10000000, 0xffff, 0xffff),
75+
/ledger_seq must not be greater than 268435455 or less than 0./,
76+
);
77+
assert.throws(
78+
() => encodeCTID(-1, 0xffff, 0xffff),
79+
/ledger_seq must not be greater than 268435455 or less than 0./,
80+
);
81+
82+
// Test case 3: txn_index greater than 0xFFFF
83+
assert.throws(
84+
() => encodeCTID(0xfffffff, 0x10000, 0xffff),
85+
/txn_index must not be greater than 65535 or less than 0./,
86+
);
87+
assert.throws(
88+
() => encodeCTID(0xfffffff, -1, 0xffff),
89+
/txn_index must not be greater than 65535 or less than 0./,
90+
);
91+
92+
// Test case 4: network_id greater than 0xFFFF
93+
assert.throws(
94+
() => encodeCTID(0xfffffff, 0xffff, 0x10000),
95+
/network_id must not be greater than 65535 or less than 0./,
96+
);
97+
assert.throws(
98+
() => encodeCTID(0xfffffff, 0xffff, -1),
99+
/network_id must not be greater than 65535 or less than 0./,
100+
);
101+
102+
// Test cases For decodeCTID
103+
104+
// Test case 5: Valid input values
105+
assert.deepEqual(decodeCTID("CFFFFFFFFFFFFFFF"), {
106+
ledger_seq: 0xfffffff,
107+
txn_index: 0xffff,
108+
network_id: 0xffff,
109+
});
110+
assert.deepEqual(decodeCTID("C000000000000000"), {
111+
ledger_seq: 0,
112+
txn_index: 0,
113+
network_id: 0,
114+
});
115+
assert.deepEqual(decodeCTID("C000000100020003"), {
116+
ledger_seq: 1,
117+
txn_index: 2,
118+
network_id: 3,
119+
});
120+
assert.deepEqual(decodeCTID("C0CA2AA7326FC045"), {
121+
ledger_seq: 13249191,
122+
txn_index: 12911,
123+
network_id: 49221,
124+
});
125+
126+
// Test case 6: ctid not a string or big int
127+
assert.throws(
128+
() => decodeCTID(0xcff),
129+
/ctid must be a hexadecimal string or BigInt/,
130+
);
131+
132+
// Test case 7: ctid not a hexadecimal string
133+
assert.throws(
134+
() => decodeCTID("C003FFFFFFFFFFFG"),
135+
/ctid must be a hexadecimal string or BigInt/,
136+
);
137+
138+
// Test case 8: ctid not exactly 16 nibbles
139+
assert.throws(
140+
() => decodeCTID("C003FFFFFFFFFFF"),
141+
/ctid must be exactly 16 nibbles and start with a C/,
142+
);
143+
144+
// Test case 9: ctid too large to be a valid CTID value
145+
assert.throws(
146+
() => decodeCTID("CFFFFFFFFFFFFFFFF"),
147+
/ctid must be exactly 16 nibbles and start with a C/,
148+
);
149+
150+
// Test case 10: ctid doesn't start with a C nibble
151+
assert.throws(
152+
() => decodeCTID("FFFFFFFFFFFFFFFF"),
153+
/ctid must be exactly 16 nibbles and start with a C/,
154+
);
155+
156+
// the same tests again but using bigint instead of string
157+
//
158+
159+
// Test case 11: Valid input values
160+
assert.deepEqual(decodeCTID(0xcfffffffffffffffn), {
161+
ledger_seq: 0xfffffff,
162+
txn_index: 0xffff,
163+
network_id: 0xffff,
164+
});
165+
assert.deepEqual(decodeCTID(0xc000000000000000n), {
166+
ledger_seq: 0,
167+
txn_index: 0,
168+
network_id: 0,
169+
});
170+
assert.deepEqual(decodeCTID(0xc000000100020003n), {
171+
ledger_seq: 1,
172+
txn_index: 2,
173+
network_id: 3,
174+
});
175+
assert.deepEqual(decodeCTID(0xc0ca2aa7326fc045n), {
176+
ledger_seq: 13249191,
177+
txn_index: 12911,
178+
network_id: 49221,
179+
});
180+
181+
// Test case 12: ctid not exactly 16 nibbles
182+
assert.throws(
183+
() => decodeCTID(0xc003fffffffffffn),
184+
/ctid must be exactly 16 nibbles and start with a C/,
185+
);
186+
187+
// Test case 13: ctid too large to be a valid CTID value
188+
assert.throws(
189+
() => decodeCTID(0xcffffffffffffffffn),
190+
/ctid must be exactly 16 nibbles and start with a C/,
191+
);
192+
193+
// Test case 14: ctid doesn't start with a C nibble
194+
assert.throws(
195+
() => decodeCTID(0xffffffffffffffffn),
196+
/ctid must be exactly 16 nibbles and start with a C/,
197+
);
198+
199+
console.log("Done.");
123200
}

0 commit comments

Comments
 (0)