mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-05 03:22:30 +00:00
Compare commits
1828 Commits
1.2.2
...
dangell7/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d1c83b1cc | ||
|
|
38850e1180 | ||
|
|
b418b416b0 | ||
|
|
2305bc98a4 | ||
|
|
677758b1cc | ||
|
|
25d7c2c4ec | ||
|
|
0a626d95f4 | ||
|
|
6006c281e2 | ||
|
|
e79673cf40 | ||
|
|
7f41012e59 | ||
|
|
b449a6ee84 | ||
|
|
34ef577604 | ||
|
|
3a172301ce | ||
|
|
6c1a92fe93 | ||
|
|
7813683091 | ||
|
|
b814a09a08 | ||
|
|
6d369e0f02 | ||
|
|
b182430178 | ||
|
|
fe31cdc9f6 | ||
|
|
ff4520cc45 | ||
|
|
fe9c8d568f | ||
|
|
a0e09187b9 | ||
|
|
f3627fb5d5 | ||
|
|
5f638f5553 | ||
|
|
92046785d1 | ||
|
|
b90a843ddd | ||
|
|
bb529d0317 | ||
|
|
a2f1973574 | ||
|
|
847e875635 | ||
|
|
778da954b4 | ||
|
|
0586b5678e | ||
|
|
66158d786f | ||
|
|
c57ffdbcb8 | ||
|
|
4e3f953fc4 | ||
|
|
a4f8aa623f | ||
|
|
8695313565 | ||
|
|
68c9d5ca0f | ||
|
|
211054baff | ||
|
|
4fd4e93b3e | ||
|
|
4cd6cc3e01 | ||
|
|
a37c556079 | ||
|
|
5e808794d8 | ||
|
|
12c0d67ff6 | ||
|
|
00d3cee6cc | ||
|
|
96d17b7f66 | ||
|
|
ec44347ffc | ||
|
|
c9458b72ca | ||
|
|
ebcfd6645d | ||
|
|
efa57e872b | ||
|
|
33f4c92b61 | ||
|
|
2601442e16 | ||
|
|
9686604963 | ||
|
|
0efae5d16e | ||
|
|
4755bb8606 | ||
|
|
92d40de4cb | ||
|
|
b2c5927b48 | ||
|
|
7c1183547a | ||
|
|
14467fba5e | ||
|
|
fc00723836 | ||
|
|
c24a6041f7 | ||
|
|
e1d97bea12 | ||
|
|
53aa5ca903 | ||
|
|
510c0d82e9 | ||
|
|
17565d21d4 | ||
|
|
07ff532d30 | ||
|
|
2c37ef7762 | ||
|
|
3c9f5b6252 | ||
|
|
f80059e467 | ||
|
|
d734c8dddd | ||
|
|
44d21b8f6d | ||
|
|
3d1b3a49b3 | ||
|
|
0b87a26f04 | ||
|
|
0f23ad820c | ||
|
|
b7139da4d0 | ||
|
|
40198d9792 | ||
|
|
f059f0beda | ||
|
|
41c1be2bac | ||
|
|
f816ffa55f | ||
|
|
cf748702af | ||
|
|
1eb0fdac65 | ||
|
|
496efb71ca | ||
|
|
9eb84a561e | ||
|
|
62efecbfb1 | ||
|
|
bff5954acf | ||
|
|
42a432c5dc | ||
|
|
4565cc280b | ||
|
|
9625514da8 | ||
|
|
a4c60b4160 | ||
|
|
b986395ecc | ||
|
|
020ea3f412 | ||
|
|
51f1fe5f9a | ||
|
|
813bc4d949 | ||
|
|
6c67f1f525 | ||
|
|
c9f17dd85d | ||
|
|
b33b506b90 | ||
|
|
f399749ee2 | ||
|
|
2ed4047840 | ||
|
|
4e25dc9291 | ||
|
|
a18b30b765 | ||
|
|
856470203a | ||
|
|
b124c9f7e3 | ||
|
|
b550dc00ed | ||
|
|
21c02232a5 | ||
|
|
a791c03dc1 | ||
|
|
800a315383 | ||
|
|
8449c6c365 | ||
|
|
58e03190ac | ||
|
|
fb74dc28e1 | ||
|
|
e4dccfd49b | ||
|
|
57f4b4eb7f | ||
|
|
adbeb94c2b | ||
|
|
a3d4be4eaf | ||
|
|
6ff495fd9b | ||
|
|
ad37461ab2 | ||
|
|
d9c27da529 | ||
|
|
3fb6acd29e | ||
|
|
77b7cef5a7 | ||
|
|
2c187461cc | ||
|
|
13a12c6402 | ||
|
|
362ecbd1cb | ||
|
|
7025e92080 | ||
|
|
f81d0d8c98 | ||
|
|
508937f3d1 | ||
|
|
8580a5795a | ||
|
|
9b53bd9871 | ||
|
|
5fc07e3979 | ||
|
|
2ebc2ca885 | ||
|
|
c2a90b706f | ||
|
|
9ffb434315 | ||
|
|
ff18cfef96 | ||
|
|
03704f712b | ||
|
|
9b332d88c1 | ||
|
|
33309480d4 | ||
|
|
098eadca0a | ||
|
|
3b810c305a | ||
|
|
3968efb5f1 | ||
|
|
12c629a1d2 | ||
|
|
8d2dff2e48 | ||
|
|
c39f9c561c | ||
|
|
173f9f7bb0 | ||
|
|
28a1f90938 | ||
|
|
673fb06c75 | ||
|
|
f28ba57b81 | ||
|
|
f3a2ec1fb2 | ||
|
|
1d42c4f6de | ||
|
|
ada83564d8 | ||
|
|
b18dece145 | ||
|
|
63a08560ca | ||
|
|
8ac8a47c99 | ||
|
|
12c4b5a632 | ||
|
|
25c5e3b17f | ||
|
|
8eb233c2ea | ||
|
|
50fc93f742 | ||
|
|
ab45a8a737 | ||
|
|
dfafb141cc | ||
|
|
4e32d2ed98 | ||
|
|
fa69918124 | ||
|
|
cbbb2b1be0 | ||
|
|
cf2d763fa1 | ||
|
|
2dd1d682ac | ||
|
|
4cb1084c02 | ||
|
|
8d1b3b3994 | ||
|
|
b39d7a6519 | ||
|
|
b0910e359e | ||
|
|
44e027e516 | ||
|
|
a10f42a3aa | ||
|
|
efd4c1b95d | ||
|
|
f8b4f692f1 | ||
|
|
80a3ae6386 | ||
|
|
48d38c1e2c | ||
|
|
553fb5be3b | ||
|
|
efa917d9f3 | ||
|
|
bd3bc917f8 | ||
|
|
ed5d6f3e22 | ||
|
|
a8e4da0b11 | ||
|
|
1dd60242de | ||
|
|
76611c3f46 | ||
|
|
5efaf0c328 | ||
|
|
0aa23933ea | ||
|
|
21f3c12d85 | ||
|
|
7d5ed0cd8d | ||
|
|
d9960d5ba0 | ||
|
|
91fa6b2295 | ||
|
|
76f774e22d | ||
|
|
f4f7618173 | ||
|
|
66f16469f9 | ||
|
|
1845b1c656 | ||
|
|
e192ffe964 | ||
|
|
2bf77cc8f6 | ||
|
|
5e33ca56fd | ||
|
|
7c39c810eb | ||
|
|
a7792ebcae | ||
|
|
83ee3788e1 | ||
|
|
ae719b86d3 | ||
|
|
dd722f8b3f | ||
|
|
30190a5feb | ||
|
|
afb6e0e41b | ||
|
|
5523557226 | ||
|
|
b64707f53b | ||
|
|
0b113f371f | ||
|
|
b4c894c1ba | ||
|
|
92281a4ede | ||
|
|
e80642fc12 | ||
|
|
640ce4988f | ||
|
|
a422855ea7 | ||
|
|
108f90586c | ||
|
|
519d1dbc34 | ||
|
|
3d44758e5a | ||
|
|
97bc94a7f6 | ||
|
|
34619f2504 | ||
|
|
3509de9c5f | ||
|
|
459d0da010 | ||
|
|
8637d606a4 | ||
|
|
8456b8275e | ||
|
|
3c88786bb0 | ||
|
|
46ba8a28fe | ||
|
|
5ecde3cf39 | ||
|
|
620fb26823 | ||
|
|
6b6b213cf5 | ||
|
|
f61086b43c | ||
|
|
176fd2b6e4 | ||
|
|
2df730438d | ||
|
|
5d79bfc531 | ||
|
|
51ef35ab55 | ||
|
|
330a3215bc | ||
|
|
85c2ceacde | ||
|
|
70d5c624e8 | ||
|
|
8e4fda160d | ||
|
|
072b1c442c | ||
|
|
294e03ecf5 | ||
|
|
550f90a75e | ||
|
|
d67dcfe3c4 | ||
|
|
0fd2f715bb | ||
|
|
807462b191 | ||
|
|
19c4226d3d | ||
|
|
d02c306f1e | ||
|
|
cfd26f444c | ||
|
|
2c3024716b | ||
|
|
a12f5de68d | ||
|
|
51c5f2bfc9 | ||
|
|
73ff54143d | ||
|
|
08b136528e | ||
|
|
6b8a589447 | ||
|
|
ffeabc9642 | ||
|
|
3cbdf818a7 | ||
|
|
c46888f8f7 | ||
|
|
2ae65d2fdb | ||
|
|
bd834c87e0 | ||
|
|
dc8b37a524 | ||
|
|
617a895af5 | ||
|
|
1af1048c58 | ||
|
|
f07ba87e51 | ||
|
|
e66558a883 | ||
|
|
510314d344 | ||
|
|
37b951859c | ||
|
|
9494fc9668 | ||
|
|
8d01f35eb9 | ||
|
|
1020a32d76 | ||
|
|
17a2606591 | ||
|
|
ccb9f1e42d | ||
|
|
3e4e9a2ddc | ||
|
|
4caebfbd0e | ||
|
|
37c377a1b6 | ||
|
|
bd182c0a3e | ||
|
|
406c26cc72 | ||
|
|
9bd1ce436a | ||
|
|
f69ad4eff6 | ||
|
|
6fe0599cc2 | ||
|
|
e6f8bc720f | ||
|
|
fbd60fc000 | ||
|
|
61d628d654 | ||
|
|
3d92375d12 | ||
|
|
cdbe70b2a7 | ||
|
|
f6426ca183 | ||
|
|
e5f7a8442d | ||
|
|
e67e0395df | ||
|
|
148f669a25 | ||
|
|
f1eaa6a264 | ||
|
|
da4c8c9550 | ||
|
|
bcde2790a4 | ||
|
|
9ebeb413e4 | ||
|
|
6d40b882a4 | ||
|
|
9fe0a154f1 | ||
|
|
cb52c9af00 | ||
|
|
6bf8338038 | ||
|
|
b0f4174e47 | ||
|
|
3865dde0b8 | ||
|
|
811c980821 | ||
|
|
cf5f65b68e | ||
|
|
c38f2a3f2e | ||
|
|
16c2ff97cc | ||
|
|
32043463a8 | ||
|
|
724e9b1313 | ||
|
|
2e6f00aef2 | ||
|
|
e0b9812fc5 | ||
|
|
e4fdf33158 | ||
|
|
6e814d7ebd | ||
|
|
1e37d00d6c | ||
|
|
87ea3ba65d | ||
|
|
dedf3d3983 | ||
|
|
2df7dcfdeb | ||
|
|
1506e65558 | ||
|
|
808c86663c | ||
|
|
92431a4238 | ||
|
|
285120684c | ||
|
|
77fef8732b | ||
|
|
7775c725f3 | ||
|
|
c61096239c | ||
|
|
c5fe970646 | ||
|
|
c57cd8b23e | ||
|
|
c14ce956ad | ||
|
|
095dc4d9cc | ||
|
|
2e255812ae | ||
|
|
896b8c3b54 | ||
|
|
58dd07bbdf | ||
|
|
b13370ac0d | ||
|
|
f847e3287c | ||
|
|
56c1e078f2 | ||
|
|
afc05659ed | ||
|
|
b04d239926 | ||
|
|
dc1caa41b2 | ||
|
|
ceb0ce5634 | ||
|
|
fb89213d4d | ||
|
|
d8628d481d | ||
|
|
a14551b151 | ||
|
|
de33a6a241 | ||
|
|
28eec6ce1b | ||
|
|
c9a723128a | ||
|
|
da82e52613 | ||
|
|
c9d73b6135 | ||
|
|
b7ed99426b | ||
|
|
97f0747e10 | ||
|
|
abf12db788 | ||
|
|
bdfc376951 | ||
|
|
b40a3684ae | ||
|
|
86ef16dbeb | ||
|
|
39b5031ab5 | ||
|
|
94decc753b | ||
|
|
991891625a | ||
|
|
69314e6832 | ||
|
|
dbeb841b5a | ||
|
|
4eae037fee | ||
|
|
b5a63b39d3 | ||
|
|
6419f9a253 | ||
|
|
31c99caa65 | ||
|
|
d835e97490 | ||
|
|
baf4b8381f | ||
|
|
9b45b6888b | ||
|
|
7179ce9c58 | ||
|
|
921aef9934 | ||
|
|
e7a7bb83c1 | ||
|
|
5c2a3a2779 | ||
|
|
b2960b9e7f | ||
|
|
5713f9782a | ||
|
|
60e340d356 | ||
|
|
80d82c5b2b | ||
|
|
433eeabfa5 | ||
|
|
faa781b71f | ||
|
|
c233df720a | ||
|
|
7ff4f79d30 | ||
|
|
60909655d3 | ||
|
|
03e46cd026 | ||
|
|
e95683a0fb | ||
|
|
13353ae36d | ||
|
|
1a40f18bdd | ||
|
|
90e6380383 | ||
|
|
8bfaa7fe0a | ||
|
|
c9135a63cd | ||
|
|
452263eaa5 | ||
|
|
8aa94ea09a | ||
|
|
258ba71363 | ||
|
|
b8626ea3c6 | ||
|
|
6534757d85 | ||
|
|
8e94ea3154 | ||
|
|
b113190563 | ||
|
|
358b7f50a7 | ||
|
|
f47e2f4e82 | ||
|
|
a7eea9546f | ||
|
|
9874d47d7f | ||
|
|
c2f3e2e263 | ||
|
|
e18f27f5f7 | ||
|
|
df6daf0d8f | ||
|
|
e9d46f0bfc | ||
|
|
42fd74b77b | ||
|
|
c55ea56c5e | ||
|
|
1e01cd34f7 | ||
|
|
e2fa5c1b7c | ||
|
|
fc0984d286 | ||
|
|
8b3dcd41f7 | ||
|
|
8f2f5310e2 | ||
|
|
edb4f0342c | ||
|
|
ea17abb92a | ||
|
|
35a40a8e62 | ||
|
|
d494bf45b2 | ||
|
|
8bf4a5cbff | ||
|
|
58c2c82a30 | ||
|
|
11edaa441d | ||
|
|
a5e953b191 | ||
|
|
506ae12a8c | ||
|
|
0310c5cbe0 | ||
|
|
053e1af7ff | ||
|
|
7e24adbdd0 | ||
|
|
621df422a7 | ||
|
|
0a34b5c691 | ||
|
|
e0bc3dd51f | ||
|
|
dacecd24ba | ||
|
|
05105743e9 | ||
|
|
9e1fe9a85e | ||
|
|
d71ce51901 | ||
|
|
be668ee26d | ||
|
|
cae5294b4e | ||
|
|
cd777f79ef | ||
|
|
8b9e21e3f5 | ||
|
|
2a61aee562 | ||
|
|
40ce8a8833 | ||
|
|
7713ff8c5c | ||
|
|
70371a4344 | ||
|
|
e514de76ed | ||
|
|
dd62cfcc22 | ||
|
|
09690f1b38 | ||
|
|
380ba9f1c1 | ||
|
|
c3e9380fb4 | ||
|
|
e3ebc253fa | ||
|
|
c6c7c84355 | ||
|
|
28f50cb7cf | ||
|
|
3e152fec74 | ||
|
|
2db2791805 | ||
|
|
9ec2d7f8ff | ||
|
|
4a084ce34c | ||
|
|
3502df2174 | ||
|
|
fa1e25abef | ||
|
|
217ba8dd4d | ||
|
|
405f4613d8 | ||
|
|
cba512068b | ||
|
|
1c99ea23d1 | ||
|
|
c4308b216f | ||
|
|
aafd2d8525 | ||
|
|
a574ec6023 | ||
|
|
e429455f4d | ||
|
|
7692eeb9a0 | ||
|
|
a099f5a804 | ||
|
|
ca0bc767fe | ||
|
|
4ba9288935 | ||
|
|
e923ec6d36 | ||
|
|
851d99d99e | ||
|
|
f608e653ca | ||
|
|
72e076b694 | ||
|
|
6cf37c4abe | ||
|
|
fc204773d6 | ||
|
|
2bc5cb240f | ||
|
|
67028d6ea6 | ||
|
|
d22a5057b9 | ||
|
|
75a20194c5 | ||
|
|
7fe81fe62e | ||
|
|
345ddc7234 | ||
|
|
d167d4864f | ||
|
|
bf504912a4 | ||
|
|
a7fb8ae915 | ||
|
|
d9b7a2688f | ||
|
|
c0299dba88 | ||
|
|
c3ecdb4746 | ||
|
|
c17676a9be | ||
|
|
ed8e32cc92 | ||
|
|
2406b28e64 | ||
|
|
2216e5a13f | ||
|
|
5bf3a308d5 | ||
|
|
53ea31c69a | ||
|
|
c1c2b5bf52 | ||
|
|
af018c7b0b | ||
|
|
0a1ca0600f | ||
|
|
cd7c62818b | ||
|
|
37d06bcce8 | ||
|
|
9745718467 | ||
|
|
ab44cc31e2 | ||
|
|
dce3e1efa6 | ||
|
|
159dfb5acb | ||
|
|
844646dc50 | ||
|
|
01fc8f2209 | ||
|
|
43e1d4440e | ||
|
|
466849efe8 | ||
|
|
db0fad6826 | ||
|
|
dd5e6559dd | ||
|
|
7c9d652d9b | ||
|
|
dc9e6c37fe | ||
|
|
01fe9477f4 | ||
|
|
97e3dae6f4 | ||
|
|
e8e7888a23 | ||
|
|
b02b8d016c | ||
|
|
a079bac153 | ||
|
|
3a55a64e1c | ||
|
|
fa5a85439f | ||
|
|
81034596a8 | ||
|
|
0968cdf340 | ||
|
|
d9e4009e33 | ||
|
|
02387fd227 | ||
|
|
fb3713bc25 | ||
|
|
f6d63082c0 | ||
|
|
33e1c42599 | ||
|
|
1b75dc8bcd | ||
|
|
3d02580c09 | ||
|
|
8458233a31 | ||
|
|
cb0ddbf863 | ||
|
|
dcc4581220 | ||
|
|
50b8f19cb5 | ||
|
|
f3e201f983 | ||
|
|
b14c24960b | ||
|
|
b6e3453f49 | ||
|
|
ed4870cdb4 | ||
|
|
5fbee8c824 | ||
|
|
3868c04e99 | ||
|
|
409c1d5aa2 | ||
|
|
20710f5232 | ||
|
|
870882f567 | ||
|
|
e1e67b2c9e | ||
|
|
eac3abdca9 | ||
|
|
ebd8e63276 | ||
|
|
839d17e7bd | ||
|
|
7be5c31bc6 | ||
|
|
9e4a7d5871 | ||
|
|
ff8b9aa439 | ||
|
|
ccc0889803 | ||
|
|
07f118caec | ||
|
|
58af62f388 | ||
|
|
040cd23e4a | ||
|
|
0324764a83 | ||
|
|
679e35fd46 | ||
|
|
49e0d54c76 | ||
|
|
7506852a99 | ||
|
|
bcbfb04992 | ||
|
|
5cd72f2431 | ||
|
|
eabca8439f | ||
|
|
ea1fffeebf | ||
|
|
6d58065909 | ||
|
|
47b0543461 | ||
|
|
8215c605b4 | ||
|
|
d7e949193f | ||
|
|
f64cf9187a | ||
|
|
b54d85d862 | ||
|
|
f419c18056 | ||
|
|
0ec17b6026 | ||
|
|
838978b869 | ||
|
|
8186253707 | ||
|
|
2316d843d7 | ||
|
|
9d58f11a60 | ||
|
|
7b18006193 | ||
|
|
9e48fc0c83 | ||
|
|
8e827e32ac | ||
|
|
c5c0e70e23 | ||
|
|
ec61f5e9d3 | ||
|
|
d57cced17b | ||
|
|
54a350be79 | ||
|
|
d6dbf0e0a6 | ||
|
|
0d887ad815 | ||
|
|
d4a5f8390e | ||
|
|
ab5d450d3c | ||
|
|
23c37fa506 | ||
|
|
63209c2646 | ||
|
|
f0dabd1446 | ||
|
|
552377c76f | ||
|
|
e7cd03325b | ||
|
|
decb3c178e | ||
|
|
f6d647d6c3 | ||
|
|
bf4a7b6ce8 | ||
|
|
8e2c85d14d | ||
|
|
1fbf8da79f | ||
|
|
a75309919e | ||
|
|
0ece395c24 | ||
|
|
b6391fe011 | ||
|
|
9a6af9c431 | ||
|
|
fa1cbb0746 | ||
|
|
68e1be3cf5 | ||
|
|
9abc4868d6 | ||
|
|
23991c99c3 | ||
|
|
cc0177be87 | ||
|
|
37b3e96b04 | ||
|
|
85214bdf81 | ||
|
|
fbbea9e6e2 | ||
|
|
7741483894 | ||
|
|
2f432e812c | ||
|
|
cad8970a57 | ||
|
|
4d7aed84ec | ||
|
|
00ed7c9424 | ||
|
|
d9bd75e683 | ||
|
|
93d8bafb24 | ||
|
|
c19a88fee9 | ||
|
|
0a331ea72e | ||
|
|
7d27b11190 | ||
|
|
eedfec015e | ||
|
|
ffc343a2bc | ||
|
|
e5aa605742 | ||
|
|
8b181ed818 | ||
|
|
f5a349558e | ||
|
|
b9b75ddcf5 | ||
|
|
a39720e94a | ||
|
|
2820feb02a | ||
|
|
8fc805d2e2 | ||
|
|
d54151e7c4 | ||
|
|
21a0a64648 | ||
|
|
20707fac4a | ||
|
|
e6ef0fc26c | ||
|
|
c157816017 | ||
|
|
eba5d19377 | ||
|
|
ad14d09a2b | ||
|
|
f3bcc651c7 | ||
|
|
e8602b81fa | ||
|
|
0f32109993 | ||
|
|
a17ccca615 | ||
|
|
7a1b238035 | ||
|
|
e1534a3200 | ||
|
|
9fec615dca | ||
|
|
ef02893f2f | ||
|
|
7cf4611d7c | ||
|
|
d028005aa6 | ||
|
|
1d23148e6d | ||
|
|
e416ee72ca | ||
|
|
2e902dee53 | ||
|
|
f6879da6c9 | ||
|
|
ae20a3ad3f | ||
|
|
c706926ee3 | ||
|
|
223e6c7590 | ||
|
|
825864032a | ||
|
|
06733ec21a | ||
|
|
9f7c619e4f | ||
|
|
3f5e3212fe | ||
|
|
20d05492d2 | ||
|
|
ae7ea33b75 | ||
|
|
263e984bf4 | ||
|
|
58f3abe3c6 | ||
|
|
d576416953 | ||
|
|
e3d1bb271f | ||
|
|
2df635693d | ||
|
|
40b4adc9cc | ||
|
|
0c971b4415 | ||
|
|
f2d37da4ca | ||
|
|
d5e5c3c220 | ||
|
|
15390bedd5 | ||
|
|
7f6a079aa4 | ||
|
|
2a25f58d40 | ||
|
|
2705109592 | ||
|
|
244ac5e024 | ||
|
|
f4da2e31d9 | ||
|
|
f650949573 | ||
|
|
76128051c0 | ||
|
|
5aa1106ba1 | ||
|
|
dccf3f49ef | ||
|
|
02ec8b7962 | ||
|
|
3f7ce939c8 | ||
|
|
b65cea1984 | ||
|
|
b422e71eed | ||
|
|
e9859ac1b1 | ||
|
|
b84f7e7c10 | ||
|
|
513842b23f | ||
|
|
985c80fbc6 | ||
|
|
35fe957020 | ||
|
|
0eebe6a5f4 | ||
|
|
760f16f568 | ||
|
|
241b9ddde9 | ||
|
|
3fcfb5cd49 | ||
|
|
e2384885f5 | ||
|
|
dd312c3cc5 | ||
|
|
80379927e8 | ||
|
|
676aae2755 | ||
|
|
f20e66e6f9 | ||
|
|
cd737ad7d3 | ||
|
|
df3aa84523 | ||
|
|
24a275ba25 | ||
|
|
aae438315f | ||
|
|
8b0d049b9f | ||
|
|
659bd99a67 | ||
|
|
c88166e055 | ||
|
|
099c0bcd34 | ||
|
|
d992e63075 | ||
|
|
c187f750fe | ||
|
|
bcbf6c1973 | ||
|
|
4bcbf70cae | ||
|
|
2d1854f354 | ||
|
|
a7c4a47723 | ||
|
|
61672ad3ff | ||
|
|
cea43099d2 | ||
|
|
6edf03c152 | ||
|
|
47c8cc24f4 | ||
|
|
64e46878e0 | ||
|
|
ea9b1e3503 | ||
|
|
2e9261cb26 | ||
|
|
69143d71f8 | ||
|
|
0c32fc5f2a | ||
|
|
af9cabe100 | ||
|
|
2ecb851926 | ||
|
|
2ffead76c1 | ||
|
|
5cc377751a | ||
|
|
ad8e9764e6 | ||
|
|
4ce426d8f6 | ||
|
|
c28e005087 | ||
|
|
22b751834f | ||
|
|
cce09b717e | ||
|
|
62dae3c6c6 | ||
|
|
97863e0b62 | ||
|
|
8a2f6bec33 | ||
|
|
e718378bdb | ||
|
|
d7d15a922a | ||
|
|
e74cb35aa4 | ||
|
|
da68651f61 | ||
|
|
be12136b8a | ||
|
|
6d3c21e369 | ||
|
|
1e96a1d6eb | ||
|
|
828bb64ebc | ||
|
|
6f00d32f7e | ||
|
|
f9e365828a | ||
|
|
90d463b925 | ||
|
|
22cdb5728b | ||
|
|
901152bd93 | ||
|
|
d9a5bca625 | ||
|
|
1676e9fe21 | ||
|
|
fad9d639bf | ||
|
|
efe6722bf8 | ||
|
|
a41f38547b | ||
|
|
87ee7868ea | ||
|
|
861bd1a96e | ||
|
|
6ac2b705dd | ||
|
|
fe4d6c68b5 | ||
|
|
5a7af5bb77 | ||
|
|
d9f90c84c0 | ||
|
|
4308407dc1 | ||
|
|
2b0313d60c | ||
|
|
350d213ee8 | ||
|
|
ca3198164c | ||
|
|
c53a5e7a72 | ||
|
|
ffb53f2085 | ||
|
|
3b191a3097 | ||
|
|
656948cd0f | ||
|
|
46f3d3ef61 | ||
|
|
06251aa76f | ||
|
|
5aef102f4f | ||
|
|
431646437e | ||
|
|
fe8621b00f | ||
|
|
c045060560 | ||
|
|
8ec475b1fd | ||
|
|
e33a6d5c2b | ||
|
|
923e1cef99 | ||
|
|
2e93dd57eb | ||
|
|
92957d685d | ||
|
|
f05acbd782 | ||
|
|
44a9266c9e | ||
|
|
c1710900b4 | ||
|
|
d5059b11b9 | ||
|
|
f95fa338c9 | ||
|
|
96c926c71e | ||
|
|
4dff203787 | ||
|
|
4977a5d43c | ||
|
|
8ce85a9750 | ||
|
|
d5939727e0 | ||
|
|
7b49f1e1de | ||
|
|
ac27089c69 | ||
|
|
4cb0bcb003 | ||
|
|
cf4e9e5578 | ||
|
|
32ced493de | ||
|
|
09e0f103f4 | ||
|
|
056255e396 | ||
|
|
85342b21c8 | ||
|
|
26b0322aa5 | ||
|
|
3b624d8bf8 | ||
|
|
ac02e56519 | ||
|
|
1eac4d2c07 | ||
|
|
3e5f770a38 | ||
|
|
2a66bb3fc7 | ||
|
|
397268394b | ||
|
|
5026cbdaf3 | ||
|
|
5af9dc5abd | ||
|
|
8d86c5e17d | ||
|
|
078bd606c7 | ||
|
|
b421945e71 | ||
|
|
41cd337506 | ||
|
|
b69156ac01 | ||
|
|
be6ac7e7a1 | ||
|
|
1fc1eb9f68 | ||
|
|
1fde585003 | ||
|
|
c915984340 | ||
|
|
50cc1cf0c9 | ||
|
|
1151fba415 | ||
|
|
3e08c390f5 | ||
|
|
053b69c63f | ||
|
|
ced14ec1ab | ||
|
|
6ba9450c89 | ||
|
|
ec8626046b | ||
|
|
4e84ad6cd7 | ||
|
|
40ebbecac8 | ||
|
|
0c43eb3973 | ||
|
|
3dea78d34b | ||
|
|
e27d24ba00 | ||
|
|
925aca764b | ||
|
|
2bb8de030f | ||
|
|
b92d511558 | ||
|
|
548c91ebb6 | ||
|
|
2c56d9fc3e | ||
|
|
6b61505ac2 | ||
|
|
e4db0fba2b | ||
|
|
8f89694fae | ||
|
|
5433e133d5 | ||
|
|
2487dab194 | ||
|
|
77e0912a0e | ||
|
|
a948203dae | ||
|
|
8f65bc24a0 | ||
|
|
9f102fc99d | ||
|
|
7bff9dc7f0 | ||
|
|
e86181c096 | ||
|
|
65df4bceaa | ||
|
|
3397922989 | ||
|
|
046d0c2f0a | ||
|
|
01fc4b0203 | ||
|
|
5b7d2c133a | ||
|
|
237b406e8c | ||
|
|
5427321260 | ||
|
|
ce570c166d | ||
|
|
649c11a78e | ||
|
|
7fae1c1262 | ||
|
|
f259cc1ab6 | ||
|
|
002893f280 | ||
|
|
1d9db1bfdd | ||
|
|
3b5fcd5873 | ||
|
|
a95505739d | ||
|
|
31c8281922 | ||
|
|
c6f6375015 | ||
|
|
6f74a745db | ||
|
|
36cb5f90e2 | ||
|
|
89780c8e4f | ||
|
|
9d4d8c22d9 | ||
|
|
b014b79d88 | ||
|
|
a61a88ea81 | ||
|
|
f31c50d04d | ||
|
|
8ceb0f3a79 | ||
|
|
d943c58b3d | ||
|
|
7ca1c644d1 | ||
|
|
300b7e078a | ||
|
|
3574956e5e | ||
|
|
e8a7b2a1fc | ||
|
|
b580049ec0 | ||
|
|
21c4aaf993 | ||
|
|
213491d94b | ||
|
|
da203b241b | ||
|
|
5d88b726c2 | ||
|
|
dcb7dd8d27 | ||
|
|
91e9658217 | ||
|
|
b28f62bbd9 | ||
|
|
4f4951022c | ||
|
|
58f7aecb0b | ||
|
|
5530a0b665 | ||
|
|
aded4a7a92 | ||
|
|
01df19c08b | ||
|
|
c197c4cdd9 | ||
|
|
5ba1f984df | ||
|
|
cb09e61d2f | ||
|
|
3c9db4b69e | ||
|
|
eeb8b41889 | ||
|
|
f7dd37e355 | ||
|
|
a45a95e5ea | ||
|
|
c6fee28b92 | ||
|
|
77dc63b549 | ||
|
|
66bfe909e6 | ||
|
|
9c50415ebe | ||
|
|
516ffb2147 | ||
|
|
f18c6dfea7 | ||
|
|
1cb67fbd20 | ||
|
|
54afdaa101 | ||
|
|
1c2ae10dc0 | ||
|
|
d34e8be316 | ||
|
|
4111382a31 | ||
|
|
11e914fbe9 | ||
|
|
0e983528e1 | ||
|
|
6b4437db39 | ||
|
|
534a36536c | ||
|
|
beba87129e | ||
|
|
b7e902dccc | ||
|
|
9eb30d4316 | ||
|
|
8fdad0d7fd | ||
|
|
0b812cdece | ||
|
|
724a301599 | ||
|
|
71d7d67fa3 | ||
|
|
264280edd7 | ||
|
|
beb0904a32 | ||
|
|
77c0a62a74 | ||
|
|
5d011c7e6b | ||
|
|
5644c8704f | ||
|
|
c9a586c243 | ||
|
|
f709311762 | ||
|
|
adde0c2d11 | ||
|
|
adf672ff83 | ||
|
|
029580886e | ||
|
|
32f8ae1af1 | ||
|
|
ce997a6de8 | ||
|
|
3620ac287e | ||
|
|
629ed5c691 | ||
|
|
78076a6903 | ||
|
|
67238b9fa6 | ||
|
|
c7ef4c9783 | ||
|
|
b21a05d465 | ||
|
|
436de0e03a | ||
|
|
8d482d3557 | ||
|
|
c5003969de | ||
|
|
1f417764c3 | ||
|
|
e75cd49313 | ||
|
|
4f95b9d7a6 | ||
|
|
066f91ca07 | ||
|
|
c3acbce82d | ||
|
|
b7f588b789 | ||
|
|
9346842eed | ||
|
|
f191c911d4 | ||
|
|
e6f49040f5 | ||
|
|
2f3f6dcb03 | ||
|
|
5ebcaf0a6c | ||
|
|
8bfdbcbab5 | ||
|
|
135b63dbe0 | ||
|
|
46167d1c46 | ||
|
|
79e621d96c | ||
|
|
66627b26cf | ||
|
|
7aad6e5127 | ||
|
|
dffcdea12b | ||
|
|
d7725837f5 | ||
|
|
7745c72b2c | ||
|
|
acb373280b | ||
|
|
4f506599f6 | ||
|
|
383f1b6ab3 | ||
|
|
da18c86cbf | ||
|
|
9fcb28acad | ||
|
|
305c9a8d61 | ||
|
|
9b2d563dec | ||
|
|
150d4a47e4 | ||
|
|
1c9df69b33 | ||
|
|
10555faa92 | ||
|
|
0f1ffff068 | ||
|
|
9309b57364 | ||
|
|
cb08f2b6ec | ||
|
|
84cde3ce0b | ||
|
|
f7b3ddd87b | ||
|
|
1e7710eee2 | ||
|
|
07f047b1e2 | ||
|
|
8687b5c3c9 | ||
|
|
ecd49e1535 | ||
|
|
c77a8d5ec6 | ||
|
|
e13676f709 | ||
|
|
74594d5348 | ||
|
|
caf4827c0b | ||
|
|
c2b03fecca | ||
|
|
60c276d90b | ||
|
|
2929748898 | ||
|
|
5ec8783d35 | ||
|
|
96aab1288f | ||
|
|
aebf2ac990 | ||
|
|
ac78b7a9a7 | ||
|
|
b72a87c7d3 | ||
|
|
39c32561bd | ||
|
|
89aa8b21ec | ||
|
|
a828e24cf0 | ||
|
|
f7a8d2de84 | ||
|
|
32559463ef | ||
|
|
8f514937a4 | ||
|
|
36b34a7bd5 | ||
|
|
5edaec2bd0 | ||
|
|
2f1f453052 | ||
|
|
6eaaa7bcfa | ||
|
|
e354497f63 | ||
|
|
6fcd654bee | ||
|
|
d275a2ab72 | ||
|
|
3f33471220 | ||
|
|
a82ad5ba76 | ||
|
|
48e804c40c | ||
|
|
c9c54c9799 | ||
|
|
24fe5f9fd0 | ||
|
|
476ee8a479 | ||
|
|
0ee63b7c7b | ||
|
|
31e7e5a56e | ||
|
|
e4b17d1cf2 | ||
|
|
0ce15e0e35 | ||
|
|
b0e0f319a1 | ||
|
|
2233f585f8 | ||
|
|
61d8c7a85b | ||
|
|
6f8750316c | ||
|
|
fda9e9a7ee | ||
|
|
d8a84e9530 | ||
|
|
c3a9f3dbf3 | ||
|
|
df1300fb37 | ||
|
|
648d6c3e2f | ||
|
|
47ffc392d7 | ||
|
|
0362e935af | ||
|
|
a79fa2026b | ||
|
|
c1e7fe2d93 | ||
|
|
4a5ad4cfac | ||
|
|
ffd453f7dd | ||
|
|
518fb6d208 | ||
|
|
093055c039 | ||
|
|
b7ac73c8e4 | ||
|
|
004ec2d201 | ||
|
|
ebbf4b64a5 | ||
|
|
649ab872ff | ||
|
|
7e9e9104ea | ||
|
|
3726f8bf31 | ||
|
|
e37dc710cf | ||
|
|
5d38e4cfbf | ||
|
|
28f4cc7817 | ||
|
|
95fabd5762 | ||
|
|
23ce431876 | ||
|
|
04ef885108 | ||
|
|
d33df35378 | ||
|
|
ba3c0e5145 | ||
|
|
be1ce5eca9 | ||
|
|
df66e4151e | ||
|
|
9a31f321cd | ||
|
|
e40e38e8d3 | ||
|
|
f5af42a640 | ||
|
|
fe05b8c4fe | ||
|
|
7b3507bb87 | ||
|
|
0ecfc7cb1a | ||
|
|
e2eed966b0 | ||
|
|
5a15229eeb | ||
|
|
d318ab612a | ||
|
|
9aaa0dff5f | ||
|
|
b88ed5a8ec | ||
|
|
ce64f7a90f | ||
|
|
5e1cb09b88 | ||
|
|
3d0c14f3e3 | ||
|
|
83ac141f65 | ||
|
|
e67f90588a | ||
|
|
69bb2be446 | ||
|
|
92d35e54c7 | ||
|
|
47dec467ea | ||
|
|
cd3a6bf530 | ||
|
|
6a9c270776 | ||
|
|
21a3f4a5b5 | ||
|
|
e5275b8577 | ||
|
|
83faf43140 | ||
|
|
22b4de2e44 | ||
|
|
b95ca98965 | ||
|
|
7e46f5342b | ||
|
|
59326bbbc5 | ||
|
|
9eb303f8e8 | ||
|
|
47ccd0b579 | ||
|
|
5e6728dccd | ||
|
|
d458e9972b | ||
|
|
b0b44d32bd | ||
|
|
8266d9d598 | ||
|
|
0839a202c9 | ||
|
|
ee60b16b3a | ||
|
|
18d437284e | ||
|
|
1f75ba23ee | ||
|
|
723733a778 | ||
|
|
8e6a0d418c | ||
|
|
f55913dcee | ||
|
|
e46d2bcf27 | ||
|
|
d632f9f6c8 | ||
|
|
3172a816fa | ||
|
|
4e724794c5 | ||
|
|
610436d737 | ||
|
|
0ee6f15b35 | ||
|
|
e32bc674aa | ||
|
|
34786abd4f | ||
|
|
d0a813a19d | ||
|
|
25474343a9 | ||
|
|
670bc22cfa | ||
|
|
80bda7cc48 | ||
|
|
dac080f1c8 | ||
|
|
767dd4ff3f | ||
|
|
01c37fed69 | ||
|
|
04bd5878f1 | ||
|
|
e836375d99 | ||
|
|
aa4a5b7fe9 | ||
|
|
5aedb0e07a | ||
|
|
dfe69f1b76 | ||
|
|
87d06a2571 | ||
|
|
7ca1f78446 | ||
|
|
b68a66928c | ||
|
|
245174c42c | ||
|
|
7c66747d27 | ||
|
|
cdd37a2a05 | ||
|
|
c66be3e6cf | ||
|
|
70779f6850 | ||
|
|
525aaecbca | ||
|
|
9d3cd718e4 | ||
|
|
656e9fe180 | ||
|
|
8aa617d972 | ||
|
|
711608e652 | ||
|
|
bc9773eb45 | ||
|
|
bea9610440 | ||
|
|
375af87a86 | ||
|
|
1502e6e2cd | ||
|
|
593677ee82 | ||
|
|
8f58687091 | ||
|
|
c7e6803956 | ||
|
|
6faaa91850 | ||
|
|
d66d960d59 | ||
|
|
18235067af | ||
|
|
3eb8aa8b80 | ||
|
|
b9903bbcc4 | ||
|
|
48803a48af | ||
|
|
1b9387eddc | ||
|
|
34ca457132 | ||
|
|
df60e46750 | ||
|
|
e7e672c3f8 | ||
|
|
4d5459d041 | ||
|
|
59f5844381 | ||
|
|
a07a729e3d | ||
|
|
b65e279db6 | ||
|
|
1ddc966b31 | ||
|
|
1a8eb5e6e3 | ||
|
|
6a8180c967 | ||
|
|
eb57679085 | ||
|
|
297def5ed3 | ||
|
|
a01cadbfd5 | ||
|
|
11ca9a946c | ||
|
|
f326f019bf | ||
|
|
90326bf756 | ||
|
|
255bf829ca | ||
|
|
0623a40f02 | ||
|
|
a529b218f3 | ||
|
|
c0cb389b20 | ||
|
|
8f82b62e0d | ||
|
|
dc213a4fab | ||
|
|
06e87e0f6a | ||
|
|
c2a08a1f26 | ||
|
|
df02eb125f | ||
|
|
0c13676d5f | ||
|
|
74e6ed1af3 | ||
|
|
72377e7bf2 | ||
|
|
5b085a75fd | ||
|
|
61389a8bef | ||
|
|
bd97e59254 | ||
|
|
95ecf296ad | ||
|
|
b7e0306d0a | ||
|
|
a9ee802240 | ||
|
|
d23d37fcfd | ||
|
|
289bc0afd9 | ||
|
|
c5dc00af74 | ||
|
|
d49b486224 | ||
|
|
417cfc2fb0 | ||
|
|
febbe14e6d | ||
|
|
44514930f9 | ||
|
|
dc778536ed | ||
|
|
18584ef2fd | ||
|
|
416ce35d73 | ||
|
|
7c12f01358 | ||
|
|
5a4654a0da | ||
|
|
89766c5f21 | ||
|
|
4ec11e692b | ||
|
|
d02f0e11c5 | ||
|
|
e28989638d | ||
|
|
915fe31274 | ||
|
|
db720a59e4 | ||
|
|
72752b1ee0 | ||
|
|
c663f1f62b | ||
|
|
d54f6278bb | ||
|
|
fc04336caa | ||
|
|
47376a0cc3 | ||
|
|
45aa0142a6 | ||
|
|
e3acb61d57 | ||
|
|
8fa33795a3 | ||
|
|
b1c9b134dc | ||
|
|
ae9930b87d | ||
|
|
aaa601841c | ||
|
|
8ca2d98496 | ||
|
|
ad805eb95b | ||
|
|
eb17325cbe | ||
|
|
b00787e161 | ||
|
|
81e7ec859d | ||
|
|
6f6179abb4 | ||
|
|
32a26a65d9 | ||
|
|
daccb5b4c0 | ||
|
|
cf97dcb992 | ||
|
|
6746b863b3 | ||
|
|
bf013c02ad | ||
|
|
fbedfb25ae | ||
|
|
9e877a929e | ||
|
|
e0eae9725b | ||
|
|
3083983fee | ||
|
|
5050b366d9 | ||
|
|
f0c237e001 | ||
|
|
970711f1fd | ||
|
|
19018e8959 | ||
|
|
7edfbbd8bd | ||
|
|
d36024394d | ||
|
|
35e0ab4280 | ||
|
|
ef60ac8348 | ||
|
|
0c47cfad6f | ||
|
|
eb6b79bed7 | ||
|
|
eaff0d30fb | ||
|
|
fae9f9b24b | ||
|
|
5d44998368 | ||
|
|
a145759d1e | ||
|
|
e2a42184b9 | ||
|
|
00a4c3a478 | ||
|
|
0320d2169e | ||
|
|
da26d11593 | ||
|
|
90aa3c75a7 | ||
|
|
1197e49068 | ||
|
|
b6ed50eb03 | ||
|
|
8c78c83d05 | ||
|
|
a5c4684273 | ||
|
|
2bbf0eb588 | ||
|
|
6095f55bf1 | ||
|
|
f64bd54093 | ||
|
|
bc91fd740f | ||
|
|
4a9bd7ed6d | ||
|
|
1ca8898703 | ||
|
|
8a25f32824 | ||
|
|
d9d001dffd | ||
|
|
bdfafa0b58 | ||
|
|
2266b04dd8 | ||
|
|
c50d166c23 | ||
|
|
de43d43560 | ||
|
|
f954faada6 | ||
|
|
9f75f2d522 | ||
|
|
cf70ecbd6d | ||
|
|
2a298469be | ||
|
|
3be668b343 | ||
|
|
2027f642ec | ||
|
|
9376d81d0d | ||
|
|
54e5d5fc35 | ||
|
|
b8552abcea | ||
|
|
3fb60a89a3 | ||
|
|
15b0ae5bf0 | ||
|
|
33b396c7b4 | ||
|
|
ea145d12c7 | ||
|
|
0d17dd8228 | ||
|
|
af5f28cbf8 | ||
|
|
234b754038 | ||
|
|
c231adf324 | ||
|
|
7a088a5280 | ||
|
|
96bbabbd2e | ||
|
|
e37c108195 | ||
|
|
53df35eef3 | ||
|
|
1061b01ab3 | ||
|
|
aee422e819 | ||
|
|
324667b877 | ||
|
|
10d73655bc | ||
|
|
96f11c786e | ||
|
|
9202197354 | ||
|
|
d78a396525 | ||
|
|
cd27b5f2bd | ||
|
|
78bc2727f7 | ||
|
|
8b58e93a2e | ||
|
|
3752234161 | ||
|
|
bf75094224 | ||
|
|
8d59c7dd40 | ||
|
|
a1fd579756 | ||
|
|
b9943d3746 | ||
|
|
b5502a49c3 | ||
|
|
7bd5d51e4e | ||
|
|
d4d937c37b | ||
|
|
2f0231025f | ||
|
|
f1a9e8840f | ||
|
|
2c559116fb | ||
|
|
4bedbd1d39 | ||
|
|
433feade5d | ||
|
|
10e4608ce0 | ||
|
|
ff3d2e7c29 | ||
|
|
7822a28c87 | ||
|
|
dcba79be48 | ||
|
|
2a7c573dec | ||
|
|
22cc9a254a | ||
|
|
09ae9168ca | ||
|
|
9eb9b8f631 | ||
|
|
6298daba1a | ||
|
|
2eb1c6a396 | ||
|
|
7717056cf2 | ||
|
|
9fd5cd303d | ||
|
|
04ff6249d5 | ||
|
|
fa9ecae2d6 | ||
|
|
62d2b76fa8 | ||
|
|
d95aab1139 | ||
|
|
80c2302fd3 | ||
|
|
38f954fd46 | ||
|
|
14b2f27c3e | ||
|
|
a2a37a928a | ||
|
|
c10c0be11b | ||
|
|
34ee4ca0cb | ||
|
|
30fd45890b | ||
|
|
36fe1966c3 | ||
|
|
1bb99e5d3c | ||
|
|
430802c1cf | ||
|
|
9106a06579 | ||
|
|
79e69da364 | ||
|
|
73116297aa | ||
|
|
8579eb0c19 | ||
|
|
9c8caddc5a | ||
|
|
2913847925 | ||
|
|
cf8438fe1d | ||
|
|
6d82fb83a0 | ||
|
|
207e1730e9 | ||
|
|
f0424fe7dd | ||
|
|
2e456a835d | ||
|
|
ab9039e77d | ||
|
|
9932a19139 | ||
|
|
64e4a89470 | ||
|
|
9d89d4c188 | ||
|
|
b2bf2b6e6b | ||
|
|
3b33318dc8 | ||
|
|
85307b29d0 | ||
|
|
95426efb8a | ||
|
|
3e2b568ef9 | ||
|
|
a06525649d | ||
|
|
b4699c3b46 | ||
|
|
27d978b891 | ||
|
|
f91b568069 | ||
|
|
06bd16c928 | ||
|
|
c0a0b79d2d | ||
|
|
1d5d902d28 | ||
|
|
f284a19246 | ||
|
|
735b8b7d48 | ||
|
|
a2e1a7a84d | ||
|
|
c138338358 | ||
|
|
e7eba93666 | ||
|
|
93ea4b2f4f | ||
|
|
5776c2ebe5 | ||
|
|
8defb4cd28 | ||
|
|
d358495f02 | ||
|
|
38dd2d6677 | ||
|
|
80bd107e57 | ||
|
|
68286df23d | ||
|
|
d494d7a725 | ||
|
|
36be4856fd | ||
|
|
c47b4f3667 | ||
|
|
fe129e8e4f | ||
|
|
0a1fb4e6ca | ||
|
|
7e97bfce10 | ||
|
|
49409dbf27 | ||
|
|
c3227a67ec | ||
|
|
a4a46a491f | ||
|
|
c11037fd27 | ||
|
|
114981f774 | ||
|
|
27543170d0 | ||
|
|
b0a39c5f86 | ||
|
|
4fbb1699be | ||
|
|
319f29da8d | ||
|
|
70bacb349e | ||
|
|
012bbcfe36 | ||
|
|
f74b469e68 | ||
|
|
55dc7a252e | ||
|
|
b015623128 | ||
|
|
c76a124d14 | ||
|
|
74d96ff4bd | ||
|
|
44fe0e1fc4 | ||
|
|
78245a072c | ||
|
|
1fd1c34112 | ||
|
|
0dae22adf2 | ||
|
|
746181cb33 | ||
|
|
4b9d3ca7de | ||
|
|
54da532ace | ||
|
|
4159b02753 | ||
|
|
42a068ab5e | ||
|
|
6f7d413d88 | ||
|
|
1aaafeb57b | ||
|
|
6dd3d825c8 | ||
|
|
02ccdeb94e | ||
|
|
7b192945eb | ||
|
|
28ed2b9e69 | ||
|
|
24b17c6de9 | ||
|
|
6eb93e9f8a | ||
|
|
8173d1f643 | ||
|
|
b29812e40b | ||
|
|
183dcd08d9 | ||
|
|
deea16e14f | ||
|
|
e96a719724 | ||
|
|
8e38d8e6f0 | ||
|
|
a0b862bbf7 | ||
|
|
434e2f4cbf | ||
|
|
cb0572d66e | ||
|
|
5c8e072b7f | ||
|
|
e39c452f31 | ||
|
|
1bb294afbc | ||
|
|
5def79e93c | ||
|
|
f072469409 | ||
|
|
4a444f7d60 | ||
|
|
ab77444fa3 | ||
|
|
57ffc58613 | ||
|
|
8c386ae07e | ||
|
|
cba6b4a749 | ||
|
|
64191a4b13 | ||
|
|
9bd6b249ce | ||
|
|
bec6c626d8 | ||
|
|
7ddf856d58 | ||
|
|
a3915fa5c4 | ||
|
|
17abca1caa | ||
|
|
f239050054 | ||
|
|
76a6956138 | ||
|
|
cf5ca9a5cf | ||
|
|
77ec62e9c8 | ||
|
|
a3f2196d4e | ||
|
|
d89c158a77 | ||
|
|
ef53197e1f | ||
|
|
8707c15b9c | ||
|
|
0b4e34b03b | ||
|
|
6968da153c | ||
|
|
03c809371a | ||
|
|
d282b0bf85 | ||
|
|
efa615a5e3 | ||
|
|
068db1f48b | ||
|
|
afacbe2a3a | ||
|
|
f8a0ef8f87 | ||
|
|
e1a2939f89 | ||
|
|
95da398e7d | ||
|
|
52adcc73d9 | ||
|
|
dbde686a97 | ||
|
|
1129110be3 | ||
|
|
a26a175957 | ||
|
|
795de3a75a | ||
|
|
8116b569c7 | ||
|
|
2bba79138f | ||
|
|
a8d481c2a5 | ||
|
|
85fc1e8235 | ||
|
|
ab4102a632 | ||
|
|
4ae2f06be4 | ||
|
|
831e03ad2a | ||
|
|
ab9f3fa42a | ||
|
|
13b8359de6 | ||
|
|
660d9c1602 | ||
|
|
b1d47c65d4 | ||
|
|
271e79095b | ||
|
|
6c268a3e9c | ||
|
|
e5ff70f606 | ||
|
|
801b1580f5 | ||
|
|
707868be33 | ||
|
|
9b9f34f881 | ||
|
|
7724cca384 | ||
|
|
01bd5a2646 | ||
|
|
2b44868373 | ||
|
|
f79a4a8cdb | ||
|
|
7bb6b75f3c | ||
|
|
e5d17a9452 | ||
|
|
dbd5f0073e | ||
|
|
12c0e8148b | ||
|
|
72a9a2bdbb | ||
|
|
80860fa8f5 | ||
|
|
8cf542abb0 | ||
|
|
a931b020b5 | ||
|
|
d317060ae4 | ||
|
|
eee07a4f96 | ||
|
|
7b048b423e | ||
|
|
a459206848 | ||
|
|
3a3b0b4c14 | ||
|
|
de0c527387 | ||
|
|
b54453d1a7 | ||
|
|
706ca874b0 | ||
|
|
51bd4626b1 | ||
|
|
cf6f40ea8f | ||
|
|
d3798f6290 | ||
|
|
4e33a1abf7 | ||
|
|
86e8f2e232 | ||
|
|
91e857874f | ||
|
|
8f50fd051e | ||
|
|
94e8e94750 | ||
|
|
54ece72b62 | ||
|
|
4702c8b591 | ||
|
|
00702f28c2 | ||
|
|
df29e98ea5 | ||
|
|
fe9922d654 | ||
|
|
362a017eee | ||
|
|
e8f3525226 | ||
|
|
1067086f71 | ||
|
|
0214d83aa5 | ||
|
|
d69a902876 | ||
|
|
f43aeda49c | ||
|
|
27484f78a9 | ||
|
|
93bf77bdec | ||
|
|
728651b5d5 | ||
|
|
fb74eefa9e | ||
|
|
853c964194 | ||
|
|
645c06764b | ||
|
|
2d23e7bd18 | ||
|
|
0290d0b82c | ||
|
|
3d86b49dae | ||
|
|
0b9e935806 | ||
|
|
17412d17e2 | ||
|
|
99f5193699 | ||
|
|
328e42ad42 | ||
|
|
6d28f2a8d9 | ||
|
|
421417ab07 | ||
|
|
68494a308e | ||
|
|
16f79d160a | ||
|
|
8f984042f4 | ||
|
|
eb1a699c5a | ||
|
|
ac766ec0eb | ||
|
|
21340a1c1e | ||
|
|
c594f3b0cf | ||
|
|
268e28a278 | ||
|
|
ca664b17d3 | ||
|
|
3936110c8d | ||
|
|
9f91870b1c | ||
|
|
97712107b7 | ||
|
|
d9fa148688 | ||
|
|
d88a7c73b4 | ||
|
|
894d3463ce | ||
|
|
5b5226d518 | ||
|
|
d025f3fb28 | ||
|
|
11be30dd40 | ||
|
|
4fad421c8a | ||
|
|
57b3543e7b | ||
|
|
a00543b6bc | ||
|
|
dbd25f0e32 | ||
|
|
62a3f33d72 | ||
|
|
74f9edef07 | ||
|
|
dbee3f01b7 | ||
|
|
6c72d5cf7e | ||
|
|
2827de4d63 | ||
|
|
381606aba2 | ||
|
|
567e42e071 | ||
|
|
2bf3b194fa | ||
|
|
444ea56182 | ||
|
|
d797589164 | ||
|
|
1577c775b3 | ||
|
|
3bf0b724a3 | ||
|
|
bd8dbb87b6 | ||
|
|
cd78ce3118 | ||
|
|
023f5704d0 | ||
|
|
123e94c603 | ||
|
|
156dc2ec4c | ||
|
|
b7b7e098be | ||
|
|
50760c6935 | ||
|
|
65dfc5d19e | ||
|
|
020b285808 | ||
|
|
bdd22e4d51 | ||
|
|
b7631d2a28 | ||
|
|
284ed38471 | ||
|
|
b96ef6adb8 | ||
|
|
ce6b427202 | ||
|
|
858e93c7f8 | ||
|
|
6477bdf3e8 | ||
|
|
ce5f240551 | ||
|
|
1c3c69f8b5 | ||
|
|
be2652544b | ||
|
|
f155eaff4b | ||
|
|
67981f002f | ||
|
|
0d83223445 | ||
|
|
9f8d648514 | ||
|
|
3d3b6d85cd | ||
|
|
8cf7c9548a | ||
|
|
323dbc7962 | ||
|
|
46a76fb318 | ||
|
|
a6246b0baa | ||
|
|
c8282795ef | ||
|
|
e93a44fe9b | ||
|
|
3e870866e0 | ||
|
|
78d771af36 | ||
|
|
6bb9dd22e0 | ||
|
|
1661c84af6 | ||
|
|
4f422f6f39 | ||
|
|
393ca87572 | ||
|
|
f4c56cbd53 | ||
|
|
9470558ecc | ||
|
|
f22fcb3b2a | ||
|
|
e257a226f3 | ||
|
|
a4e9878790 | ||
|
|
25b13978e7 | ||
|
|
3e9cff9287 | ||
|
|
758a3792eb | ||
|
|
ade5eb71cf | ||
|
|
d097819c52 | ||
|
|
905a97e0aa | ||
|
|
cc452dfa9b | ||
|
|
f00f263852 | ||
|
|
b54d672710 | ||
|
|
5047b89922 | ||
|
|
78ea75b116 | ||
|
|
c0964832f5 | ||
|
|
4e3dc0e820 | ||
|
|
2a2ad898b1 | ||
|
|
b26ed948c8 | ||
|
|
ba53722425 | ||
|
|
4852daf695 | ||
|
|
2d1be70ba2 | ||
|
|
b126641f13 | ||
|
|
6529d3e6f7 | ||
|
|
16c659b22c | ||
|
|
ec137044a0 | ||
|
|
053b6d9fd3 | ||
|
|
f76a5a3183 | ||
|
|
cfe59ee028 | ||
|
|
20d4a39b63 | ||
|
|
e7ce3909d2 | ||
|
|
acf4b78892 | ||
|
|
e9b3c58043 | ||
|
|
455105d3dc | ||
|
|
2dac108c57 | ||
|
|
0c6d380780 | ||
|
|
2c71802e38 | ||
|
|
3753840de5 | ||
|
|
5ff23f8f31 | ||
|
|
4315913a5d | ||
|
|
facb627786 | ||
|
|
b784988caf | ||
|
|
172ead8221 | ||
|
|
d224d7e404 | ||
|
|
7ea78c8517 | ||
|
|
ce589225dd | ||
|
|
79896af275 | ||
|
|
2831ed0538 | ||
|
|
e24dd2f954 | ||
|
|
60f0f5224d | ||
|
|
3578acaf0b | ||
|
|
2f9edf495e | ||
|
|
cc4cefaa4b | ||
|
|
81326a6d08 | ||
|
|
9d3626fec5 | ||
|
|
ae707b814f | ||
|
|
9c580b20a3 | ||
|
|
70c21f90b9 | ||
|
|
0964379a66 | ||
|
|
a176f58a92 | ||
|
|
fc0a082700 | ||
|
|
f7fffee28d | ||
|
|
51ed7db002 | ||
|
|
6e4945c56b | ||
|
|
c48be14f4f | ||
|
|
ecbbabfc3c | ||
|
|
687cdbb78b | ||
|
|
098086592b | ||
|
|
90d9ca901d | ||
|
|
eb016456a1 | ||
|
|
cd9732b47a | ||
|
|
7d867b806d | ||
|
|
761bb5744e | ||
|
|
e3b5b808c5 | ||
|
|
1901b981f3 | ||
|
|
c624fc9b17 | ||
|
|
9294a07362 | ||
|
|
9fcc30df89 | ||
|
|
1f5d9404d0 | ||
|
|
5096cc1f5f | ||
|
|
2aa11fa41d | ||
|
|
79e9085dd1 | ||
|
|
14f0234a26 | ||
|
|
a65c91a676 | ||
|
|
607328e1a0 | ||
|
|
a96dc2ecea | ||
|
|
3a77990781 | ||
|
|
4bb951d48e | ||
|
|
63503ee8f0 | ||
|
|
4a1148eb28 | ||
|
|
f6916bfd42 | ||
|
|
3ea525430e | ||
|
|
fb0d065723 | ||
|
|
47501b7f99 | ||
|
|
11cf27e006 | ||
|
|
ade1afe1b0 | ||
|
|
6cda070fe0 | ||
|
|
9bd470f2c7 | ||
|
|
530f1939d6 | ||
|
|
e4ea3752ac | ||
|
|
b728bf0d09 | ||
|
|
194fb2b86d | ||
|
|
ce5d901e6e | ||
|
|
14075630d4 | ||
|
|
5c1dd87fab | ||
|
|
06c371544a | ||
|
|
ffa0f048f3 | ||
|
|
22ca0041b8 | ||
|
|
232975bfdb | ||
|
|
4e84868747 | ||
|
|
9e1ccb900e | ||
|
|
98d55b988f | ||
|
|
e720a66076 | ||
|
|
7be7343e05 | ||
|
|
e26dd7bdfe | ||
|
|
906b9ae00b | ||
|
|
15c5f9c111 | ||
|
|
726dd69ab9 | ||
|
|
41b2c80dde | ||
|
|
cd01502d17 | ||
|
|
b2317f8b41 | ||
|
|
113167acf4 | ||
|
|
a3a9dc26b4 | ||
|
|
7e7664c29a | ||
|
|
fccb7e1c70 | ||
|
|
3f45b8c3bd | ||
|
|
ca6d5798e9 | ||
|
|
2110b24090 | ||
|
|
82484e26f5 | ||
|
|
ca47583a3b | ||
|
|
f4d6b0e1c4 | ||
|
|
9196d9541a | ||
|
|
b53fda1e1a | ||
|
|
9a5911f94c | ||
|
|
80acc85e59 | ||
|
|
8ce1c189f7 | ||
|
|
7228b2e068 | ||
|
|
33ab0cd7bd | ||
|
|
e33ac1d450 | ||
|
|
826cbbc3bf | ||
|
|
38f82115f7 | ||
|
|
d9bb78c8b8 | ||
|
|
905f631b71 | ||
|
|
9213c49ca1 | ||
|
|
fc7ecd672a | ||
|
|
a6944be5cf | ||
|
|
e5b61c9ac9 | ||
|
|
a9a4e2c8fb | ||
|
|
56eac5c9a1 | ||
|
|
4b1970afa9 | ||
|
|
22c9de487a | ||
|
|
66fad62e66 | ||
|
|
008fc5155a | ||
|
|
5834fbbc5d | ||
|
|
06219f1151 | ||
|
|
c2d2ba9f45 | ||
|
|
1eb3753f26 | ||
|
|
0a256247a0 | ||
|
|
7912ee6f7b | ||
|
|
9c58f23cf8 | ||
|
|
9245b0b666 | ||
|
|
92925a0af6 | ||
|
|
70c2e1b419 | ||
|
|
5d1728cc96 | ||
|
|
4076b6d92e | ||
|
|
b9e73b4852 | ||
|
|
014df67fed | ||
|
|
014ec021bb | ||
|
|
7fa9b91d23 | ||
|
|
98c4a7a2b1 | ||
|
|
c04c00d279 | ||
|
|
ef139e8b3c | ||
|
|
45c1c38993 | ||
|
|
1942fee581 | ||
|
|
b3c85e2709 | ||
|
|
561942da23 | ||
|
|
c217baa367 | ||
|
|
c699864c85 | ||
|
|
4ff0f482c3 | ||
|
|
28b942b186 | ||
|
|
4900e3081d | ||
|
|
145326c00c | ||
|
|
c7d90bfddd | ||
|
|
bfa84cfca5 | ||
|
|
cbc6e500b6 | ||
|
|
13a4fefe34 | ||
|
|
87e9ee5ce9 | ||
|
|
20cc5df5fe | ||
|
|
9e117b7b38 | ||
|
|
a02d914093 | ||
|
|
c5a95f1eb5 | ||
|
|
e1adbd7ddd | ||
|
|
355a7b04a8 | ||
|
|
d3ee0df93a | ||
|
|
7c24f7b170 | ||
|
|
a3060516c6 | ||
|
|
caa5c9e223 | ||
|
|
846538304f | ||
|
|
7b7e3b6750 | ||
|
|
a988b3224f | ||
|
|
89b3bf0796 | ||
|
|
6d8988b78a | ||
|
|
3acbd84f1d | ||
|
|
45403b877f | ||
|
|
f17d9bc421 | ||
|
|
ba2714fa22 | ||
|
|
2c4b3d515d | ||
|
|
59973a435e | ||
|
|
93232ec7df | ||
|
|
efa926676c | ||
|
|
dc24748c24 | ||
|
|
f8365f5009 | ||
|
|
c2138c4e88 | ||
|
|
bfad96dbb9 | ||
|
|
0ef6d9f9a0 | ||
|
|
c1a1cfe550 | ||
|
|
773dcd1d48 | ||
|
|
de99e79bf1 | ||
|
|
e83d367f49 | ||
|
|
aa76b382af | ||
|
|
595b7b194c | ||
|
|
5f908ba870 | ||
|
|
adc1b8a36b | ||
|
|
73c6e47e8a | ||
|
|
3a780f80f1 | ||
|
|
c78404e233 | ||
|
|
79a0cb096b | ||
|
|
6f9e8dc720 | ||
|
|
b39b0fef39 | ||
|
|
be139d9bde | ||
|
|
c6d82c722b | ||
|
|
0c20e2eb8b | ||
|
|
63eeb8d734 | ||
|
|
5214b3c1b0 | ||
|
|
5f7a61f040 | ||
|
|
c5a938de55 | ||
|
|
9372a587e4 | ||
|
|
948e724dff | ||
|
|
06faf2bd5b | ||
|
|
1dd81c04f3 | ||
|
|
56dbf70c3c | ||
|
|
f8a4ac6ad7 | ||
|
|
61bd06177f | ||
|
|
80e535a13c | ||
|
|
64b55c0f88 | ||
|
|
afcc4ff296 | ||
|
|
57fe197d3e | ||
|
|
9279a3fee7 | ||
|
|
b6363289bf | ||
|
|
8c1123edc6 | ||
|
|
834f545498 | ||
|
|
dd99bf479f | ||
|
|
2e26377e7c | ||
|
|
0329ee236f | ||
|
|
b347afcc5b | ||
|
|
fa57859477 | ||
|
|
88cb0e5928 | ||
|
|
e239eed6de | ||
|
|
504b3441dd | ||
|
|
872478d965 | ||
|
|
185f2baf76 | ||
|
|
36d6758945 | ||
|
|
d8c450d272 | ||
|
|
8ef5b9bab4 | ||
|
|
e6370a6482 | ||
|
|
b2170d016a | ||
|
|
5c124f11c2 | ||
|
|
2aed24a552 | ||
|
|
296469f5fe | ||
|
|
08371ba2c4 | ||
|
|
56bc2a2ade | ||
|
|
1084dc6dd3 | ||
|
|
8023caaa97 | ||
|
|
8b97466285 | ||
|
|
de1d102535 | ||
|
|
1e1e8c2547 | ||
|
|
aa49be65a1 | ||
|
|
cd820b3777 | ||
|
|
8d59ed5b2a | ||
|
|
e03efdbe0b | ||
|
|
4f52c2989c | ||
|
|
3fb13233a9 | ||
|
|
9695fd44ba | ||
|
|
1bb32134f8 |
@@ -1,5 +1,21 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
@@ -18,48 +34,41 @@ AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<(BeastConfig)'
|
||||
Priority: 0
|
||||
- Regex: '^<(ripple)/'
|
||||
Priority: 2
|
||||
- Regex: '^<(boost)/'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 4
|
||||
IncludeIsMainRegex: '$'
|
||||
ForEachMacros: [Q_FOREACH, BOOST_FOREACH]
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: "^<(test)/"
|
||||
Priority: 0
|
||||
- Regex: "^<(xrpld)/"
|
||||
Priority: 1
|
||||
- Regex: "^<(xrpl)/"
|
||||
Priority: 2
|
||||
- Regex: "^<(boost)/"
|
||||
Priority: 3
|
||||
- Regex: "^.*/"
|
||||
Priority: 4
|
||||
- Regex: '^.*\.h'
|
||||
Priority: 5
|
||||
- Regex: ".*"
|
||||
Priority: 6
|
||||
IncludeIsMainRegex: "$"
|
||||
IndentCaseLabels: true
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
IndentWidth: 4
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
@@ -70,18 +79,25 @@ PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
ReflowComments: true
|
||||
RequiresClausePosition: OwnLine
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
QualifierAlignment: Right
|
||||
---
|
||||
Language: Proto
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 0
|
||||
IndentWidth: 2
|
||||
|
||||
54
.claude/CLAUDE.md
Normal file
54
.claude/CLAUDE.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Workflow Orchestration
|
||||
|
||||
## 1. Plan Mode Default
|
||||
- Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions)
|
||||
- If something goes sideways, STOP and re-plan immediately - don't keep pushing
|
||||
- Use plan mode for verification steps, not just building
|
||||
- Write detailed specs upfront to reduce ambiguity
|
||||
|
||||
## 2. Subagent Strategy
|
||||
- Use subagents liberally to keep main context window clean
|
||||
- Offload research, exploration, and parallel analysis to subagents
|
||||
- For complex problems, throw compute at it via parallelizing
|
||||
- One task per subagent for focused execution
|
||||
|
||||
## 3. Self-Improvement Loop
|
||||
- After ANY correction from the user: update `tasks/lessons.md` with the pattern
|
||||
- Write rules for yourself that prevent the same mistake
|
||||
- Ruthlessly iterate on these rules until mistake drops
|
||||
- Review lessons at session start for relevant project
|
||||
|
||||
## 4. Verification Before Done
|
||||
- Never mark a task complete without proving it works
|
||||
- Diff behavior between main and your changes when relevant
|
||||
- Ask yourself: "Would a staff engineer approve this?"
|
||||
- Run tests, check logs, demonstrate correctness
|
||||
|
||||
## 5. Demand Elegance (Balanced)
|
||||
- For non-trivial changes: pause and ask "is there a more elegant way?"
|
||||
- If a fix feels hacky: "Know now, do later, implement the elegant solution"
|
||||
- Skip this for simple, obvious fixes - don't over-engineer
|
||||
- Challenge your own first solution
|
||||
|
||||
## 6. Autonomous Bug Fixing
|
||||
- When given a bug report: just fix it. Don't ask for hand-holding
|
||||
- Point at logs, errors, failing tests - then resolve them
|
||||
- Zero context switching required from the user
|
||||
- Go fix failing CI tests without being told how
|
||||
|
||||
# Task Management
|
||||
|
||||
1. **Plan First**: Write plan to `tasks/todo.md` with checkable items
|
||||
2. **Verify Plans**: Check in before starting implementation
|
||||
3. **Track Progress**: Mark items complete as you go
|
||||
4. **Explain Changes**: High-level summary at each step
|
||||
5. **Document Results**: Add review section to `tasks/todo.md`
|
||||
6. **Capture Lessons**: Update `tasks/lessons.md` after corrections
|
||||
|
||||
# Core Principles
|
||||
|
||||
**Simplicity First**: Make every change as simple as possible. Impact minimal code.
|
||||
|
||||
**No Boilerplate**: Skip documentation. No README/docs bloat. Test only if requested.
|
||||
|
||||
**Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs.
|
||||
530
.claude/skills/amendment.md
Normal file
530
.claude/skills/amendment.md
Normal file
@@ -0,0 +1,530 @@
|
||||
# XRPL Amendment Creation Skill
|
||||
|
||||
This skill guides you through creating XRPL amendments, whether for brand new features or fixes/extensions to existing functionality.
|
||||
|
||||
## Amendment Types
|
||||
|
||||
There are two main types of amendments:
|
||||
|
||||
1. **New Feature Amendment** (`feature{Name}`) - Entirely new functionality
|
||||
2. **Fix/Extension Amendment** (`fix{Name}`) - Modifications to existing functionality
|
||||
|
||||
## Step 1: Determine Amendment Type
|
||||
|
||||
Ask the user:
|
||||
- Is this a **brand new feature** (new transaction type, ledger entry, or capability)?
|
||||
- Or is this a **fix or extension** to existing functionality?
|
||||
|
||||
---
|
||||
|
||||
## For NEW FEATURE Amendments
|
||||
|
||||
### Checklist:
|
||||
|
||||
#### 1. Feature Definition in features.macro
|
||||
**ONLY FILE TO EDIT:** `include/xrpl/protocol/detail/features.macro`
|
||||
|
||||
- [ ] Add to TOP of features.macro (reverse chronological order):
|
||||
```
|
||||
XRPL_FEATURE(YourFeatureName, Supported::no, VoteBehavior::DefaultNo)
|
||||
```
|
||||
- [ ] This creates the variable `featureYourFeatureName` automatically
|
||||
- [ ] Follow naming convention: Use the feature name WITHOUT the "feature" prefix
|
||||
- [ ] Examples: `Batch` → `featureBatch`, `LendingProtocol` → `featureLendingProtocol`
|
||||
|
||||
#### 2. Support Status
|
||||
- [ ] Start with `Supported::no` during development
|
||||
- [ ] Change to `Supported::yes` when ready for network voting
|
||||
- [ ] Use `VoteBehavior::DefaultNo` (validators must explicitly vote for it)
|
||||
|
||||
#### 3. Code Implementation
|
||||
- [ ] Implement new functionality (transaction type, ledger entry, etc.)
|
||||
- [ ] Add feature gate check in preflight:
|
||||
```cpp
|
||||
if (!env.current()->rules().enabled(feature{Name}))
|
||||
{
|
||||
return temDISABLED;
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Disable Route Handling
|
||||
- [ ] Ensure transaction returns `temDISABLED` when amendment is disabled
|
||||
- [ ] Implement early rejection in preflight/preclaim phase
|
||||
- [ ] Add appropriate error messages
|
||||
|
||||
#### 5. Test Implementation
|
||||
Create comprehensive test suite with this structure:
|
||||
|
||||
```cpp
|
||||
class {FeatureName}_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void testEnable(FeatureBitset features)
|
||||
{
|
||||
testcase("enabled");
|
||||
|
||||
// Test with feature DISABLED
|
||||
{
|
||||
auto const amendNoFeature = features - feature{Name};
|
||||
Env env{*this, amendNoFeature};
|
||||
|
||||
env(transaction, ter(temDISABLED));
|
||||
}
|
||||
|
||||
// Test with feature ENABLED
|
||||
{
|
||||
Env env{*this, features};
|
||||
|
||||
env(transaction, ter(tesSUCCESS));
|
||||
// Validate new functionality works
|
||||
}
|
||||
}
|
||||
|
||||
void testPreflight(FeatureBitset features)
|
||||
{
|
||||
testcase("preflight");
|
||||
// Test malformed transaction validation
|
||||
}
|
||||
|
||||
void testPreclaim(FeatureBitset features)
|
||||
{
|
||||
testcase("preclaim");
|
||||
// Test signature and claim phase validation
|
||||
}
|
||||
|
||||
void testWithFeats(FeatureBitset features)
|
||||
{
|
||||
testEnable(features);
|
||||
testPreflight(features);
|
||||
testPreclaim(features);
|
||||
// Add feature-specific tests
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
using namespace test::jtx;
|
||||
auto const all = supported_amendments();
|
||||
testWithFeats(all);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
#### 6. Test Coverage Requirements
|
||||
- [ ] Test amendment DISABLED state (returns `temDISABLED`)
|
||||
- [ ] Test amendment ENABLED state (returns `tesSUCCESS`)
|
||||
- [ ] Test malformed transactions
|
||||
- [ ] Test signature validation
|
||||
- [ ] Test edge cases specific to feature
|
||||
- [ ] Test amendment transition behavior
|
||||
|
||||
#### 7. Documentation
|
||||
- [ ] Create specification document (XLS_{NAME}.md)
|
||||
- [ ] Document new transaction types, ledger entries, or capabilities
|
||||
- [ ] Create test plan document
|
||||
- [ ] Document expected behavior when enabled/disabled
|
||||
|
||||
---
|
||||
|
||||
## For FIX/EXTENSION Amendments
|
||||
|
||||
### Checklist:
|
||||
|
||||
#### 1. Fix Definition in features.macro
|
||||
**ONLY FILE TO EDIT:** `include/xrpl/protocol/detail/features.macro`
|
||||
|
||||
- [ ] Add to TOP of features.macro (reverse chronological order):
|
||||
```
|
||||
XRPL_FIX(YourFixName, Supported::no, VoteBehavior::DefaultNo)
|
||||
```
|
||||
- [ ] This creates the variable `fixYourFixName` automatically
|
||||
- [ ] Follow naming convention: Use the fix name WITHOUT the "fix" prefix (it's added automatically)
|
||||
- [ ] Examples: `TokenEscrowV1` → `fixTokenEscrowV1`, `DirectoryLimit` → `fixDirectoryLimit`
|
||||
- [ ] Start with `Supported::no` during development, change to `Supported::yes` when ready
|
||||
|
||||
#### 2. Backward Compatibility Implementation
|
||||
**Critical**: Use enable() with if/else to preserve existing functionality
|
||||
|
||||
```cpp
|
||||
// Check if fix is enabled
|
||||
bool const fix{Name} = env.current()->rules().enabled(fix{Name});
|
||||
|
||||
// Conditional logic based on amendment state
|
||||
if (fix{Name})
|
||||
{
|
||||
// NEW behavior with fix applied
|
||||
// This is the corrected/improved logic
|
||||
}
|
||||
else
|
||||
{
|
||||
// OLD behavior (legacy path)
|
||||
// Preserve original functionality for backward compatibility
|
||||
}
|
||||
```
|
||||
|
||||
**Alternative pattern with ternary operator:**
|
||||
```cpp
|
||||
auto& viewToUse = sb.rules().enabled(fix{Name}) ? sb : legacyView;
|
||||
```
|
||||
|
||||
#### 3. Multiple Fix Versions Pattern
|
||||
For iterative fixes, use version checking:
|
||||
|
||||
```cpp
|
||||
bool const fixV1 = rv.rules().enabled(fixXahauV1);
|
||||
bool const fixV2 = rv.rules().enabled(fixXahauV2);
|
||||
|
||||
switch (transactionType)
|
||||
{
|
||||
case TYPE_1:
|
||||
if (fixV1) {
|
||||
// Behavior with V1 fix
|
||||
} else {
|
||||
// Legacy behavior
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_2:
|
||||
if (fixV2) {
|
||||
// Behavior with V2 fix
|
||||
} else if (fixV1) {
|
||||
// Behavior with only V1
|
||||
} else {
|
||||
// Legacy behavior
|
||||
}
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Test Both Paths
|
||||
Always test BOTH enabled and disabled states:
|
||||
|
||||
```cpp
|
||||
void testFix(FeatureBitset features)
|
||||
{
|
||||
testcase("fix behavior");
|
||||
|
||||
for (bool withFix : {false, true})
|
||||
{
|
||||
auto const amend = withFix ? features : features - fix{Name};
|
||||
Env env{*this, amend};
|
||||
|
||||
// Setup test scenario
|
||||
env.fund(XRP(1000), alice);
|
||||
env.close();
|
||||
|
||||
if (!withFix)
|
||||
{
|
||||
// Test OLD behavior (before fix)
|
||||
env(operation, ter(expectedErrorWithoutFix));
|
||||
// Verify old behavior is preserved
|
||||
}
|
||||
else
|
||||
{
|
||||
// Test NEW behavior (after fix)
|
||||
env(operation, ter(expectedErrorWithFix));
|
||||
// Verify fix works correctly
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. Security Fix Pattern
|
||||
For security-critical fixes (like fixBatchInnerSigs):
|
||||
|
||||
```cpp
|
||||
// Test vulnerability exists WITHOUT fix
|
||||
{
|
||||
auto const amendNoFix = features - fix{Name};
|
||||
Env env{*this, amendNoFix};
|
||||
|
||||
// Demonstrate vulnerability
|
||||
// Expected: Validity::Valid (WRONG - vulnerable!)
|
||||
BEAST_EXPECT(result == Validity::Valid);
|
||||
}
|
||||
|
||||
// Test vulnerability is FIXED WITH amendment
|
||||
{
|
||||
Env env{*this, features};
|
||||
|
||||
// Demonstrate fix
|
||||
// Expected: Validity::SigBad (CORRECT - protected!)
|
||||
BEAST_EXPECT(result == Validity::SigBad);
|
||||
}
|
||||
```
|
||||
|
||||
#### 6. Test Coverage Requirements
|
||||
- [ ] Test fix DISABLED (legacy behavior preserved)
|
||||
- [ ] Test fix ENABLED (new behavior applied)
|
||||
- [ ] Test amendment transition
|
||||
- [ ] For security fixes: demonstrate vulnerability without fix
|
||||
- [ ] For security fixes: demonstrate protection with fix
|
||||
- [ ] Test edge cases that triggered the fix
|
||||
- [ ] Test combinations with other amendments
|
||||
|
||||
#### 7. Documentation
|
||||
- [ ] Document what was broken/suboptimal
|
||||
- [ ] Document the fix applied
|
||||
- [ ] Document backward compatibility behavior
|
||||
- [ ] Create test summary showing both paths
|
||||
|
||||
---
|
||||
|
||||
## Best Practices for All Amendments
|
||||
|
||||
### 1. Naming Conventions
|
||||
- New features: `feature{DescriptiveName}` (e.g., `featureBatch`, `featureHooks`)
|
||||
- Fixes: `fix{IssueDescription}` (e.g., `fixBatchInnerSigs`, `fixNSDelete`)
|
||||
- Use CamelCase without underscores
|
||||
|
||||
### 2. Feature Flag Checking
|
||||
```cpp
|
||||
// At the point where behavior diverges:
|
||||
bool const amendmentEnabled = env.current()->rules().enabled(feature{Name});
|
||||
|
||||
// Or in view/rules context:
|
||||
if (!rv.rules().enabled(feature{Name}))
|
||||
return {}; // or legacy behavior
|
||||
```
|
||||
|
||||
### 3. Error Codes
|
||||
- New features when disabled: `temDISABLED`
|
||||
- Fixes may return different validation errors based on state
|
||||
- Document all error code changes
|
||||
|
||||
### 4. Test Structure Template
|
||||
```cpp
|
||||
class Amendment_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
// Core tests
|
||||
void testEnable(FeatureBitset features); // Enable/disable states
|
||||
void testPreflight(FeatureBitset features); // Validation
|
||||
void testPreclaim(FeatureBitset features); // Claim phase
|
||||
|
||||
// Feature-specific tests
|
||||
void test{SpecificScenario1}(FeatureBitset features);
|
||||
void test{SpecificScenario2}(FeatureBitset features);
|
||||
|
||||
// Master orchestrator
|
||||
void testWithFeats(FeatureBitset features)
|
||||
{
|
||||
testEnable(features);
|
||||
testPreflight(features);
|
||||
testPreclaim(features);
|
||||
test{SpecificScenario1}(features);
|
||||
test{SpecificScenario2}(features);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
using namespace test::jtx;
|
||||
auto const all = supported_amendments();
|
||||
testWithFeats(all);
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Amendment, app, ripple);
|
||||
```
|
||||
|
||||
### 5. Documentation Files
|
||||
Create these files:
|
||||
- **Specification**: `XLS_{FEATURE_NAME}.md` - Technical specification
|
||||
- **Test Plan**: `{FEATURE}_COMPREHENSIVE_TEST_PLAN.md` - Test strategy
|
||||
- **Test Summary**: `{FEATURE}_TEST_IMPLEMENTATION_SUMMARY.md` - Test results
|
||||
- **Review Findings**: `{FEATURE}_REVIEW_FINDINGS.md` (if applicable)
|
||||
|
||||
### 6. Amendment Transition Testing
|
||||
Test the moment an amendment activates:
|
||||
|
||||
```cpp
|
||||
void testAmendmentTransition(FeatureBitset features)
|
||||
{
|
||||
testcase("amendment transition");
|
||||
|
||||
// Start with amendment disabled
|
||||
auto const amendNoFeature = features - feature{Name};
|
||||
Env env{*this, amendNoFeature};
|
||||
|
||||
// Perform operations in disabled state
|
||||
env(operation1, ter(temDISABLED));
|
||||
|
||||
// Enable amendment mid-test (if testing mechanism supports it)
|
||||
// Verify state transitions correctly
|
||||
|
||||
// Perform operations in enabled state
|
||||
env(operation2, ter(tesSUCCESS));
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Cache Behavior
|
||||
If amendment affects caching (like fixBatchInnerSigs):
|
||||
- [ ] Test cache behavior without fix
|
||||
- [ ] Test cache behavior with fix
|
||||
- [ ] Document cache invalidation requirements
|
||||
|
||||
### 8. Multi-Amendment Combinations
|
||||
Test interactions with other amendments:
|
||||
|
||||
```cpp
|
||||
void testMultipleAmendments(FeatureBitset features)
|
||||
{
|
||||
// Test all combinations
|
||||
for (bool withFeature1 : {false, true})
|
||||
for (bool withFeature2 : {false, true})
|
||||
{
|
||||
auto amend = features;
|
||||
if (!withFeature1) amend -= feature1;
|
||||
if (!withFeature2) amend -= feature2;
|
||||
|
||||
Env env{*this, amend};
|
||||
// Test interaction behavior
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. Performance Considerations
|
||||
- [ ] Minimize runtime checks (cache `rules().enabled()` result if used multiple times)
|
||||
- [ ] Avoid nested feature checks where possible
|
||||
- [ ] Document performance impact
|
||||
|
||||
### 10. Code Review Checklist
|
||||
- [ ] Both enabled/disabled paths are tested
|
||||
- [ ] Backward compatibility is preserved (for fixes)
|
||||
- [ ] Error codes are appropriate
|
||||
- [ ] Documentation is complete
|
||||
- [ ] Security implications are considered
|
||||
- [ ] Cache behavior is correct
|
||||
- [ ] Edge cases are covered
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns Reference
|
||||
|
||||
### Pattern: New Transaction Type
|
||||
```cpp
|
||||
// In transactor code:
|
||||
TER doApply() override
|
||||
{
|
||||
if (!ctx_.view().rules().enabled(feature{Name}))
|
||||
return temDISABLED;
|
||||
|
||||
// New transaction logic here
|
||||
return tesSUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern: New Ledger Entry Type
|
||||
```cpp
|
||||
// In ledger entry creation:
|
||||
if (!view.rules().enabled(feature{Name}))
|
||||
return temDISABLED;
|
||||
|
||||
auto const sle = std::make_shared<SLE>(ltNEW_TYPE, keylet);
|
||||
view.insert(sle);
|
||||
```
|
||||
|
||||
### Pattern: Behavioral Fix
|
||||
```cpp
|
||||
// At decision point:
|
||||
bool const useFix = view.rules().enabled(fix{Name});
|
||||
|
||||
if (useFix)
|
||||
{
|
||||
// Corrected behavior
|
||||
return performCorrectValidation();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy behavior (preserved for compatibility)
|
||||
return performLegacyValidation();
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern: View Selection
|
||||
```cpp
|
||||
// Select which view to use based on amendment:
|
||||
auto& applyView = sb.rules().enabled(feature{Name}) ? newView : legacyView;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Workflow 1: Creating a New Feature Amendment
|
||||
|
||||
1. User requests: "Add a new ClaimReward transaction type"
|
||||
2. Skill asks: "What should the amendment be called? (e.g., BalanceRewards - without 'feature' prefix)"
|
||||
3. Add to features.macro:
|
||||
```
|
||||
XRPL_FEATURE(BalanceRewards, Supported::no, VoteBehavior::DefaultNo)
|
||||
```
|
||||
4. Implement transaction with `temDISABLED` gate using `featureBalanceRewards`
|
||||
5. Create test suite with testEnable, testPreflight, testPreclaim
|
||||
6. Run tests with amendment enabled and disabled
|
||||
7. When ready, update to `Supported::yes` in features.macro
|
||||
8. Create specification document
|
||||
9. Review checklist
|
||||
|
||||
### Workflow 2: Creating a Fix Amendment
|
||||
|
||||
1. User requests: "Fix the signature validation bug in batch transactions"
|
||||
2. Skill asks: "What should the fix be called? (e.g., BatchInnerSigs - without 'fix' prefix)"
|
||||
3. Add to features.macro:
|
||||
```
|
||||
XRPL_FIX(BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)
|
||||
```
|
||||
4. Implement fix with if/else using `fixBatchInnerSigs` to preserve old behavior
|
||||
5. Create test demonstrating vulnerability without fix
|
||||
6. Create test showing fix works when enabled
|
||||
7. When ready, update to `Supported::yes` in features.macro
|
||||
8. Document both code paths
|
||||
9. Review checklist
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: File Locations
|
||||
|
||||
- **Amendment definitions (ONLY place to add)**: `include/xrpl/protocol/detail/features.macro`
|
||||
- **Feature.h (auto-generated, DO NOT EDIT)**: `include/xrpl/protocol/Feature.h`
|
||||
- **Feature.cpp (auto-generated, DO NOT EDIT)**: `src/libxrpl/protocol/Feature.cpp`
|
||||
- **Test files**: `src/test/app/` or `src/test/protocol/`
|
||||
- **Specifications**: Project root (e.g., `XLS_SMART_CONTRACTS.md`)
|
||||
- **Test plans**: Project root (e.g., `BATCH_COMPREHENSIVE_TEST_PLAN.md`)
|
||||
|
||||
## How the Macro System Works
|
||||
|
||||
The amendment system uses C preprocessor macros:
|
||||
|
||||
1. **features.macro** - Single source of truth (ONLY file you edit):
|
||||
```
|
||||
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX(TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
```
|
||||
|
||||
2. **Feature.h** - Auto-generated declarations from macro:
|
||||
```cpp
|
||||
extern uint256 const featureBatch;
|
||||
extern uint256 const fixTokenEscrowV1;
|
||||
```
|
||||
|
||||
3. **Feature.cpp** - Auto-generated registrations from macro:
|
||||
```cpp
|
||||
uint256 const featureBatch = registerFeature("Batch", ...);
|
||||
uint256 const fixTokenEscrowV1 = registerFeature("fixTokenEscrowV1", ...);
|
||||
```
|
||||
|
||||
**DO NOT** modify Feature.h or Feature.cpp directly - they process features.macro automatically.
|
||||
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Invoke this skill when:
|
||||
- Creating a new XRPL amendment
|
||||
- Adding a new transaction type or ledger entry
|
||||
- Fixing existing XRPL functionality
|
||||
- Need guidance on amendment best practices
|
||||
- Setting up amendment tests
|
||||
- Reviewing amendment implementation
|
||||
|
||||
The skill will guide you through the appropriate workflow based on amendment type.
|
||||
99
.claude/skills/index.md
Normal file
99
.claude/skills/index.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# xrpld Codebase Skills Index
|
||||
|
||||
## Description
|
||||
This is the top-level guide for all best-practices skills in this repository. Use this to understand the codebase organization and find the right skill for any task.
|
||||
|
||||
## When to Use Skills
|
||||
Reference a skill whenever you are:
|
||||
- **Writing new code** in a module - check the skill first for established patterns
|
||||
- **Modifying existing code** - verify your changes follow module conventions
|
||||
- **Adding a new transaction type** - see `libxrpl/tx/transactors.md` for the full template
|
||||
- **Debugging** - skills list key files and common pitfalls per module
|
||||
- **Reviewing code** - skills document what "correct" looks like for each module
|
||||
|
||||
## Codebase Architecture
|
||||
|
||||
The codebase is split into two main areas:
|
||||
|
||||
### `src/libxrpl/` — The Library (skills in `.claude/skills/libxrpl/`)
|
||||
Reusable library code: data types, serialization, cryptography, ledger state, transaction processing, and storage. This is the **protocol layer**.
|
||||
|
||||
| Module | Responsibility |
|
||||
|--------|---------------|
|
||||
| `basics` | Foundational types: Buffer, Slice, base_uint, Number, logging, error contracts |
|
||||
| `beast` | Support layer: Journal logging, test framework, instrumentation, IP types |
|
||||
| `conditions` | Crypto-conditions (RFC): fulfillment validation, DER encoding |
|
||||
| `core` | Job queue, load monitoring, hash-based message dedup |
|
||||
| `crypto` | CSPRNG, secure erasure, RFC1751 encoding |
|
||||
| `json` | Json::Value, parsing, serialization, StaticString optimization |
|
||||
| `ledger` | ReadView/ApplyView, state tables, payment sandbox, credit ops |
|
||||
| `net` | HTTP/HTTPS client, SSL certs, async I/O |
|
||||
| `nodestore` | Persistent node storage: RocksDB, NuDB, Memory backends |
|
||||
| `protocol` | STObject hierarchy, SField, Serializer, TER codes, Features, Keylets |
|
||||
| `proto` | Protocol Buffer generated headers (gRPC API definitions) |
|
||||
| `rdb` | SOCI database wrapper, checkpointing |
|
||||
| `resource` | Rate limiting, endpoint tracking, abuse prevention |
|
||||
| `server` | Port config, SSL/TLS, WebSocket, admin networks |
|
||||
| `shamap` | SHA-256 Merkle radix tree (16-way branching, COW) |
|
||||
| `tx` | Transaction pipeline: Transactor base, preflight/preclaim/doApply |
|
||||
|
||||
### `src/xrpld/` — The Server Application (skills in `.claude/skills/xrpld/`)
|
||||
The running rippled server: application lifecycle, consensus, networking, RPC, and peer management. This is the **application layer**.
|
||||
|
||||
| Module | Responsibility |
|
||||
|--------|---------------|
|
||||
| `app` | Application singleton, ledger management, consensus adapters, services |
|
||||
| `app/main` | Application initialization and lifecycle |
|
||||
| `app/ledger` | Ledger storage, retrieval, immutable state management |
|
||||
| `app/consensus` | RCL consensus adapters (bridges generic algorithm to rippled) |
|
||||
| `app/misc` | Fee voting, amendments, SHAMapStore, TxQ, validators, NetworkOPs |
|
||||
| `app/paths` | Payment path finding algorithm, trust line caching |
|
||||
| `app/rdb` | Application-level database operations |
|
||||
| `app/tx` | Application-level transaction handling |
|
||||
| `consensus` | Generic consensus algorithm (CRTP-based, app-independent) |
|
||||
| `core` | Configuration (Config.h), time keeping, network ID |
|
||||
| `overlay` | P2P networking: peer connections, protocol buffers, clustering |
|
||||
| `peerfinder` | Network discovery: bootcache, livecache, slot management |
|
||||
| `perflog` | Performance logging and instrumentation |
|
||||
| `rpc` | RPC handler dispatch, coroutine suspension, 40+ command handlers |
|
||||
| `shamap` | Application-level SHAMap operations (NodeFamily) |
|
||||
|
||||
### `include/xrpl/` — Header Files
|
||||
Headers live in `include/xrpl/` and mirror the `src/libxrpl/` structure. Each skill already references its corresponding headers in the "Key Files" section.
|
||||
|
||||
## Cross-Cutting Conventions
|
||||
|
||||
### Error Handling
|
||||
- **Transaction errors**: Return `TER` enum (tesSUCCESS, tecFROZEN, temBAD_AMOUNT, etc.)
|
||||
- **Logic errors**: `Throw<std::runtime_error>()`, `LogicError()`, `XRPL_ASSERT()`
|
||||
- **I/O errors**: `Status` enum or `boost::system::error_code`
|
||||
- **RPC errors**: Inject via `context.params`
|
||||
|
||||
### Assertions
|
||||
```cpp
|
||||
XRPL_ASSERT(condition, "ClassName::method : description"); // Debug only
|
||||
XRPL_VERIFY(condition, "ClassName::method : description"); // Always enabled
|
||||
```
|
||||
|
||||
### Logging
|
||||
```cpp
|
||||
JLOG(j_.warn()) << "Message"; // Always wrap in JLOG macro
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
- `IntrusiveRefCounts` + `SharedIntrusive` for shared ownership in libxrpl
|
||||
- `std::shared_ptr` for shared ownership in xrpld
|
||||
- `std::unique_ptr` for exclusive ownership
|
||||
- `CountedObject<T>` mixin for instance tracking
|
||||
|
||||
### Feature Gating
|
||||
```cpp
|
||||
if (ctx.rules.enabled(featureMyFeature)) { /* new behavior */ }
|
||||
```
|
||||
|
||||
### Code Organization
|
||||
- Headers in `include/xrpl/`, implementations in `src/libxrpl/` or `src/xrpld/`
|
||||
- `#pragma once` (never `#ifndef` guards)
|
||||
- `namespace xrpl { }` for all code
|
||||
- `detail/` namespace for internal helpers
|
||||
- Factory functions: `make_*()` returning `unique_ptr` or `shared_ptr`
|
||||
79
.claude/skills/libxrpl/basics.md
Normal file
79
.claude/skills/libxrpl/basics.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Basics Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with foundational utilities in `src/libxrpl/basics/` or `include/xrpl/basics/`. Covers data structures, memory management, logging, numeric operations, error handling, and string utilities.
|
||||
|
||||
## Responsibility
|
||||
Provides fundamental building blocks for the entire codebase: memory types (Buffer, Slice, Blob), intrusive smart pointers, arbitrary-precision integers (base_uint), multi-precision decimal arithmetic (Number), logging infrastructure, exception handling contracts, and platform abstractions.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Memory Types
|
||||
- **Slice** - Non-owning view into contiguous bytes (like std::span)
|
||||
- **Buffer** - Owning byte container (like std::vector<uint8_t>)
|
||||
- **Blob** - Alias for std::vector<unsigned char>
|
||||
- Prefer `Slice` for read-only parameters, `Buffer` for owned data
|
||||
|
||||
### Intrusive Smart Pointers
|
||||
```cpp
|
||||
// Prefer intrusive pointers over std::shared_ptr for minimal overhead
|
||||
// Object embeds its own reference count
|
||||
class MyObject : public IntrusiveRefCounts {
|
||||
// ...
|
||||
};
|
||||
// Use SharedIntrusive<MyObject> when weak pointers needed
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
```cpp
|
||||
// Contract-based exceptions (logs call stack then throws)
|
||||
Throw<std::runtime_error>("Invalid source file");
|
||||
LogThrow("exception message");
|
||||
|
||||
// Logic errors for invariant violations
|
||||
LogicError("This should never happen");
|
||||
|
||||
// Assertions (fuzzing-aware)
|
||||
XRPL_ASSERT(condition, "function_name : description");
|
||||
XRPL_VERIFY(condition, "message"); // Always enabled, not just debug
|
||||
```
|
||||
|
||||
### Logging
|
||||
```cpp
|
||||
// Use JLOG macro - short-circuits if level disabled
|
||||
JLOG(debugLog().warn()) << "Message: " << value;
|
||||
JLOG(j_.trace()) << "Verbose detail";
|
||||
// Never: debugLog().warn() << "msg"; // Missing JLOG wastes formatting
|
||||
```
|
||||
|
||||
### Number Precision
|
||||
```cpp
|
||||
// Use Number for multi-precision decimal arithmetic
|
||||
// Always use RAII guard for rounding mode
|
||||
NumberRoundModeGuard mg(Number::towards_zero);
|
||||
auto result = amount * rate;
|
||||
// Guard restores previous mode on scope exit
|
||||
```
|
||||
|
||||
### base_uint Template
|
||||
```cpp
|
||||
// Typed big-endian integers: base_uint<Bits, Tag>
|
||||
// Tag prevents mixing unrelated types of same width
|
||||
using uint256 = base_uint<256, void>;
|
||||
using AccountID = base_uint<160, detail::AccountIDTag>;
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never use `std::shared_ptr` when IntrusiveRefCounts is available - it adds a separate allocation
|
||||
- Never format log messages without JLOG wrapper - wastes CPU when level is disabled
|
||||
- Never use raw `assert()` - use `XRPL_ASSERT` for fuzzing instrumentation support
|
||||
- Never mix `Buffer` and `Slice` ownership semantics - Slice does NOT own its data
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/basics/IntrusiveRefCounts.h` - Atomic reference counting
|
||||
- `include/xrpl/basics/IntrusivePointer.h` - Smart pointer using intrusive refs
|
||||
- `include/xrpl/basics/base_uint.h` - Arbitrary-length big-endian integers
|
||||
- `include/xrpl/basics/Buffer.h`, `Blob.h`, `Slice.h` - Memory types
|
||||
- `include/xrpl/basics/Number.h` - Multi-precision decimal arithmetic
|
||||
- `include/xrpl/basics/Log.h` - Logging infrastructure
|
||||
- `include/xrpl/basics/contract.h` - Throw, LogicError, XRPL_ASSERT
|
||||
62
.claude/skills/libxrpl/beast.md
Normal file
62
.claude/skills/libxrpl/beast.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Beast Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with the Beast support layer in `src/libxrpl/beast/` or `include/xrpl/beast/`. Covers networking types, unit testing, Journal logging, and instrumentation.
|
||||
|
||||
## Responsibility
|
||||
Library support layer providing network types (IP addresses, endpoints), unit testing framework, Journal/logging abstractions, instrumentation/assertion macros, and type introspection utilities.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Journal Logging
|
||||
```cpp
|
||||
// Journal wraps a Sink pointer - copy by value is cheap
|
||||
beast::Journal const j_;
|
||||
|
||||
// Severity levels: kTrace, kDebug, kInfo, kWarning, kError, kFatal
|
||||
JLOG(j_.warn()) << "User-facing issue";
|
||||
JLOG(j_.debug()) << "Implementation detail";
|
||||
JLOG(j_.trace()) << "Very verbose diagnostic";
|
||||
JLOG(j_.error()) << "Unexpected failure";
|
||||
```
|
||||
|
||||
### Unit Testing
|
||||
```cpp
|
||||
class MyTest : public beast::unit_test::suite {
|
||||
void run() override {
|
||||
testcase("feature description");
|
||||
BEAST_EXPECT(value == expected); // Non-fatal assertion
|
||||
BEAST_REQUIRE(value == expected); // Fatal - aborts test on failure
|
||||
}
|
||||
};
|
||||
BEAST_DEFINE_TESTSUITE(MyTest, module, ripple);
|
||||
```
|
||||
|
||||
### Instrumentation
|
||||
```cpp
|
||||
// Use XRPL_ASSERT for debug-only assertions (fuzzing-aware)
|
||||
XRPL_ASSERT(ptr != nullptr, "MyClass::method : null pointer");
|
||||
|
||||
// Format: "ClassName::methodName : description"
|
||||
// The string format is important for fuzzing instrumentation
|
||||
```
|
||||
|
||||
### IP Endpoint Types
|
||||
```cpp
|
||||
// Use beast::IP::Endpoint for network addresses
|
||||
beast::IP::Endpoint endpoint;
|
||||
// Supports both IPv4 and IPv6
|
||||
// Includes port information
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never use `BEAST_EXPECT` when the test cannot continue on failure - use `BEAST_REQUIRE` instead
|
||||
- Never create a Journal with a dangling Sink pointer - ensure Sink outlives Journal
|
||||
- Always include "ClassName::methodName" prefix in XRPL_ASSERT messages for traceability
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/beast/utility/Journal.h` - Log sink abstraction
|
||||
- `include/xrpl/beast/unit_test/suite.h` - Test framework
|
||||
- `include/xrpl/beast/utility/instrumentation.h` - XRPL_ASSERT macros
|
||||
- `include/xrpl/beast/net/IPEndpoint.h` - Network endpoint types
|
||||
- `include/xrpl/beast/core/SemanticVersion.h` - Version parsing
|
||||
33
.claude/skills/libxrpl/beast/clock.md
Normal file
33
.claude/skills/libxrpl/beast/clock.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Beast Clock Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with clock abstractions in `src/libxrpl/beast/clock/` or `include/xrpl/beast/clock/`. Covers abstract clock interfaces and manual clock implementations for testing.
|
||||
|
||||
## Responsibility
|
||||
Provides clock abstractions that decouple code from system time, enabling deterministic testing with manual clocks and supporting different time granularities.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Abstract Clock Interface
|
||||
```cpp
|
||||
// Use abstract_clock<T> for testable time-dependent code
|
||||
// Production: uses system clock
|
||||
// Testing: uses manual_clock for deterministic control
|
||||
```
|
||||
|
||||
### Manual Clock for Testing
|
||||
```cpp
|
||||
// Advance time manually in tests
|
||||
manual_clock<std::chrono::steady_clock> clock;
|
||||
clock.advance(std::chrono::seconds(30));
|
||||
// Deterministic - no flaky tests from timing issues
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never use `std::chrono::system_clock::now()` directly - inject clock dependency
|
||||
- Always use manual_clock in unit tests for deterministic behavior
|
||||
- Be aware of Ripple Epoch vs Unix Epoch when working with ledger timestamps
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/beast/clock/abstract_clock.h` - Abstract clock interface
|
||||
- `include/xrpl/beast/clock/manual_clock.h` - Testable clock implementation
|
||||
29
.claude/skills/libxrpl/beast/core.md
Normal file
29
.claude/skills/libxrpl/beast/core.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Beast Core Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with core beast utilities in `src/libxrpl/beast/core/` or `include/xrpl/beast/core/`. Covers semantic versioning and core type utilities.
|
||||
|
||||
## Responsibility
|
||||
Provides core utilities including semantic version parsing/comparison, system abstractions, and foundational type support.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Semantic Version Parsing
|
||||
```cpp
|
||||
// Parse version strings following semver spec
|
||||
SemanticVersion version;
|
||||
if (version.parse("1.2.3-beta")) {
|
||||
auto major = version.majorVersion;
|
||||
auto minor = version.minorVersion;
|
||||
auto patch = version.patchVersion;
|
||||
}
|
||||
// Supports comparison operators for version ordering
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always validate version strings before using - parse() returns false on invalid input
|
||||
- Remember that pre-release versions have lower precedence than release versions
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/beast/core/SemanticVersion.h` - Version parsing and comparison
|
||||
- `src/libxrpl/beast/core/SemanticVersion.cpp` - Implementation
|
||||
41
.claude/skills/libxrpl/beast/insight.md
Normal file
41
.claude/skills/libxrpl/beast/insight.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Beast Insight Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with metrics and monitoring in `src/libxrpl/beast/insight/` or `include/xrpl/beast/insight/`. Covers counters, gauges, and metrics collection.
|
||||
|
||||
## Responsibility
|
||||
Provides metrics collection infrastructure for monitoring application performance: counters for cumulative values, gauges for point-in-time measurements, and hooks for metrics export.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Metrics Types
|
||||
```cpp
|
||||
// Counter: Monotonically increasing value (e.g., total requests)
|
||||
insight::Counter requests;
|
||||
++requests;
|
||||
|
||||
// Gauge: Point-in-time value (e.g., current connections)
|
||||
insight::Gauge connections;
|
||||
connections = currentCount;
|
||||
|
||||
// Event: Timed operation tracking
|
||||
insight::Event latency;
|
||||
```
|
||||
|
||||
### Null Metrics
|
||||
```cpp
|
||||
// Use NullCollector when metrics disabled
|
||||
// All operations become no-ops with zero overhead
|
||||
auto collector = insight::NullCollector::New();
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Use Counter for cumulative values, Gauge for current state - don't mix them
|
||||
- Always use NullCollector for tests - avoids metrics overhead
|
||||
- Never store raw metric values in long-lived objects - use the insight types
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/beast/insight/Counter.h` - Cumulative counter
|
||||
- `include/xrpl/beast/insight/Gauge.h` - Point-in-time gauge
|
||||
- `include/xrpl/beast/insight/Collector.h` - Metrics collector interface
|
||||
- `include/xrpl/beast/insight/NullCollector.h` - No-op collector
|
||||
46
.claude/skills/libxrpl/beast/net.md
Normal file
46
.claude/skills/libxrpl/beast/net.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Beast Net Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with network types in `src/libxrpl/beast/net/` or `include/xrpl/beast/net/`. Covers IP address and endpoint representations.
|
||||
|
||||
## Responsibility
|
||||
Provides network type abstractions for IP addresses (v4 and v6) and endpoints (address + port), with parsing utilities and comparison operators.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### IP Endpoint Usage
|
||||
```cpp
|
||||
// beast::IP::Endpoint combines address + port
|
||||
beast::IP::Endpoint endpoint(
|
||||
beast::IP::Address::from_string("127.0.0.1"), 51235);
|
||||
|
||||
// Supports both IPv4 and IPv6
|
||||
beast::IP::Endpoint v6endpoint(
|
||||
beast::IP::Address::from_string("::1"), 51235);
|
||||
```
|
||||
|
||||
### Address Parsing
|
||||
```cpp
|
||||
// Parse from string with error handling
|
||||
boost::system::error_code ec;
|
||||
auto address = beast::IP::Address::from_string(input, ec);
|
||||
if (ec) { /* handle invalid address */ }
|
||||
```
|
||||
|
||||
### Comparison and Ordering
|
||||
```cpp
|
||||
// Endpoints support full comparison for use in containers
|
||||
std::set<beast::IP::Endpoint> endpoints;
|
||||
std::map<beast::IP::Endpoint, Consumer> consumers;
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always handle both IPv4 and IPv6 when working with endpoints
|
||||
- Use error_code overload of from_string to handle invalid input gracefully
|
||||
- Never assume address format - always parse and validate
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/beast/net/IPEndpoint.h` - Combined address + port
|
||||
- `include/xrpl/beast/net/IPAddress.h` - IP address types
|
||||
- `include/xrpl/beast/net/IPAddressV4.h` - IPv4 specific
|
||||
- `include/xrpl/beast/net/IPAddressV6.h` - IPv6 specific
|
||||
47
.claude/skills/libxrpl/beast/utility.md
Normal file
47
.claude/skills/libxrpl/beast/utility.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Beast Utility Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with beast utility classes in `src/libxrpl/beast/utility/` or `include/xrpl/beast/utility/`. Covers Journal logging, instrumentation, and type introspection.
|
||||
|
||||
## Responsibility
|
||||
Provides utility classes including the Journal logging abstraction (Sink + Stream), XRPL_ASSERT/XRPL_VERIFY instrumentation macros, and type introspection helpers.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Journal and Sink Architecture
|
||||
```cpp
|
||||
// Sink: abstract base for log message routing
|
||||
class Sink {
|
||||
virtual void write(beast::severities::Severity level, std::string const& text) = 0;
|
||||
void console(bool output); // Enable console output
|
||||
};
|
||||
|
||||
// Journal: lightweight wrapper around Sink* (copy by value)
|
||||
beast::Journal j(sinkPtr);
|
||||
JLOG(j.warn()) << "Message";
|
||||
|
||||
// WrappedSink: adds prefix to all messages
|
||||
beast::WrappedSink wrappedSink(parentSink, "MyModule");
|
||||
```
|
||||
|
||||
### Instrumentation Macros
|
||||
```cpp
|
||||
// XRPL_ASSERT: Debug-only assertion (disabled in release, fuzzing-aware)
|
||||
XRPL_ASSERT(condition, "ClassName::method : description");
|
||||
|
||||
// XRPL_VERIFY: Always-enabled assertion
|
||||
XRPL_VERIFY(condition, "ClassName::method : description");
|
||||
|
||||
// Format convention: "ClassName::methodName : human-readable description"
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always use "ClassName::methodName" prefix in assertion messages
|
||||
- Journal is cheap to copy (just a pointer) - pass by value is fine
|
||||
- WrappedSink must outlive any Journal created from it
|
||||
- XRPL_ASSERT is no-op in release builds - don't put side effects in the condition
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/beast/utility/Journal.h` - Log sink abstraction and Journal
|
||||
- `include/xrpl/beast/utility/instrumentation.h` - XRPL_ASSERT, XRPL_VERIFY
|
||||
- `include/xrpl/beast/utility/WrappedSink.h` - Prefixed log sink
|
||||
63
.claude/skills/libxrpl/conditions.md
Normal file
63
.claude/skills/libxrpl/conditions.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Conditions Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with crypto-conditions in `src/libxrpl/conditions/` or `include/xrpl/conditions/`. Implements the RFC crypto-conditions specification.
|
||||
|
||||
## Responsibility
|
||||
Implements crypto-conditions for conditional payments: condition fingerprints, fulfillment validation, multiple condition types (preimage, prefix, threshold, RSA, Ed25519), and binary DER serialization/deserialization.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Fulfillment Interface
|
||||
```cpp
|
||||
// Abstract base for all fulfillment types
|
||||
struct Fulfillment {
|
||||
virtual ~Fulfillment() = default;
|
||||
virtual Buffer fingerprint() const = 0;
|
||||
virtual Type type() const = 0;
|
||||
virtual bool validate(Slice data) const = 0;
|
||||
virtual std::uint32_t cost() const = 0;
|
||||
virtual Condition condition() const = 0;
|
||||
};
|
||||
```
|
||||
|
||||
### Factory Pattern for Deserialization
|
||||
```cpp
|
||||
// Returns unique_ptr + sets error_code (non-throwing)
|
||||
std::unique_ptr<Fulfillment> deserialize(Slice s, std::error_code& ec);
|
||||
|
||||
// Usage:
|
||||
std::error_code ec;
|
||||
auto fulfillment = Fulfillment::deserialize(data, ec);
|
||||
if (ec) return {}; // Early return on error
|
||||
```
|
||||
|
||||
### Type-Safe Enums
|
||||
```cpp
|
||||
enum class Type : std::uint8_t {
|
||||
preimageSha256 = 0,
|
||||
prefixSha256 = 1,
|
||||
thresholdSha256 = 2,
|
||||
rsaSha256 = 3,
|
||||
ed25519Sha256 = 4
|
||||
};
|
||||
```
|
||||
|
||||
### Size Limits
|
||||
```cpp
|
||||
static constexpr std::size_t maxSerializedCondition = 128;
|
||||
static constexpr std::size_t maxSerializedFulfillment = 256;
|
||||
// Always respect these limits when creating conditions
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never throw exceptions from binary parsing - use `std::error_code` parameter pattern
|
||||
- Always check `ec` after deserialization before using the result
|
||||
- Respect `maxSerializedFulfillment` size limits
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/conditions/Condition.h` - Base condition with type/fingerprint/cost
|
||||
- `include/xrpl/conditions/Fulfillment.h` - Abstract fulfillment interface
|
||||
- `include/xrpl/conditions/detail/PreimageSha256.h` - Preimage implementation
|
||||
- `include/xrpl/conditions/detail/utils.h` - DER encoding/decoding
|
||||
- `include/xrpl/conditions/detail/error.h` - Error codes
|
||||
61
.claude/skills/libxrpl/core.md
Normal file
61
.claude/skills/libxrpl/core.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Core Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with job processing and routing infrastructure in `src/libxrpl/core/` or `include/xrpl/core/`. Covers job queues, load monitoring, and message deduplication.
|
||||
|
||||
## Responsibility
|
||||
Distributed job processing with priority levels, load monitoring for execution tracking, and hash-based message suppression/routing for peer deduplication.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Job Queue Priorities
|
||||
```cpp
|
||||
// Job types ordered by priority (lower enum = lower priority)
|
||||
enum JobType {
|
||||
jtINVALID = -1,
|
||||
jtPACK, // Lowest priority
|
||||
jtCLIENT_WEBSOCKET,
|
||||
// ...
|
||||
jtVALIDATION_t, // Trusted validation (high)
|
||||
jtADMIN // Admin operations (highest)
|
||||
};
|
||||
// Position in enum determines scheduling priority
|
||||
```
|
||||
|
||||
### HashRouter for Deduplication
|
||||
```cpp
|
||||
// Suppress duplicate messages from peers
|
||||
std::optional<std::set<PeerShortID>> shouldRelay(uint256 const& key);
|
||||
// Returns {} if already relayed, set of peers if should relay
|
||||
|
||||
// Track peer that sent a message
|
||||
auto result = router.addSuppressionPeer(key, peer);
|
||||
```
|
||||
|
||||
### RAII Locking
|
||||
```cpp
|
||||
// Always use lock_guard for mutex protection
|
||||
std::lock_guard lock(mutex_);
|
||||
auto result = emplace(key);
|
||||
result.first.addPeer(peer);
|
||||
return result.second; // Return while lock is held
|
||||
```
|
||||
|
||||
### Optional Return Types
|
||||
```cpp
|
||||
// Use std::optional for "maybe" results
|
||||
std::optional<std::set<PeerShortID>> shouldRelay(uint256 const& key);
|
||||
// Caller checks: if (auto peers = shouldRelay(key)) { ... }
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never hold locks longer than necessary - lock_guard scope = critical section
|
||||
- Never ignore job priorities when scheduling work - use appropriate JobType
|
||||
- Always let HashRouter handle message deduplication rather than implementing custom logic
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/core/Job.h` - Job wrapper with type, index, function
|
||||
- `include/xrpl/core/JobTypes.h` - Job type enumerations and metadata
|
||||
- `include/xrpl/core/JobQueue.h` - Priority queue for dispatching jobs
|
||||
- `include/xrpl/core/HashRouter.h` - Duplicate message suppression
|
||||
- `include/xrpl/core/LoadMonitor.h` - Job execution time tracking
|
||||
32
.claude/skills/libxrpl/core/detail.md
Normal file
32
.claude/skills/libxrpl/core/detail.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Core Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with internal core implementation details in `src/libxrpl/core/detail/`. These are private implementation helpers not intended for direct external use.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for the core module, including helper functions and private data structures used by JobQueue, HashRouter, and LoadMonitor.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Detail Namespace Convention
|
||||
```cpp
|
||||
namespace xrpl {
|
||||
namespace detail {
|
||||
// Internal helpers - not part of public API
|
||||
// May change without notice between versions
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Encapsulation
|
||||
- Code in `detail/` should only be included by its parent module
|
||||
- Never include detail headers from outside the core module
|
||||
- If you need functionality from detail, use the public core API instead
|
||||
|
||||
## Common Pitfalls
|
||||
- Never depend on detail namespace types or functions from outside the core module
|
||||
- Detail implementations may change without preserving API compatibility
|
||||
- Always use the public `core/` headers for stable interfaces
|
||||
|
||||
## Key Files
|
||||
- Files in this directory are implementation details of `include/xrpl/core/` headers
|
||||
51
.claude/skills/libxrpl/crypto.md
Normal file
51
.claude/skills/libxrpl/crypto.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Crypto Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with cryptographic operations in `src/libxrpl/crypto/` or `include/xrpl/crypto/`. Covers CSPRNG, secure memory erasure, and RFC1751 encoding.
|
||||
|
||||
## Responsibility
|
||||
Low-level cryptographic operations: cryptographically secure random number generation (CSPRNG), RFC1751 word-based encoding for keys, and secure memory erasure to prevent sensitive data leakage.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### CSPRNG Usage
|
||||
```cpp
|
||||
// Thread-safe PRNG - use the global singleton
|
||||
auto& prng = crypto_prng();
|
||||
|
||||
// Generate random value
|
||||
auto randomValue = prng();
|
||||
|
||||
// Fill buffer with random bytes
|
||||
prng(buffer.data(), buffer.size());
|
||||
|
||||
// NEVER create your own csprng_engine - use crypto_prng()
|
||||
```
|
||||
|
||||
### Secure Memory Erasure
|
||||
```cpp
|
||||
// Use volatile memset to prevent compiler optimization
|
||||
secure_erase(secretKey.data(), secretKey.size());
|
||||
// MUST be called before destroying any buffer containing secrets
|
||||
```
|
||||
|
||||
### Engine Concept Conformance
|
||||
```cpp
|
||||
// csprng_engine meets UniformRandomNumberEngine requirements
|
||||
using result_type = std::uint64_t;
|
||||
static constexpr result_type min();
|
||||
static constexpr result_type max();
|
||||
// Can be used with standard distributions
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never create a local `csprng_engine` instance - always use `crypto_prng()` singleton
|
||||
- Never use `std::rand()` or `std::mt19937` for security-sensitive operations
|
||||
- Always call `secure_erase()` on secret key material before destruction
|
||||
- Never copy or move a `csprng_engine` - it's non-copyable and non-movable by design
|
||||
- Be aware of OpenSSL version differences - locking behavior varies
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/crypto/csprng.h` - Thread-safe PRNG engine
|
||||
- `include/xrpl/crypto/RFC1751.h` - Human-readable key encoding
|
||||
- `include/xrpl/crypto/secure_erase.h` - Volatile memset for secrets
|
||||
68
.claude/skills/libxrpl/json.md
Normal file
68
.claude/skills/libxrpl/json.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# JSON Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with JSON parsing and serialization in `src/libxrpl/json/` or `include/xrpl/json/`. Covers Json::Value, readers, writers, and custom allocators.
|
||||
|
||||
## Responsibility
|
||||
JSON value representation (discriminated union for all JSON types), parsing text to Value objects, serialization from Value to text, and custom string allocation for memory control.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Json::Value Usage
|
||||
```cpp
|
||||
// Discriminated union - supports all JSON types
|
||||
Json::Value obj(Json::objectValue);
|
||||
obj["key"] = "string_value";
|
||||
obj["count"] = 42u;
|
||||
obj["flag"] = true;
|
||||
obj["nested"] = Json::objectValue;
|
||||
|
||||
// Array creation
|
||||
Json::Value arr(Json::arrayValue);
|
||||
arr.append("item");
|
||||
arr.append(123);
|
||||
|
||||
// Type checking
|
||||
if (obj.isObject()) { ... }
|
||||
if (obj.isMember("key")) { ... }
|
||||
```
|
||||
|
||||
### StaticString Optimization
|
||||
```cpp
|
||||
// Use StaticString for compile-time known keys to avoid allocation
|
||||
static const Json::StaticString code("code");
|
||||
static const Json::StaticString message("message");
|
||||
object[code] = 1234; // No dynamic allocation for key
|
||||
object[message] = "ok"; // Key stored as pointer, not copied
|
||||
```
|
||||
|
||||
### Value Type Enum
|
||||
```cpp
|
||||
enum ValueType {
|
||||
nullValue = 0,
|
||||
intValue, uintValue, realValue,
|
||||
stringValue, booleanValue,
|
||||
arrayValue, objectValue
|
||||
};
|
||||
// Check type before accessing to avoid undefined behavior
|
||||
```
|
||||
|
||||
### Lazy Initialization
|
||||
```cpp
|
||||
// Container elements auto-created on access (like JavaScript)
|
||||
Json::Value obj;
|
||||
obj["newKey"]["nested"] = 1; // Creates intermediate objects automatically
|
||||
// Be aware: accessing a non-existent key creates it
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Accessing a non-existent key via `operator[]` creates a null entry - use `isMember()` to check first if you don't want side effects
|
||||
- Use `const` overload of `operator[]` to avoid auto-creation: `obj["key"]` on const ref returns null reference
|
||||
- Prefer `StaticString` for frequently-used keys to avoid repeated allocations
|
||||
- Never assume JSON numeric types - check `isInt()`, `isUInt()`, `isDouble()` explicitly
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/json/json_value.h` - Main Value class
|
||||
- `include/xrpl/json/json_reader.h` - Text-to-Value parser
|
||||
- `include/xrpl/json/json_writer.h` - Value-to-text serializer
|
||||
- `include/xrpl/json/json_forwards.h` - Forward declarations and aliases
|
||||
84
.claude/skills/libxrpl/ledger.md
Normal file
84
.claude/skills/libxrpl/ledger.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Ledger Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with ledger state management in `src/libxrpl/ledger/` or `include/xrpl/ledger/`. Covers views, state tables, payments, and credit operations.
|
||||
|
||||
## Responsibility
|
||||
Manages the state of the distributed ledger: abstractions for viewing, reading, and applying transactions to ledger state. Handles account ownership tracking, trust lines, payment processing, directory management, and credential verification.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### ReadView vs ApplyView
|
||||
```cpp
|
||||
// ReadView: Read-only access to ledger state
|
||||
bool exists = view.exists(keylet::account(accountID));
|
||||
auto sle = view.read(keylet::account(accountID)); // Returns shared_ptr<SLE const>
|
||||
|
||||
// ApplyView: Mutable access for transaction application
|
||||
auto sle = view.peek(keylet::account(accountID)); // Returns shared_ptr<SLE>
|
||||
sle->setFieldAmount(sfBalance, newBalance);
|
||||
view.update(sle); // Commit change
|
||||
view.insert(newSle); // Create new entry
|
||||
view.erase(sle); // Remove entry
|
||||
```
|
||||
|
||||
### Enum-Based Control (No Boolean Blindness)
|
||||
```cpp
|
||||
// NEVER: bool ignoreFreeze = true;
|
||||
// ALWAYS: Use named enums
|
||||
enum FreezeHandling { fhIGNORE_FREEZE, fhZERO_IF_FROZEN };
|
||||
enum AuthHandling { ahIGNORE_AUTH, ahZERO_IF_UNAUTHORIZED };
|
||||
|
||||
STAmount accountHolds(ReadView const& view, AccountID const& account,
|
||||
Currency const& currency, AccountID const& issuer,
|
||||
FreezeHandling zeroIfFrozen, beast::Journal j);
|
||||
```
|
||||
|
||||
### Asset Variant Handling
|
||||
```cpp
|
||||
// Use std::visit for Asset (Issue or MPTIssue)
|
||||
return std::visit(
|
||||
[&](auto const& issue) {
|
||||
return isIndividualFrozen(view, account, issue);
|
||||
},
|
||||
asset.value());
|
||||
```
|
||||
|
||||
### PaymentSandbox for Isolation
|
||||
```cpp
|
||||
// Test payment effects before committing
|
||||
PaymentSandbox sandbox(&view);
|
||||
// ... apply changes to sandbox ...
|
||||
sandbox.apply(view); // Commit all changes atomically
|
||||
// Or let sandbox destruct to discard
|
||||
```
|
||||
|
||||
### TER Return Codes
|
||||
```cpp
|
||||
// Transaction results are returned as TER, not exceptions
|
||||
TER result = doApply();
|
||||
if (result != tesSUCCESS) return result;
|
||||
// TER categories: tes (success), tec (claimed fee), tef (failure), tel (local), tem (malformed)
|
||||
```
|
||||
|
||||
### Depth Limiting
|
||||
```cpp
|
||||
// Recursive operations use depth parameter to prevent infinite recursion
|
||||
TER checkVaultState(ReadView const& view, AccountID const& id, int depth = 0);
|
||||
if (depth > maxDepth) return tecINTERNAL;
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never use `read()` when you need to modify - use `peek()` instead
|
||||
- Never forget to call `view.update(sle)` after modifying a peeked SLE
|
||||
- Never use bare booleans for control flags - use the enum types
|
||||
- Always check for frozen/unauthorized states before operating on trust lines
|
||||
- Never ignore TER return values - propagate them up the call chain
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/ledger/View.h` - Core read/write operations (largest file)
|
||||
- `include/xrpl/ledger/ReadView.h` - Read-only interface
|
||||
- `include/xrpl/ledger/ApplyView.h` - Mutable interface
|
||||
- `src/libxrpl/ledger/PaymentSandbox.cpp` - Isolated payment testing
|
||||
- `src/libxrpl/ledger/ApplyStateTable.cpp` - State change management
|
||||
- `src/libxrpl/ledger/Credit.cpp` - Trust line and IOU operations
|
||||
58
.claude/skills/libxrpl/net.md
Normal file
58
.claude/skills/libxrpl/net.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Net Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with network communication in `src/libxrpl/net/` or `include/xrpl/net/`. Covers HTTP/HTTPS client functionality and SSL certificate management.
|
||||
|
||||
## Responsibility
|
||||
Provides HTTP/HTTPS client functionality for network requests, including SSL certificate registration, asynchronous request handling with boost::asio, and callback-based completion.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Async HTTP with Callbacks
|
||||
```cpp
|
||||
// Callback returns bool indicating success/continuation
|
||||
HTTPClient::get(
|
||||
bSSL, io_context,
|
||||
std::deque<std::string>{"site1.com", "site2.com"}, // Fallback sites
|
||||
443, "/path",
|
||||
maxResponseBytes,
|
||||
timeout,
|
||||
[](boost::system::error_code const& ec, int status, std::string const& body) -> bool {
|
||||
if (ec) return false; // Stop
|
||||
// Process response
|
||||
return true; // Success
|
||||
},
|
||||
headers, journal);
|
||||
```
|
||||
|
||||
### Lifetime Management with shared_from_this
|
||||
```cpp
|
||||
// Async callbacks use intrusive_ptr for safe lifetime
|
||||
class HTTPClientImp : public HTTPClient,
|
||||
public std::enable_shared_from_this<HTTPClientImp> {
|
||||
void startAsync() {
|
||||
auto self = shared_from_this(); // Prevent premature destruction
|
||||
// ... schedule async operations ...
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Deadline Timers
|
||||
```cpp
|
||||
// Always set timeouts for network operations
|
||||
boost::asio::basic_waitable_timer<std::chrono::steady_clock> timer_;
|
||||
timer_.expires_after(std::chrono::seconds(timeout));
|
||||
// Cancel pending operation on timeout
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never start async operations without capturing shared_from_this - object may be destroyed before callback
|
||||
- Always set deadline timers on network operations to prevent hanging connections
|
||||
- Always set maximum response size limits to prevent resource exhaustion
|
||||
- Never assume DNS resolution will succeed - handle resolver errors
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/net/HTTPClient.h` - Main HTTP client interface
|
||||
- `src/libxrpl/net/HTTPClient.cpp` - Implementation with async I/O
|
||||
- `src/libxrpl/net/RegisterSSLCerts.cpp` - SSL certificate registration
|
||||
- `include/xrpl/net/HTTPClientSSLContext.h` - SSL context management
|
||||
24
.claude/skills/libxrpl/net/images.md
Normal file
24
.claude/skills/libxrpl/net/images.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Net Images Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with static image assets in `src/libxrpl/net/images/`. Contains embedded image data used by the HTTP server.
|
||||
|
||||
## Responsibility
|
||||
Stores static image assets (favicons, logos) as embedded byte arrays for serving via the built-in HTTP server without external file dependencies.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Embedded Assets
|
||||
```cpp
|
||||
// Images stored as static const byte arrays
|
||||
// Compiled directly into the binary - no file I/O needed at runtime
|
||||
static unsigned char const favicon[] = { /* ... */ };
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Keep embedded images small - they increase binary size
|
||||
- Use appropriate image formats (ICO for favicons, PNG for logos)
|
||||
- Update both the source image and the byte array when changing assets
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/net/images/` - Static image byte arrays embedded in the binary
|
||||
68
.claude/skills/libxrpl/nodestore.md
Normal file
68
.claude/skills/libxrpl/nodestore.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# NodeStore Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with persistent node storage in `src/libxrpl/nodestore/` or `include/xrpl/nodestore/`. Covers the storage abstraction layer, backend implementations, and caching.
|
||||
|
||||
## Responsibility
|
||||
Abstraction layer for persistent storage of ledger nodes (SHAMap leaves and inner nodes). Supports multiple backend implementations (RocksDB, NuDB, Memory, Null) with a plugin architecture, caching, and async operations.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Abstract Factory for Backends
|
||||
```cpp
|
||||
// Backend is pure virtual - concrete implementations selected at runtime
|
||||
class Backend {
|
||||
virtual ~Backend() = default;
|
||||
virtual Status fetch(void const* key, std::shared_ptr<NodeObject>*) = 0;
|
||||
virtual void store(std::shared_ptr<NodeObject> const&) = 0;
|
||||
virtual void storeBatch(Batch const& batch) = 0;
|
||||
};
|
||||
// Backends: RocksDB, NuDB, Memory (testing), Null (disabled)
|
||||
```
|
||||
|
||||
### Batch Operations
|
||||
```cpp
|
||||
// Always prefer batch operations for multiple reads/writes
|
||||
virtual std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
|
||||
fetchBatch(std::vector<uint256 const*> const& hashes) = 0;
|
||||
virtual void storeBatch(Batch const& batch) = 0;
|
||||
// Significantly reduces I/O overhead vs individual operations
|
||||
```
|
||||
|
||||
### Status Enum (Not Exceptions)
|
||||
```cpp
|
||||
enum class Status { ok, notFound, keyTooBig, /* ... */ };
|
||||
// I/O operations return Status, NOT throw exceptions
|
||||
auto [objects, status] = backend->fetchBatch(hashes);
|
||||
if (status != Status::ok) { /* handle */ }
|
||||
```
|
||||
|
||||
### Configuration via Section
|
||||
```cpp
|
||||
// Backend options come from config file sections
|
||||
RocksDBBackend(int keyBytes, Section const& keyValues,
|
||||
Scheduler& scheduler, beast::Journal journal);
|
||||
// Allows runtime tuning without recompilation
|
||||
```
|
||||
|
||||
### Async Fetch with Scheduler
|
||||
```cpp
|
||||
// Non-blocking reads via scheduler integration
|
||||
virtual void asyncFetch(uint256 const& hash,
|
||||
std::function<void(std::shared_ptr<NodeObject>)>&& callback);
|
||||
// Callback invoked on scheduler thread
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never use individual fetch/store in tight loops - use batch operations
|
||||
- Never throw exceptions from backend implementations - return Status enum
|
||||
- Always configure appropriate cache sizes for the workload
|
||||
- Never assume a fetch will succeed - always check Status
|
||||
- Use Memory backend for unit tests, never RocksDB
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/nodestore/Database.h` - Main storage interface
|
||||
- `include/xrpl/nodestore/Backend.h` - Abstract backend interface
|
||||
- `include/xrpl/nodestore/Manager.h` - Backend factory
|
||||
- `include/xrpl/nodestore/NodeObject.h` - Individual node wrapper
|
||||
- `src/libxrpl/nodestore/BatchWriter.cpp` - Batch write optimization
|
||||
66
.claude/skills/libxrpl/nodestore/backend.md
Normal file
66
.claude/skills/libxrpl/nodestore/backend.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# NodeStore Backend Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with storage backend implementations in `src/libxrpl/nodestore/backend/`. Covers RocksDB, NuDB, Memory, and Null backend factories.
|
||||
|
||||
## Responsibility
|
||||
Concrete backend implementations for the NodeStore abstraction layer. Each backend provides persistent (or ephemeral) storage with different performance characteristics and use cases.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Backend Factory Registration
|
||||
```cpp
|
||||
// Each backend is a factory that creates Backend instances
|
||||
// Registered by name in the Manager
|
||||
class RocksDBFactory : public Factory {
|
||||
std::string getName() const override { return "RocksDB"; }
|
||||
std::unique_ptr<Backend> createInstance(...) override;
|
||||
};
|
||||
```
|
||||
|
||||
### RocksDB Configuration
|
||||
```cpp
|
||||
// Extensive tuning via config Section
|
||||
// Key options:
|
||||
// open_files - Max open file descriptors
|
||||
// filter_bits - Bloom filter bits per key (default 10)
|
||||
// cache_mb - Block cache size in MB
|
||||
// file_size_mb - Target SST file size
|
||||
// compression - snappy (default), zlib, lz4, none
|
||||
// block_size - Block size in KB (default 4)
|
||||
// num_threads - Background compaction threads
|
||||
```
|
||||
|
||||
### NuDB for Deterministic Storage
|
||||
```cpp
|
||||
// NuDB supports deterministic initialization
|
||||
// Useful for reproducible test databases
|
||||
// Hash-based storage with direct memory-mapped I/O
|
||||
// Lower CPU overhead than RocksDB for write-heavy workloads
|
||||
```
|
||||
|
||||
### Memory Backend for Testing
|
||||
```cpp
|
||||
// In-memory storage - fast but not persistent
|
||||
// Use for unit tests only
|
||||
// Thread-safe with internal mutex
|
||||
```
|
||||
|
||||
### Null Backend for Disabled Storage
|
||||
```cpp
|
||||
// No-op backend - all operations succeed but store nothing
|
||||
// Use when storage feature is disabled in config
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Use Memory backend for tests, never RocksDB (test isolation and speed)
|
||||
- Always tune RocksDB bloom filter bits - default 10 is good for most workloads
|
||||
- NuDB doesn't support range queries - only point lookups by hash
|
||||
- Never use Null backend in production - data loss guaranteed
|
||||
- Always configure appropriate open_files limits for the OS
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/nodestore/backend/RocksDBFactory.cpp` - RocksDB backend (~12.5KB)
|
||||
- `src/libxrpl/nodestore/backend/NuDBFactory.cpp` - NuDB backend (~12KB)
|
||||
- `src/libxrpl/nodestore/backend/MemoryFactory.cpp` - In-memory backend (~5KB)
|
||||
- `src/libxrpl/nodestore/backend/NullFactory.cpp` - No-op backend (~2KB)
|
||||
35
.claude/skills/libxrpl/proto.md
Normal file
35
.claude/skills/libxrpl/proto.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Proto Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with Protocol Buffer definitions in `include/xrpl/proto/`. Covers gRPC API definitions and generated protobuf headers.
|
||||
|
||||
## Responsibility
|
||||
Contains Protocol Buffer generated headers defining the gRPC API for rippled. These define the wire format for RPC communication between clients and the server.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Proto Organization
|
||||
```
|
||||
include/xrpl/proto/
|
||||
└── org/xrpl/rpc/v1/
|
||||
└── *.proto generated headers
|
||||
```
|
||||
|
||||
### Usage
|
||||
```cpp
|
||||
#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
|
||||
// Use generated types for gRPC request/response
|
||||
```
|
||||
|
||||
### Versioning
|
||||
- API is versioned under `org/xrpl/rpc/v1/`
|
||||
- New versions get a new directory (v2/, etc.)
|
||||
- Never modify generated files directly - modify the .proto source
|
||||
|
||||
## Common Pitfalls
|
||||
- Never hand-edit generated .pb.h files - regenerate from .proto sources
|
||||
- Always use the versioned path (v1/) when including proto headers
|
||||
- Proto types are for serialization only - convert to native types for business logic
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/proto/org/xrpl/rpc/v1/` - Generated gRPC API headers
|
||||
123
.claude/skills/libxrpl/protocol.md
Normal file
123
.claude/skills/libxrpl/protocol.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Protocol Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with serialization and data types in `src/libxrpl/protocol/` or `include/xrpl/protocol/`. Covers STObject hierarchy, SField registry, serialization, TER codes, features, and keylets.
|
||||
|
||||
## Responsibility
|
||||
Defines serialization formats, data types, and protocol constants. Handles conversion between C++ objects and wire format, JSON representation, and database storage. The largest module in libxrpl with 60+ files.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### STObject Hierarchy
|
||||
```cpp
|
||||
// STBase is the abstract root for all serializable types
|
||||
// Concrete types: STInteger<N>, STBlob, STAmount, STArray, STObject, STPathSet, STVector256
|
||||
|
||||
// Access fields type-safely via SField references
|
||||
auto amount = obj[sfAmount]; // Returns STAmount
|
||||
auto flags = obj[sfFlags]; // Returns uint32
|
||||
auto dest = obj[sfDestination]; // Returns AccountID
|
||||
auto has = obj.isFieldPresent(sfMemos); // Check presence
|
||||
```
|
||||
|
||||
### SField Registry
|
||||
```cpp
|
||||
// Fields are statically registered - never create SField at runtime
|
||||
// SField carries type information and field ID
|
||||
extern SField const sfAmount; // STAmount type
|
||||
extern SField const sfFlags; // STInteger<uint32> type
|
||||
extern SField const sfDestination; // STAccount type
|
||||
|
||||
// Field IDs are protocol-defined and must not change
|
||||
```
|
||||
|
||||
### Serializer for Binary Format
|
||||
```cpp
|
||||
// Deterministic binary serialization
|
||||
Serializer s;
|
||||
obj.add(s); // Append binary representation
|
||||
auto blob = s.peekData(); // Get bytes
|
||||
|
||||
// Deserialization
|
||||
SerialIter sit(blob.data(), blob.size());
|
||||
auto obj = std::make_shared<STObject>(sit, sfTransaction);
|
||||
```
|
||||
|
||||
### Bidirectional JSON/Binary Conversion
|
||||
```cpp
|
||||
// Object to JSON
|
||||
Json::Value json = obj.getJson(JsonOptions::none);
|
||||
|
||||
// JSON to Object
|
||||
STParsedJSONObject parsed("tx_json", json);
|
||||
if (parsed.object) { /* use parsed.object */ }
|
||||
```
|
||||
|
||||
### TER (Transaction Error Result) Codes
|
||||
```cpp
|
||||
// Categories:
|
||||
// tes - success (tesSUCCESS)
|
||||
// tec - claimed fee, no effect (tecNO_DST, tecFROZEN, tecINSUFFICIENT_RESERVE)
|
||||
// tef - failure (tefFAILURE)
|
||||
// tel - local error (telNETWORK_ID_MAKES_TX_NON_CANONICAL)
|
||||
// tem - malformed (temINVALID, temBAD_AMOUNT, temDISABLED)
|
||||
|
||||
// Check categories:
|
||||
isTesSuccess(ter) // ter == tesSUCCESS
|
||||
isTecClaim(ter) // tec range
|
||||
isTemMalformed(ter) // tem range
|
||||
```
|
||||
|
||||
### Feature/Amendment Flags
|
||||
```cpp
|
||||
// Gate new behavior on amendments
|
||||
if (ctx.rules.enabled(featureMyFeature)) {
|
||||
// New behavior
|
||||
} else {
|
||||
// Legacy behavior
|
||||
}
|
||||
// Register features in Feature.cpp
|
||||
```
|
||||
|
||||
### Keylet for Ledger Entry Keys
|
||||
```cpp
|
||||
// Type-safe ledger key generation
|
||||
auto key = keylet::account(accountID); // Account root
|
||||
auto key = keylet::line(a, b, currency); // Trust line
|
||||
auto key = keylet::offer(account, seq); // Offer
|
||||
auto key = keylet::nftoken(tokenID); // NFT
|
||||
// Keylet carries both the key (uint256) and the expected ledger entry type
|
||||
```
|
||||
|
||||
### SOTemplate for Schema Validation
|
||||
```cpp
|
||||
// Define expected fields for a ledger entry type
|
||||
SOTemplate const ltACCOUNT_ROOT = {
|
||||
{sfAccount, soeREQUIRED},
|
||||
{sfBalance, soeREQUIRED},
|
||||
{sfFlags, soeREQUIRED},
|
||||
{sfSequence, soeREQUIRED},
|
||||
{sfOwnerCount, soeDEFAULT},
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never create SField instances at runtime - they are static protocol definitions
|
||||
- Never modify field IDs - they are part of the binary protocol
|
||||
- Always use `isFieldPresent()` before accessing optional fields
|
||||
- Never ignore TER return values - they carry critical error information
|
||||
- Always gate new fields/behavior on feature amendments for consensus safety
|
||||
- Respect JSON parsing depth limit of 10 to prevent stack overflow
|
||||
- Use `[[nodiscard]]` on functions returning TER
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/protocol/STObject.h` - Generic structured object container
|
||||
- `include/xrpl/protocol/STAmount.h` - XRP and IOU amounts
|
||||
- `include/xrpl/protocol/SField.h` - Field definitions
|
||||
- `include/xrpl/protocol/TER.h` - Transaction result codes
|
||||
- `include/xrpl/protocol/Feature.h` - Amendment flags
|
||||
- `include/xrpl/protocol/Indexes.h` - Ledger entry key generation
|
||||
- `include/xrpl/protocol/Keylet.h` - Type-safe ledger keys
|
||||
- `include/xrpl/protocol/SOTemplate.h` - Object schema definitions
|
||||
- `src/libxrpl/protocol/STParsedJSON.cpp` - JSON to object conversion
|
||||
60
.claude/skills/libxrpl/rdb.md
Normal file
60
.claude/skills/libxrpl/rdb.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# RDB Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with relational database access in `src/libxrpl/rdb/` or `include/xrpl/rdb/`. Covers SOCI wrapper, database configuration, and checkpointing.
|
||||
|
||||
## Responsibility
|
||||
Provides a C++ wrapper around SOCI (SQLite/PostgreSQL abstraction) for relational data access, configuration management, blob type conversions, and periodic WAL checkpoint management.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### DBConfig Lazy Initialization
|
||||
```cpp
|
||||
// Construct config without opening connection
|
||||
DBConfig config(basicConfig, "my_database");
|
||||
|
||||
// Open session later when needed
|
||||
soci::session session;
|
||||
config.open(session);
|
||||
// Allows config parsing separate from database I/O
|
||||
```
|
||||
|
||||
### Blob Conversions
|
||||
```cpp
|
||||
// Convert between SOCI blobs and standard types
|
||||
soci::blob blob(session);
|
||||
std::vector<std::uint8_t> bytes;
|
||||
convert(blob, bytes); // blob -> vector
|
||||
|
||||
std::string str;
|
||||
convert(blob, str); // blob -> string
|
||||
```
|
||||
|
||||
### Checkpointer with Weak Pointer Safety
|
||||
```cpp
|
||||
// Checkpointer uses weak_ptr to detect session destruction
|
||||
auto checkpointer = makeCheckpointer(
|
||||
id,
|
||||
std::weak_ptr<soci::session>(sessionPtr),
|
||||
jobQueue,
|
||||
logs);
|
||||
checkpointer->schedule(); // Periodic WAL checkpoints
|
||||
// If session is destroyed, checkpointer safely no-ops
|
||||
```
|
||||
|
||||
### Thread-Safe Sessions
|
||||
```cpp
|
||||
// Each thread gets its own soci::session from the pool
|
||||
// Never share a soci::session across threads
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never share a soci::session across threads - each thread needs its own
|
||||
- Always use `std::weak_ptr` for session references in long-lived objects (like Checkpointer)
|
||||
- Be aware of SOCI include warnings - use pragma diagnostic push/pop
|
||||
- Always convert blobs to standard types before processing
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/rdb/SociDB.h` - Main wrapper interface
|
||||
- `src/libxrpl/rdb/SociDB.cpp` - Implementation
|
||||
- `src/libxrpl/rdb/DatabaseCon.cpp` - Database connection setup
|
||||
64
.claude/skills/libxrpl/resource.md
Normal file
64
.claude/skills/libxrpl/resource.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Resource Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with rate limiting and resource management in `src/libxrpl/resource/` or `include/xrpl/resource/`. Covers endpoint tracking, charge/fee management, and abuse prevention.
|
||||
|
||||
## Responsibility
|
||||
Tracks resource consumption by network endpoints (inbound/outbound connections) to prevent abuse and ensure fair resource allocation. Manages consumer lifecycle, charge accounting, and gossip-based reputation sharing.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Manager/Impl Pattern
|
||||
```cpp
|
||||
// Abstract Manager interface with factory function
|
||||
class Manager { virtual ~Manager() = 0; };
|
||||
std::unique_ptr<Manager> make_Manager(beast::Journal journal);
|
||||
|
||||
// Implementation hidden in cpp
|
||||
class ManagerImp : public Manager { /* ... */ };
|
||||
```
|
||||
|
||||
### Consumer Factory
|
||||
```cpp
|
||||
// Different consumer types for different connection sources
|
||||
Consumer newInboundEndpoint(beast::IP::Endpoint const& address);
|
||||
Consumer newOutboundEndpoint(beast::IP::Endpoint const& address);
|
||||
Consumer newUnlimitedEndpoint(beast::IP::Endpoint const& address);
|
||||
```
|
||||
|
||||
### Background Thread Shutdown
|
||||
```cpp
|
||||
// Clean shutdown pattern with condition variable
|
||||
~ManagerImp() {
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
stop_ = true;
|
||||
cond_.notify_one();
|
||||
}
|
||||
thread_.join(); // Wait for thread to finish
|
||||
}
|
||||
```
|
||||
|
||||
### Proxy-Aware Endpoint Detection
|
||||
```cpp
|
||||
// Handle forwarded-for headers safely
|
||||
boost::system::error_code ec;
|
||||
auto proxiedIp = boost::asio::ip::make_address(forwardedFor, ec);
|
||||
if (ec) {
|
||||
journal_.warn() << "Invalid IP: " << ec.message();
|
||||
return newInboundEndpoint(address); // Fallback to socket IP
|
||||
}
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never trust forwarded-for headers without proxy flag validation
|
||||
- Always use the factory methods - never construct Consumer directly
|
||||
- Always join background threads in destructor
|
||||
- Use separate consumer types for different connection trust levels
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/resource/ResourceManager.h` - Manager interface
|
||||
- `src/libxrpl/resource/ResourceManager.cpp` - Implementation
|
||||
- `include/xrpl/resource/Consumer.h` - Per-endpoint tracking
|
||||
- `src/libxrpl/resource/Charge.cpp` - Cost definitions
|
||||
- `src/libxrpl/resource/Fees.cpp` - Fee calculations
|
||||
68
.claude/skills/libxrpl/server.md
Normal file
68
.claude/skills/libxrpl/server.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Server Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with server configuration in `src/libxrpl/server/` or `include/xrpl/server/`. Covers port configuration, SSL/TLS, WebSocket options, and authentication.
|
||||
|
||||
## Responsibility
|
||||
Manages server listening ports, WebSocket configuration, SSL/TLS setup, authentication credentials, and admin network restrictions. Handles parsing configuration into validated port structures.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Dual ParsedPort/Port Pattern
|
||||
```cpp
|
||||
// ParsedPort: intermediate parsing result (may be incomplete)
|
||||
struct ParsedPort { /* partially validated fields */ };
|
||||
|
||||
// Port: final validated configuration (ready to use)
|
||||
struct Port {
|
||||
std::string name;
|
||||
boost::asio::ip::address ip;
|
||||
std::uint16_t port = 0;
|
||||
std::set<std::string, iless> protocol;
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### Configuration Section Parsing
|
||||
```cpp
|
||||
// Parse from config file section, log errors to stream
|
||||
void parse_Port(ParsedPort& port, Section const& section, std::ostream& log);
|
||||
// Does NOT throw - logs issues and sets defaults
|
||||
```
|
||||
|
||||
### CIDR Admin Networks
|
||||
```cpp
|
||||
// IP-based admin access control with CIDR support
|
||||
std::vector<boost::asio::ip::network_v4> admin_nets_v4;
|
||||
std::vector<boost::asio::ip::network_v6> admin_nets_v6;
|
||||
// Supports both IPv4 and IPv6 ranges
|
||||
```
|
||||
|
||||
### WebSocket Options
|
||||
```cpp
|
||||
// Fine-grained compression control
|
||||
boost::beast::websocket::permessage_deflate pmd_options;
|
||||
// Queue limits prevent memory exhaustion
|
||||
std::optional<std::uint16_t> ws_queue_limit;
|
||||
// limit=0 means unlimited (not -1)
|
||||
```
|
||||
|
||||
### SSL Context Lazy Creation
|
||||
```cpp
|
||||
// SSL context created only when needed
|
||||
std::shared_ptr<boost::asio::ssl::context> context;
|
||||
// Initialized when first SSL connection established
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never use port-only access control - always use CIDR network restrictions for admin
|
||||
- Use `iless` comparator for protocol names (case-insensitive)
|
||||
- Remember that `limit=0` means unlimited, not disabled
|
||||
- Always log parsing errors rather than throwing
|
||||
- Separate user/admin credentials - don't reuse
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/server/Port.h` - Port configuration structure
|
||||
- `src/libxrpl/server/Port.cpp` - Parsing and validation
|
||||
- `src/libxrpl/server/JSONRPCUtil.cpp` - RPC utility functions
|
||||
- `src/libxrpl/server/LoadFeeTrack.cpp` - Load and fee tracking
|
||||
83
.claude/skills/libxrpl/shamap.md
Normal file
83
.claude/skills/libxrpl/shamap.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# SHAMap Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with the Merkle tree implementation in `src/libxrpl/shamap/` or `include/xrpl/shamap/`. Covers the SHA-256 based radix tree used for ledger state representation.
|
||||
|
||||
## Responsibility
|
||||
Implements a SHA-256 based Merkle radix tree with 16-way branching (hexadecimal). Provides efficient ledger state representation with O(log N) proof-of-inclusion, copy-on-write snapshots, synchronization, and delta calculation.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### State Machine Lifecycle
|
||||
```cpp
|
||||
enum class SHAMapState { Modifying, Immutable, Synching, Invalid };
|
||||
// Modifying: Can add/remove/modify entries
|
||||
// Immutable: Snapshot - no modifications allowed
|
||||
// Synching: Being synchronized from peers
|
||||
// Invalid: Corrupted or destroyed
|
||||
// Transitions are one-way: Modifying -> Immutable (via snapshot)
|
||||
```
|
||||
|
||||
### Copy-on-Write via COWID
|
||||
```cpp
|
||||
std::uint32_t cowid_ = 1;
|
||||
// Each snapshot gets a new COWID
|
||||
// Children are only copied when modified (lazy copy)
|
||||
// Immutable snapshots share nodes with the active map
|
||||
auto snapshot = map.snapShot(true); // Creates immutable copy
|
||||
```
|
||||
|
||||
### 16-Way Radix Branching
|
||||
```cpp
|
||||
static inline constexpr unsigned int branchFactor = 16;
|
||||
static inline constexpr unsigned int leafDepth = 64;
|
||||
// 256-bit key / 4 bits per nibble = 64 levels max
|
||||
// Each inner node has up to 16 children
|
||||
```
|
||||
|
||||
### Node Type Hierarchy
|
||||
```cpp
|
||||
// SHAMapTreeNode (base) -> SHAMapInnerNode (16 children)
|
||||
// -> SHAMapLeafNode (data + key)
|
||||
// Use dynamic_pointer_cast for safe downcasting
|
||||
auto inner = intr_ptr::dynamic_pointer_cast<SHAMapInnerNode>(node);
|
||||
if (inner) { /* process inner node */ }
|
||||
```
|
||||
|
||||
### Walk-Up for Modifications (dirtyUp)
|
||||
```cpp
|
||||
// After modifying a leaf, propagate hash changes to root
|
||||
void dirtyUp(SharedPtrNodeStack& stack, uint256 const& target, ...);
|
||||
// Updates hashes from leaf -> root through the stack
|
||||
```
|
||||
|
||||
### Lazy Traversal
|
||||
```cpp
|
||||
// Navigate to a leaf by key
|
||||
SHAMapLeafNode* walkTowardsKey(uint256 const& id,
|
||||
SharedPtrNodeStack* stack = nullptr);
|
||||
// Returns leaf or nullptr; optionally records path for dirtyUp
|
||||
```
|
||||
|
||||
### Intrusive Pointers for Nodes
|
||||
```cpp
|
||||
// Nodes use intrusive reference counting (not std::shared_ptr)
|
||||
intr_ptr::SharedPtr<SHAMapTreeNode> root_;
|
||||
// Minimal overhead - reference count embedded in node
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never modify an Immutable map - check state before mutations
|
||||
- Always call dirtyUp after modifying a leaf to maintain hash integrity
|
||||
- Never assume node type without dynamic_pointer_cast check
|
||||
- Remember that snapshots share nodes - COW means nodes are only copied on write
|
||||
- Always use the provided iterators for safe traversal, not manual tree walking
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/shamap/SHAMap.h` - Main map implementation
|
||||
- `include/xrpl/shamap/SHAMapTreeNode.h` - Base node class
|
||||
- `include/xrpl/shamap/SHAMapInnerNode.h` - Interior nodes (16-way)
|
||||
- `include/xrpl/shamap/SHAMapLeafNode.h` - Leaf nodes with data
|
||||
- `include/xrpl/shamap/SHAMapNodeID.h` - Tree position identifier
|
||||
- `src/libxrpl/shamap/SHAMapDelta.cpp` - Difference between maps
|
||||
- `src/libxrpl/shamap/SHAMapSync.cpp` - Synchronization algorithm
|
||||
137
.claude/skills/libxrpl/tx.md
Normal file
137
.claude/skills/libxrpl/tx.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Transaction (tx) Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with transaction processing in `src/libxrpl/tx/` or `include/xrpl/tx/`. Covers the Transactor base class, transaction pipeline, invariant checks, and apply context.
|
||||
|
||||
## Responsibility
|
||||
Implements the transaction processing pipeline: static validation (preflight), fee-claim checks (preclaim), transaction execution (doApply), and post-apply invariant verification. All transaction types derive from the Transactor base class.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Transaction Pipeline (3 Phases)
|
||||
```cpp
|
||||
// Phase 1: Preflight - Static validation, NO ledger access
|
||||
static NotTEC preflight(PreflightContext const& ctx) {
|
||||
if (ctx.tx[sfAmount] <= beast::zero)
|
||||
return temBAD_AMOUNT;
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// Phase 2: Preclaim - Ledger read-only checks
|
||||
static TER preclaim(PreclaimContext const& ctx) {
|
||||
auto sle = ctx.view.read(keylet::account(ctx.tx[sfAccount]));
|
||||
if (!sle) return tecNO_DST;
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// Phase 3: doApply - Actual ledger mutations
|
||||
TER doApply() override {
|
||||
auto sle = view().peek(keylet::account(account_));
|
||||
sle->setFieldAmount(sfBalance, newBalance);
|
||||
view().update(sle);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
### Transactor Base Class
|
||||
```cpp
|
||||
class MyTransaction : public Transactor {
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit MyTransaction(ApplyContext& ctx) : Transactor(ctx) {}
|
||||
|
||||
// Optional: Gate on amendment
|
||||
static bool checkExtraFeatures(PreflightContext const& ctx);
|
||||
|
||||
// Optional: Custom flag mask
|
||||
static std::uint32_t getFlagsMask(PreflightContext const& ctx);
|
||||
|
||||
// Required
|
||||
static NotTEC preflight(PreflightContext const& ctx);
|
||||
static TER preclaim(PreclaimContext const& ctx);
|
||||
TER doApply() override;
|
||||
|
||||
// Optional: Custom fee calculation
|
||||
static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
};
|
||||
```
|
||||
|
||||
### Feature Gating
|
||||
```cpp
|
||||
static bool checkExtraFeatures(PreflightContext const& ctx) {
|
||||
// Return false to disable when amendment not enabled
|
||||
return ctx.rules.enabled(featureMyFeature);
|
||||
}
|
||||
```
|
||||
|
||||
### Flag Validation
|
||||
```cpp
|
||||
static std::uint32_t getFlagsMask(PreflightContext const& ctx) {
|
||||
return tfMyTransactionMask; // Allowed flags
|
||||
}
|
||||
// Base class validates: (tx.getFlags() & ~getFlagsMask()) == 0
|
||||
```
|
||||
|
||||
### ConsequencesFactory Types
|
||||
```cpp
|
||||
// Normal: Standard transaction
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
// Blocker: Affects subsequent transactions' ability to claim fees
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Blocker};
|
||||
// Custom: Override makeTxConsequences() static method
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
```
|
||||
|
||||
### TER Error Code Progression
|
||||
```
|
||||
tem* (malformed): temINVALID, temBAD_AMOUNT, temDISABLED - preflight errors
|
||||
tef* (failure): tefFAILURE, tefNESTED_FAILURE - infrastructure errors
|
||||
tel* (local): telNETWORK_ID_MAKES_TX_NON_CANONICAL - local-only errors
|
||||
tec* (claimed): tecNO_DST, tecFROZEN, tecINSUFFICIENT_RESERVE - fee claimed, no effect
|
||||
tes (success): tesSUCCESS - transaction applied
|
||||
```
|
||||
|
||||
### Logging Convention
|
||||
```cpp
|
||||
JLOG(ctx.j.warn()) << "User error message"; // User-facing issues
|
||||
JLOG(ctx.j.debug()) << "Detailed diagnostic"; // Implementation details
|
||||
JLOG(ctx.j.trace()) << "Very verbose info"; // Deep debugging
|
||||
JLOG(ctx.j.error()) << "Unexpected failure"; // Should not happen
|
||||
```
|
||||
|
||||
### View Operations in doApply
|
||||
```cpp
|
||||
// Read-only (returns const SLE)
|
||||
auto sle = view().read(keylet::account(accountID));
|
||||
|
||||
// Mutable (returns non-const SLE)
|
||||
auto sle = view().peek(keylet::account(accountID));
|
||||
sle->setFieldAmount(sfBalance, newBalance);
|
||||
view().update(sle); // MUST call after modification
|
||||
|
||||
// Create new entry
|
||||
auto sle = std::make_shared<SLE>(keylet::myEntry(id));
|
||||
sle->setFieldText(sfData, data);
|
||||
view().insert(sle);
|
||||
|
||||
// Remove entry
|
||||
view().erase(sle);
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never access ledger state in preflight - it only has PreflightContext (no view)
|
||||
- Never mutate ledger state in preclaim - it has ReadView only
|
||||
- Always call `view().update(sle)` after modifying a peeked SLE
|
||||
- Never return `tesSUCCESS` from preclaim/preflight if validation failed
|
||||
- Always gate new transaction types on feature amendments
|
||||
- Use `NotTEC` return type for preflight (not TER) - prevents returning tec codes from static checks
|
||||
- Never forget to register new transaction types in `transactions.macro` and `applySteps.cpp`
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/tx/Transactor.h` - Base class with static method signatures
|
||||
- `src/libxrpl/tx/Transactor.cpp` - Base implementation (41KB)
|
||||
- `src/libxrpl/tx/apply.cpp` - Transaction application entry point
|
||||
- `src/libxrpl/tx/ApplyContext.cpp` - Context management
|
||||
- `src/libxrpl/tx/InvariantCheck.cpp` - Post-apply invariant validation (117KB)
|
||||
- `src/libxrpl/tx/applySteps.cpp` - Step-by-step dispatch
|
||||
72
.claude/skills/libxrpl/tx/paths.md
Normal file
72
.claude/skills/libxrpl/tx/paths.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Transaction Paths Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with payment path finding and execution in `src/libxrpl/tx/paths/` or `include/xrpl/tx/paths/`. Covers the flow engine, ripple calculation, and offer stream processing.
|
||||
|
||||
## Responsibility
|
||||
Implements payment path finding and execution for cross-currency payments. Handles the flow engine for executing payments across multiple paths (strands), offer book management, and amount calculation.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Flow Engine Entry Point
|
||||
```cpp
|
||||
path::RippleCalc::Output flow(
|
||||
PaymentSandbox& view,
|
||||
STAmount const& deliver,
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
STPathSet const& paths,
|
||||
bool defaultPaths,
|
||||
bool partialPayment,
|
||||
bool ownerPaysTransferFee,
|
||||
OfferCrossing offerCrossing,
|
||||
std::optional<Quality> const& limitQuality,
|
||||
std::optional<STAmount> const& sendMax,
|
||||
std::optional<uint256> const& domainID,
|
||||
beast::Journal j,
|
||||
path::detail::FlowDebugInfo* flowDebugInfo = nullptr);
|
||||
```
|
||||
|
||||
### Strand-Based Execution
|
||||
```cpp
|
||||
// A "strand" is a single payment path through the DEX
|
||||
// Multiple strands can be tried to find the best rate
|
||||
// StrandFlow executes a single strand
|
||||
// Flow tries all strands and picks the best result
|
||||
```
|
||||
|
||||
### OfferStream for Order Book Processing
|
||||
```cpp
|
||||
// Iterates through offers in an order book
|
||||
// Handles expired offers, unfunded offers, and self-crossing
|
||||
// Automatically cleans up stale offers during traversal
|
||||
```
|
||||
|
||||
### Quality-Based Routing
|
||||
```cpp
|
||||
// Quality = exchange rate between input and output
|
||||
// Lower quality number = better rate
|
||||
// limitQuality prevents accepting rates worse than threshold
|
||||
```
|
||||
|
||||
### PaymentSandbox Isolation
|
||||
```cpp
|
||||
// All path calculations happen in a PaymentSandbox
|
||||
// Changes are only committed if the payment succeeds
|
||||
// Allows trying multiple paths without side effects
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never modify the ledger directly during path calculation - use PaymentSandbox
|
||||
- Always respect limitQuality to prevent unfavorable exchange rates
|
||||
- Be aware that offer traversal may clean up stale offers as a side effect
|
||||
- FlowDebugInfo is optional and only for debugging - never rely on it in production logic
|
||||
- Path finding is computationally expensive - respect depth and complexity limits
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/tx/paths/Flow.h` - Main flow engine entry point
|
||||
- `include/xrpl/tx/paths/RippleCalc.h` - Payment amount calculation
|
||||
- `src/libxrpl/tx/paths/OfferStream.cpp` - Order book traversal (~12KB)
|
||||
- `src/libxrpl/tx/paths/BookTip.cpp` - Order book tip management
|
||||
- `src/libxrpl/tx/paths/detail/Steps.h` - Step-by-step calculation
|
||||
- `src/libxrpl/tx/paths/detail/StrandFlow.h` - Single path execution
|
||||
164
.claude/skills/libxrpl/tx/transactors.md
Normal file
164
.claude/skills/libxrpl/tx/transactors.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Transactors Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when adding or modifying transaction types in `src/libxrpl/tx/transactors/`. This is the guide for implementing new transactors following the established patterns.
|
||||
|
||||
## Responsibility
|
||||
Contains all concrete transaction type implementations. Each transactor follows the Transactor base class pattern with preflight/preclaim/doApply phases. Transaction types are organized by feature area in subdirectories.
|
||||
|
||||
## Template for New Transactors
|
||||
|
||||
### Header File (`include/xrpl/tx/transactors/MyTx.h`)
|
||||
```cpp
|
||||
#pragma once
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class MyTransaction : public Transactor {
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit MyTransaction(ApplyContext& ctx) : Transactor(ctx) {}
|
||||
|
||||
static bool checkExtraFeatures(PreflightContext const& ctx);
|
||||
static std::uint32_t getFlagsMask(PreflightContext const& ctx);
|
||||
static NotTEC preflight(PreflightContext const& ctx);
|
||||
static TER preclaim(PreclaimContext const& ctx);
|
||||
TER doApply() override;
|
||||
};
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Implementation File (`src/libxrpl/tx/transactors/MyFeature/MyTx.cpp`)
|
||||
```cpp
|
||||
#include <xrpl/tx/transactors/MyTx.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
bool
|
||||
MyTransaction::checkExtraFeatures(PreflightContext const& ctx)
|
||||
{
|
||||
return ctx.rules.enabled(featureMyFeature);
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
MyTransaction::getFlagsMask(PreflightContext const& ctx)
|
||||
{
|
||||
return tfUniversalMask; // Or custom mask
|
||||
}
|
||||
|
||||
NotTEC
|
||||
MyTransaction::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
// Static validation - NO ledger access
|
||||
auto const& tx = ctx.tx;
|
||||
|
||||
if (tx[sfAmount] <= beast::zero)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Bad amount.";
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
MyTransaction::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
// Ledger read-only checks
|
||||
auto const sle = ctx.view.read(
|
||||
keylet::account(ctx.tx[sfAccount]));
|
||||
if (!sle)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
MyTransaction::doApply()
|
||||
{
|
||||
// Mutate ledger state
|
||||
auto sle = view().peek(keylet::account(account_));
|
||||
if (!sle)
|
||||
return tefINTERNAL;
|
||||
|
||||
sle->setFieldAmount(sfBalance, newBalance);
|
||||
view().update(sle);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Registration Checklist
|
||||
1. Add transaction type to `include/xrpl/protocol/detail/transactions.macro`
|
||||
2. Add dispatch case to `src/libxrpl/tx/applySteps.cpp`
|
||||
3. Add feature flag to `include/xrpl/protocol/Feature.h` and `src/libxrpl/protocol/Feature.cpp`
|
||||
4. Add invariant checks if needed in `src/libxrpl/tx/InvariantCheck.cpp`
|
||||
5. Add to `disabledTxTypes` in Batch.cpp if not batch-compatible
|
||||
|
||||
## Key Patterns Across All Transactors
|
||||
|
||||
### Feature Gating
|
||||
```cpp
|
||||
static bool checkExtraFeatures(PreflightContext const& ctx) {
|
||||
return ctx.rules.enabled(featureMyFeature);
|
||||
}
|
||||
```
|
||||
|
||||
### Variant-Aware Validation
|
||||
```cpp
|
||||
// When handling Asset (Issue or MPTIssue):
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) { return preflightHelper<T>(ctx); },
|
||||
ctx.tx[sfAmount].asset().value()); !isTesSuccess(ret))
|
||||
return ret;
|
||||
```
|
||||
|
||||
### Ledger Entry CRUD in doApply
|
||||
```cpp
|
||||
// Create
|
||||
auto sle = std::make_shared<SLE>(keylet::myEntry(id));
|
||||
view().insert(sle);
|
||||
|
||||
// Read (mutable)
|
||||
auto sle = view().peek(keylet::myEntry(id));
|
||||
|
||||
// Update
|
||||
sle->setFieldU32(sfFlags, newFlags);
|
||||
view().update(sle);
|
||||
|
||||
// Delete
|
||||
view().erase(sle);
|
||||
```
|
||||
|
||||
### Helper/Utils Files
|
||||
```cpp
|
||||
// Complex features use a separate Helpers/Utils file:
|
||||
// AMM -> AMMHelpers.h, AMMUtils.h
|
||||
// NFT -> NFTokenUtils.h
|
||||
// Lending -> LendingHelpers.h
|
||||
// Keep reusable logic in helpers, transaction-specific logic in transactors
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never forget to register in `transactions.macro` and `applySteps.cpp`
|
||||
- Never access ledger state in preflight (no view available)
|
||||
- Never mutate state in preclaim (read-only view)
|
||||
- Always call `view().update(sle)` after modifying a peeked entry
|
||||
- Always gate on feature amendment for consensus safety
|
||||
- Use `NotTEC` return type from preflight, `TER` from preclaim/doApply
|
||||
- Put shared logic in a *Helpers.h file, not duplicated across transactors
|
||||
|
||||
## Key Files
|
||||
- `include/xrpl/tx/Transactor.h` - Base class definition
|
||||
- `src/libxrpl/tx/applySteps.cpp` - Transaction type dispatch
|
||||
- `include/xrpl/protocol/detail/transactions.macro` - Transaction type registry
|
||||
- `src/libxrpl/tx/InvariantCheck.cpp` - Post-apply validation
|
||||
68
.claude/skills/libxrpl/tx/transactors/AMM.md
Normal file
68
.claude/skills/libxrpl/tx/transactors/AMM.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# AMM (Automated Market Maker) Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with AMM transaction types in `src/libxrpl/tx/transactors/AMM/`. Covers pool creation, deposits, withdrawals, voting, bidding, deletion, and clawback.
|
||||
|
||||
## Responsibility
|
||||
Implements decentralized trading pools with liquidity provider (LP) tokens. Allows users to create AMM pools, deposit/withdraw liquidity, vote on trading fees, bid on auction slots, and manage pool lifecycle.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### AMM Transaction Types
|
||||
- **AMMCreate** - Create a new AMM pool with two assets
|
||||
- **AMMDeposit** - Add liquidity to a pool, receive LP tokens
|
||||
- **AMMWithdraw** - Remove liquidity, burn LP tokens
|
||||
- **AMMVote** - Vote on trading fee percentage
|
||||
- **AMMBid** - Bid on the auction slot for discounted trading
|
||||
- **AMMDelete** - Remove an empty AMM pool
|
||||
- **AMMClawback** - Issuer clawback of assets from AMM
|
||||
|
||||
### Precision Arithmetic
|
||||
```cpp
|
||||
// AMM calculations require controlled rounding
|
||||
// ALWAYS use NumberRoundModeGuard for rounding control
|
||||
NumberRoundModeGuard mg(Number::towards_zero);
|
||||
auto lpTokens = ammLPTokens(amount1, amount2, lptIssue);
|
||||
|
||||
// Or explicit mode changes with RAII save
|
||||
{
|
||||
saveNumberRoundMode _{Number::getround()};
|
||||
Number::setround(Number::upward);
|
||||
auto value = calculation;
|
||||
}
|
||||
```
|
||||
|
||||
### Helper Functions (AMMHelpers.h)
|
||||
```cpp
|
||||
ammLPTokens() // Calculate LP tokens from pool reserves
|
||||
lpTokensOut() // LP tokens from deposit
|
||||
ammAssetIn() / ammAssetOut() // Calculate swap amounts
|
||||
withinRelativeDistance() // Quality tolerance checks
|
||||
changeSpotPriceQuality() // Quote generation algorithm
|
||||
// Quadratic equation solving for pricing
|
||||
```
|
||||
|
||||
### Feature Gates
|
||||
```cpp
|
||||
// Multiple amendment versions
|
||||
ammEnabled(ctx.rules) // Base AMM feature
|
||||
fixAMMv1_1 // First fix amendment
|
||||
fixAMMv1_3 // Third fix amendment
|
||||
// Always check which amendments are active
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never perform AMM math without setting the rounding mode first
|
||||
- Always use `NumberRoundModeGuard` (RAII) - never manually set/restore rounding
|
||||
- Be aware that AMM calculations involve quadratic equations - precision matters
|
||||
- AMMClawback has different authorization requirements than regular clawback
|
||||
- Check `withinRelativeDistance` for quality tolerance rather than exact equality
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/AMM/AMMCreate.cpp` - Pool creation
|
||||
- `src/libxrpl/tx/transactors/AMM/AMMDeposit.cpp` - Liquidity deposit (~887 lines)
|
||||
- `src/libxrpl/tx/transactors/AMM/AMMWithdraw.cpp` - Liquidity withdrawal (~911 lines)
|
||||
- `src/libxrpl/tx/transactors/AMM/AMMVote.cpp` - Fee voting
|
||||
- `src/libxrpl/tx/transactors/AMM/AMMBid.cpp` - Auction slot bidding
|
||||
- `include/xrpl/tx/transactors/AMM/AMMHelpers.h` - Shared math utilities
|
||||
- `include/xrpl/tx/transactors/AMM/AMMUtils.h` - AMM state utilities
|
||||
44
.claude/skills/libxrpl/tx/transactors/Check.md
Normal file
44
.claude/skills/libxrpl/tx/transactors/Check.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Check Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with Check transaction types in `src/libxrpl/tx/transactors/Check/`. Covers check creation, cashing, and cancellation.
|
||||
|
||||
## Responsibility
|
||||
Implements a check-like payment mechanism (delayed payment authorization). A sender creates a check, the recipient cashes it, and either party can cancel it (with expiration support).
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Check Lifecycle
|
||||
```cpp
|
||||
// 1. CreateCheck - Sender authorizes payment
|
||||
// Validates: destination exists, amount valid, expiration future
|
||||
// Creates: Check ledger entry with sender, destination, amount
|
||||
|
||||
// 2. CashCheck - Recipient claims payment
|
||||
// Validates: caller is destination, check not expired
|
||||
// Executes: transfers funds from sender to destination
|
||||
|
||||
// 3. CancelCheck - Either party cancels
|
||||
// Validates: caller is sender or destination, or check expired
|
||||
// Removes: Check ledger entry
|
||||
```
|
||||
|
||||
### Error Codes
|
||||
```cpp
|
||||
tecNO_DST // Destination account doesn't exist
|
||||
temREDUNDANT // Check to self
|
||||
temBAD_AMOUNT // Invalid amount
|
||||
temBAD_EXPIRATION // Expiration in the past
|
||||
tecEXPIRED // Check has expired (for CashCheck)
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Checks can be cancelled by either sender or destination
|
||||
- Expired checks can be cancelled by anyone
|
||||
- CashCheck must handle both exact amount and "deliver minimum" modes
|
||||
- Always validate expiration against the parent ledger close time
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/Check/CreateCheck.cpp` - Check creation
|
||||
- `src/libxrpl/tx/transactors/Check/CashCheck.cpp` - Check fulfillment (~440 lines)
|
||||
- `src/libxrpl/tx/transactors/Check/CancelCheck.cpp` - Check cancellation
|
||||
43
.claude/skills/libxrpl/tx/transactors/Delegate.md
Normal file
43
.claude/skills/libxrpl/tx/transactors/Delegate.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Delegate Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with delegation transaction types in `src/libxrpl/tx/transactors/Delegate/`. Covers delegate set and utilities.
|
||||
|
||||
## Responsibility
|
||||
Manages transaction signing delegation, allowing accounts to authorize other accounts to sign transactions on their behalf without exposing the master key.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Delegate Operations
|
||||
```cpp
|
||||
// DelegateSet - Create or modify a delegation
|
||||
// Validates: delegate account exists, permissions valid
|
||||
// Creates/Updates: Delegate ledger entry
|
||||
|
||||
// DelegateUtils - Shared utilities
|
||||
// deleteDelegate() - Public cleanup interface, used by DeleteAccount
|
||||
```
|
||||
|
||||
### Feature Gates
|
||||
```cpp
|
||||
// fixDelegateV1_1 - Added data existence checks
|
||||
if (ctx.rules.enabled(fixDelegateV1_1)) {
|
||||
// Perform additional validation
|
||||
}
|
||||
```
|
||||
|
||||
### Integration with DeleteAccount
|
||||
```cpp
|
||||
// DelegateUtils::deleteDelegate() is called by DeleteAccount
|
||||
// for cleanup when an account is being deleted
|
||||
// Must handle all delegation-related ledger entries
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always check feature gate `fixDelegateV1_1` for data existence validation
|
||||
- Delegate cleanup must be thorough - used by DeleteAccount
|
||||
- Never allow self-delegation
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/Delegate/DelegateSet.cpp` - Delegation management
|
||||
- `include/xrpl/tx/transactors/Delegate/DelegateUtils.h` - Shared utilities
|
||||
69
.claude/skills/libxrpl/tx/transactors/Lending.md
Normal file
69
.claude/skills/libxrpl/tx/transactors/Lending.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Lending Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with lending protocol transaction types in `src/libxrpl/tx/transactors/Lending/`. Covers loan management, broker operations, and payment calculation.
|
||||
|
||||
## Responsibility
|
||||
Implements a complex loan protocol with amortization schedules, interest calculation, broker management, and collateral handling. The largest transactor feature area by code volume.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Loan Lifecycle
|
||||
```cpp
|
||||
// LoanSet - Create or configure a loan
|
||||
// LoanPay - Make loan payments (principal + interest)
|
||||
// LoanManage - Manage loan state transitions
|
||||
// LoanDelete - Remove a completed/cancelled loan
|
||||
```
|
||||
|
||||
### Broker Operations
|
||||
```cpp
|
||||
// LoanBrokerSet - Create/configure a broker
|
||||
// LoanBrokerDelete - Remove a broker
|
||||
// LoanBrokerCoverDeposit - Deposit collateral
|
||||
// LoanBrokerCoverWithdraw - Withdraw collateral
|
||||
// LoanBrokerCoverClawback - Clawback broker assets
|
||||
```
|
||||
|
||||
### Payment Calculation (LendingHelpers.h)
|
||||
```cpp
|
||||
struct LoanPaymentParts {
|
||||
Number principalPaid; // Reduces loan balance
|
||||
Number interestPaid; // Goes to Vault
|
||||
Number valueChange; // Loan value adjustment
|
||||
Number feePaid; // Goes to Broker
|
||||
};
|
||||
|
||||
// Key helper functions:
|
||||
checkLendingProtocolDependencies() // Validate feature gates
|
||||
loanPeriodicRate() // Interest with secondsInYear
|
||||
roundPeriodicPayment() // Consistent rounding
|
||||
```
|
||||
|
||||
### Feature Gate
|
||||
```cpp
|
||||
// All lending operations gated on single feature
|
||||
ctx.rules.enabled(featureLendingProtocol)
|
||||
```
|
||||
|
||||
### Batch Transaction Restriction
|
||||
```cpp
|
||||
// Lending transactions are DISABLED in batch transactions
|
||||
// Listed in Batch::disabledTxTypes
|
||||
// Cannot be included in atomic batch operations
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Lending is disabled in Batch transactions - do not try to batch lending ops
|
||||
- Payment calculations require precise rounding - use LendingHelpers functions
|
||||
- Always validate lending protocol dependencies before operations
|
||||
- Interest calculation uses `secondsInYear` constant - be aware of leap year handling
|
||||
- LendingHelpers.h is ~1800 lines - the most complex helper file in the codebase
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/Lending/LoanSet.cpp` - Loan configuration (~585 lines)
|
||||
- `src/libxrpl/tx/transactors/Lending/LoanPay.cpp` - Payment processing (~548 lines)
|
||||
- `src/libxrpl/tx/transactors/Lending/LoanManage.cpp` - State management
|
||||
- `src/libxrpl/tx/transactors/Lending/LoanDelete.cpp` - Loan removal
|
||||
- `src/libxrpl/tx/transactors/Lending/LoanBrokerSet.cpp` - Broker setup
|
||||
- `include/xrpl/tx/transactors/Lending/LendingHelpers.h` - Shared calculations (~1799 lines)
|
||||
53
.claude/skills/libxrpl/tx/transactors/MPT.md
Normal file
53
.claude/skills/libxrpl/tx/transactors/MPT.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# MPT (Multi-Purpose Token) Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with MPT transaction types in `src/libxrpl/tx/transactors/MPT/`. Covers token issuance creation, configuration, destruction, and authorization.
|
||||
|
||||
## Responsibility
|
||||
Implements Multi-Purpose Token (MPT) operations - a fungible token system simpler than full IOU trust lines. Handles token issuance lifecycle and holder authorization.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### MPT Transaction Types
|
||||
```cpp
|
||||
// MPTokenIssuanceCreate - Create a new token issuance
|
||||
// MPTokenIssuanceSet - Modify issuance settings
|
||||
// MPTokenIssuanceDestroy - Destroy an issuance (if no holders)
|
||||
// MPTokenAuthorize - Authorize/deauthorize a holder
|
||||
```
|
||||
|
||||
### MPT vs IOU Trust Lines
|
||||
```cpp
|
||||
// MPT is simpler than IOU trust lines:
|
||||
// - No rippling mechanics
|
||||
// - No transfer fees between holders (only issuer)
|
||||
// - Simpler authorization model
|
||||
// - Uses MPTIssue instead of Issue
|
||||
// - Uses MPTAmount instead of IOUAmount
|
||||
```
|
||||
|
||||
### Feature Gate
|
||||
```cpp
|
||||
ctx.rules.enabled(featureMPTokensV1)
|
||||
```
|
||||
|
||||
### Asset Variant Handling
|
||||
```cpp
|
||||
// MPTIssue is part of the Asset variant (Issue | MPTIssue)
|
||||
// Use std::visit when handling Asset generically:
|
||||
std::visit([&](auto const& issue) {
|
||||
// Works for both Issue and MPTIssue
|
||||
}, asset.value());
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- MPT issuances cannot be destroyed if any holders exist
|
||||
- Authorization is per-holder, not per-token
|
||||
- Don't confuse MPTIssue with Issue - they have different keylet types
|
||||
- Always check `featureMPTokensV1` before MPT operations
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceCreate.cpp` - Create issuance
|
||||
- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceSet.cpp` - Modify settings
|
||||
- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceDestroy.cpp` - Destroy issuance
|
||||
- `src/libxrpl/tx/transactors/MPT/MPTokenAuthorize.cpp` - Holder authorization
|
||||
76
.claude/skills/libxrpl/tx/transactors/NFT.md
Normal file
76
.claude/skills/libxrpl/tx/transactors/NFT.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# NFT (Non-Fungible Token) Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with NFT transaction types in `src/libxrpl/tx/transactors/NFT/`. Covers minting, burning, offer management, and token modification.
|
||||
|
||||
## Responsibility
|
||||
Implements NFT creation, trading, and lifecycle management. Handles token minting, burning, buy/sell offer creation and acceptance, offer cancellation, and dynamic NFT modification.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### NFT Transaction Types
|
||||
```cpp
|
||||
// NFTokenMint - Create a new NFT
|
||||
// NFTokenBurn - Destroy an NFT
|
||||
// NFTokenCreateOffer - Create a buy or sell offer
|
||||
// NFTokenCancelOffer - Cancel an existing offer
|
||||
// NFTokenAcceptOffer - Accept a buy or sell offer (execute trade)
|
||||
// NFTokenModify - Modify NFT metadata (dynamic NFTs)
|
||||
```
|
||||
|
||||
### NFTokenUtils - Shared Utilities (~1025 lines)
|
||||
```cpp
|
||||
// Key utility functions:
|
||||
findToken() // Find an NFT in owner's token pages
|
||||
insertToken() // Add NFT to owner's directory
|
||||
removeToken() // Remove NFT from owner's directory
|
||||
deleteTokenOffer() // Clean up a single offer
|
||||
removeTokenOffersWithLimit() // Batch cleanup with limit
|
||||
notTooManyOffers() // Check offer count limits
|
||||
changeTokenURI() // Update NFT URI (dynamic NFTs)
|
||||
|
||||
struct TokenAndPage {
|
||||
STObject token;
|
||||
std::shared_ptr<SLE> page;
|
||||
};
|
||||
```
|
||||
|
||||
### Token Storage in Pages
|
||||
```cpp
|
||||
// NFTs are stored in paginated directories
|
||||
// Each page holds multiple tokens
|
||||
// Pages are linked as a doubly-linked list
|
||||
// insertToken/removeToken manage page splits and merges
|
||||
```
|
||||
|
||||
### Feature Gates
|
||||
```cpp
|
||||
featureNFTokenMintOffer // Combined mint + offer
|
||||
fixRemoveNFTokenAutoTrustLine // Fix for auto trust line removal
|
||||
featureDynamicNFT // NFTokenModify support
|
||||
```
|
||||
|
||||
### Offer Directory Structure
|
||||
```cpp
|
||||
// Buy offers and sell offers stored in separate directories
|
||||
// Indexed by token ID
|
||||
// Offers can have expiration times
|
||||
// Offers can specify a destination (private offers)
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Token page management is complex - always use NFTokenUtils functions
|
||||
- Offer cleanup has limits (`removeTokenOffersWithLimit`) - don't assume all offers removed
|
||||
- `notTooManyOffers()` must be checked before creating new offers
|
||||
- Dynamic NFT modification requires `featureDynamicNFT` amendment
|
||||
- Transfer fees only apply when the NFT issuer is not a party to the trade
|
||||
- Burning an NFT with outstanding offers requires offer cleanup
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/NFT/NFTokenMint.cpp` - Token minting
|
||||
- `src/libxrpl/tx/transactors/NFT/NFTokenBurn.cpp` - Token destruction
|
||||
- `src/libxrpl/tx/transactors/NFT/NFTokenCreateOffer.cpp` - Offer creation
|
||||
- `src/libxrpl/tx/transactors/NFT/NFTokenAcceptOffer.cpp` - Offer acceptance (trade)
|
||||
- `src/libxrpl/tx/transactors/NFT/NFTokenCancelOffer.cpp` - Offer cancellation
|
||||
- `src/libxrpl/tx/transactors/NFT/NFTokenModify.cpp` - Dynamic NFT changes
|
||||
- `include/xrpl/tx/transactors/NFT/NFTokenUtils.h` - Shared utilities (~1025 lines)
|
||||
56
.claude/skills/libxrpl/tx/transactors/Offer.md
Normal file
56
.claude/skills/libxrpl/tx/transactors/Offer.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Offer Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with DEX offer transaction types in `src/libxrpl/tx/transactors/Offer/`. Covers order creation and cancellation on the native decentralized exchange.
|
||||
|
||||
## Responsibility
|
||||
Implements decentralized exchange order management for the native XRPL order book. Handles offer creation (with matching/crossing), cancellation, and order book management.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Offer Transaction Types
|
||||
```cpp
|
||||
// CreateOffer (~854 lines) - Create a new DEX order
|
||||
// - Validates amounts, currency pairs, account state
|
||||
// - Attempts to cross with existing offers (matching engine)
|
||||
// - Remaining amount becomes a standing order if not fully filled
|
||||
// - Handles self-crossing, expired offers, unfunded offers
|
||||
|
||||
// CancelOffer - Remove an existing order
|
||||
// - Validates caller owns the offer
|
||||
// - Removes offer from order book directory
|
||||
```
|
||||
|
||||
### Offer Crossing (Matching Engine)
|
||||
```cpp
|
||||
// CreateOffer performs offer crossing inline:
|
||||
// 1. Look up existing offers on the opposite side
|
||||
// 2. Match at the offer's quality (exchange rate)
|
||||
// 3. Consume matched offers (partial or full)
|
||||
// 4. Place remaining amount as standing order
|
||||
// This is the core DEX matching engine
|
||||
```
|
||||
|
||||
### Quality and Order Books
|
||||
```cpp
|
||||
// Quality = exchange rate between TakerPays and TakerGets
|
||||
// Order books indexed by currency pair and sorted by quality
|
||||
// Lower quality number = better rate for taker
|
||||
```
|
||||
|
||||
### Ticket Support
|
||||
```cpp
|
||||
// Offers can use tickets for sequence management
|
||||
// Feature gate: featureTickets
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- CreateOffer is one of the most complex transactors (~854 lines) - be thorough with changes
|
||||
- Offer crossing modifies multiple ledger entries atomically
|
||||
- Self-crossing (same account on both sides) has special handling
|
||||
- Expired and unfunded offers are cleaned up during crossing
|
||||
- Always validate that TakerPays and TakerGets are different assets
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/Offer/CreateOffer.cpp` - Order creation and matching (~854 lines)
|
||||
- `src/libxrpl/tx/transactors/Offer/CancelOffer.cpp` - Order cancellation
|
||||
36
.claude/skills/libxrpl/tx/transactors/PermissionedDomain.md
Normal file
36
.claude/skills/libxrpl/tx/transactors/PermissionedDomain.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# PermissionedDomain Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with permissioned domain transaction types in `src/libxrpl/tx/transactors/PermissionedDomain/`. Covers domain-based access control for the DEX.
|
||||
|
||||
## Responsibility
|
||||
Implements domain-based access control for permissioned DEX operations. Allows creating and deleting permissioned domains that gate who can participate in certain trading activities.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### PermissionedDomain Transaction Types
|
||||
```cpp
|
||||
// PermissionedDomainSet - Create or update a permissioned domain
|
||||
// PermissionedDomainDelete - Remove a permissioned domain
|
||||
```
|
||||
|
||||
### Integration with Payments
|
||||
```cpp
|
||||
// Payments can reference a domain via sfDomainID field
|
||||
// The domain gates which accounts can participate
|
||||
// Used for regulated/permissioned trading environments
|
||||
```
|
||||
|
||||
### Feature Gate
|
||||
```cpp
|
||||
ctx.rules.enabled(featurePermissionedDEX)
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Domains are referenced by other transactions (Payments) - deletion must check for references
|
||||
- Always validate the feature gate before domain operations
|
||||
- Domain ID matching is exact - no partial matches
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/PermissionedDomain/PermissionedDomainSet.cpp` - Create/update domain
|
||||
- `src/libxrpl/tx/transactors/PermissionedDomain/PermissionedDomainDelete.cpp` - Remove domain
|
||||
61
.claude/skills/libxrpl/tx/transactors/Vault.md
Normal file
61
.claude/skills/libxrpl/tx/transactors/Vault.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Vault Transactors Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with vault transaction types in `src/libxrpl/tx/transactors/Vault/`. Covers vault creation, configuration, deposits, withdrawals, deletion, and clawback.
|
||||
|
||||
## Responsibility
|
||||
Implements the vault mechanism for asset holding and loan collateral management. Allows creating vaults, depositing/withdrawing assets, configuring vault parameters, and managing vault lifecycle.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Vault Transaction Types
|
||||
```cpp
|
||||
// VaultCreate - Create a new vault
|
||||
// VaultSet - Configure vault parameters
|
||||
// VaultDelete - Remove an empty vault
|
||||
// VaultDeposit - Deposit assets into a vault
|
||||
// VaultWithdraw - Withdraw assets from a vault
|
||||
// VaultClawback - Issuer clawback from vault
|
||||
```
|
||||
|
||||
### Feature Gate
|
||||
```cpp
|
||||
ctx.rules.enabled(featureSingleAssetVault)
|
||||
```
|
||||
|
||||
### Batch Transaction Restriction
|
||||
```cpp
|
||||
// Vault transactions are DISABLED in batch transactions
|
||||
// Listed in Batch::disabledTxTypes alongside Lending
|
||||
// Cannot be included in atomic batch operations
|
||||
```
|
||||
|
||||
### Depth Limiting for Recursive Operations
|
||||
```cpp
|
||||
// Vault operations may involve recursive state checks
|
||||
// Use depth parameter to prevent infinite recursion
|
||||
TER checkVaultState(ReadView const& view, AccountID const& id, int depth = 0);
|
||||
if (depth > maxDepth) return tecINTERNAL;
|
||||
```
|
||||
|
||||
### Integration with Lending
|
||||
```cpp
|
||||
// Vaults serve as collateral for the lending protocol
|
||||
// VaultDeposit/Withdraw affect loan collateralization
|
||||
// Vault state changes may trigger loan state recalculation
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Vault operations are disabled in batch transactions
|
||||
- Vaults can only be deleted when empty
|
||||
- Clawback has different authorization requirements than regular withdrawal
|
||||
- Always respect depth limits in recursive vault state checks
|
||||
- Vault operations may interact with lending protocol state
|
||||
|
||||
## Key Files
|
||||
- `src/libxrpl/tx/transactors/Vault/VaultCreate.cpp` - Vault creation
|
||||
- `src/libxrpl/tx/transactors/Vault/VaultSet.cpp` - Configuration
|
||||
- `src/libxrpl/tx/transactors/Vault/VaultDelete.cpp` - Deletion
|
||||
- `src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp` - Asset deposit
|
||||
- `src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp` - Asset withdrawal
|
||||
- `src/libxrpl/tx/transactors/Vault/VaultClawback.cpp` - Issuer clawback
|
||||
228
.claude/skills/merge-conflicts.md
Normal file
228
.claude/skills/merge-conflicts.md
Normal file
@@ -0,0 +1,228 @@
|
||||
# Merge Conflict Resolution Guide
|
||||
|
||||
## Description
|
||||
Use when resolving merge conflicts after merging `develop` into a feature branch. Covers the key files that commonly conflict, field number allocation, namespace conventions, and the correct resolution strategy for each file type.
|
||||
|
||||
## General Principles
|
||||
|
||||
### Namespace
|
||||
- All code uses `namespace xrpl { }` (not `ripple`). If a conflict shows `namespace ripple`, take the `xrpl` version.
|
||||
- Qualified references: `xrpl::sign(...)`, `xrpl::sha256_hasher`, etc. Never `ripple::`.
|
||||
|
||||
### Header Guards
|
||||
- Always `#pragma once`. Never `#ifndef` include guards. If a conflict shows old-style guards, take the `#pragma once` version.
|
||||
|
||||
### Copyright Headers
|
||||
- The `develop` branch has removed copyright/license comment blocks from source files. If a conflict is just about the copyright header, take `develop`'s version (no header).
|
||||
|
||||
### File Moves
|
||||
- Many files have been moved from `src/xrpld/` to `src/libxrpl/` or from `src/xrpld/` headers to `include/xrpl/`. If git shows a file as "deleted in develop" but it exists at a new path, delete the old-path file (`git rm`) and keep the new-path version.
|
||||
- Common moves:
|
||||
- `src/xrpld/app/tx/detail/*.h` → `include/xrpl/tx/transactors/*.h`
|
||||
- `src/xrpld/app/tx/detail/*.cpp` → `src/libxrpl/tx/*.cpp` or `src/libxrpl/tx/transactors/*.cpp`
|
||||
- `src/xrpld/app/tx/detail/InvariantCheck.cpp` → `src/libxrpl/tx/invariants/InvariantCheck.cpp`
|
||||
|
||||
### Transactor Migration
|
||||
When merging transactors from `src/xrpld/app/tx/detail/` into `develop`, they must be fully migrated to the new libxrpl structure:
|
||||
|
||||
**File locations:**
|
||||
- Header: `src/xrpld/app/tx/detail/Foo.h` → `include/xrpl/tx/transactors/Foo.h`
|
||||
- Source: `src/xrpld/app/tx/detail/Foo.cpp` → `src/libxrpl/tx/transactors/Foo.cpp`
|
||||
- Delete the old `.cpp` (both `src/xrpld/` and `src/libxrpl/` are GLOB_RECURSE discovered — duplicates cause linker errors)
|
||||
- Optionally leave a forwarding header at the old `.h` location: `#include <xrpl/tx/transactors/Foo.h>`
|
||||
|
||||
**Header changes:**
|
||||
- `#pragma once` (not `#ifndef` guards)
|
||||
- `namespace xrpl` (not `ripple`)
|
||||
- `#include <xrpl/tx/Transactor.h>` (not `<xrpld/app/tx/detail/Transactor.h>`)
|
||||
|
||||
**Source changes:**
|
||||
- `namespace xrpl` (not `ripple`)
|
||||
- `#include <xrpl/tx/transactors/Foo.h>` (not `<xrpld/app/tx/detail/Foo.h>`)
|
||||
- `#include <xrpl/ledger/ApplyView.h>` (not `<xrpld/ledger/ApplyView.h>`)
|
||||
- `#include <xrpl/ledger/View.h>` for `describeOwnerDir`
|
||||
|
||||
**API changes in the new Transactor:**
|
||||
- `preflight1()` and `preflight2()` are **private** — transactor `preflight()` must NOT call them. The framework calls them automatically.
|
||||
- Flag checking (`tfUniversalMask`) is handled by the framework via `getFlagsMask()`. Override `getFlagsMask()` only if custom flag handling is needed; otherwise the default handles `tfUniversalMask`.
|
||||
- A simple `preflight()` that only did flag checks + preflight1/preflight2 should just `return tesSUCCESS;`
|
||||
- `ctx_.app.journal(...)` → `ctx_.registry.journal(...)`
|
||||
- `ctx_.app` does not exist in the new `ApplyContext`; use `ctx_.registry` for service access
|
||||
|
||||
**transactions.macro entry:**
|
||||
Every transactor must have a `#if TRANSACTION_INCLUDE` block:
|
||||
```cpp
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/Foo.h>
|
||||
#endif
|
||||
TRANSACTION(ttFOO, <number>, Foo, ...)
|
||||
```
|
||||
|
||||
### Include Paths
|
||||
- `develop` uses the new macro-based transactor include system via `transactions.macro` with `TRANSACTION_INCLUDE`. Old-style explicit `#include <xrpld/app/tx/detail/*.h>` lists should be replaced with the macro approach.
|
||||
|
||||
## File-Specific Resolution Rules
|
||||
|
||||
### `include/xrpl/protocol/detail/features.macro`
|
||||
|
||||
New feature amendments go **at the top** of the active list (below the macro guard checks and `// clang-format off`), in reverse chronological order.
|
||||
|
||||
```
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(MyNewFeature, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ExistingFix, Supported::yes, VoteBehavior::DefaultNo)
|
||||
...
|
||||
```
|
||||
|
||||
Resolution: Keep both sides' new amendments. Place your feature branch's new amendments at the very top.
|
||||
|
||||
### `include/xrpl/protocol/detail/sfields.macro`
|
||||
|
||||
Fields are grouped by type (UINT32, UINT64, UINT128, etc.) with common and uncommon sections. Each field has a unique **type + field number** pair.
|
||||
|
||||
**Resolution strategy:**
|
||||
1. Keep both sides' new fields.
|
||||
2. Check for field number collisions within each type. Use the next available number for your feature's fields.
|
||||
3. Common fields come first, uncommon fields after (there's a comment separator).
|
||||
|
||||
To find the next available field number for a type:
|
||||
```bash
|
||||
grep "TYPED_SFIELD.*UINT32" include/xrpl/protocol/detail/sfields.macro | sed 's/.*UINT32, *//;s/).*//' | sort -n
|
||||
```
|
||||
|
||||
Similarly for OBJECT and ARRAY types (using `UNTYPED_SFIELD`):
|
||||
```bash
|
||||
grep "UNTYPED_SFIELD.*OBJECT" include/xrpl/protocol/detail/sfields.macro | sed 's/.*OBJECT, *//;s/).*//' | sort -n
|
||||
grep "UNTYPED_SFIELD.*ARRAY" include/xrpl/protocol/detail/sfields.macro | sed 's/.*ARRAY, *//;s/).*//' | sort -n
|
||||
```
|
||||
|
||||
### `include/xrpl/protocol/detail/transactions.macro`
|
||||
|
||||
Transaction types have a unique **transaction type number**. New feature transactions go **at the bottom** of the active transaction list (before the system transactions starting at 100+).
|
||||
|
||||
**Resolution strategy:**
|
||||
1. Keep all of `develop`'s transactions.
|
||||
2. Add your feature's transactions at the bottom with the next available number.
|
||||
3. Use the new 7-argument `TRANSACTION` macro format:
|
||||
|
||||
```cpp
|
||||
/** Description of the transaction */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/MyTransactor.h>
|
||||
#endif
|
||||
TRANSACTION(ttMY_TX, <next_number>, MyTx,
|
||||
Delegation::delegable,
|
||||
featureMyFeature,
|
||||
noPriv, ({
|
||||
{sfSomeField, soeREQUIRED},
|
||||
}))
|
||||
```
|
||||
|
||||
To find the next available transaction number:
|
||||
```bash
|
||||
grep "^TRANSACTION(" include/xrpl/protocol/detail/transactions.macro | sed 's/.*,\s*\([0-9]*\),.*/\1/' | sort -n
|
||||
```
|
||||
|
||||
Note: Transaction numbers 100+ are reserved for system transactions (amendments, fees, UNL).
|
||||
|
||||
### `include/xrpl/protocol/detail/ledger_entries.macro`
|
||||
|
||||
Ledger entry types have a unique **ledger type number** (hex). New entries go **at the bottom** of the active list.
|
||||
|
||||
**Resolution strategy:**
|
||||
1. Keep all of `develop`'s entries.
|
||||
2. Add your feature's entries at the bottom with the next available hex number.
|
||||
3. Check for collisions:
|
||||
|
||||
```bash
|
||||
grep "^LEDGER_ENTRY(" include/xrpl/protocol/detail/ledger_entries.macro | grep -o '0x[0-9a-fA-F]*' | sort
|
||||
```
|
||||
|
||||
### `src/libxrpl/protocol/Indexes.cpp`
|
||||
|
||||
The `LedgerNameSpace` enum assigns a unique single character to each ledger entry type for index hashing.
|
||||
|
||||
**Resolution strategy:**
|
||||
1. Keep both sides' entries.
|
||||
2. Check for character collisions. Each entry needs a unique char.
|
||||
3. Find used characters:
|
||||
|
||||
```bash
|
||||
grep -E "^\s+[A-Z_]+ = " src/libxrpl/protocol/Indexes.cpp | sed "s/.*= '//;s/'.*//" | sort | tr -d '\n'
|
||||
```
|
||||
|
||||
Also check the deprecated chars (reserved, cannot reuse):
|
||||
```bash
|
||||
grep "deprecated" src/libxrpl/protocol/Indexes.cpp | sed "s/.*= '//;s/'.*//"
|
||||
```
|
||||
|
||||
### `src/libxrpl/protocol/InnerObjectFormats.cpp`
|
||||
|
||||
Inner object formats define the fields allowed inside array elements (e.g., `sfSigners`, `sfPasskeys`).
|
||||
|
||||
**Resolution:** Keep both sides' `add(...)` calls. No numbering conflicts here — just ensure no duplicate registrations.
|
||||
|
||||
### `src/libxrpl/protocol/STTx.cpp`
|
||||
|
||||
The `singleSignHelper` function was refactored in `develop`:
|
||||
- Parameter name: `sigObject` (not `signer`)
|
||||
- Signature retrieval: `sigObject.getFieldVL(sfTxnSignature)` (not `getSignature(signer)`)
|
||||
- No `fullyCanonical` parameter — canonical sig checking was simplified
|
||||
|
||||
**Resolution:** Take `develop`'s function signatures and patterns. Adapt any feature-specific logic to match.
|
||||
|
||||
### `src/libxrpl/protocol/SecretKey.cpp`
|
||||
|
||||
**Resolution:** Use `namespace xrpl`. Keep any additional `#include` directives your feature needs (e.g., OpenSSL headers for new key types).
|
||||
|
||||
### `src/libxrpl/tx/Transactor.cpp`
|
||||
|
||||
The `checkSign` / `checkSingleSign` / `checkMultiSign` functions were refactored in `develop`:
|
||||
- `checkSingleSign` no longer takes a `Rules` parameter
|
||||
- `checkSign` has a new overload taking `PreclaimContext`
|
||||
- `checkBatchSign` uses the simplified `checkSingleSign` call
|
||||
|
||||
**Resolution:** Take `develop`'s function signatures. Add any new authentication checks (e.g., passkey verification) into `checkSingleSign` before the final `return tefBAD_AUTH`, using `view.read(...)` to check ledger state.
|
||||
|
||||
### `src/libxrpl/tx/applySteps.cpp`
|
||||
|
||||
**Resolution:** Always take `develop`'s macro-based include approach:
|
||||
```cpp
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
#pragma push_macro("TRANSACTION")
|
||||
#undef TRANSACTION
|
||||
|
||||
#define TRANSACTION(...)
|
||||
#define TRANSACTION_INCLUDE 1
|
||||
|
||||
#include <xrpl/protocol/detail/transactions.macro>
|
||||
|
||||
#undef TRANSACTION
|
||||
#pragma pop_macro("TRANSACTION")
|
||||
```
|
||||
|
||||
Never use the old explicit `#include <xrpld/app/tx/detail/*.h>` list.
|
||||
|
||||
### `src/test/jtx/impl/utility.cpp`
|
||||
|
||||
The `sign` function was refactored in `develop`:
|
||||
- Takes `sigObject` parameter: `sign(Json::Value& jv, Account const& account, Json::Value& sigObject)`
|
||||
- Has an overload: `sign(Json::Value& jv, Account const& account)` that calls `sign(jv, account, jv)`
|
||||
- Uses `xrpl::sign(...)` not `ripple::sign(...)`
|
||||
|
||||
**Resolution:** Take `develop`'s function signatures. Adapt feature-specific signing logic to the new pattern.
|
||||
|
||||
## Conflict Resolution Checklist
|
||||
|
||||
1. List all conflicted files: `git diff --name-only --diff-filter=U`
|
||||
2. Check which have actual conflict markers vs just unmerged: `grep -l "<<<<<<< HEAD" <file>`
|
||||
3. For files without markers: stage them or `git rm` if they were moved
|
||||
4. For each file with markers:
|
||||
- Take `develop`'s structural changes (namespace, function signatures, macro formats)
|
||||
- Preserve your feature's additions (new fields, entries, transactions, logic)
|
||||
- Resolve any numbering collisions by incrementing to the next available number
|
||||
5. Stage resolved files: `git add <file>`
|
||||
6. Verify no remaining markers: `grep -r "<<<<<<< " --include="*.cpp" --include="*.h" --include="*.macro"`
|
||||
7. Verify no remaining unmerged: `git diff --name-only --diff-filter=U`
|
||||
57
.claude/skills/xrpld/app.md
Normal file
57
.claude/skills/xrpld/app.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# App Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with the main application layer in `src/xrpld/app/`. Covers the Application singleton, ledger management, consensus adapters, services, and runtime coordination.
|
||||
|
||||
## Responsibility
|
||||
Contains the main application logic and runtime coordination for the rippled server. The Application singleton provides access to all services. Sub-modules handle ledger management, consensus, fee voting, amendments, path finding, and transaction queuing.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Application Singleton
|
||||
```cpp
|
||||
// Application is the master interface - access all services through it
|
||||
class Application {
|
||||
virtual Config& config() = 0;
|
||||
virtual Logs& logs() = 0;
|
||||
virtual JobQueue& getJobQueue() = 0;
|
||||
virtual LedgerMaster& getLedgerMaster() = 0;
|
||||
virtual NetworkOPs& getOPs() = 0;
|
||||
virtual NodeStore::Database& getNodeStore() = 0;
|
||||
// ... many more service accessors
|
||||
};
|
||||
// Implemented by ApplicationImp (hidden in .cpp)
|
||||
```
|
||||
|
||||
### ServiceRegistry Pattern
|
||||
```cpp
|
||||
// Services are injected via ServiceRegistry from libxrpl
|
||||
// Application provides centralized access to all registered services
|
||||
```
|
||||
|
||||
### Master Mutex
|
||||
```cpp
|
||||
// Recursive mutex protects shared state:
|
||||
using MutexType = std::recursive_mutex;
|
||||
// Protects: open ledger, server state, consensus engine
|
||||
// Use std::lock_guard<Application::MutexType> for access
|
||||
```
|
||||
|
||||
### Module Interface Pattern
|
||||
```cpp
|
||||
// Public interface: Module.h (abstract)
|
||||
// Implementation: ModuleImp.h/cpp (hidden)
|
||||
// Factory: make_Module() returns unique_ptr
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never access Application services before setup() completes
|
||||
- Always acquire master mutex when modifying open ledger or consensus state
|
||||
- Use `std::recursive_mutex` (not plain mutex) - multiple services may lock re-entrantly
|
||||
- Never create a second Application instance
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/main/Application.h` - Core application interface
|
||||
- `src/xrpld/app/main/Application.cpp` - Implementation (150+ includes)
|
||||
- `src/xrpld/app/main/BasicApp.h` - Base application services
|
||||
- `src/xrpld/app/main/GRPCServer.h` - gRPC server integration
|
||||
47
.claude/skills/xrpld/app/consensus.md
Normal file
47
.claude/skills/xrpld/app/consensus.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# App Consensus Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with RCL consensus adapters in `src/xrpld/app/consensus/`. Bridges the generic consensus algorithm to rippled-specific types.
|
||||
|
||||
## Responsibility
|
||||
Adapts the generic consensus algorithm (in `xrpld/consensus/`) to work with rippled application types. Provides concrete type adapters for transactions, transaction sets, and ledgers.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### RCL Adapters
|
||||
```cpp
|
||||
// RCLCxTx - Adapts SHAMapItem as a consensus transaction
|
||||
// RCLCxTxSet - Adapts SHAMap as a consensus transaction set
|
||||
// RCLCxLedger - Adapts Ledger as a consensus ledger
|
||||
// RCLConsensus - Glues generic consensus to rippled Application
|
||||
```
|
||||
|
||||
### Adapter Pattern
|
||||
```cpp
|
||||
// Generic consensus works with abstract types via CRTP
|
||||
// RCL adapters provide concrete implementations
|
||||
class RCLConsensus : public Consensus<RCLConsensus> {
|
||||
// Implements required methods using rippled types
|
||||
// e.g., acquireLedger(), proposeTx(), relay()
|
||||
};
|
||||
```
|
||||
|
||||
### Validation Handling
|
||||
```cpp
|
||||
// RCLValidations tracks validation messages from the network
|
||||
// Maps to the generic Validations<> template
|
||||
// Handles trusted vs untrusted validators
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Adapter methods must match the CRTP interface exactly - compiler errors are cryptic
|
||||
- Never import generic consensus types into adapter code - always go through the adapter
|
||||
- RCLConsensus holds references to Application services - ensure Application outlives it
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/consensus/RCLConsensus.h` - Main consensus orchestrator
|
||||
- `src/xrpld/app/consensus/RCLConsensus.cpp` - Implementation
|
||||
- `src/xrpld/app/consensus/RCLValidations.h` - Validation handling
|
||||
- `src/xrpld/app/consensus/RCLCxTx.h` - Transaction adapter
|
||||
- `src/xrpld/app/consensus/RCLCxTxSet.h` - Transaction set adapter
|
||||
- `src/xrpld/app/consensus/RCLCxLedger.h` - Ledger adapter
|
||||
67
.claude/skills/xrpld/app/ledger.md
Normal file
67
.claude/skills/xrpld/app/ledger.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# App Ledger Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with ledger management in `src/xrpld/app/ledger/`. Covers ledger storage, retrieval, history, and the Ledger class itself.
|
||||
|
||||
## Responsibility
|
||||
Manages the lifecycle of ledger objects: creation, storage, retrieval, history tracking, inbound acquisition from network, and order book caching. The Ledger class is the central data structure.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Ledger Class
|
||||
```cpp
|
||||
// Ledger is composed of two SHAMaps:
|
||||
// 1. State Map - Account roots, order books, ledger entries (STLedgerEntry)
|
||||
// 2. Transaction Map - Transactions and metadata for that ledger
|
||||
|
||||
class Ledger final : public std::enable_shared_from_this<Ledger>,
|
||||
public CountedObject<Ledger> {
|
||||
// Can be mutable (sole ownership) or immutable (shared, read-only)
|
||||
// Genesis ledger has special constructor
|
||||
};
|
||||
```
|
||||
|
||||
### Mutable vs Immutable
|
||||
```cpp
|
||||
// Mutable: Only one owner, can be modified
|
||||
// Immutable: Shared via shared_ptr, read-only
|
||||
// Transition: mutable -> immutable when accepted
|
||||
// Never modify an immutable ledger
|
||||
```
|
||||
|
||||
### LedgerMaster
|
||||
```cpp
|
||||
// Manages the chain of validated ledgers
|
||||
// Tracks: current, validated, closed ledgers
|
||||
// Handles ledger transitions during consensus
|
||||
```
|
||||
|
||||
### Inbound Ledger Acquisition
|
||||
```cpp
|
||||
// InboundLedgers manages acquiring missing ledgers from peers
|
||||
// InboundTransactions handles transaction set acquisition
|
||||
// Both use async fetch with timeout and retry
|
||||
```
|
||||
|
||||
### Iterator Adapters
|
||||
```cpp
|
||||
// sles_iter_impl - Iterate over SLE (state entries)
|
||||
// txs_iter_impl - Iterate over transactions
|
||||
// Efficient iteration without copying
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never modify an immutable ledger - check mutability first
|
||||
- Ledger must be shared via shared_ptr (enable_shared_from_this)
|
||||
- Genesis ledger construction is special - don't use for normal ledgers
|
||||
- LedgerMaster state transitions must be atomic with consensus
|
||||
- CountedObject tracking helps detect leaks - don't disable it
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/ledger/Ledger.h` - Core ledger class
|
||||
- `src/xrpld/app/ledger/LedgerMaster.h` - Ledger chain management
|
||||
- `src/xrpld/app/ledger/LedgerHistory.h` - Historical tracking
|
||||
- `src/xrpld/app/ledger/LedgerCleaner.h` - Online deletion
|
||||
- `src/xrpld/app/ledger/InboundLedgers.h` - Network acquisition
|
||||
- `src/xrpld/app/ledger/OrderBookDB.h` - Order book cache
|
||||
- `src/xrpld/app/ledger/TransactionMaster.h` - Transaction lookup
|
||||
18
.claude/skills/xrpld/app/ledger/detail.md
Normal file
18
.claude/skills/xrpld/app/ledger/detail.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# App Ledger Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with ledger implementation details in `src/xrpld/app/ledger/detail/`. Internal helpers for the ledger module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for the app/ledger module. Contains private helpers for ledger state management, iteration, and storage operations.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Detail Namespace Convention
|
||||
- Code in `detail/` is internal to the `app/ledger` module
|
||||
- Never include detail headers from outside `app/ledger`
|
||||
- If you need functionality, use the public `app/ledger/` headers instead
|
||||
|
||||
## Common Pitfalls
|
||||
- Detail implementations may change without API compatibility
|
||||
- Never expose detail types in public interfaces
|
||||
54
.claude/skills/xrpld/app/main.md
Normal file
54
.claude/skills/xrpld/app/main.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# App Main Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with application initialization and lifecycle in `src/xrpld/app/main/`. Covers Application startup, shutdown, and core services.
|
||||
|
||||
## Responsibility
|
||||
Application initialization, lifecycle management, and core service wiring. Contains the Application interface and its implementation, gRPC server, load management, node identity, and the node store scheduler.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Application Lifecycle
|
||||
```cpp
|
||||
// 1. Construct Application (parse config, create services)
|
||||
// 2. setup() - Initialize all services, open databases
|
||||
// 3. run() - Main event loop
|
||||
// 4. signalStop() - Graceful shutdown
|
||||
// 5. Destructor - Clean up resources
|
||||
```
|
||||
|
||||
### Node Identity
|
||||
```cpp
|
||||
// NodeIdentity manages the node's public/private key pair
|
||||
// Used for peer handshake, session signatures, and cluster membership
|
||||
// Keys persisted in wallet_db
|
||||
```
|
||||
|
||||
### Load Manager
|
||||
```cpp
|
||||
// Tracks server load across all subsystems
|
||||
// Triggers load-based fee escalation
|
||||
// Monitors job queue depth and execution time
|
||||
```
|
||||
|
||||
### gRPC Server
|
||||
```cpp
|
||||
// Optional gRPC server alongside JSON-RPC
|
||||
// Uses proto definitions from include/xrpl/proto/
|
||||
// Separate handler set from JSON-RPC
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- setup() must complete before any service is used
|
||||
- signalStop() should be called for graceful shutdown - avoid hard kills
|
||||
- Node identity keys must never be logged or exposed
|
||||
- Load manager affects fee escalation - test under load
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/main/Application.h` - Core interface
|
||||
- `src/xrpld/app/main/Application.cpp` - Implementation
|
||||
- `src/xrpld/app/main/BasicApp.h` - Base services
|
||||
- `src/xrpld/app/main/GRPCServer.h` - gRPC integration
|
||||
- `src/xrpld/app/main/LoadManager.h` - Load tracking
|
||||
- `src/xrpld/app/main/NodeIdentity.h` - Node key management
|
||||
- `src/xrpld/app/main/NodeStoreScheduler.h` - Async DB scheduler
|
||||
75
.claude/skills/xrpld/app/misc.md
Normal file
75
.claude/skills/xrpld/app/misc.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# App Misc Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with application services in `src/xrpld/app/misc/`. Covers fee voting, amendments, SHAMapStore, transaction queue, validator management, and NetworkOPs.
|
||||
|
||||
## Responsibility
|
||||
Collection of application-level services: fee voting system, amendment mechanism, online deletion (SHAMapStore), transaction queue (TxQ), validator key/list management, and NetworkOPs (the central operations coordinator).
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Fee Voting
|
||||
```cpp
|
||||
// Validators vote on fee schedules every 256 ledgers ("voting ledgers")
|
||||
// Pseudo-transactions injected to set fees
|
||||
// Majority vote determines new fee schedule
|
||||
// FeeVote.h - voting logic
|
||||
// FeeEscalation.md - escalation documentation
|
||||
```
|
||||
|
||||
### Amendment Mechanism
|
||||
```cpp
|
||||
// Network-wide ledger rule changes
|
||||
// Requires 80% validator approval sustained for 2 weeks
|
||||
// Tracked as pseudo-transactions in each ledger
|
||||
// AmendmentTableImpl.h manages tracking and state
|
||||
```
|
||||
|
||||
### SHAMapStore (Online Delete)
|
||||
```cpp
|
||||
// Prunes old ledger history automatically
|
||||
// Uses rotation between two databases
|
||||
// Configurable deletion intervals
|
||||
// Must not delete data needed for active operations
|
||||
```
|
||||
|
||||
### Transaction Queue (TxQ)
|
||||
```cpp
|
||||
// Queues transactions when ledger is full
|
||||
// Priority based on fee level
|
||||
// Handles fee escalation under load
|
||||
// TxQ.h - queue implementation
|
||||
```
|
||||
|
||||
### Validator Management
|
||||
```cpp
|
||||
// ValidatorKeys.h - Node's own validator keys
|
||||
// ValidatorList.h - Trusted validator list (UNL)
|
||||
// ValidatorSite.h - Sites serving validator lists
|
||||
// Keys loaded from config, lists fetched from URLs
|
||||
```
|
||||
|
||||
### NetworkOPs
|
||||
```cpp
|
||||
// Central operations coordinator - the "god object"
|
||||
// Coordinates: consensus, ledger acceptance, transaction submission
|
||||
// NetworkOPs.cpp is one of the largest files in the codebase
|
||||
// Access via app.getOPs()
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Fee voting only happens on voting ledgers (every 256) - don't trigger manually
|
||||
- Amendments require 2-week sustained 80% approval - no fast path
|
||||
- SHAMapStore deletion must respect the advisory_delete safety window
|
||||
- TxQ priority depends on current fee escalation level
|
||||
- NetworkOPs is massive - changes here affect many systems
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/misc/FeeVote.h` - Fee voting system
|
||||
- `src/xrpld/app/misc/AmendmentTableImpl.h` - Amendment tracking
|
||||
- `src/xrpld/app/misc/SHAMapStore.h` - Online deletion
|
||||
- `src/xrpld/app/misc/TxQ.h` - Transaction queue
|
||||
- `src/xrpld/app/misc/ValidatorKeys.h` - Validator key management
|
||||
- `src/xrpld/app/misc/ValidatorList.h` - Trusted validator list
|
||||
- `src/xrpld/app/misc/NetworkOPs.cpp` - Central operations
|
||||
- `src/xrpld/app/misc/README.md` - Architecture documentation
|
||||
18
.claude/skills/xrpld/app/misc/detail.md
Normal file
18
.claude/skills/xrpld/app/misc/detail.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# App Misc Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with internal service implementation details in `src/xrpld/app/misc/detail/`. Internal helpers for the misc services module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for app/misc services (fee voting internals, amendment table implementation, SHAMapStore internals, etc.).
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Detail Namespace Convention
|
||||
- Code in `detail/` is internal to the `app/misc` module
|
||||
- Implementation classes (e.g., AmendmentTableImpl) live here
|
||||
- Never include detail headers from outside `app/misc`
|
||||
|
||||
## Common Pitfalls
|
||||
- Detail implementations may change without API compatibility
|
||||
- Always use the public `app/misc/` interfaces
|
||||
53
.claude/skills/xrpld/app/paths.md
Normal file
53
.claude/skills/xrpld/app/paths.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# App Paths Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with payment path finding in `src/xrpld/app/paths/`. Covers the path finding algorithm, trust line caching, and AMM liquidity integration.
|
||||
|
||||
## Responsibility
|
||||
Implements the XRP Ledger payment path finding algorithm at the application level. Manages path requests, trust line caching, and integration with Automated Market Maker liquidity.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Path Finding
|
||||
```cpp
|
||||
// Pathfinder: Algorithm that finds payment paths between accounts
|
||||
// Considers: trust lines, order books, AMM pools
|
||||
// Returns: Set of paths ranked by cost/quality
|
||||
```
|
||||
|
||||
### Path Request Management
|
||||
```cpp
|
||||
// PathRequest - Individual path find request
|
||||
// PathRequests - Manages collection of active requests
|
||||
// Requests can be one-shot or subscribed (streaming updates)
|
||||
```
|
||||
|
||||
### Trust Line Caching
|
||||
```cpp
|
||||
// RippleLineCache caches trust line data
|
||||
// Avoids repeated ledger lookups during path finding
|
||||
// Cache is invalidated on ledger close
|
||||
// TrustLine.h provides the trust line representation
|
||||
```
|
||||
|
||||
### AMM Integration
|
||||
```cpp
|
||||
// AMMLiquidity.h - Integrates AMM pools into path finding
|
||||
// AMMOffer.h - Represents AMM as a synthetic offer
|
||||
// AMM pools are treated as a special offer type in the path finder
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Path finding is computationally expensive - respect search depth limits
|
||||
- Trust line cache must be invalidated on ledger close
|
||||
- AMM liquidity changes with pool state - don't cache AMM offers across ledgers
|
||||
- Path subscriptions can be memory-intensive with many clients
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/paths/Pathfinder.h` - Path finding algorithm
|
||||
- `src/xrpld/app/paths/PathRequest.h` - Individual request handling
|
||||
- `src/xrpld/app/paths/PathRequests.h` - Request collection management
|
||||
- `src/xrpld/app/paths/RippleLineCache.h` - Trust line caching
|
||||
- `src/xrpld/app/paths/TrustLine.h` - Trust line representation
|
||||
- `src/xrpld/app/paths/AMMLiquidity.h` - AMM pool integration
|
||||
- `src/xrpld/app/paths/AMMOffer.h` - Synthetic AMM offers
|
||||
18
.claude/skills/xrpld/app/paths/detail.md
Normal file
18
.claude/skills/xrpld/app/paths/detail.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# App Paths Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with path finding implementation details in `src/xrpld/app/paths/detail/`. Internal helpers for the path finding module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for the path finding algorithm, including search heuristics, cost calculation helpers, and internal data structures.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Detail Namespace Convention
|
||||
- Code in `detail/` is internal to the `app/paths` module
|
||||
- Contains algorithm-specific helpers not needed by callers
|
||||
- Never include detail headers from outside `app/paths`
|
||||
|
||||
## Common Pitfalls
|
||||
- Path finding internals are performance-sensitive - profile before modifying
|
||||
- Detail implementations may change without API compatibility
|
||||
39
.claude/skills/xrpld/app/rdb.md
Normal file
39
.claude/skills/xrpld/app/rdb.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# App RDB Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with application-level database operations in `src/xrpld/app/rdb/`. Covers database abstractions and backend implementations.
|
||||
|
||||
## Responsibility
|
||||
Application-level relational database operations. Provides interfaces for peer finding data storage, SQLite backend implementation, and database operation details.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Interface-Based Design
|
||||
```cpp
|
||||
// PeerFinder.h - Abstract interface for peer data storage
|
||||
// Backend implementations in backend/ subdirectory
|
||||
// Allows swapping database backends without changing callers
|
||||
```
|
||||
|
||||
### SQLite Backend
|
||||
```cpp
|
||||
// SQLiteDatabase.h - Primary backend implementation
|
||||
// Uses SOCI wrapper from libxrpl/rdb
|
||||
// Handles: peer data, transaction history, ledger metadata
|
||||
```
|
||||
|
||||
### Backend Abstraction
|
||||
```cpp
|
||||
// backend/ directory contains concrete implementations
|
||||
// backend/detail/ has implementation-specific helpers
|
||||
// detail/ has shared implementation details
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always use the abstract interface, not the SQLite backend directly
|
||||
- Database operations should be off the main thread (use job queue)
|
||||
- Respect the SOCI wrapper patterns from libxrpl/rdb
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/rdb/PeerFinder.h` - Peer data interface
|
||||
- `src/xrpld/app/rdb/backend/SQLiteDatabase.h` - SQLite implementation
|
||||
31
.claude/skills/xrpld/app/rdb/backend.md
Normal file
31
.claude/skills/xrpld/app/rdb/backend.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# App RDB Backend Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with database backend implementations in `src/xrpld/app/rdb/backend/`. Covers concrete database implementations.
|
||||
|
||||
## Responsibility
|
||||
Concrete database backend implementations for the app/rdb module. Primary implementation is SQLiteDatabase.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### SQLiteDatabase
|
||||
```cpp
|
||||
// Primary backend implementation using SQLite via SOCI
|
||||
// Handles: peer storage, transaction history, ledger metadata
|
||||
// Thread-safe via session-per-thread pattern from libxrpl/rdb
|
||||
```
|
||||
|
||||
### Backend Detail
|
||||
```cpp
|
||||
// backend/detail/ contains SQLite-specific helpers
|
||||
// Schema creation, migration, and optimization queries
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always use parameterized queries via SOCI - never raw string SQL
|
||||
- Database files can grow large - implement periodic VACUUM
|
||||
- WAL checkpoint scheduling prevents unbounded WAL growth
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/rdb/backend/SQLiteDatabase.h` - SQLite implementation
|
||||
- `src/xrpld/app/rdb/backend/detail/` - SQLite-specific helpers
|
||||
11
.claude/skills/xrpld/app/rdb/backend/detail.md
Normal file
11
.claude/skills/xrpld/app/rdb/backend/detail.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# App RDB Backend Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with database backend implementation details in `src/xrpld/app/rdb/backend/detail/`. SQLite-specific internal helpers.
|
||||
|
||||
## Responsibility
|
||||
SQLite-specific implementation details: schema definitions, migration scripts, query optimization, and SOCI binding helpers.
|
||||
|
||||
## Common Pitfalls
|
||||
- Schema migrations must be backwards-compatible
|
||||
- Never include these headers from outside the rdb/backend module
|
||||
18
.claude/skills/xrpld/app/rdb/detail.md
Normal file
18
.claude/skills/xrpld/app/rdb/detail.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# App RDB Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with database implementation details in `src/xrpld/app/rdb/detail/`. Internal helpers for the relational database module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for app-level database operations, including SQL query helpers and schema management.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Detail Namespace Convention
|
||||
- Code in `detail/` is internal to the `app/rdb` module
|
||||
- Contains SQL query construction and result parsing helpers
|
||||
- Never include detail headers from outside `app/rdb`
|
||||
|
||||
## Common Pitfalls
|
||||
- SQL queries must use parameterized bindings (SOCI style) - never string concatenation
|
||||
- Detail implementations may change without API compatibility
|
||||
34
.claude/skills/xrpld/app/tx.md
Normal file
34
.claude/skills/xrpld/app/tx.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# App Tx Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with application-level transaction handling in `src/xrpld/app/tx/`. Covers transaction submission, validation, and application-layer processing.
|
||||
|
||||
## Responsibility
|
||||
Application-level transaction handling that bridges the protocol-layer transaction processing (libxrpl/tx) with the running server. Handles transaction submission, validation, and integration with the consensus process.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Relationship to libxrpl/tx
|
||||
```cpp
|
||||
// libxrpl/tx: Protocol-level transaction processing (Transactor, preflight, preclaim, doApply)
|
||||
// xrpld/app/tx: Application-level orchestration (submission, queuing, consensus integration)
|
||||
// This module calls into libxrpl/tx for actual transaction execution
|
||||
```
|
||||
|
||||
### Transaction Submission Flow
|
||||
```cpp
|
||||
// 1. Client submits transaction via RPC
|
||||
// 2. app/tx validates and queues transaction
|
||||
// 3. Transaction enters TxQ (app/misc/TxQ)
|
||||
// 4. Consensus selects transactions for next ledger
|
||||
// 5. libxrpl/tx executes selected transactions
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Don't duplicate transaction validation logic - defer to libxrpl/tx
|
||||
- Application-level checks (queue depth, fee escalation) happen here, not in libxrpl
|
||||
- Transaction metadata is generated at this level after execution
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/app/tx/` - Application transaction handling
|
||||
- `src/xrpld/app/tx/detail/` - Implementation details
|
||||
11
.claude/skills/xrpld/app/tx/detail.md
Normal file
11
.claude/skills/xrpld/app/tx/detail.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# App Tx Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with application transaction handling details in `src/xrpld/app/tx/detail/`. Internal helpers for transaction submission and processing.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for application-level transaction handling, including submission validation, queue integration, and metadata generation.
|
||||
|
||||
## Common Pitfalls
|
||||
- Don't duplicate libxrpl/tx validation logic here
|
||||
- Detail implementations may change without API compatibility
|
||||
59
.claude/skills/xrpld/consensus.md
Normal file
59
.claude/skills/xrpld/consensus.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Consensus Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with the generic consensus algorithm in `src/xrpld/consensus/`. This is the application-independent consensus implementation.
|
||||
|
||||
## Responsibility
|
||||
Implements the generic consensus algorithm separate from application-specific types. Uses CRTP (Curiously Recurring Template Pattern) to allow the application layer to plug in concrete types without virtual dispatch overhead.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### CRTP Design
|
||||
```cpp
|
||||
// Generic consensus uses CRTP - derived class provides concrete types
|
||||
template <class Derived>
|
||||
class Consensus {
|
||||
// Calls static_cast<Derived*>(this)->method() for app-specific behavior
|
||||
// No virtual dispatch overhead
|
||||
};
|
||||
|
||||
// Application adapter:
|
||||
class RCLConsensus : public Consensus<RCLConsensus> {
|
||||
// Provides concrete types: RCLCxTx, RCLCxTxSet, RCLCxLedger
|
||||
};
|
||||
```
|
||||
|
||||
### Consensus Phases
|
||||
```cpp
|
||||
// Open -> Establish -> Accept
|
||||
// Open: Collecting transactions
|
||||
// Establish: Proposing and voting on transaction set
|
||||
// Accept: Applying agreed-upon transaction set to ledger
|
||||
```
|
||||
|
||||
### Consensus Parameters (ConsensusParms.h)
|
||||
```cpp
|
||||
// Timing parameters for consensus rounds
|
||||
// These are tuned for network behavior - don't change without careful analysis
|
||||
```
|
||||
|
||||
### Disputed Transactions
|
||||
```cpp
|
||||
// DisputedTx tracks transactions where validators disagree
|
||||
// Votes are collected and transaction is included/excluded based on threshold
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Never modify consensus parameters without understanding network-wide impact
|
||||
- CRTP means compilation errors from type mismatches appear in template instantiation - read errors carefully
|
||||
- The generic consensus module should NEVER depend on application-specific types (Ledger, STTx, etc.)
|
||||
- Always test consensus changes with multi-node simulation
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/consensus/Consensus.h` - Main consensus class (extensively documented)
|
||||
- `src/xrpld/consensus/ConsensusParms.h` - Timing parameters
|
||||
- `src/xrpld/consensus/ConsensusProposal.h` - Proposal structures
|
||||
- `src/xrpld/consensus/DisputedTx.h` - Transaction dispute tracking
|
||||
- `src/xrpld/consensus/LedgerTiming.h` - Ledger timing calculations
|
||||
- `src/xrpld/consensus/LedgerTrie.h` - Transaction set representation
|
||||
- `src/xrpld/consensus/Validations.h` - Generic validation tracking
|
||||
55
.claude/skills/xrpld/core.md
Normal file
55
.claude/skills/xrpld/core.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Core Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with core configuration and system services in `src/xrpld/core/`. Covers Config, time keeping, and network identity.
|
||||
|
||||
## Responsibility
|
||||
System-level configuration and core services. The Config class extends BasicConfig from libxrpl with rippled-specific settings. Provides time keeping and network ID management.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Config Class
|
||||
```cpp
|
||||
// Config extends BasicConfig from libxrpl
|
||||
class Config : public BasicConfig {
|
||||
// SizedItem enum for memory-dependent configuration
|
||||
enum SizedItem { siSweepInterval, siNodeCacheSize, ... };
|
||||
|
||||
// FeeSetup for fee parameters
|
||||
struct FeeSetup {
|
||||
XRPAmount reference_fee;
|
||||
XRPAmount account_reserve;
|
||||
XRPAmount owner_reserve;
|
||||
};
|
||||
|
||||
// Access sections by name
|
||||
auto const& section = config["server"];
|
||||
};
|
||||
```
|
||||
|
||||
### Configuration Sections
|
||||
```cpp
|
||||
// Section names defined in ConfigSections.h
|
||||
static constexpr char const* SECTION_NODE_DB = "node_db";
|
||||
static constexpr char const* SECTION_VALIDATORS = "validators";
|
||||
// Always use constants, never string literals
|
||||
```
|
||||
|
||||
### Gradual Refactoring
|
||||
```cpp
|
||||
// Legacy config uses mixed patterns - refactoring is ongoing
|
||||
// New code should follow the Section-based approach
|
||||
// Deprecated patterns are documented with TODO comments
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always use `ConfigSections.h` constants for section names
|
||||
- Config extends BasicConfig - check both for available methods
|
||||
- SizedItem values scale with node size configuration - don't hardcode sizes
|
||||
- Never modify Config after Application startup
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/core/Config.h` - Configuration object
|
||||
- `src/xrpld/core/ConfigSections.h` - Section name constants
|
||||
- `src/xrpld/core/TimeKeeper.h` - System time tracking
|
||||
- `src/xrpld/core/NetworkIDServiceImpl.h` - Network ID implementation
|
||||
11
.claude/skills/xrpld/core/detail.md
Normal file
11
.claude/skills/xrpld/core/detail.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Core Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with core configuration implementation details in `src/xrpld/core/detail/`. Internal helpers for the Config system.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for the core configuration module, including config parsing helpers and platform-specific abstractions.
|
||||
|
||||
## Common Pitfalls
|
||||
- Never include detail headers from outside the core module
|
||||
- Config parsing must handle all edge cases gracefully (missing sections, invalid values)
|
||||
74
.claude/skills/xrpld/overlay.md
Normal file
74
.claude/skills/xrpld/overlay.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Overlay Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with P2P networking in `src/xrpld/overlay/`. Covers peer connections, protocol negotiation, message relay, and clustering.
|
||||
|
||||
## Responsibility
|
||||
Manages peer-to-peer connections and the overlay network protocol. Handles HTTP/1.1 upgrade handshake, session signatures (MITM prevention), Protocol Buffer message serialization, message compression, and cluster node management.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### HTTP/1.1 Upgrade Handshake
|
||||
```cpp
|
||||
// Connection starts as HTTP, upgrades to ripple protocol
|
||||
// Custom headers:
|
||||
// Connect-As, Public-Key, Session-Signature
|
||||
// Network-ID, Network-Time
|
||||
// Closed-Ledger, Previous-Ledger
|
||||
// Remote-IP, Local-IP, Crawl
|
||||
```
|
||||
|
||||
### Session Signature (MITM Prevention)
|
||||
```cpp
|
||||
// Binds SSL/TLS session to node identities
|
||||
// Each peer signs the shared SSL session data
|
||||
// Prevents man-in-the-middle attacks at the protocol level
|
||||
```
|
||||
|
||||
### Message Serialization
|
||||
```cpp
|
||||
// Google Protocol Buffers for all p2p messages
|
||||
// Messages are compressed before transmission
|
||||
// Compression.h handles LZ4/no-compression selection
|
||||
```
|
||||
|
||||
### Peer Management
|
||||
```cpp
|
||||
// Overlay manages the set of connected peers
|
||||
class Overlay {
|
||||
virtual Peer::ptr findPeerByShortID(Peer::id_t) = 0;
|
||||
virtual void send(std::shared_ptr<Message> const&) = 0; // Broadcast
|
||||
virtual void relay(Message const&, uint256 const& suppression) = 0;
|
||||
};
|
||||
```
|
||||
|
||||
### Clustering
|
||||
```cpp
|
||||
// Multiple rippled nodes can form a cluster
|
||||
// Cluster nodes: share load, distribute crypto operations
|
||||
// Cluster membership verified via node public keys
|
||||
```
|
||||
|
||||
### Reduce Relay
|
||||
```cpp
|
||||
// ReduceRelayCommon.h - Minimize redundant message relay
|
||||
// Uses HashRouter for message deduplication
|
||||
// Peers track which messages they've already seen
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always validate session signatures during handshake - never skip
|
||||
- Never send uncompressed messages to peers that advertise compression support
|
||||
- Cluster keys must be pre-configured - no dynamic cluster joining
|
||||
- Message suppression via HashRouter is critical for network health - never bypass
|
||||
- Protocol Buffer messages must match the expected schema version
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/overlay/Overlay.h` - Main overlay manager interface
|
||||
- `src/xrpld/overlay/Peer.h` - Peer connection representation
|
||||
- `src/xrpld/overlay/PeerSet.h` - Collection of peers
|
||||
- `src/xrpld/overlay/Cluster.h` - Cluster management
|
||||
- `src/xrpld/overlay/Message.h` - Message structure
|
||||
- `src/xrpld/overlay/Compression.h` - Message compression
|
||||
- `src/xrpld/overlay/ReduceRelayCommon.h` - Relay optimization
|
||||
- `src/xrpld/overlay/README.md` - Comprehensive protocol documentation
|
||||
27
.claude/skills/xrpld/overlay/detail.md
Normal file
27
.claude/skills/xrpld/overlay/detail.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Overlay Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with P2P networking implementation details in `src/xrpld/overlay/detail/`. Internal helpers for the overlay module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for the overlay networking layer, including protocol message handling, peer connection state machines, and handshake implementation.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### PeerImp
|
||||
```cpp
|
||||
// PeerImp is the concrete implementation of the Peer interface
|
||||
// Manages: SSL connection, protocol state, message queuing
|
||||
// Uses enable_shared_from_this for async callback safety
|
||||
```
|
||||
|
||||
### OverlayImpl
|
||||
```cpp
|
||||
// OverlayImpl is the concrete implementation of Overlay
|
||||
// Manages: listening sockets, peer lifecycle, broadcast
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Peer connection state machine transitions must be atomic
|
||||
- Never access PeerImp internals from outside overlay/detail/
|
||||
- Message queuing must respect back-pressure limits
|
||||
58
.claude/skills/xrpld/peerfinder.md
Normal file
58
.claude/skills/xrpld/peerfinder.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# PeerFinder Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with network discovery in `src/xrpld/peerfinder/`. Covers peer bootstrap, cache management, and connection slot strategy.
|
||||
|
||||
## Responsibility
|
||||
Bootstraps into the XRP Ledger network and discovers peers. Manages bootcache (persistent addresses ranked by success), livecache (ephemeral recently-seen peers), and connection slot allocation.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Three-Stage Connection Strategy
|
||||
```cpp
|
||||
// Stage 1: Connect to fixed peers (configured addresses)
|
||||
// Stage 2: Try Livecache addresses (recently seen, with open slots)
|
||||
// Stage 3: Fall back to Bootcache (persistent, ranked by valence)
|
||||
```
|
||||
|
||||
### Bootcache (Persistent)
|
||||
```cpp
|
||||
// Persistent store of peer addresses ranked by "valence" (connection success)
|
||||
// Higher valence = more reliable peer
|
||||
// Persisted across restarts
|
||||
// Used as fallback when livecache is empty
|
||||
```
|
||||
|
||||
### Livecache (Ephemeral)
|
||||
```cpp
|
||||
// Recently seen peers with available connection slots
|
||||
// Uses hop counts for distance estimation
|
||||
// Random distribution for load balancing
|
||||
// Not persisted - rebuilt on restart via gossip
|
||||
```
|
||||
|
||||
### Slot Management
|
||||
```cpp
|
||||
// Slot states: accept, connect, connected, active, closing
|
||||
// Slot properties: Inbound/Outbound, Fixed, Cluster
|
||||
// Slots track connection lifecycle from handshake to disconnect
|
||||
```
|
||||
|
||||
### Callback Pattern
|
||||
```cpp
|
||||
// Abstract interface for socket operations
|
||||
// PeerFinder doesn't directly manage sockets
|
||||
// Delegates I/O to the overlay layer via callbacks
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Fixed peers should always be tried first (Stage 1) - they are trusted
|
||||
- Bootcache valence can decay over time - implement proper aging
|
||||
- Livecache entries expire quickly - don't rely on stale data
|
||||
- Slot limits prevent connection exhaustion - never bypass them
|
||||
- Always check README.md for algorithm details before modifying
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/peerfinder/PeerfinderManager.h` - Main manager interface
|
||||
- `src/xrpld/peerfinder/Slot.h` - Connection slot representation
|
||||
- `src/xrpld/peerfinder/README.md` - Extensive design documentation
|
||||
21
.claude/skills/xrpld/peerfinder/detail.md
Normal file
21
.claude/skills/xrpld/peerfinder/detail.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# PeerFinder Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with peer discovery implementation details in `src/xrpld/peerfinder/detail/`. Internal helpers for the peerfinder module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for peer discovery: bootcache persistence, livecache management, slot state machine, and connection strategy implementation.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Logic Class
|
||||
```cpp
|
||||
// The main implementation class for peer finding
|
||||
// Implements the three-stage connection strategy
|
||||
// Manages bootcache and livecache state
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Bootcache persistence must be atomic to prevent corruption
|
||||
- Livecache expiration must be checked on every access
|
||||
- Never include detail headers from outside peerfinder/
|
||||
31
.claude/skills/xrpld/perflog.md
Normal file
31
.claude/skills/xrpld/perflog.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# PerfLog Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with performance logging in `src/xrpld/perflog/`. Covers performance instrumentation and metric collection.
|
||||
|
||||
## Responsibility
|
||||
Performance logging and instrumentation for the rippled server. Tracks timing data, throughput metrics, and operational statistics for monitoring and debugging.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Performance Logging Interface
|
||||
```cpp
|
||||
// Abstract interface for performance data collection
|
||||
// Implementations can log to file, export to monitoring systems, etc.
|
||||
// Enabled/disabled via configuration
|
||||
```
|
||||
|
||||
### Detail Namespace
|
||||
```cpp
|
||||
// Implementation details in detail/ subdirectory
|
||||
// Not part of public API
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Performance logging should have minimal overhead when disabled
|
||||
- Never log sensitive data (keys, balances) in performance logs
|
||||
- Ensure timestamps use consistent clock sources
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/perflog/` - Performance logging implementation
|
||||
- `src/xrpld/perflog/detail/` - Implementation details
|
||||
11
.claude/skills/xrpld/perflog/detail.md
Normal file
11
.claude/skills/xrpld/perflog/detail.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# PerfLog Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with performance logging implementation details in `src/xrpld/perflog/detail/`. Internal helpers for the perflog module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for performance logging, including metric collection, formatting, and output management.
|
||||
|
||||
## Common Pitfalls
|
||||
- Performance logging overhead must be minimal when disabled
|
||||
- Never include detail headers from outside perflog/
|
||||
91
.claude/skills/xrpld/rpc.md
Normal file
91
.claude/skills/xrpld/rpc.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# RPC Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with RPC request handling in `src/xrpld/rpc/`. Covers command dispatch, handler implementation, coroutine suspension, and the gRPC interface.
|
||||
|
||||
## Responsibility
|
||||
HTTP/JSON and gRPC RPC interface to rippled. Dispatches requests to 40+ command handlers, manages request context, supports coroutine-based suspension for async operations, and handles user roles/permissions.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### RPC Handler Pattern
|
||||
```cpp
|
||||
// Each handler is a function taking context, returning Json::Value
|
||||
Json::Value doMyCommand(RPC::JsonContext& context) {
|
||||
// Validate parameters
|
||||
if (!context.params.isMember("field"))
|
||||
return RPC::missing_field_error("field");
|
||||
|
||||
// Access application services
|
||||
auto& app = context.app;
|
||||
|
||||
// Build response
|
||||
Json::Value result(Json::objectValue);
|
||||
result["status"] = "success";
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
### Coroutine Suspension
|
||||
```cpp
|
||||
// RPC handlers can suspend for async operations
|
||||
// Key types:
|
||||
// Callback - 0-argument function
|
||||
// Continuation - Takes callback, promises to call it later
|
||||
// Suspend - Function from coroutine that takes continuation
|
||||
// Coroutine - Function given suspend to enable suspension
|
||||
|
||||
// This allows handlers to yield without blocking threads
|
||||
```
|
||||
|
||||
### Request Context
|
||||
```cpp
|
||||
struct JsonContext {
|
||||
Application& app;
|
||||
Resource::Charge& loadType;
|
||||
Json::Value params;
|
||||
beast::Journal j;
|
||||
Role role; // User, Admin, Identified, etc.
|
||||
};
|
||||
```
|
||||
|
||||
### Role-Based Access
|
||||
```cpp
|
||||
enum class Role { GUEST, USER, ADMIN, IDENTIFIED, PROXY, FORBID };
|
||||
// Handlers specify minimum required role
|
||||
// Admin handlers only accessible from admin IP ranges
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
```cpp
|
||||
// Standard error helpers:
|
||||
RPC::missing_field_error("field_name");
|
||||
RPC::invalid_field_error("field_name");
|
||||
RPC::make_error(rpcINVALID_PARAMS, "description");
|
||||
// Errors injected into JSON response
|
||||
```
|
||||
|
||||
### gRPC Handlers
|
||||
```cpp
|
||||
// Separate handler set for gRPC interface
|
||||
// Defined in GRPCHandlers.h
|
||||
// Use Protocol Buffer request/response types
|
||||
// Convert to/from native types at boundary
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always validate parameters before accessing them
|
||||
- Check user Role before executing privileged operations
|
||||
- Use coroutine suspension for any operation that might block
|
||||
- Never return internal data structures directly - always convert to JSON
|
||||
- Handler functions are in `handlers/` directory - one file per command or group
|
||||
- gRPC handlers must convert proto types to native types at the boundary
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/rpc/RPCHandler.h` - Command dispatcher
|
||||
- `src/xrpld/rpc/Context.h` - RPC context/state
|
||||
- `src/xrpld/rpc/Status.h` - RPC status codes
|
||||
- `src/xrpld/rpc/Role.h` - User role/permissions
|
||||
- `src/xrpld/rpc/GRPCHandlers.h` - gRPC integration
|
||||
- `src/xrpld/rpc/handlers/` - Individual command handlers (40+)
|
||||
- `src/xrpld/rpc/README.md` - Coroutine documentation
|
||||
11
.claude/skills/xrpld/rpc/detail.md
Normal file
11
.claude/skills/xrpld/rpc/detail.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# RPC Detail Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with RPC implementation details in `src/xrpld/rpc/detail/`. Internal helpers for the RPC module.
|
||||
|
||||
## Responsibility
|
||||
Internal implementation details for RPC handling, including request parsing, response formatting, coroutine machinery, and middleware.
|
||||
|
||||
## Common Pitfalls
|
||||
- Coroutine state must be carefully managed to prevent leaks
|
||||
- Never include detail headers from outside rpc/
|
||||
74
.claude/skills/xrpld/rpc/handlers.md
Normal file
74
.claude/skills/xrpld/rpc/handlers.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# RPC Handlers Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when adding or modifying RPC command handlers in `src/xrpld/rpc/handlers/`. Contains 40+ individual RPC command implementations.
|
||||
|
||||
## Responsibility
|
||||
Individual RPC command handler implementations. Each file implements one or more related RPC commands following the standard handler pattern.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Handler Function Signature
|
||||
```cpp
|
||||
// Standard handler pattern
|
||||
Json::Value doMyCommand(RPC::JsonContext& context) {
|
||||
// 1. Validate parameters
|
||||
if (!context.params.isMember("required_field"))
|
||||
return RPC::missing_field_error("required_field");
|
||||
|
||||
// 2. Check permissions
|
||||
// (Role already verified by dispatcher based on handler metadata)
|
||||
|
||||
// 3. Access application services
|
||||
auto& app = context.app;
|
||||
auto& ledger = context.ledgerMaster.getValidatedLedger();
|
||||
|
||||
// 4. Execute logic
|
||||
// ...
|
||||
|
||||
// 5. Build and return response
|
||||
Json::Value result(Json::objectValue);
|
||||
result["status"] = "success";
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
### Parameter Validation
|
||||
```cpp
|
||||
// Use standard error helpers
|
||||
RPC::missing_field_error("field_name"); // Required field missing
|
||||
RPC::invalid_field_error("field_name"); // Field has wrong type/value
|
||||
RPC::make_error(rpcINVALID_PARAMS, "description"); // Generic error
|
||||
```
|
||||
|
||||
### Adding a New Handler
|
||||
1. Create a new .cpp file in `handlers/`
|
||||
2. Implement the handler function following the pattern above
|
||||
3. Register the command in the handler dispatch table
|
||||
4. Document the command parameters and response format
|
||||
|
||||
### Common Handler Files
|
||||
```
|
||||
AccountInfo.cpp - account_info command
|
||||
AccountLines.cpp - account_lines (trust lines)
|
||||
AccountOffers.cpp - account_offers
|
||||
Submit.cpp - submit (transaction submission)
|
||||
Subscribe.cpp - subscribe (event streaming)
|
||||
LedgerData.cpp - ledger_data
|
||||
ServerInfo.cpp - server_info
|
||||
Fee1.cpp - fee command
|
||||
Tx.cpp - tx (transaction lookup)
|
||||
BookOffers.cpp - book_offers (order book)
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always validate ALL parameters before using them
|
||||
- Never return internal data structures - convert to JSON at the boundary
|
||||
- Respect Role-based access control - admin handlers must check role
|
||||
- Handlers should be stateless - all state comes from context
|
||||
- Use coroutine suspension for any blocking operation (DB queries, network)
|
||||
- Error responses must follow the standard error format
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/rpc/handlers/` - All handler implementations
|
||||
- `src/xrpld/rpc/RPCHandler.h` - Dispatch table and registration
|
||||
32
.claude/skills/xrpld/shamap.md
Normal file
32
.claude/skills/xrpld/shamap.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# SHAMap (xrpld) Module Best Practices
|
||||
|
||||
## Description
|
||||
Use when working with application-level SHAMap operations in `src/xrpld/shamap/`. Covers NodeFamily and application integration with the Merkle tree.
|
||||
|
||||
## Responsibility
|
||||
Application-level integration of the SHAMap (Merkle radix tree) with the rippled server. Provides NodeFamily for managing tree node relationships and connecting the generic SHAMap to the node store.
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### NodeFamily
|
||||
```cpp
|
||||
// NodeFamily connects SHAMap to the persistent NodeStore
|
||||
// Provides: database access, tree node creation, hash verification
|
||||
// Each SHAMap references a Family for storage operations
|
||||
```
|
||||
|
||||
### Relationship to libxrpl/shamap
|
||||
```cpp
|
||||
// libxrpl/shamap: Generic Merkle tree implementation
|
||||
// xrpld/shamap: Application-specific integration (NodeFamily, storage)
|
||||
// The generic tree doesn't know about databases - NodeFamily bridges the gap
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
- Always use NodeFamily to create SHAMap instances connected to storage
|
||||
- The libxrpl SHAMap is the implementation - this module is the glue layer
|
||||
- Don't duplicate SHAMap logic here - extend via NodeFamily only
|
||||
|
||||
## Key Files
|
||||
- `src/xrpld/shamap/NodeFamily.h` - Family relationship management
|
||||
- `src/xrpld/shamap/NodeFamily.cpp` - Implementation
|
||||
247
.cmake-format.yaml
Normal file
247
.cmake-format.yaml
Normal file
@@ -0,0 +1,247 @@
|
||||
_help_parse: Options affecting listfile parsing
|
||||
parse:
|
||||
_help_additional_commands:
|
||||
- Specify structure for custom cmake functions
|
||||
additional_commands:
|
||||
target_protobuf_sources:
|
||||
pargs:
|
||||
- target
|
||||
- prefix
|
||||
kwargs:
|
||||
PROTOS: "*"
|
||||
LANGUAGE: cpp
|
||||
IMPORT_DIRS: "*"
|
||||
GENERATE_EXTENSIONS: "*"
|
||||
PLUGIN: "*"
|
||||
_help_override_spec:
|
||||
- Override configurations per-command where available
|
||||
override_spec: {}
|
||||
_help_vartags:
|
||||
- Specify variable tags.
|
||||
vartags: []
|
||||
_help_proptags:
|
||||
- Specify property tags.
|
||||
proptags: []
|
||||
_help_format: Options affecting formatting.
|
||||
format:
|
||||
_help_disable:
|
||||
- Disable formatting entirely, making cmake-format a no-op
|
||||
disable: false
|
||||
_help_line_width:
|
||||
- How wide to allow formatted cmake files
|
||||
line_width: 120
|
||||
_help_tab_size:
|
||||
- How many spaces to tab for indent
|
||||
tab_size: 4
|
||||
_help_use_tabchars:
|
||||
- If true, lines are indented using tab characters (utf-8
|
||||
- 0x09) instead of <tab_size> space characters (utf-8 0x20).
|
||||
- In cases where the layout would require a fractional tab
|
||||
- character, the behavior of the fractional indentation is
|
||||
- governed by <fractional_tab_policy>
|
||||
use_tabchars: false
|
||||
_help_fractional_tab_policy:
|
||||
- If <use_tabchars> is True, then the value of this variable
|
||||
- indicates how fractional indentions are handled during
|
||||
- whitespace replacement. If set to 'use-space', fractional
|
||||
- indentation is left as spaces (utf-8 0x20). If set to
|
||||
- "`round-up` fractional indentation is replaced with a single"
|
||||
- tab character (utf-8 0x09) effectively shifting the column
|
||||
- to the next tabstop
|
||||
fractional_tab_policy: use-space
|
||||
_help_max_subgroups_hwrap:
|
||||
- If an argument group contains more than this many sub-groups
|
||||
- (parg or kwarg groups) then force it to a vertical layout.
|
||||
max_subgroups_hwrap: 4
|
||||
_help_max_pargs_hwrap:
|
||||
- If a positional argument group contains more than this many
|
||||
- arguments, then force it to a vertical layout.
|
||||
max_pargs_hwrap: 5
|
||||
_help_max_rows_cmdline:
|
||||
- If a cmdline positional group consumes more than this many
|
||||
- lines without nesting, then invalidate the layout (and nest)
|
||||
max_rows_cmdline: 2
|
||||
_help_separate_ctrl_name_with_space:
|
||||
- If true, separate flow control names from their parentheses
|
||||
- with a space
|
||||
separate_ctrl_name_with_space: true
|
||||
_help_separate_fn_name_with_space:
|
||||
- If true, separate function names from parentheses with a
|
||||
- space
|
||||
separate_fn_name_with_space: false
|
||||
_help_dangle_parens:
|
||||
- If a statement is wrapped to more than one line, than dangle
|
||||
- the closing parenthesis on its own line.
|
||||
dangle_parens: false
|
||||
_help_dangle_align:
|
||||
- If the trailing parenthesis must be 'dangled' on its on
|
||||
- "line, then align it to this reference: `prefix`: the start"
|
||||
- "of the statement, `prefix-indent`: the start of the"
|
||||
- "statement, plus one indentation level, `child`: align to"
|
||||
- the column of the arguments
|
||||
dangle_align: prefix
|
||||
_help_min_prefix_chars:
|
||||
- If the statement spelling length (including space and
|
||||
- parenthesis) is smaller than this amount, then force reject
|
||||
- nested layouts.
|
||||
min_prefix_chars: 18
|
||||
_help_max_prefix_chars:
|
||||
- If the statement spelling length (including space and
|
||||
- parenthesis) is larger than the tab width by more than this
|
||||
- amount, then force reject un-nested layouts.
|
||||
max_prefix_chars: 10
|
||||
_help_max_lines_hwrap:
|
||||
- If a candidate layout is wrapped horizontally but it exceeds
|
||||
- this many lines, then reject the layout.
|
||||
max_lines_hwrap: 2
|
||||
_help_line_ending:
|
||||
- What style line endings to use in the output.
|
||||
line_ending: unix
|
||||
_help_command_case:
|
||||
- Format command names consistently as 'lower' or 'upper' case
|
||||
command_case: canonical
|
||||
_help_keyword_case:
|
||||
- Format keywords consistently as 'lower' or 'upper' case
|
||||
keyword_case: unchanged
|
||||
_help_always_wrap:
|
||||
- A list of command names which should always be wrapped
|
||||
always_wrap: []
|
||||
_help_enable_sort:
|
||||
- If true, the argument lists which are known to be sortable
|
||||
- will be sorted lexicographicall
|
||||
enable_sort: true
|
||||
_help_autosort:
|
||||
- If true, the parsers may infer whether or not an argument
|
||||
- list is sortable (without annotation).
|
||||
autosort: true
|
||||
_help_require_valid_layout:
|
||||
- By default, if cmake-format cannot successfully fit
|
||||
- everything into the desired linewidth it will apply the
|
||||
- last, most aggressive attempt that it made. If this flag is
|
||||
- True, however, cmake-format will print error, exit with non-
|
||||
- zero status code, and write-out nothing
|
||||
require_valid_layout: false
|
||||
_help_layout_passes:
|
||||
- A dictionary mapping layout nodes to a list of wrap
|
||||
- decisions. See the documentation for more information.
|
||||
layout_passes: {}
|
||||
_help_markup: Options affecting comment reflow and formatting.
|
||||
markup:
|
||||
_help_bullet_char:
|
||||
- What character to use for bulleted lists
|
||||
bullet_char: "-"
|
||||
_help_enum_char:
|
||||
- What character to use as punctuation after numerals in an
|
||||
- enumerated list
|
||||
enum_char: .
|
||||
_help_first_comment_is_literal:
|
||||
- If comment markup is enabled, don't reflow the first comment
|
||||
- block in each listfile. Use this to preserve formatting of
|
||||
- your copyright/license statements.
|
||||
first_comment_is_literal: false
|
||||
_help_literal_comment_pattern:
|
||||
- If comment markup is enabled, don't reflow any comment block
|
||||
- which matches this (regex) pattern. Default is `None`
|
||||
- (disabled).
|
||||
literal_comment_pattern: null
|
||||
_help_fence_pattern:
|
||||
- Regular expression to match preformat fences in comments
|
||||
- default= ``r'^\s*([`~]{3}[`~]*)(.*)$'``
|
||||
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
|
||||
_help_ruler_pattern:
|
||||
- Regular expression to match rulers in comments default=
|
||||
- '``r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''``'
|
||||
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
|
||||
_help_explicit_trailing_pattern:
|
||||
- If a comment line matches starts with this pattern then it
|
||||
- is explicitly a trailing comment for the preceding
|
||||
- argument. Default is '#<'
|
||||
explicit_trailing_pattern: "#<"
|
||||
_help_hashruler_min_length:
|
||||
- If a comment line starts with at least this many consecutive
|
||||
- hash characters, then don't lstrip() them off. This allows
|
||||
- for lazy hash rulers where the first hash char is not
|
||||
- separated by space
|
||||
hashruler_min_length: 10
|
||||
_help_canonicalize_hashrulers:
|
||||
- If true, then insert a space between the first hash char and
|
||||
- remaining hash chars in a hash ruler, and normalize its
|
||||
- length to fill the column
|
||||
canonicalize_hashrulers: true
|
||||
_help_enable_markup:
|
||||
- enable comment markup parsing and reflow
|
||||
enable_markup: false
|
||||
_help_lint: Options affecting the linter
|
||||
lint:
|
||||
_help_disabled_codes:
|
||||
- a list of lint codes to disable
|
||||
disabled_codes: []
|
||||
_help_function_pattern:
|
||||
- regular expression pattern describing valid function names
|
||||
function_pattern: "[0-9a-z_]+"
|
||||
_help_macro_pattern:
|
||||
- regular expression pattern describing valid macro names
|
||||
macro_pattern: "[0-9A-Z_]+"
|
||||
_help_global_var_pattern:
|
||||
- regular expression pattern describing valid names for
|
||||
- variables with global (cache) scope
|
||||
global_var_pattern: "[A-Z][0-9A-Z_]+"
|
||||
_help_internal_var_pattern:
|
||||
- regular expression pattern describing valid names for
|
||||
- variables with global scope (but internal semantic)
|
||||
internal_var_pattern: _[A-Z][0-9A-Z_]+
|
||||
_help_local_var_pattern:
|
||||
- regular expression pattern describing valid names for
|
||||
- variables with local scope
|
||||
local_var_pattern: "[a-z][a-z0-9_]+"
|
||||
_help_private_var_pattern:
|
||||
- regular expression pattern describing valid names for
|
||||
- privatedirectory variables
|
||||
private_var_pattern: _[0-9a-z_]+
|
||||
_help_public_var_pattern:
|
||||
- regular expression pattern describing valid names for public
|
||||
- directory variables
|
||||
public_var_pattern: "[A-Z][0-9A-Z_]+"
|
||||
_help_argument_var_pattern:
|
||||
- regular expression pattern describing valid names for
|
||||
- function/macro arguments and loop variables.
|
||||
argument_var_pattern: "[a-z][a-z0-9_]+"
|
||||
_help_keyword_pattern:
|
||||
- regular expression pattern describing valid names for
|
||||
- keywords used in functions or macros
|
||||
keyword_pattern: "[A-Z][0-9A-Z_]+"
|
||||
_help_max_conditionals_custom_parser:
|
||||
- In the heuristic for C0201, how many conditionals to match
|
||||
- within a loop in before considering the loop a parser.
|
||||
max_conditionals_custom_parser: 2
|
||||
_help_min_statement_spacing:
|
||||
- Require at least this many newlines between statements
|
||||
min_statement_spacing: 1
|
||||
_help_max_statement_spacing:
|
||||
- Require no more than this many newlines between statements
|
||||
max_statement_spacing: 2
|
||||
max_returns: 6
|
||||
max_branches: 12
|
||||
max_arguments: 5
|
||||
max_localvars: 15
|
||||
max_statements: 50
|
||||
_help_encode: Options affecting file encoding
|
||||
encode:
|
||||
_help_emit_byteorder_mark:
|
||||
- If true, emit the unicode byte-order mark (BOM) at the start
|
||||
- of the file
|
||||
emit_byteorder_mark: false
|
||||
_help_input_encoding:
|
||||
- Specify the encoding of the input file. Defaults to utf-8
|
||||
input_encoding: utf-8
|
||||
_help_output_encoding:
|
||||
- Specify the encoding of the output file. Defaults to utf-8.
|
||||
- Note that cmake only claims to support utf-8 so be careful
|
||||
- when using anything else
|
||||
output_encoding: utf-8
|
||||
_help_misc: Miscellaneous configurations options.
|
||||
misc:
|
||||
_help_per_command:
|
||||
- A dictionary containing any per-command configuration
|
||||
- overrides. Currently only `command_case` is supported.
|
||||
per_command: {}
|
||||
42
.codecov.yml
42
.codecov.yml
@@ -1,6 +1,38 @@
|
||||
|
||||
codecov:
|
||||
ci:
|
||||
- ci.ops.ripple.com # add custom jenkins server
|
||||
- !appveyor
|
||||
- !travis
|
||||
require_ci_to_pass: true
|
||||
|
||||
comment:
|
||||
behavior: default
|
||||
layout: reach,diff,flags,tree,reach
|
||||
show_carryforward_flags: false
|
||||
|
||||
coverage:
|
||||
range: "70..85"
|
||||
precision: 1
|
||||
round: nearest
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: 75%
|
||||
threshold: 2%
|
||||
patch:
|
||||
default:
|
||||
target: auto
|
||||
threshold: 2%
|
||||
changes: false
|
||||
|
||||
github_checks:
|
||||
annotations: true
|
||||
|
||||
parsers:
|
||||
cobertura:
|
||||
partials_as_hits: true
|
||||
handle_missing_conditions: true
|
||||
|
||||
slack_app: false
|
||||
|
||||
ignore:
|
||||
- "src/test/"
|
||||
- "src/tests/"
|
||||
- "include/xrpl/beast/test/"
|
||||
- "include/xrpl/beast/unit_test/"
|
||||
|
||||
290
.config/cspell.config.yaml
Normal file
290
.config/cspell.config.yaml
Normal file
@@ -0,0 +1,290 @@
|
||||
ignorePaths:
|
||||
- build/**
|
||||
- src/libxrpl/crypto
|
||||
- src/test/** # Will be removed in the future
|
||||
- CMakeUserPresets.json
|
||||
- Doxyfile
|
||||
- docs/**/*.puml
|
||||
- cmake/**
|
||||
- LICENSE.md
|
||||
language: en
|
||||
allowCompoundWords: true
|
||||
ignoreRandomStrings: true
|
||||
minWordLength: 5
|
||||
dictionaries:
|
||||
- cpp
|
||||
- en_US
|
||||
- en_GB
|
||||
ignoreRegExpList:
|
||||
- /[rs][1-9A-HJ-NP-Za-km-z]{25,34}/g # addresses and seeds
|
||||
- /(XRPL|BEAST)_[A-Z_0-9]+_H_INCLUDED+/g # include guards
|
||||
- /(XRPL|BEAST)_[A-Z_0-9]+_H+/g # include guards
|
||||
- /::[a-z:_]+/g # things from other namespaces
|
||||
- /lib[a-z]+/g # libraries
|
||||
- /[0-9]{4}-[0-9]{2}-[0-9]{2}[,:][A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright dates
|
||||
- /[0-9]{4}[,:]?\s*[A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright years
|
||||
- /\[[A-Za-z0-9-]+\]\(https:\/\/github.com\/[A-Za-z0-9-]+\)/g # Github usernames
|
||||
- /-[DWw][a-zA-Z0-9_-]+=/g # compile flags
|
||||
- /[\['"`]-[DWw][a-zA-Z0-9_-]+['"`\]]/g # compile flags
|
||||
suggestWords:
|
||||
- xprl->xrpl
|
||||
- xprld->xrpld
|
||||
- unsynched->unsynced
|
||||
- synched->synced
|
||||
- synch->sync
|
||||
words:
|
||||
- abempty
|
||||
- AMMID
|
||||
- amt
|
||||
- amts
|
||||
- asnode
|
||||
- asynchrony
|
||||
- attestation
|
||||
- authorises
|
||||
- autobridge
|
||||
- autobridged
|
||||
- autobridging
|
||||
- bimap
|
||||
- bindir
|
||||
- bookdir
|
||||
- Bougalis
|
||||
- Britto
|
||||
- Btrfs
|
||||
- canonicality
|
||||
- checkme
|
||||
- choco
|
||||
- chrono
|
||||
- citardauq
|
||||
- clawback
|
||||
- clawbacks
|
||||
- coeffs
|
||||
- coldwallet
|
||||
- compr
|
||||
- conanfile
|
||||
- conanrun
|
||||
- confs
|
||||
- connectability
|
||||
- coro
|
||||
- coros
|
||||
- cowid
|
||||
- cryptocondition
|
||||
- cryptoconditional
|
||||
- cryptoconditions
|
||||
- csprng
|
||||
- ctest
|
||||
- ctid
|
||||
- currenttxhash
|
||||
- daria
|
||||
- dcmake
|
||||
- dearmor
|
||||
- deleteme
|
||||
- demultiplexer
|
||||
- deserializaton
|
||||
- desync
|
||||
- desynced
|
||||
- determ
|
||||
- distro
|
||||
- doxyfile
|
||||
- dxrpl
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- Falco
|
||||
- finalizers
|
||||
- firewalled
|
||||
- fmtdur
|
||||
- fsanitize
|
||||
- funclets
|
||||
- gcov
|
||||
- gcovr
|
||||
- ghead
|
||||
- Gnutella
|
||||
- gpgcheck
|
||||
- gpgkey
|
||||
- hotwallet
|
||||
- hwrap
|
||||
- ifndef
|
||||
- inequation
|
||||
- insuf
|
||||
- insuff
|
||||
- iou
|
||||
- ious
|
||||
- isrdc
|
||||
- itype
|
||||
- jemalloc
|
||||
- jlog
|
||||
- keylet
|
||||
- keylets
|
||||
- keyvadb
|
||||
- kwarg
|
||||
- kwargs
|
||||
- ledgerentry
|
||||
- ledgerhash
|
||||
- ledgerindex
|
||||
- leftw
|
||||
- legleux
|
||||
- levelization
|
||||
- levelized
|
||||
- libpb
|
||||
- libxrpl
|
||||
- llection
|
||||
- LOCALGOOD
|
||||
- logwstream
|
||||
- lseq
|
||||
- lsmf
|
||||
- ltype
|
||||
- mcmodel
|
||||
- MEMORYSTATUSEX
|
||||
- Merkle
|
||||
- Metafuncton
|
||||
- misprediction
|
||||
- mptbalance
|
||||
- mptflags
|
||||
- mptid
|
||||
- mptissuance
|
||||
- mptissuanceid
|
||||
- mptoken
|
||||
- mptokenid
|
||||
- mptokenissuance
|
||||
- mptokens
|
||||
- mpts
|
||||
- multisig
|
||||
- multisign
|
||||
- multisigned
|
||||
- Nakamoto
|
||||
- nftid
|
||||
- nftoffer
|
||||
- nftoken
|
||||
- nftokenid
|
||||
- nftokenpages
|
||||
- nftokens
|
||||
- nftpage
|
||||
- nikb
|
||||
- nonxrp
|
||||
- noripple
|
||||
- nudb
|
||||
- nullptr
|
||||
- nunl
|
||||
- Nyffenegger
|
||||
- ostr
|
||||
- pargs
|
||||
- partitioner
|
||||
- paychan
|
||||
- paychans
|
||||
- permdex
|
||||
- perminute
|
||||
- permissioned
|
||||
- pointee
|
||||
- preauth
|
||||
- preauthorization
|
||||
- preauthorize
|
||||
- preauthorizes
|
||||
- preclaim
|
||||
- protobuf
|
||||
- protos
|
||||
- ptrs
|
||||
- pyenv
|
||||
- qalloc
|
||||
- queuable
|
||||
- Raphson
|
||||
- replayer
|
||||
- rerere
|
||||
- retriable
|
||||
- RIPD
|
||||
- ripdtop
|
||||
- rippleci
|
||||
- rippled
|
||||
- ripplerpc
|
||||
- rippletest
|
||||
- RLUSD
|
||||
- rngfill
|
||||
- rocksdb
|
||||
- Rohrs
|
||||
- roundings
|
||||
- sahyadri
|
||||
- Satoshi
|
||||
- scons
|
||||
- secp
|
||||
- sendq
|
||||
- seqit
|
||||
- sf
|
||||
- SFIELD
|
||||
- shamap
|
||||
- shamapitem
|
||||
- sidechain
|
||||
- SIGGOOD
|
||||
- sle
|
||||
- sles
|
||||
- soci
|
||||
- socidb
|
||||
- sslws
|
||||
- statsd
|
||||
- STATSDCOLLECTOR
|
||||
- stissue
|
||||
- stnum
|
||||
- stobj
|
||||
- stobject
|
||||
- stpath
|
||||
- stpathset
|
||||
- sttx
|
||||
- stvar
|
||||
- stvector
|
||||
- stxchainattestations
|
||||
- superpeer
|
||||
- superpeers
|
||||
- takergets
|
||||
- takerpays
|
||||
- ters
|
||||
- TMEndpointv2
|
||||
- trixie
|
||||
- tx
|
||||
- txid
|
||||
- txids
|
||||
- txjson
|
||||
- txn
|
||||
- txns
|
||||
- txs
|
||||
- UBSAN
|
||||
- ubsan
|
||||
- umant
|
||||
- unacquired
|
||||
- unambiguity
|
||||
- unauthorizes
|
||||
- unauthorizing
|
||||
- unergonomic
|
||||
- unfetched
|
||||
- unflatten
|
||||
- unfund
|
||||
- unimpair
|
||||
- unroutable
|
||||
- unscalable
|
||||
- unserviced
|
||||
- unshareable
|
||||
- unshares
|
||||
- unsquelch
|
||||
- unsquelched
|
||||
- unsquelching
|
||||
- unvalidated
|
||||
- unveto
|
||||
- unvetoed
|
||||
- upvotes
|
||||
- USDB
|
||||
- variadics
|
||||
- venv
|
||||
- vfalco
|
||||
- vinnie
|
||||
- wextra
|
||||
- wptr
|
||||
- writeme
|
||||
- wsrch
|
||||
- wthread
|
||||
- xbridge
|
||||
- xchain
|
||||
- ximinez
|
||||
- EXPECT_STREQ
|
||||
- XMACRO
|
||||
- xrpkuwait
|
||||
- xrpl
|
||||
- xrpld
|
||||
- xrplf
|
||||
- xxhash
|
||||
- xxhasher
|
||||
16
.git-blame-ignore-revs
Normal file
16
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,16 @@
|
||||
# This feature requires Git >= 2.24
|
||||
# To use it by default in git blame:
|
||||
# git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
50760c693510894ca368e90369b0cc2dabfd07f3
|
||||
e2384885f5f630c8f0ffe4bf21a169b433a16858
|
||||
241b9ddde9e11beb7480600fd5ed90e1ef109b21
|
||||
760f16f56835663d9286bd29294d074de26a7ba6
|
||||
0eebe6a5f4246fced516d52b83ec4e7f47373edd
|
||||
2189cc950c0cebb89e4e2fa3b2d8817205bf7cef
|
||||
b9d007813378ad0ff45660dc07285b823c7e9855
|
||||
fe9a5365b8a52d4acc42eb27369247e6f238a4f9
|
||||
9a93577314e6a8d4b4a8368cc9d2b15a5d8303e8
|
||||
552377c76f55b403a1c876df873a23d780fcc81c
|
||||
97f0747e103f13e26e45b731731059b32f7679ac
|
||||
b13370ac0d207217354f1fc1c29aef87769fb8a1
|
||||
896b8c3b54a22b0497cb0d1ce95e1095f9a227ce
|
||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1,9 +1,6 @@
|
||||
# Set default behaviour, in case users don't have core.autocrlf set.
|
||||
#* text=auto
|
||||
|
||||
# These annoying files
|
||||
rippled.1 binary
|
||||
LICENSE binary
|
||||
# cspell: disable
|
||||
|
||||
# Visual Studio
|
||||
*.sln text eol=crlf
|
||||
|
||||
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve xrpld
|
||||
title: "[Title with short description] (Version: [xrpld version])"
|
||||
labels: ""
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates.-->
|
||||
|
||||
## Issue Description
|
||||
|
||||
<!--Provide a summary for your issue/bug.-->
|
||||
|
||||
## Steps to Reproduce
|
||||
|
||||
<!--List in detail the exact steps to reproduce the unexpected behavior of the software.-->
|
||||
|
||||
## Expected Result
|
||||
|
||||
<!--Explain in detail what behavior you expected to happen.-->
|
||||
|
||||
## Actual Result
|
||||
|
||||
<!--Explain in detail what behavior actually happened.-->
|
||||
|
||||
## Environment
|
||||
|
||||
<!--Please describe your environment setup (such as Ubuntu 18.04 with Boost 1.70).-->
|
||||
<!-- If you are using a formal release, please use the version returned by './xrpld --version' as the version number-->
|
||||
<!-- If you are working off of develop, please add the git hash via 'git rev-parse HEAD'-->
|
||||
|
||||
## Supporting Files
|
||||
|
||||
<!--If you have supporting files such as a log, feel free to post a link here using Github Gist.-->
|
||||
<!--Consider adding configuration files with private information removed via Github Gist. -->
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: XRP Ledger Documentation
|
||||
url: https://xrpl.org/
|
||||
about: All things about XRPL
|
||||
- name: Security bug bounty program
|
||||
url: https://ripple.com/bug-bounty/
|
||||
about: Please report security-relevant bugs in our software here.
|
||||
25
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature for the rippled project
|
||||
title: "[Title with short description] (Version: [rippled version])"
|
||||
labels: Feature Request
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates.-->
|
||||
|
||||
## Summary
|
||||
|
||||
<!-- Provide a summary to the feature request-->
|
||||
|
||||
## Motivation
|
||||
|
||||
<!-- Why do we need this feature?-->
|
||||
|
||||
## Solution
|
||||
|
||||
<!-- What is the solution?-->
|
||||
|
||||
## Paths Not Taken
|
||||
|
||||
<!-- What other alternatives have been considered?-->
|
||||
48
.github/actions/build-deps/action.yml
vendored
Normal file
48
.github/actions/build-deps/action.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Build Conan dependencies
|
||||
description: "Install Conan dependencies, optionally forcing a rebuild of all dependencies."
|
||||
|
||||
# Note that actions do not support 'type' and all inputs are strings, see
|
||||
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
|
||||
inputs:
|
||||
build_type:
|
||||
description: 'The build type to use ("Debug", "Release").'
|
||||
required: true
|
||||
build_nproc:
|
||||
description: "The number of processors to use for building."
|
||||
required: true
|
||||
force_build:
|
||||
description: 'Force building of all dependencies ("true", "false").'
|
||||
required: false
|
||||
default: "false"
|
||||
log_verbosity:
|
||||
description: "The logging verbosity."
|
||||
required: false
|
||||
default: "verbose"
|
||||
sanitizers:
|
||||
description: "The sanitizers to enable."
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install Conan dependencies
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_NPROC: ${{ inputs.build_nproc }}
|
||||
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
LOG_VERBOSITY: ${{ inputs.log_verbosity }}
|
||||
SANITIZERS: ${{ inputs.sanitizers }}
|
||||
run: |
|
||||
echo 'Installing dependencies.'
|
||||
conan install \
|
||||
--profile ci \
|
||||
--build="${BUILD_OPTION}" \
|
||||
--options:host='&:tests=True' \
|
||||
--options:host='&:xrpld=True' \
|
||||
--settings:all build_type="${BUILD_TYPE}" \
|
||||
--conf:all tools.build:jobs=${BUILD_NPROC} \
|
||||
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
|
||||
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
|
||||
.
|
||||
44
.github/actions/generate-version/action.yml
vendored
Normal file
44
.github/actions/generate-version/action.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Generate build version number
|
||||
description: "Generate build version number."
|
||||
|
||||
outputs:
|
||||
version:
|
||||
description: "The generated build version number."
|
||||
value: ${{ steps.version.outputs.version }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# When a tag is pushed, the version is used as-is.
|
||||
- name: Generate version for tag event
|
||||
if: ${{ github.event_name == 'tag' }}
|
||||
shell: bash
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
run: echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
|
||||
|
||||
# When a tag is not pushed, then the version (e.g. 1.2.3-b0) is extracted
|
||||
# from the BuildInfo.cpp file and the shortened commit hash appended to it.
|
||||
# We use a plus sign instead of a hyphen because Conan recipe versions do
|
||||
# not support two hyphens.
|
||||
- name: Generate version for non-tag event
|
||||
if: ${{ github.event_name != 'tag' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Extracting version from BuildInfo.cpp.'
|
||||
VERSION="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')"
|
||||
if [[ -z "${VERSION}" ]]; then
|
||||
echo 'Unable to extract version from BuildInfo.cpp.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'Appending shortened commit hash to version.'
|
||||
SHA='${{ github.sha }}'
|
||||
VERSION="${VERSION}+${SHA:0:7}"
|
||||
|
||||
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
|
||||
|
||||
- name: Output version
|
||||
id: version
|
||||
shell: bash
|
||||
run: echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
43
.github/actions/print-env/action.yml
vendored
Normal file
43
.github/actions/print-env/action.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Print build environment
|
||||
description: "Print environment and some tooling versions"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Check configuration (Windows)
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Checking environment variables.'
|
||||
set
|
||||
|
||||
- name: Check configuration (Linux and macOS)
|
||||
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Checking path.'
|
||||
echo ${PATH} | tr ':' '\n'
|
||||
|
||||
echo 'Checking environment variables.'
|
||||
env | sort
|
||||
|
||||
echo 'Checking compiler version.'
|
||||
${{ runner.os == 'Linux' && '${CC}' || 'clang' }} --version
|
||||
|
||||
echo 'Checking Ninja version.'
|
||||
ninja --version
|
||||
|
||||
echo 'Checking nproc version.'
|
||||
nproc --version
|
||||
|
||||
- name: Check configuration (all)
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Checking Ccache version.'
|
||||
ccache --version
|
||||
|
||||
echo 'Checking CMake version.'
|
||||
cmake --version
|
||||
|
||||
echo 'Checking Conan version.'
|
||||
conan --version
|
||||
46
.github/actions/setup-conan/action.yml
vendored
Normal file
46
.github/actions/setup-conan/action.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Setup Conan
|
||||
description: "Set up Conan configuration, profile, and remote."
|
||||
|
||||
inputs:
|
||||
remote_name:
|
||||
description: "The name of the Conan remote to use."
|
||||
required: false
|
||||
default: xrplf
|
||||
remote_url:
|
||||
description: "The URL of the Conan endpoint to use."
|
||||
required: false
|
||||
default: https://conan.ripplex.io
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Set up Conan configuration
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Installing configuration.'
|
||||
cat conan/global.conf ${{ runner.os == 'Linux' && '>>' || '>' }} $(conan config home)/global.conf
|
||||
|
||||
echo 'Conan configuration:'
|
||||
conan config show '*'
|
||||
|
||||
- name: Set up Conan profile
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'Installing profile.'
|
||||
conan config install conan/profiles/ -tf $(conan config home)/profiles/
|
||||
|
||||
echo 'Conan profile:'
|
||||
conan profile show --profile ci
|
||||
|
||||
- name: Set up Conan remote
|
||||
shell: bash
|
||||
env:
|
||||
REMOTE_NAME: ${{ inputs.remote_name }}
|
||||
REMOTE_URL: ${{ inputs.remote_url }}
|
||||
run: |
|
||||
echo "Adding Conan remote '${REMOTE_NAME}' at '${REMOTE_URL}'."
|
||||
conan remote add --index 0 --force "${REMOTE_NAME}" "${REMOTE_URL}"
|
||||
|
||||
echo 'Listing Conan remotes.'
|
||||
conan remote list
|
||||
85
.github/pull_request_template.md
vendored
Normal file
85
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<!--
|
||||
This PR template helps you to write a good pull request description.
|
||||
Please feel free to include additional useful information even beyond what is requested below.
|
||||
|
||||
If your branch is on a personal fork and has a name that allows it to
|
||||
run CI build/test jobs (e.g. "ci/foo"), remember to rename it BEFORE
|
||||
opening the PR. This avoids unnecessary redundant test runs. Renaming
|
||||
the branch after opening the PR will close the PR.
|
||||
https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/renaming-a-branch
|
||||
-->
|
||||
|
||||
## High Level Overview of Change
|
||||
|
||||
<!--
|
||||
Please include a summary of the changes.
|
||||
This may be a direct input to the release notes.
|
||||
If too broad, please consider splitting into multiple PRs.
|
||||
If a relevant task or issue, please link it here.
|
||||
-->
|
||||
|
||||
### Context of Change
|
||||
|
||||
<!--
|
||||
Please include the context of a change.
|
||||
If a bug fix, when was the bug introduced? What was the behavior?
|
||||
If a new feature, why was this architecture chosen? What were the alternatives?
|
||||
If a refactor, how is this better than the previous implementation?
|
||||
|
||||
If there is a spec or design document for this feature, please link it here.
|
||||
-->
|
||||
|
||||
### Type of Change
|
||||
|
||||
<!--
|
||||
Please check [x] relevant options, delete irrelevant ones.
|
||||
-->
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Refactor (non-breaking change that only restructures code)
|
||||
- [ ] Performance (increase or change in throughput and/or latency)
|
||||
- [ ] Tests (you added tests for code that already exists, or your new feature included in this PR)
|
||||
- [ ] Documentation update
|
||||
- [ ] Chore (no impact to binary, e.g. `.gitignore`, formatting, dropping support for older tooling)
|
||||
- [ ] Release
|
||||
|
||||
### API Impact
|
||||
|
||||
<!--
|
||||
Please check [x] relevant options, delete irrelevant ones.
|
||||
|
||||
* If there is any impact to the public API methods (HTTP / WebSocket), please update https://github.com/xrplf/rippled/blob/develop/API-CHANGELOG.md
|
||||
* Update API-CHANGELOG.md and add the change directly in this PR by pushing to your PR branch.
|
||||
* libxrpl: See https://github.com/XRPLF/rippled/blob/develop/docs/build/depend.md
|
||||
* Peer Protocol: See https://xrpl.org/peer-protocol.html
|
||||
-->
|
||||
|
||||
- [ ] Public API: New feature (new methods and/or new fields)
|
||||
- [ ] Public API: Breaking change (in general, breaking changes should only impact the next api_version)
|
||||
- [ ] `libxrpl` change (any change that may affect `libxrpl` or dependents of `libxrpl`)
|
||||
- [ ] Peer protocol change (must be backward compatible or bump the peer protocol version)
|
||||
|
||||
<!--
|
||||
## Before / After
|
||||
If relevant, use this section for an English description of the change at a technical level.
|
||||
If this change affects an API, examples should be included here.
|
||||
|
||||
For performance-impacting changes, please provide these details:
|
||||
1. Is this a new feature, bug fix, or improvement to existing functionality?
|
||||
2. What behavior/functionality does the change impact?
|
||||
3. In what processing can the impact be measured? Be as specific as possible - e.g. RPC client call, payment transaction that involves LOB, AMM, caching, DB operations, etc.
|
||||
4. Does this change affect concurrent processing - e.g. does it involve acquiring locks, multi-threaded processing, or async processing?
|
||||
-->
|
||||
|
||||
<!--
|
||||
## Test Plan
|
||||
If helpful, please describe the tests that you ran to verify your changes and provide instructions so that others can reproduce.
|
||||
This section may not be needed if your change includes thoroughly commented unit tests.
|
||||
-->
|
||||
|
||||
<!--
|
||||
## Future Tasks
|
||||
For future tasks related to PR.
|
||||
-->
|
||||
134
.github/scripts/levelization/README.md
vendored
Normal file
134
.github/scripts/levelization/README.md
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
# Levelization
|
||||
|
||||
Levelization is the term used to describe efforts to prevent rippled from
|
||||
having or creating cyclic dependencies.
|
||||
|
||||
rippled code is organized into directories under `src/xrpld`, `src/libxrpl` (and
|
||||
`src/test`) representing modules. The modules are intended to be
|
||||
organized into "tiers" or "levels" such that a module from one level can
|
||||
only include code from lower levels. Additionally, a module
|
||||
in one level should never include code in an `impl` or `detail` folder of any level
|
||||
other than it's own.
|
||||
|
||||
The codebase is split into two main areas:
|
||||
|
||||
- **libxrpl** (`src/libxrpl`, `include/xrpl`): Reusable library modules with public interfaces
|
||||
- **xrpld** (`src/xrpld`): Application-specific implementation code
|
||||
|
||||
Unfortunately, over time, enforcement of levelization has been
|
||||
inconsistent, so the current state of the code doesn't necessarily
|
||||
reflect these rules. Whenever possible, developers should refactor any
|
||||
levelization violations they find (by moving files or individual
|
||||
classes). At the very least, don't make things worse.
|
||||
|
||||
The table below summarizes the _desired_ division of modules, based on the current
|
||||
state of the rippled code. The levels are numbered from
|
||||
the bottom up with the lower level, lower numbered, more independent
|
||||
modules listed first, and the higher level, higher numbered modules with
|
||||
more dependencies listed later.
|
||||
|
||||
**tl;dr:** The modules listed first are more independent than the modules
|
||||
listed later.
|
||||
|
||||
## libxrpl Modules (Reusable Libraries)
|
||||
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | ----------------------------------- |
|
||||
| 01 | xrpl/beast |
|
||||
| 02 | xrpl/basics |
|
||||
| 03 | xrpl/json xrpl/crypto |
|
||||
| 04 | xrpl/protocol |
|
||||
| 05 | xrpl/core xrpl/resource xrpl/server |
|
||||
| 06 | xrpl/ledger xrpl/nodestore xrpl/net |
|
||||
| 07 | xrpl/shamap |
|
||||
|
||||
## xrpld Modules (Application Implementation)
|
||||
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | -------------------------------- |
|
||||
| 05 | xrpld/conditions xrpld/consensus |
|
||||
| 06 | xrpld/core xrpld/peerfinder |
|
||||
| 07 | xrpld/shamap xrpld/overlay |
|
||||
| 08 | xrpld/app |
|
||||
| 09 | xrpld/rpc |
|
||||
| 10 | xrpld/perflog |
|
||||
|
||||
## Test Modules
|
||||
|
||||
| Level / Tier | Module(s) |
|
||||
| ------------ | -------------------------------------------------------------------------------------------------------- |
|
||||
| 11 | test/jtx test/beast test/csf |
|
||||
| 12 | test/unit_test |
|
||||
| 13 | test/crypto test/conditions test/json test/resource test/shamap test/peerfinder test/basics test/overlay |
|
||||
| 14 | test |
|
||||
| 15 | test/net test/protocol test/ledger test/consensus test/core test/server test/nodestore |
|
||||
| 16 | test/rpc test/app |
|
||||
|
||||
(Note that `test` levelization is _much_ less important and _much_ less
|
||||
strictly enforced than `xrpl`/`xrpld` levelization, other than the requirement
|
||||
that `test` code should _never_ be included in `xrpl` or `xrpld` code.)
|
||||
|
||||
## Validation
|
||||
|
||||
The [levelization](generate.sh) script takes no parameters,
|
||||
reads no environment variables, and can be run from any directory,
|
||||
as long as it is in the expected location in the rippled repo.
|
||||
It can be run at any time from within a checked out repo, and will
|
||||
do an analysis of all the `#include`s in
|
||||
the rippled source. The only caveat is that it runs much slower
|
||||
under Windows than in Linux. It hasn't yet been tested under MacOS.
|
||||
It generates many files of [results](results):
|
||||
|
||||
- `rawincludes.txt`: The raw dump of the `#includes`
|
||||
- `paths.txt`: A second dump grouping the source module
|
||||
to the destination module, de-duped, and with frequency counts.
|
||||
- `includes/`: A directory where each file represents a module and
|
||||
contains a list of modules and counts that the module _includes_.
|
||||
- `included_by/`: Similar to `includes/`, but the other way around. Each
|
||||
file represents a module and contains a list of modules and counts
|
||||
that _include_ the module.
|
||||
- [`loops.txt`](results/loops.txt): A list of direct loops detected
|
||||
between modules as they actually exist, as opposed to how they are
|
||||
desired as described above. In a perfect repo, this file will be
|
||||
empty.
|
||||
This file is committed to the repo, and is used by the [levelization
|
||||
Github workflow](../../workflows/reusable-check-levelization.yml) to validate
|
||||
that nothing changed.
|
||||
- [`ordering.txt`](results/ordering.txt): A list showing relationships
|
||||
between modules where there are no loops as they actually exist, as
|
||||
opposed to how they are desired as described above.
|
||||
This file is committed to the repo, and is used by the [levelization
|
||||
Github workflow](../../workflows/reusable-check-levelization.yml) to validate
|
||||
that nothing changed.
|
||||
- [`levelization.yml`](../../workflows/reusable-check-levelization.yml)
|
||||
Github Actions workflow to test that levelization loops haven't
|
||||
changed. Unfortunately, if changes are detected, it can't tell if
|
||||
they are improvements or not, so if you have resolved any issues or
|
||||
done anything else to improve levelization, run `levelization.sh`,
|
||||
and commit the updated results.
|
||||
|
||||
The `loops.txt` and `ordering.txt` files relate the modules
|
||||
using comparison signs, which indicate the number of times each
|
||||
module is included in the other.
|
||||
|
||||
- `A > B` means that A should probably be at a higher level than B,
|
||||
because B is included in A significantly more than A is included in B.
|
||||
These results can be included in both `loops.txt` and `ordering.txt`.
|
||||
Because `ordering.txt`only includes relationships where B is not
|
||||
included in A at all, it will only include these types of results.
|
||||
- `A ~= B` means that A and B are included in each other a different
|
||||
number of times, but the values are so close that the script can't
|
||||
definitively say that one should be above the other. These results
|
||||
will only be included in `loops.txt`.
|
||||
- `A == B` means that A and B include each other the same number of
|
||||
times, so the script has no clue which should be higher. These results
|
||||
will only be included in `loops.txt`.
|
||||
|
||||
The committed files hide the detailed values intentionally, to
|
||||
prevent false alarms and merging issues, and because it's easy to
|
||||
get those details locally.
|
||||
|
||||
1. Run `levelization.sh`
|
||||
2. Grep the modules in `paths.txt`.
|
||||
- For example, if a cycle is found `A ~= B`, simply `grep -w
|
||||
A .github/scripts/levelization/results/paths.txt | grep -w B`
|
||||
130
.github/scripts/levelization/generate.sh
vendored
Executable file
130
.github/scripts/levelization/generate.sh
vendored
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: generate.sh
|
||||
# This script takes no parameters, reads no environment variables,
|
||||
# and can be run from any directory, as long as it is in the expected
|
||||
# location in the repo.
|
||||
|
||||
pushd $( dirname $0 )
|
||||
|
||||
if [ -v PS1 ]
|
||||
then
|
||||
# if the shell is interactive, clean up any flotsam before analyzing
|
||||
git clean -ix
|
||||
fi
|
||||
|
||||
# Ensure all sorting is ASCII-order consistently across platforms.
|
||||
export LANG=C
|
||||
|
||||
rm -rfv results
|
||||
mkdir results
|
||||
includes="$( pwd )/results/rawincludes.txt"
|
||||
pushd ../../..
|
||||
echo Raw includes:
|
||||
grep -r '^[ ]*#include.*/.*\.h' include src | \
|
||||
grep -v boost | tee ${includes}
|
||||
popd
|
||||
pushd results
|
||||
|
||||
oldifs=${IFS}
|
||||
IFS=:
|
||||
mkdir includes
|
||||
mkdir included_by
|
||||
echo Build levelization paths
|
||||
exec 3< ${includes} # open rawincludes.txt for input
|
||||
while read -r -u 3 file include
|
||||
do
|
||||
level=$( echo ${file} | cut -d/ -f 2,3 )
|
||||
# If the "level" indicates a file, cut off the filename
|
||||
if [[ "${level##*.}" != "${level}" ]]
|
||||
then
|
||||
# Use the "toplevel" label as a workaround for `sort`
|
||||
# inconsistencies between different utility versions
|
||||
level="$( dirname ${level} )/toplevel"
|
||||
fi
|
||||
level=$( echo ${level} | tr '/' '.' )
|
||||
|
||||
includelevel=$( echo ${include} | sed 's/.*["<]//; s/[">].*//' | \
|
||||
cut -d/ -f 1,2 )
|
||||
if [[ "${includelevel##*.}" != "${includelevel}" ]]
|
||||
then
|
||||
# Use the "toplevel" label as a workaround for `sort`
|
||||
# inconsistencies between different utility versions
|
||||
includelevel="$( dirname ${includelevel} )/toplevel"
|
||||
fi
|
||||
includelevel=$( echo ${includelevel} | tr '/' '.' )
|
||||
|
||||
if [[ "$level" != "$includelevel" ]]
|
||||
then
|
||||
echo $level $includelevel | tee -a paths.txt
|
||||
fi
|
||||
done
|
||||
echo Sort and deduplicate paths
|
||||
sort -ds paths.txt | uniq -c | tee sortedpaths.txt
|
||||
mv sortedpaths.txt paths.txt
|
||||
exec 3>&- #close fd 3
|
||||
IFS=${oldifs}
|
||||
unset oldifs
|
||||
|
||||
echo Split into flat-file database
|
||||
exec 4<paths.txt # open paths.txt for input
|
||||
while read -r -u 4 count level include
|
||||
do
|
||||
echo ${include} ${count} | tee -a includes/${level}
|
||||
echo ${level} ${count} | tee -a included_by/${include}
|
||||
done
|
||||
exec 4>&- #close fd 4
|
||||
|
||||
loops="$( pwd )/loops.txt"
|
||||
ordering="$( pwd )/ordering.txt"
|
||||
pushd includes
|
||||
echo Search for loops
|
||||
# Redirect stdout to a file
|
||||
exec 4>&1
|
||||
exec 1>"${loops}"
|
||||
for source in *
|
||||
do
|
||||
if [[ -f "$source" ]]
|
||||
then
|
||||
exec 5<"${source}" # open for input
|
||||
while read -r -u 5 include includefreq
|
||||
do
|
||||
if [[ -f $include ]]
|
||||
then
|
||||
if grep -q -w $source $include
|
||||
then
|
||||
if grep -q -w "Loop: $include $source" "${loops}"
|
||||
then
|
||||
continue
|
||||
fi
|
||||
sourcefreq=$( grep -w $source $include | cut -d\ -f2 )
|
||||
echo "Loop: $source $include"
|
||||
# If the counts are close, indicate that the two modules are
|
||||
# on the same level, though they shouldn't be
|
||||
if [[ $(( $includefreq - $sourcefreq )) -gt 3 ]]
|
||||
then
|
||||
echo -e " $source > $include\n"
|
||||
elif [[ $(( $sourcefreq - $includefreq )) -gt 3 ]]
|
||||
then
|
||||
echo -e " $include > $source\n"
|
||||
elif [[ $sourcefreq -eq $includefreq ]]
|
||||
then
|
||||
echo -e " $include == $source\n"
|
||||
else
|
||||
echo -e " $include ~= $source\n"
|
||||
fi
|
||||
else
|
||||
echo "$source > $include" >> "${ordering}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
exec 5>&- #close fd 5
|
||||
fi
|
||||
done
|
||||
exec 1>&4 #close fd 1
|
||||
exec 4>&- #close fd 4
|
||||
cat "${ordering}"
|
||||
cat "${loops}"
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
24
.github/scripts/levelization/results/loops.txt
vendored
Normal file
24
.github/scripts/levelization/results/loops.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Loop: test.jtx test.toplevel
|
||||
test.toplevel > test.jtx
|
||||
|
||||
Loop: test.jtx test.unit_test
|
||||
test.unit_test == test.jtx
|
||||
|
||||
Loop: xrpld.app xrpld.core
|
||||
xrpld.app > xrpld.core
|
||||
|
||||
Loop: xrpld.app xrpld.overlay
|
||||
xrpld.overlay > xrpld.app
|
||||
|
||||
Loop: xrpld.app xrpld.peerfinder
|
||||
xrpld.peerfinder ~= xrpld.app
|
||||
|
||||
Loop: xrpld.app xrpld.rpc
|
||||
xrpld.rpc > xrpld.app
|
||||
|
||||
Loop: xrpld.app xrpld.shamap
|
||||
xrpld.shamap ~= xrpld.app
|
||||
|
||||
Loop: xrpld.overlay xrpld.rpc
|
||||
xrpld.rpc ~= xrpld.overlay
|
||||
|
||||
221
.github/scripts/levelization/results/ordering.txt
vendored
Normal file
221
.github/scripts/levelization/results/ordering.txt
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
libxrpl.basics > xrpl.basics
|
||||
libxrpl.core > xrpl.basics
|
||||
libxrpl.core > xrpl.core
|
||||
libxrpl.crypto > xrpl.basics
|
||||
libxrpl.json > xrpl.basics
|
||||
libxrpl.json > xrpl.json
|
||||
libxrpl.ledger > xrpl.basics
|
||||
libxrpl.ledger > xrpl.json
|
||||
libxrpl.ledger > xrpl.ledger
|
||||
libxrpl.ledger > xrpl.protocol
|
||||
libxrpl.net > xrpl.basics
|
||||
libxrpl.net > xrpl.net
|
||||
libxrpl.nodestore > xrpl.basics
|
||||
libxrpl.nodestore > xrpl.json
|
||||
libxrpl.nodestore > xrpl.nodestore
|
||||
libxrpl.nodestore > xrpl.protocol
|
||||
libxrpl.protocol > xrpl.basics
|
||||
libxrpl.protocol > xrpl.json
|
||||
libxrpl.protocol > xrpl.protocol
|
||||
libxrpl.resource > xrpl.basics
|
||||
libxrpl.resource > xrpl.json
|
||||
libxrpl.resource > xrpl.resource
|
||||
libxrpl.server > xrpl.basics
|
||||
libxrpl.server > xrpl.json
|
||||
libxrpl.server > xrpl.protocol
|
||||
libxrpl.server > xrpl.server
|
||||
libxrpl.shamap > xrpl.basics
|
||||
libxrpl.shamap > xrpl.protocol
|
||||
libxrpl.shamap > xrpl.shamap
|
||||
test.app > test.jtx
|
||||
test.app > test.rpc
|
||||
test.app > test.toplevel
|
||||
test.app > test.unit_test
|
||||
test.app > xrpl.basics
|
||||
test.app > xrpl.core
|
||||
test.app > xrpld.app
|
||||
test.app > xrpld.core
|
||||
test.app > xrpld.overlay
|
||||
test.app > xrpld.rpc
|
||||
test.app > xrpl.json
|
||||
test.app > xrpl.ledger
|
||||
test.app > xrpl.nodestore
|
||||
test.app > xrpl.protocol
|
||||
test.app > xrpl.resource
|
||||
test.basics > test.jtx
|
||||
test.basics > test.unit_test
|
||||
test.basics > xrpl.basics
|
||||
test.basics > xrpl.core
|
||||
test.basics > xrpld.rpc
|
||||
test.basics > xrpl.json
|
||||
test.basics > xrpl.protocol
|
||||
test.beast > xrpl.basics
|
||||
test.conditions > xrpl.basics
|
||||
test.conditions > xrpld.conditions
|
||||
test.consensus > test.csf
|
||||
test.consensus > test.toplevel
|
||||
test.consensus > test.unit_test
|
||||
test.consensus > xrpl.basics
|
||||
test.consensus > xrpld.app
|
||||
test.consensus > xrpld.consensus
|
||||
test.consensus > xrpl.json
|
||||
test.consensus > xrpl.ledger
|
||||
test.core > test.jtx
|
||||
test.core > test.toplevel
|
||||
test.core > test.unit_test
|
||||
test.core > xrpl.basics
|
||||
test.core > xrpl.core
|
||||
test.core > xrpld.core
|
||||
test.core > xrpl.json
|
||||
test.core > xrpl.server
|
||||
test.csf > xrpl.basics
|
||||
test.csf > xrpld.consensus
|
||||
test.csf > xrpl.json
|
||||
test.csf > xrpl.protocol
|
||||
test.json > test.jtx
|
||||
test.json > xrpl.json
|
||||
test.jtx > xrpl.basics
|
||||
test.jtx > xrpld.app
|
||||
test.jtx > xrpld.core
|
||||
test.jtx > xrpld.rpc
|
||||
test.jtx > xrpl.json
|
||||
test.jtx > xrpl.ledger
|
||||
test.jtx > xrpl.net
|
||||
test.jtx > xrpl.protocol
|
||||
test.jtx > xrpl.resource
|
||||
test.jtx > xrpl.server
|
||||
test.ledger > test.jtx
|
||||
test.ledger > test.toplevel
|
||||
test.ledger > xrpl.basics
|
||||
test.ledger > xrpld.app
|
||||
test.ledger > xrpld.core
|
||||
test.ledger > xrpl.ledger
|
||||
test.ledger > xrpl.protocol
|
||||
test.nodestore > test.jtx
|
||||
test.nodestore > test.toplevel
|
||||
test.nodestore > test.unit_test
|
||||
test.nodestore > xrpl.basics
|
||||
test.nodestore > xrpld.core
|
||||
test.nodestore > xrpl.nodestore
|
||||
test.overlay > test.jtx
|
||||
test.overlay > test.toplevel
|
||||
test.overlay > test.unit_test
|
||||
test.overlay > xrpl.basics
|
||||
test.overlay > xrpld.app
|
||||
test.overlay > xrpld.overlay
|
||||
test.overlay > xrpld.peerfinder
|
||||
test.overlay > xrpl.nodestore
|
||||
test.overlay > xrpl.protocol
|
||||
test.overlay > xrpl.shamap
|
||||
test.peerfinder > test.beast
|
||||
test.peerfinder > test.unit_test
|
||||
test.peerfinder > xrpl.basics
|
||||
test.peerfinder > xrpld.core
|
||||
test.peerfinder > xrpld.peerfinder
|
||||
test.peerfinder > xrpl.protocol
|
||||
test.protocol > test.toplevel
|
||||
test.protocol > xrpl.basics
|
||||
test.protocol > xrpl.json
|
||||
test.protocol > xrpl.protocol
|
||||
test.resource > test.unit_test
|
||||
test.resource > xrpl.basics
|
||||
test.resource > xrpl.resource
|
||||
test.rpc > test.jtx
|
||||
test.rpc > test.toplevel
|
||||
test.rpc > xrpl.basics
|
||||
test.rpc > xrpl.core
|
||||
test.rpc > xrpld.app
|
||||
test.rpc > xrpld.core
|
||||
test.rpc > xrpld.overlay
|
||||
test.rpc > xrpld.rpc
|
||||
test.rpc > xrpl.json
|
||||
test.rpc > xrpl.protocol
|
||||
test.rpc > xrpl.resource
|
||||
test.server > test.jtx
|
||||
test.server > test.toplevel
|
||||
test.server > test.unit_test
|
||||
test.server > xrpl.basics
|
||||
test.server > xrpld.app
|
||||
test.server > xrpld.core
|
||||
test.server > xrpld.rpc
|
||||
test.server > xrpl.json
|
||||
test.server > xrpl.server
|
||||
test.shamap > test.unit_test
|
||||
test.shamap > xrpl.basics
|
||||
test.shamap > xrpl.nodestore
|
||||
test.shamap > xrpl.protocol
|
||||
test.shamap > xrpl.shamap
|
||||
test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.json
|
||||
tests.libxrpl > xrpl.net
|
||||
xrpl.core > xrpl.basics
|
||||
xrpl.core > xrpl.json
|
||||
xrpl.core > xrpl.ledger
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
xrpl.ledger > xrpl.protocol
|
||||
xrpl.net > xrpl.basics
|
||||
xrpl.nodestore > xrpl.basics
|
||||
xrpl.nodestore > xrpl.protocol
|
||||
xrpl.protocol > xrpl.basics
|
||||
xrpl.protocol > xrpl.json
|
||||
xrpl.resource > xrpl.basics
|
||||
xrpl.resource > xrpl.json
|
||||
xrpl.resource > xrpl.protocol
|
||||
xrpl.server > xrpl.basics
|
||||
xrpl.server > xrpl.json
|
||||
xrpl.server > xrpl.protocol
|
||||
xrpl.shamap > xrpl.basics
|
||||
xrpl.shamap > xrpl.nodestore
|
||||
xrpl.shamap > xrpl.protocol
|
||||
xrpld.app > test.unit_test
|
||||
xrpld.app > xrpl.basics
|
||||
xrpld.app > xrpl.core
|
||||
xrpld.app > xrpld.conditions
|
||||
xrpld.app > xrpld.consensus
|
||||
xrpld.app > xrpl.json
|
||||
xrpld.app > xrpl.ledger
|
||||
xrpld.app > xrpl.net
|
||||
xrpld.app > xrpl.nodestore
|
||||
xrpld.app > xrpl.protocol
|
||||
xrpld.app > xrpl.resource
|
||||
xrpld.app > xrpl.shamap
|
||||
xrpld.conditions > xrpl.basics
|
||||
xrpld.conditions > xrpl.protocol
|
||||
xrpld.consensus > xrpl.basics
|
||||
xrpld.consensus > xrpl.json
|
||||
xrpld.consensus > xrpl.protocol
|
||||
xrpld.core > xrpl.basics
|
||||
xrpld.core > xrpl.core
|
||||
xrpld.core > xrpl.json
|
||||
xrpld.core > xrpl.net
|
||||
xrpld.core > xrpl.protocol
|
||||
xrpld.overlay > xrpl.basics
|
||||
xrpld.overlay > xrpl.core
|
||||
xrpld.overlay > xrpld.core
|
||||
xrpld.overlay > xrpld.peerfinder
|
||||
xrpld.overlay > xrpl.json
|
||||
xrpld.overlay > xrpl.protocol
|
||||
xrpld.overlay > xrpl.resource
|
||||
xrpld.overlay > xrpl.server
|
||||
xrpld.peerfinder > xrpl.basics
|
||||
xrpld.peerfinder > xrpld.core
|
||||
xrpld.peerfinder > xrpl.protocol
|
||||
xrpld.perflog > xrpl.basics
|
||||
xrpld.perflog > xrpl.core
|
||||
xrpld.perflog > xrpld.rpc
|
||||
xrpld.perflog > xrpl.json
|
||||
xrpld.rpc > xrpl.basics
|
||||
xrpld.rpc > xrpl.core
|
||||
xrpld.rpc > xrpld.core
|
||||
xrpld.rpc > xrpl.json
|
||||
xrpld.rpc > xrpl.ledger
|
||||
xrpld.rpc > xrpl.net
|
||||
xrpld.rpc > xrpl.nodestore
|
||||
xrpld.rpc > xrpl.protocol
|
||||
xrpld.rpc > xrpl.resource
|
||||
xrpld.rpc > xrpl.server
|
||||
xrpld.shamap > xrpl.shamap
|
||||
47
.github/scripts/rename/README.md
vendored
Normal file
47
.github/scripts/rename/README.md
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
## Renaming ripple(d) to xrpl(d)
|
||||
|
||||
In the initial phases of development of the XRPL, the open source codebase was
|
||||
called "rippled" and it remains with that name even today. Today, over 1000
|
||||
nodes run the application, and code contributions have been submitted by
|
||||
developers located around the world. The XRPL community is larger than ever.
|
||||
In light of the decentralized and diversified nature of XRPL, we will rename any
|
||||
references to `ripple` and `rippled` to `xrpl` and `xrpld`, when appropriate.
|
||||
|
||||
See [here](https://xls.xrpl.org/xls/XLS-0095-rename-rippled-to-xrpld.html) for
|
||||
more information.
|
||||
|
||||
### Scripts
|
||||
|
||||
To facilitate this transition, there will be multiple scripts that developers
|
||||
can run on their own PRs and forks to minimize conflicts. Each script should be
|
||||
run from the repository root.
|
||||
|
||||
1. `.github/scripts/rename/definitions.sh`: This script will rename all
|
||||
definitions, such as include guards, from `RIPPLE_XXX` and `RIPPLED_XXX` to
|
||||
`XRPL_XXX`.
|
||||
2. `.github/scripts/rename/copyright.sh`: This script will remove superfluous
|
||||
copyright notices.
|
||||
3. `.github/scripts/rename/cmake.sh`: This script will rename all CMake files
|
||||
from `RippleXXX.cmake` or `RippledXXX.cmake` to `XrplXXX.cmake`, and any
|
||||
references to `ripple` and `rippled` (with or without capital letters) to
|
||||
`xrpl` and `xrpld`, respectively. The name of the binary will remain as-is,
|
||||
and will only be renamed to `xrpld` by a later script.
|
||||
4. `.github/scripts/rename/binary.sh`: This script will rename the binary from
|
||||
`rippled` to `xrpld`, and reverses the symlink so that `rippled` points to
|
||||
the `xrpld` binary.
|
||||
5. `.github/scripts/rename/namespace.sh`: This script will rename the C++
|
||||
namespaces from `ripple` to `xrpl`.
|
||||
6. `.github/scripts/rename/config.sh`: This script will rename the config from
|
||||
`rippled.cfg` to `xrpld.cfg`, and updating the code accordingly. The old
|
||||
filename will still be accepted.
|
||||
|
||||
You can run all these scripts from the repository root as follows:
|
||||
|
||||
```shell
|
||||
./.github/scripts/rename/definitions.sh .
|
||||
./.github/scripts/rename/copyright.sh .
|
||||
./.github/scripts/rename/cmake.sh .
|
||||
./.github/scripts/rename/binary.sh .
|
||||
./.github/scripts/rename/namespace.sh .
|
||||
./.github/scripts/rename/config.sh .
|
||||
```
|
||||
54
.github/scripts/rename/binary.sh
vendored
Executable file
54
.github/scripts/rename/binary.sh
vendored
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
|
||||
SED_COMMAND=sed
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
fi
|
||||
|
||||
# This script changes the binary name from `rippled` to `xrpld`, and reverses
|
||||
# the symlink that currently points from `xrpld` to `rippled` so that it points
|
||||
# from `rippled` to `xrpld` instead.
|
||||
# Usage: .github/scripts/rename/binary.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
|
||||
# Remove the binary name override added by the cmake.sh script.
|
||||
${SED_COMMAND} -z -i -E 's@\s+# For the time being.+"rippled"\)@@' cmake/XrplCore.cmake
|
||||
|
||||
# Reverse the symlink.
|
||||
${SED_COMMAND} -i -E 's@create_symbolic_link\(rippled@create_symbolic_link(xrpld@' cmake/XrplInstall.cmake
|
||||
${SED_COMMAND} -i -E 's@/xrpld\$\{suffix\}@/rippled${suffix}@' cmake/XrplInstall.cmake
|
||||
|
||||
# Rename references to the binary.
|
||||
${SED_COMMAND} -i -E 's@rippled@xrpld@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@rippled@xrpld@g' CONTRIBUTING.md
|
||||
${SED_COMMAND} -i -E 's@rippled@xrpld@g' .github/ISSUE_TEMPLATE/bug_report.md
|
||||
|
||||
# Restore and/or fix certain renames. The pre-commit hook will update the
|
||||
# formatting upon saving/committing.
|
||||
${SED_COMMAND} -i -E 's@ripple/xrpld@XRPLF/rippled@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@xrpld \(`xrpld`\)@xrpld@g' BUILD.md
|
||||
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' CONTRIBUTING.md
|
||||
|
||||
popd
|
||||
echo "Processing complete."
|
||||
92
.github/scripts/rename/cmake.sh
vendored
Executable file
92
.github/scripts/rename/cmake.sh
vendored
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed and head are installed and available as `gsed`
|
||||
# and `ghead`, respectively.
|
||||
SED_COMMAND=sed
|
||||
HEAD_COMMAND=head
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
if ! command -v ghead &> /dev/null; then
|
||||
echo "Error: ghead is not installed. Please install it using 'brew install coreutils'."
|
||||
exit 1
|
||||
fi
|
||||
HEAD_COMMAND=ghead
|
||||
fi
|
||||
|
||||
# This script renames CMake files from `RippleXXX.cmake` or `RippledXXX.cmake`
|
||||
# to `XrplXXX.cmake`, and any references to `ripple` and `rippled` (with or
|
||||
# without capital letters) to `xrpl` and `xrpld`, respectively. The name of the
|
||||
# binary will remain as-is, and will only be renamed to `xrpld` in a different
|
||||
# script, but the proto file will be renamed.
|
||||
# Usage: .github/scripts/rename/cmake.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
|
||||
# Rename the files.
|
||||
find cmake -type f -name 'Rippled*.cmake' -exec bash -c 'mv "${1}" "${1/Rippled/Xrpl}"' - {} \;
|
||||
find cmake -type f -name 'Ripple*.cmake' -exec bash -c 'mv "${1}" "${1/Ripple/Xrpl}"' - {} \;
|
||||
if [ -e cmake/xrpl_add_test.cmake ]; then
|
||||
mv cmake/xrpl_add_test.cmake cmake/XrplAddTest.cmake
|
||||
fi
|
||||
if [ -e include/xrpl/proto/ripple.proto ]; then
|
||||
mv include/xrpl/proto/ripple.proto include/xrpl/proto/xrpl.proto
|
||||
fi
|
||||
|
||||
# Rename inside the files.
|
||||
find cmake -type f -name '*.cmake' | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i 's/Rippled/Xrpld/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/Ripple/Xrpl/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/ripple/xrpl/g' "${FILE}"
|
||||
done
|
||||
${SED_COMMAND} -i -E 's/Rippled?/Xrpl/g' CMakeLists.txt
|
||||
${SED_COMMAND} -i 's/ripple/xrpl/g' CMakeLists.txt
|
||||
${SED_COMMAND} -i 's/include(xrpl_add_test)/include(XrplAddTest)/' src/tests/libxrpl/CMakeLists.txt
|
||||
${SED_COMMAND} -i 's/ripple.pb.h/xrpl.pb.h/' include/xrpl/protocol/messages.h
|
||||
${SED_COMMAND} -i 's/ripple.pb.h/xrpl.pb.h/' BUILD.md
|
||||
${SED_COMMAND} -i 's/ripple.pb.h/xrpl.pb.h/' BUILD.md
|
||||
|
||||
# Restore the name of the validator keys repository.
|
||||
${SED_COMMAND} -i 's@xrpl/validator-keys-tool@ripple/validator-keys-tool@' cmake/XrplValidatorKeys.cmake
|
||||
|
||||
# Ensure the name of the binary and config remain 'rippled' for now.
|
||||
${SED_COMMAND} -i -E 's/xrpld(-example)?\.cfg/rippled\1.cfg/g' cmake/XrplInstall.cmake
|
||||
if grep -q '"xrpld"' cmake/XrplCore.cmake; then
|
||||
# The script has been rerun, so just restore the name of the binary.
|
||||
${SED_COMMAND} -i 's/"xrpld"/"rippled"/' cmake/XrplCore.cmake
|
||||
elif ! grep -q '"rippled"' cmake/XrplCore.cmake; then
|
||||
${HEAD_COMMAND} -n -1 cmake/XrplCore.cmake > cmake.tmp
|
||||
echo ' # For the time being, we will keep the name of the binary as it was.' >> cmake.tmp
|
||||
echo ' set_target_properties(xrpld PROPERTIES OUTPUT_NAME "rippled")' >> cmake.tmp
|
||||
tail -1 cmake/XrplCore.cmake >> cmake.tmp
|
||||
mv cmake.tmp cmake/XrplCore.cmake
|
||||
fi
|
||||
|
||||
# Restore the symlink from 'xrpld' to 'rippled'.
|
||||
${SED_COMMAND} -i -E 's@create_symbolic_link\(xrpld@create_symbolic_link(rippled@' cmake/XrplInstall.cmake
|
||||
|
||||
# Remove the symlink that previously pointed from 'ripple' to 'xrpl' but now is
|
||||
# no longer needed.
|
||||
${SED_COMMAND} -z -i -E 's@install\(CODE.+CMAKE_INSTALL_INCLUDEDIR}/xrpl\)\n"\)\n+@@' cmake/XrplInstall.cmake
|
||||
|
||||
popd
|
||||
echo "Renaming complete."
|
||||
72
.github/scripts/rename/config.sh
vendored
Executable file
72
.github/scripts/rename/config.sh
vendored
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
|
||||
SED_COMMAND=sed
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
fi
|
||||
|
||||
# This script renames the config from `rippled.cfg` to `xrpld.cfg`, and updates
|
||||
# the code accordingly. The old filename will still be accepted.
|
||||
# Usage: .github/scripts/rename/config.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
|
||||
# Add the xrpld.cfg to the .gitignore.
|
||||
if ! grep -q 'xrpld.cfg' .gitignore; then
|
||||
${SED_COMMAND} -i '/rippled.cfg/a\
|
||||
/xrpld.cfg' .gitignore
|
||||
fi
|
||||
|
||||
# Rename the files.
|
||||
if [ -e rippled.cfg ]; then
|
||||
mv rippled.cfg xrpld.cfg
|
||||
fi
|
||||
if [ -e cfg/rippled-example.cfg ]; then
|
||||
mv cfg/rippled-example.cfg cfg/xrpld-example.cfg
|
||||
fi
|
||||
|
||||
# Rename inside the files.
|
||||
DIRECTORIES=("cfg" "cmake" "include" "src")
|
||||
for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.cmake" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i -E 's/rippled(-example)?[ .]cfg/xrpld\1.cfg/g' "${FILE}"
|
||||
done
|
||||
done
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' cfg/xrpld-example.cfg
|
||||
${SED_COMMAND} -i 's/rippled/xrpld/g' src/test/core/Config_test.cpp
|
||||
${SED_COMMAND} -i 's/ripplevalidators/xrplvalidators/g' src/test/core/Config_test.cpp # cspell: disable-line
|
||||
${SED_COMMAND} -i 's/rippleConfig/xrpldConfig/g' src/test/core/Config_test.cpp
|
||||
${SED_COMMAND} -i 's@ripple/@xrpld/@g' src/test/core/Config_test.cpp
|
||||
${SED_COMMAND} -i 's/Rippled/File/g' src/test/core/Config_test.cpp
|
||||
|
||||
|
||||
# Restore the old config file name in the code that maintains support for now.
|
||||
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
|
||||
|
||||
# Restore an URL.
|
||||
${SED_COMMAND} -i 's/connect-your-xrpld-to-the-xrp-test-net.html/connect-your-rippled-to-the-xrp-test-net.html/g' cfg/xrpld-example.cfg
|
||||
|
||||
popd
|
||||
echo "Renaming complete."
|
||||
103
.github/scripts/rename/copyright.sh
vendored
Executable file
103
.github/scripts/rename/copyright.sh
vendored
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
|
||||
SED_COMMAND=sed
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
fi
|
||||
|
||||
# This script removes superfluous copyright notices in source and header files
|
||||
# in this project. Specifically, it removes all notices referencing Ripple,
|
||||
# XRPLF, and certain individual contributors upon mutual agreement, so the one
|
||||
# in the LICENSE.md file applies throughout. Copyright notices referencing
|
||||
# external contributions, e.g. from Bitcoin, remain as-is.
|
||||
# Usage: .github/scripts/rename/copyright.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
|
||||
# Prevent sed and echo from removing newlines and tabs in string literals by
|
||||
# temporarily replacing them with placeholders. This only affects one file.
|
||||
PLACEHOLDER_NEWLINE="__NEWLINE__"
|
||||
PLACEHOLDER_TAB="__TAB__"
|
||||
${SED_COMMAND} -i -E "s@\\\n@${PLACEHOLDER_NEWLINE}@g" src/test/rpc/ValidatorInfo_test.cpp
|
||||
${SED_COMMAND} -i -E "s@\\\t@${PLACEHOLDER_TAB}@g" src/test/rpc/ValidatorInfo_test.cpp
|
||||
|
||||
# Process the include/ and src/ directories.
|
||||
DIRECTORIES=("include" "src")
|
||||
for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.macro" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
# Handle the cases where the copyright notice is enclosed in /* ... */
|
||||
# and usually surrounded by //---- and //======.
|
||||
${SED_COMMAND} -z -i -E 's@^//-------+\n+@@' "${FILE}"
|
||||
${SED_COMMAND} -z -i -E 's@^.*Copyright.+(Ripple|Bougalis|Falco|Hinnant|Null|Ritchford|XRPLF).+PERFORMANCE OF THIS SOFTWARE\.\n\*/\n+@@' "${FILE}" # cspell: ignore Bougalis Falco Hinnant Ritchford
|
||||
${SED_COMMAND} -z -i -E 's@^//=======+\n+@@' "${FILE}"
|
||||
|
||||
# Handle the cases where the copyright notice is commented out with //.
|
||||
${SED_COMMAND} -z -i -E 's@^//\n// Copyright.+Falco \(vinnie dot falco at gmail dot com\)\n//\n+@@' "${FILE}" # cspell: ignore Vinnie Falco
|
||||
done
|
||||
done
|
||||
|
||||
# Restore copyright notices that were removed from specific files, without
|
||||
# restoring the verbiage that is already present in LICENSE.md. Ensure that if
|
||||
# the script is run multiple times, duplicate notices are not added.
|
||||
if ! grep -q 'Raw Material Software' include/xrpl/beast/core/CurrentThreadName.h; then
|
||||
echo -e "// Portions of this file are from JUCE (http://www.juce.com).\n// Copyright (c) 2013 - Raw Material Software Ltd.\n// Please visit http://www.juce.com\n\n$(cat include/xrpl/beast/core/CurrentThreadName.h)" > include/xrpl/beast/core/CurrentThreadName.h
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/test/app/NetworkID_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/NetworkID_test.cpp)" > src/test/app/NetworkID_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/test/app/tx/apply_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/tx/apply_test.cpp)" > src/test/app/tx/apply_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/test/rpc/ManifestRPC_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ManifestRPC_test.cpp)" > src/test/rpc/ManifestRPC_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/test/rpc/ValidatorInfo_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ValidatorInfo_test.cpp)" > src/test/rpc/ValidatorInfo_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/DoManifest.cpp; then
|
||||
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/DoManifest.cpp)" > src/xrpld/rpc/handlers/DoManifest.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/ValidatorInfo.cpp; then
|
||||
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/ValidatorInfo.cpp)" > src/xrpld/rpc/handlers/ValidatorInfo.cpp
|
||||
fi
|
||||
if ! grep -q 'Bougalis' include/xrpl/basics/SlabAllocator.h; then
|
||||
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/SlabAllocator.h)" > include/xrpl/basics/SlabAllocator.h # cspell: ignore Nikolaos Bougalis nikb
|
||||
fi
|
||||
if ! grep -q 'Bougalis' include/xrpl/basics/spinlock.h; then
|
||||
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/spinlock.h)" > include/xrpl/basics/spinlock.h # cspell: ignore Nikolaos Bougalis nikb
|
||||
fi
|
||||
if ! grep -q 'Bougalis' include/xrpl/basics/tagged_integer.h; then
|
||||
echo -e "// Copyright (c) 2014, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/tagged_integer.h)" > include/xrpl/basics/tagged_integer.h # cspell: ignore Nikolaos Bougalis nikb
|
||||
fi
|
||||
if ! grep -q 'Ritchford' include/xrpl/beast/utility/Zero.h; then
|
||||
echo -e "// Copyright (c) 2014, Tom Ritchford <tom@swirly.com>\n\n$(cat include/xrpl/beast/utility/Zero.h)" > include/xrpl/beast/utility/Zero.h # cspell: ignore Ritchford
|
||||
fi
|
||||
|
||||
# Restore newlines and tabs in string literals in the affected file.
|
||||
${SED_COMMAND} -i -E "s@${PLACEHOLDER_NEWLINE}@\\\n@g" src/test/rpc/ValidatorInfo_test.cpp
|
||||
${SED_COMMAND} -i -E "s@${PLACEHOLDER_TAB}@\\\t@g" src/test/rpc/ValidatorInfo_test.cpp
|
||||
|
||||
popd
|
||||
echo "Removal complete."
|
||||
42
.github/scripts/rename/definitions.sh
vendored
Executable file
42
.github/scripts/rename/definitions.sh
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
|
||||
SED_COMMAND=sed
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
fi
|
||||
|
||||
# This script renames definitions, such as include guards, in this project.
|
||||
# Specifically, it renames "RIPPLED_XXX" and "RIPPLE_XXX" to "XRPL_XXX" by
|
||||
# scanning all cmake, header, and source files in the specified directory and
|
||||
# its subdirectories.
|
||||
# Usage: .github/scripts/rename/definitions.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i -E 's@#(define|endif|if|ifdef|ifndef)(.*)(RIPPLED_|RIPPLE_)([A-Z0-9_]+)@#\1\2XRPL_\4@g' "${FILE}"
|
||||
done
|
||||
find "${DIRECTORY}" -type f \( -name "*.cmake" -o -name "*.txt" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i -E 's@(RIPPLED_|RIPPLE_)([A-Z0-9_]+)@XRPL_\2@g' "${FILE}"
|
||||
done
|
||||
echo "Renaming complete."
|
||||
30
.github/scripts/rename/include.sh
vendored
Executable file
30
.github/scripts/rename/include.sh
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# This script checks whether there are no new include guards introduced by a new
|
||||
# PR, as header files should use "#pragma once" instead. The script assumes any
|
||||
# include guards will use "XRPL_" as prefix.
|
||||
# Usage: .github/scripts/rename/include.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
if grep -q "#ifndef XRPL_" "${FILE}"; then
|
||||
echo "Please replace all include guards by #pragma once."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "Checking complete."
|
||||
58
.github/scripts/rename/namespace.sh
vendored
Executable file
58
.github/scripts/rename/namespace.sh
vendored
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit the script as soon as an error occurs.
|
||||
set -e
|
||||
|
||||
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
|
||||
SED_COMMAND=sed
|
||||
if [[ "${OSTYPE}" == 'darwin'* ]]; then
|
||||
if ! command -v gsed &> /dev/null; then
|
||||
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
|
||||
exit 1
|
||||
fi
|
||||
SED_COMMAND=gsed
|
||||
fi
|
||||
|
||||
# This script renames the `ripple` namespace to `xrpl` in this project.
|
||||
# Specifically, it renames all occurrences of `namespace ripple` and `ripple::`
|
||||
# to `namespace xrpl` and `xrpl::`, respectively, by scanning all header and
|
||||
# source files in the specified directory and its subdirectories, as well as any
|
||||
# occurrences in the documentation. It also renames them in the test suites.
|
||||
# Usage: .github/scripts/rename/namespace.sh <repository directory>
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <repository directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY=$1
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
if [ ! -d "${DIRECTORY}" ]; then
|
||||
echo "Error: Directory '${DIRECTORY}' does not exist."
|
||||
exit 1
|
||||
fi
|
||||
pushd ${DIRECTORY}
|
||||
|
||||
DIRECTORIES=("include" "src" "tests")
|
||||
for DIRECTORY in "${DIRECTORIES[@]}"; do
|
||||
echo "Processing directory: ${DIRECTORY}"
|
||||
|
||||
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" \) | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i 's/namespace ripple/namespace xrpl/g' "${FILE}"
|
||||
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
|
||||
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' "${FILE}"
|
||||
done
|
||||
done
|
||||
|
||||
# Special case for NuDBFactory that has ripple twice in the test suite name.
|
||||
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' src/test/nodestore/NuDBFactory_test.cpp
|
||||
|
||||
DIRECTORY=$1
|
||||
find "${DIRECTORY}" -type f -name "*.md" | while read -r FILE; do
|
||||
echo "Processing file: ${FILE}"
|
||||
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
|
||||
done
|
||||
|
||||
popd
|
||||
echo "Renaming complete."
|
||||
333
.github/scripts/strategy-matrix/generate.py
vendored
Executable file
333
.github/scripts/strategy-matrix/generate.py
vendored
Executable file
@@ -0,0 +1,333 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
THIS_DIR = Path(__file__).parent.resolve()
|
||||
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
architecture: list[dict]
|
||||
os: list[dict]
|
||||
build_type: list[str]
|
||||
cmake_args: list[str]
|
||||
|
||||
|
||||
"""
|
||||
Generate a strategy matrix for GitHub Actions CI.
|
||||
|
||||
On each PR commit we will build a selection of Debian, RHEL, Ubuntu, MacOS, and
|
||||
Windows configurations, while upon merge into the develop or release branches,
|
||||
we will build all configurations, and test most of them.
|
||||
|
||||
We will further set additional CMake arguments as follows:
|
||||
- All builds will have the `tests`, `werr`, and `xrpld` options.
|
||||
- All builds will have the `wextra` option except for GCC 12 and Clang 16.
|
||||
- All release builds will have the `assert` option.
|
||||
- Certain Debian Bookworm configurations will change the reference fee, enable
|
||||
codecov, and enable voidstar in PRs.
|
||||
"""
|
||||
|
||||
|
||||
def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
configurations = []
|
||||
for architecture, os, build_type, cmake_args in itertools.product(
|
||||
config.architecture, config.os, config.build_type, config.cmake_args
|
||||
):
|
||||
# The default CMake target is 'all' for Linux and MacOS and 'install'
|
||||
# for Windows, but it can get overridden for certain configurations.
|
||||
cmake_target = "install" if os["distro_name"] == "windows" else "all"
|
||||
|
||||
# We build and test all configurations by default, except for Windows in
|
||||
# Debug, because it is too slow, as well as when code coverage is
|
||||
# enabled as that mode already runs the tests.
|
||||
build_only = False
|
||||
if os["distro_name"] == "windows" and build_type == "Debug":
|
||||
build_only = True
|
||||
|
||||
# Only generate a subset of configurations in PRs.
|
||||
if not all:
|
||||
# Debian:
|
||||
# - Bookworm using GCC 13: Release on linux/amd64, set the reference
|
||||
# fee to 500.
|
||||
# - Bookworm using GCC 15: Debug on linux/amd64, enable code
|
||||
# coverage (which will be done below).
|
||||
# - Bookworm using Clang 16: Debug on linux/arm64, enable voidstar.
|
||||
# - Bookworm using Clang 17: Release on linux/amd64, set the
|
||||
# reference fee to 1000.
|
||||
# - Bookworm using Clang 20: Debug on linux/amd64.
|
||||
if os["distro_name"] == "debian":
|
||||
skip = True
|
||||
if os["distro_version"] == "bookworm":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
cmake_args = f"-Dvoidstar=ON {cmake_args}"
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-17"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}"
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if skip:
|
||||
continue
|
||||
|
||||
# RHEL:
|
||||
# - 9 using GCC 12: Debug on linux/amd64.
|
||||
# - 10 using Clang: Release on linux/amd64.
|
||||
if os["distro_name"] == "rhel":
|
||||
skip = True
|
||||
if os["distro_version"] == "9":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
elif os["distro_version"] == "10":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-any"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if skip:
|
||||
continue
|
||||
|
||||
# Ubuntu:
|
||||
# - Jammy using GCC 12: Debug on linux/arm64.
|
||||
# - Noble using GCC 14: Release on linux/amd64.
|
||||
# - Noble using Clang 18: Debug on linux/amd64.
|
||||
# - Noble using Clang 19: Release on linux/arm64.
|
||||
if os["distro_name"] == "ubuntu":
|
||||
skip = True
|
||||
if os["distro_version"] == "jammy":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
skip = False
|
||||
elif os["distro_version"] == "noble":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-18"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-19"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
skip = False
|
||||
if skip:
|
||||
continue
|
||||
|
||||
# MacOS:
|
||||
# - Debug on macos/arm64.
|
||||
if os["distro_name"] == "macos" and not (
|
||||
build_type == "Debug" and architecture["platform"] == "macos/arm64"
|
||||
):
|
||||
continue
|
||||
|
||||
# Windows:
|
||||
# - Release on windows/amd64.
|
||||
if os["distro_name"] == "windows" and not (
|
||||
build_type == "Release" and architecture["platform"] == "windows/amd64"
|
||||
):
|
||||
continue
|
||||
|
||||
# Additional CMake arguments.
|
||||
cmake_args = f"{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON"
|
||||
if not f"{os['compiler_name']}-{os['compiler_version']}" in [
|
||||
"gcc-12",
|
||||
"clang-16",
|
||||
]:
|
||||
cmake_args = f"{cmake_args} -Dwextra=ON"
|
||||
if build_type == "Release":
|
||||
cmake_args = f"{cmake_args} -Dassert=ON"
|
||||
|
||||
# We skip all RHEL on arm64 due to a build failure that needs further
|
||||
# investigation.
|
||||
if os["distro_name"] == "rhel" and architecture["platform"] == "linux/arm64":
|
||||
continue
|
||||
|
||||
# We skip all clang 20+ on arm64 due to Boost build error.
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}"
|
||||
in ["clang-20", "clang-21"]
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
continue
|
||||
|
||||
# Enable code coverage for Debian Bookworm using GCC 15 in Debug on
|
||||
# linux/amd64
|
||||
if (
|
||||
f"{os['distro_name']}-{os['distro_version']}" == "debian-bookworm"
|
||||
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"{cmake_args} -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0"
|
||||
|
||||
# Enable unity build for Ubuntu Jammy using GCC 12 in Debug on
|
||||
# linux/amd64.
|
||||
if (
|
||||
f"{os['distro_name']}-{os['distro_version']}" == "ubuntu-jammy"
|
||||
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"{cmake_args} -Dunity=ON"
|
||||
|
||||
# Generate a unique name for the configuration, e.g. macos-arm64-debug
|
||||
# or debian-bookworm-gcc-12-amd64-release.
|
||||
config_name = os["distro_name"]
|
||||
if (n := os["distro_version"]) != "":
|
||||
config_name += f"-{n}"
|
||||
if (n := os["compiler_name"]) != "":
|
||||
config_name += f"-{n}"
|
||||
if (n := os["compiler_version"]) != "":
|
||||
config_name += f"-{n}"
|
||||
config_name += (
|
||||
f"-{architecture['platform'][architecture['platform'].find('/')+1:]}"
|
||||
)
|
||||
config_name += f"-{build_type.lower()}"
|
||||
if "-Dcoverage=ON" in cmake_args:
|
||||
config_name += "-coverage"
|
||||
if "-Dunity=ON" in cmake_args:
|
||||
config_name += "-unity"
|
||||
|
||||
# Add the configuration to the list, with the most unique fields first,
|
||||
# so that they are easier to identify in the GitHub Actions UI, as long
|
||||
# names get truncated.
|
||||
# Add Address and Thread (both coupled with UB) sanitizers for specific bookworm distros.
|
||||
# GCC-Asan rippled-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
|
||||
if (
|
||||
os["distro_version"] == "bookworm"
|
||||
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
|
||||
):
|
||||
# Add ASAN + UBSAN configuration.
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name + "-asan-ubsan",
|
||||
"cmake_args": cmake_args,
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
"os": os,
|
||||
"architecture": architecture,
|
||||
"sanitizers": "address,undefinedbehavior",
|
||||
}
|
||||
)
|
||||
# TSAN is deactivated due to seg faults with latest compilers.
|
||||
activate_tsan = False
|
||||
if activate_tsan:
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name + "-tsan-ubsan",
|
||||
"cmake_args": cmake_args,
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
"os": os,
|
||||
"architecture": architecture,
|
||||
"sanitizers": "thread,undefinedbehavior",
|
||||
}
|
||||
)
|
||||
else:
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name,
|
||||
"cmake_args": cmake_args,
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
"os": os,
|
||||
"architecture": architecture,
|
||||
"sanitizers": "",
|
||||
}
|
||||
)
|
||||
|
||||
return configurations
|
||||
|
||||
|
||||
def read_config(file: Path) -> Config:
|
||||
config = json.loads(file.read_text())
|
||||
if (
|
||||
config["architecture"] is None
|
||||
or config["os"] is None
|
||||
or config["build_type"] is None
|
||||
or config["cmake_args"] is None
|
||||
):
|
||||
raise Exception("Invalid configuration file.")
|
||||
|
||||
return Config(**config)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
"--all",
|
||||
help="Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
help="Path to the JSON file containing the strategy matrix configurations.",
|
||||
required=False,
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
matrix = []
|
||||
if args.config is None or args.config == "":
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "linux.json")
|
||||
)
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "macos.json")
|
||||
)
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "windows.json")
|
||||
)
|
||||
else:
|
||||
matrix += generate_strategy_matrix(args.all, read_config(args.config))
|
||||
|
||||
# Generate the strategy matrix.
|
||||
print(f"matrix={json.dumps({'include': matrix})}")
|
||||
212
.github/scripts/strategy-matrix/linux.json
vendored
Normal file
212
.github/scripts/strategy-matrix/linux.json
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
{
|
||||
"architecture": [
|
||||
{
|
||||
"platform": "linux/amd64",
|
||||
"runner": ["self-hosted", "Linux", "X64", "heavy"]
|
||||
},
|
||||
{
|
||||
"platform": "linux/arm64",
|
||||
"runner": ["self-hosted", "Linux", "ARM64", "heavy-arm64"]
|
||||
}
|
||||
],
|
||||
"os": [
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "15",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "16",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "17",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "18",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "19",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "bookworm",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "20",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "15",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "20",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "debian",
|
||||
"distro_version": "trixie",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "21",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "jammy",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "16",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "17",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "18",
|
||||
"image_sha": "ab4d1f0"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
"distro_version": "noble",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "19",
|
||||
"image_sha": "ab4d1f0"
|
||||
}
|
||||
],
|
||||
"build_type": ["Debug", "Release"],
|
||||
"cmake_args": [""]
|
||||
}
|
||||
19
.github/scripts/strategy-matrix/macos.json
vendored
Normal file
19
.github/scripts/strategy-matrix/macos.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"architecture": [
|
||||
{
|
||||
"platform": "macos/arm64",
|
||||
"runner": ["self-hosted", "macOS", "ARM64", "mac-runner-m1"]
|
||||
}
|
||||
],
|
||||
"os": [
|
||||
{
|
||||
"distro_name": "macos",
|
||||
"distro_version": "",
|
||||
"compiler_name": "",
|
||||
"compiler_version": "",
|
||||
"image_sha": ""
|
||||
}
|
||||
],
|
||||
"build_type": ["Debug", "Release"],
|
||||
"cmake_args": ["-DCMAKE_POLICY_VERSION_MINIMUM=3.5"]
|
||||
}
|
||||
19
.github/scripts/strategy-matrix/windows.json
vendored
Normal file
19
.github/scripts/strategy-matrix/windows.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"architecture": [
|
||||
{
|
||||
"platform": "windows/amd64",
|
||||
"runner": ["self-hosted", "Windows", "devbox"]
|
||||
}
|
||||
],
|
||||
"os": [
|
||||
{
|
||||
"distro_name": "windows",
|
||||
"distro_version": "",
|
||||
"compiler_name": "",
|
||||
"compiler_version": "",
|
||||
"image_sha": ""
|
||||
}
|
||||
],
|
||||
"build_type": ["Debug", "Release"],
|
||||
"cmake_args": [""]
|
||||
}
|
||||
165
.github/workflows/on-pr.yml
vendored
Normal file
165
.github/workflows/on-pr.yml
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
# This workflow runs all workflows to check, build and test the project on
|
||||
# various Linux flavors, as well as on MacOS and Windows, on every push to a
|
||||
# user branch. However, it will not run if the pull request is a draft unless it
|
||||
# has the 'DraftRunCI' label. For commits to PRs that target a release branch,
|
||||
# it also uploads the libxrpl recipe to the Conan remote.
|
||||
name: PR
|
||||
|
||||
on:
|
||||
merge_group:
|
||||
types:
|
||||
- checks_requested
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
# This job determines whether the rest of the workflow should run. It runs
|
||||
# when the PR is not a draft (which should also cover merge-group) or
|
||||
# has the 'DraftRunCI' label.
|
||||
should-run:
|
||||
if: ${{ !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
- name: Determine changed files
|
||||
# This step checks whether any files have changed that should
|
||||
# cause the next jobs to run. We do it this way rather than
|
||||
# using `paths` in the `on:` section, because all required
|
||||
# checks must pass, even for changes that do not modify anything
|
||||
# that affects those checks. We would therefore like to make the
|
||||
# checks required only if the job runs, but GitHub does not
|
||||
# support that directly. By always executing the workflow on new
|
||||
# commits and by using the changed-files action below, we ensure
|
||||
# that Github considers any skipped jobs to have passed, and in
|
||||
# turn the required checks as well.
|
||||
id: changes
|
||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
|
||||
with:
|
||||
files: |
|
||||
# These paths are unique to `on-pr.yml`.
|
||||
.github/scripts/levelization/**
|
||||
.github/scripts/rename/**
|
||||
.github/workflows/reusable-check-levelization.yml
|
||||
.github/workflows/reusable-check-rename.yml
|
||||
.github/workflows/on-pr.yml
|
||||
|
||||
# Keep the paths below in sync with those in `on-trigger.yml`.
|
||||
.github/actions/build-deps/**
|
||||
.github/actions/build-test/**
|
||||
.github/actions/generate-version/**
|
||||
.github/actions/setup-conan/**
|
||||
.github/scripts/strategy-matrix/**
|
||||
.github/workflows/reusable-build.yml
|
||||
.github/workflows/reusable-build-test-config.yml
|
||||
.github/workflows/reusable-build-test.yml
|
||||
.github/workflows/reusable-strategy-matrix.yml
|
||||
.github/workflows/reusable-test.yml
|
||||
.github/workflows/reusable-upload-recipe.yml
|
||||
.codecov.yml
|
||||
cmake/**
|
||||
conan/**
|
||||
external/**
|
||||
include/**
|
||||
src/**
|
||||
tests/**
|
||||
CMakeLists.txt
|
||||
conanfile.py
|
||||
conan.lock
|
||||
- name: Check whether to run
|
||||
# This step determines whether the rest of the workflow should
|
||||
# run. The rest of the workflow will run if this job runs AND at
|
||||
# least one of:
|
||||
# * Any of the files checked in the `changes` step were modified
|
||||
# * The PR is NOT a draft and is labeled "Ready to merge"
|
||||
# * The workflow is running from the merge queue
|
||||
id: go
|
||||
env:
|
||||
FILES: ${{ steps.changes.outputs.any_changed }}
|
||||
DRAFT: ${{ github.event.pull_request.draft }}
|
||||
READY: ${{ contains(github.event.pull_request.labels.*.name, 'Ready to merge') }}
|
||||
MERGE: ${{ github.event_name == 'merge_group' }}
|
||||
run: |
|
||||
echo "go=${{ (env.DRAFT != 'true' && env.READY == 'true') || env.FILES == 'true' || env.MERGE == 'true' }}" >> "${GITHUB_OUTPUT}"
|
||||
cat "${GITHUB_OUTPUT}"
|
||||
outputs:
|
||||
go: ${{ steps.go.outputs.go == 'true' }}
|
||||
|
||||
check-levelization:
|
||||
needs: should-run
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-check-levelization.yml
|
||||
|
||||
check-rename:
|
||||
needs: should-run
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-check-rename.yml
|
||||
|
||||
build-test:
|
||||
needs: should-run
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
with:
|
||||
# Enable ccache only for events targeting the XRPLF repository, since
|
||||
# other accounts will not have access to our remote cache storage.
|
||||
ccache_enabled: ${{ github.repository_owner == 'XRPLF' }}
|
||||
os: ${{ matrix.os }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
upload-recipe:
|
||||
needs:
|
||||
- should-run
|
||||
- build-test
|
||||
# Only run when committing to a PR that targets a release branch in the
|
||||
# XRPLF repository.
|
||||
if: ${{ github.repository_owner == 'XRPLF' && needs.should-run.outputs.go == 'true' && startsWith(github.ref, 'refs/heads/release') }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
notify-clio:
|
||||
needs: upload-recipe
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Notify the Clio repository about the newly proposed release version, so
|
||||
# it can be checked for compatibility before the release is actually made.
|
||||
- name: Notify Clio
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CLIO_NOTIFY_TOKEN }}
|
||||
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||
run: |
|
||||
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
|
||||
-F "client_payload[ref]=${{ needs.upload-recipe.outputs.recipe_ref }}" \
|
||||
-F "client_payload[pr_url]=${PR_URL}"
|
||||
|
||||
passed:
|
||||
if: failure() || cancelled()
|
||||
needs:
|
||||
- check-levelization
|
||||
- check-rename
|
||||
- build-test
|
||||
- upload-recipe
|
||||
- notify-clio
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fail
|
||||
run: false
|
||||
25
.github/workflows/on-tag.yml
vendored
Normal file
25
.github/workflows/on-tag.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# This workflow uploads the libxrpl recipe to the Conan remote when a versioned
|
||||
# tag is pushed.
|
||||
name: Tag
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
upload-recipe:
|
||||
# Only run when a tag is pushed to the XRPLF repository.
|
||||
if: ${{ github.repository_owner == 'XRPLF' }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
88
.github/workflows/on-trigger.yml
vendored
Normal file
88
.github/workflows/on-trigger.yml
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
# This workflow runs all workflows to build and test the code on various Linux
|
||||
# flavors, as well as on MacOS and Windows, on a scheduled basis, on merge into
|
||||
# the 'develop' or 'release*' branches, or when requested manually. Upon pushes
|
||||
# to the develop branch it also uploads the libxrpl recipe to the Conan remote.
|
||||
name: Trigger
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
- "release*"
|
||||
paths:
|
||||
# These paths are unique to `on-trigger.yml`.
|
||||
- ".github/workflows/on-trigger.yml"
|
||||
|
||||
# Keep the paths below in sync with those in `on-pr.yml`.
|
||||
- ".github/actions/build-deps/**"
|
||||
- ".github/actions/build-test/**"
|
||||
- ".github/actions/generate-version/**"
|
||||
- ".github/actions/setup-conan/**"
|
||||
- ".github/scripts/strategy-matrix/**"
|
||||
- ".github/workflows/reusable-build.yml"
|
||||
- ".github/workflows/reusable-build-test-config.yml"
|
||||
- ".github/workflows/reusable-build-test.yml"
|
||||
- ".github/workflows/reusable-strategy-matrix.yml"
|
||||
- ".github/workflows/reusable-test.yml"
|
||||
- ".github/workflows/reusable-upload-recipe.yml"
|
||||
- ".codecov.yml"
|
||||
- "cmake/**"
|
||||
- "conan/**"
|
||||
- "external/**"
|
||||
- "include/**"
|
||||
- "src/**"
|
||||
- "tests/**"
|
||||
- "CMakeLists.txt"
|
||||
- "conanfile.py"
|
||||
- "conan.lock"
|
||||
|
||||
# Run at 06:32 UTC on every day of the week from Monday through Friday. This
|
||||
# will force all dependencies to be rebuilt, which is useful to verify that
|
||||
# all dependencies can be built successfully. Only the dependencies that
|
||||
# are actually missing from the remote will be uploaded.
|
||||
schedule:
|
||||
- cron: "32 6 * * 1-5"
|
||||
|
||||
# Run when manually triggered via the GitHub UI or API.
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
# When a PR is merged into the develop branch it will be assigned a unique
|
||||
# group identifier, so execution will continue even if another PR is merged
|
||||
# while it is still running. In all other cases the group identifier is shared
|
||||
# per branch, so that any in-progress runs are cancelled when a new commit is
|
||||
# pushed.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build-test:
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
with:
|
||||
# Enable ccache only for events targeting the XRPLF repository, since
|
||||
# other accounts will not have access to our remote cache storage.
|
||||
# However, we do not enable ccache for events targeting a release branch,
|
||||
# to protect against the rare case that the output produced by ccache is
|
||||
# not identical to a regular compilation.
|
||||
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release') }}
|
||||
os: ${{ matrix.os }}
|
||||
strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }}
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
upload-recipe:
|
||||
needs: build-test
|
||||
# Only run when pushing to the develop branch in the XRPLF repository.
|
||||
if: ${{ github.repository_owner == 'XRPLF' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
|
||||
uses: ./.github/workflows/reusable-upload-recipe.yml
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user