mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-06 12:15:52 +00:00
Compare commits
4811 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
0ebed96142 | ||
|
|
4c06b3f86f | ||
|
|
a3470c225b | ||
|
|
c5d215d901 | ||
|
|
9dbf8495ee | ||
|
|
2529edd2b6 | ||
|
|
e974c7d8a4 | ||
|
|
b335adb674 | ||
|
|
c6ab880c03 | ||
|
|
7779dcdda0 | ||
|
|
132f1b218c | ||
|
|
e5d6f16f19 | ||
|
|
8f973621fc | ||
|
|
b75c2d71a5 | ||
|
|
eed210bb67 | ||
|
|
eab2a0d668 | ||
|
|
148bbf4e8f | ||
|
|
494724578a | ||
|
|
ea76103d5f | ||
|
|
2151110976 | ||
|
|
dfb45baa93 | ||
| f443439f1f | |||
|
|
6d0b108ec1 | ||
|
|
710f9ee1ac | ||
|
|
76d5ecb595 | ||
|
|
ba9ca1378e | ||
|
|
1be8094ee2 | ||
|
|
96c949a997 | ||
|
|
9121e26708 | ||
|
|
2432f13903 | ||
|
|
259fb1c32e | ||
|
|
e0515b0015 | ||
|
|
412a3ec710 | ||
|
|
30bba29da2 | ||
|
|
4f3a76dec0 | ||
|
|
61f443e3bb | ||
|
|
bd2a38f584 | ||
|
|
4cff94f7a4 | ||
|
|
fbdbffed67 | ||
|
|
ad5c5f1969 | ||
|
|
c354809e1c | ||
|
|
dc4d76f626 | ||
|
|
c1a02440dc | ||
|
|
e7a69cce65 | ||
|
|
60dc949314 | ||
|
|
cc824685e7 | ||
|
|
be70d81bd7 | ||
|
|
6df96f08df | ||
|
|
9ad2b9be45 | ||
|
|
0d2b2923da | ||
|
|
265f5f1fb1 | ||
|
|
a2ab6c4b02 | ||
|
|
6bdc9e7b30 | ||
|
|
c71eb45240 | ||
|
|
753600a2a0 | ||
|
|
945493d9cf | ||
|
|
2a8b0e4b88 | ||
|
|
513b1dd194 | ||
|
|
77462b8f72 | ||
|
|
1682fe3a39 | ||
|
|
58f786cbb4 | ||
|
|
a96cb8fc1c | ||
|
|
c587012e5c | ||
|
|
ad4bbd8dff | ||
|
|
202d91c9f0 | ||
|
|
146ea5d44e | ||
|
|
157c066f2b | ||
|
|
156e8dae83 | ||
|
|
5e96da51f9 | ||
|
|
cb71d493a0 | ||
|
|
8124c1f51f | ||
|
|
6ed2270bc9 | ||
|
|
4e7c038520 | ||
|
|
7b48dc36f5 | ||
|
|
d5c0e1216d | ||
|
|
a999894dae | ||
|
|
63e167b7a3 | ||
|
|
8fc6a8175b | ||
|
|
af1697cc6a | ||
|
|
e98c76110a | ||
|
|
7fe1d4b9c2 | ||
|
|
b36e11bc49 | ||
|
|
72e6005f56 | ||
|
|
152d698957 | ||
|
|
7c96bbafbd | ||
|
|
bdaad19e70 | ||
|
|
63c3fc30d8 | ||
|
|
1ac9694dbc | ||
|
|
3661dc88fe | ||
|
|
86c066cd7e | ||
|
|
d70464032c | ||
|
|
0bbe6e226c | ||
|
|
49e61cc0a6 | ||
|
|
6572fc8e95 | ||
|
|
3ce4dda5cb | ||
|
|
7295cf979b | ||
|
|
e14f913244 | ||
|
|
cd1c5a30dd | ||
|
|
8dd8433bb6 | ||
|
|
eeb9d92fb0 | ||
|
|
4104778067 | ||
|
|
4dcb3c9199 | ||
|
|
b0092aee24 | ||
|
|
bb52b04c25 | ||
|
|
83dac8b382 | ||
|
|
8a4951947d | ||
|
|
ab6163e989 | ||
|
|
5741a8356f | ||
|
|
b2f2d89a08 | ||
|
|
c946043280 | ||
|
|
820546c873 | ||
|
|
b36e9dd1b4 | ||
|
|
582d1691a9 | ||
|
|
3e22a1e9e8 | ||
|
|
7b0367730c | ||
|
|
8c14002c25 | ||
|
|
c0d396fb3c | ||
|
|
65d517d0df | ||
|
|
38c3a46a33 | ||
|
|
d3258c7f1f | ||
|
|
8a02903fa5 | ||
|
|
dbc8f147c9 | ||
|
|
7a547b8cf2 | ||
|
|
2c13ca0109 | ||
|
|
a7ed5bfbee | ||
|
|
a73372cb9d | ||
|
|
658f904ce0 | ||
|
|
9212c28ef8 | ||
|
|
5336e3715a | ||
|
|
c12dbc4386 | ||
|
|
2901577be7 | ||
|
|
4aa0bc37c0 | ||
|
|
24d2687f2d | ||
|
|
ed5a0bdc3c | ||
|
|
04745b11a8 | ||
|
|
9b63f4fb53 | ||
|
|
8ac6799149 | ||
|
|
09050a860b | ||
|
|
32ca1dd6ed | ||
|
|
37d9544ef7 | ||
|
|
63370b4441 | ||
|
|
49bcdda418 | ||
|
|
d89ff1b63d | ||
|
|
d289512aeb | ||
|
|
d98c4992dd | ||
|
|
d257d1b2c9 | ||
|
|
574ea2c14d | ||
|
|
70d9d88cda | ||
|
|
79d819584f | ||
|
|
e222ff5868 | ||
|
|
f58916a2e4 | ||
|
|
7e30897ef4 | ||
|
|
cff1abba5d | ||
|
|
aa4e3a98f7 | ||
|
|
381a1b948b | ||
|
|
873ba1ba9b | ||
|
|
16b9bbb517 | ||
|
|
7427cf7506 | ||
|
|
b14bdb068a | ||
|
|
8098cba4c2 | ||
|
|
68bebc472a | ||
|
|
243e181c08 | ||
|
|
b0a1aef43d | ||
|
|
aab47e09b6 | ||
|
|
fc3a3d8267 | ||
|
|
73fb3f0bfa | ||
|
|
5f8037c55b | ||
|
|
3aaf6d7857 | ||
|
|
11ab98cced | ||
|
|
06d0ff6e52 | ||
|
|
5a830b63e9 | ||
|
|
f658656b82 | ||
|
|
31e511afcf | ||
|
|
f0cc7c4c8d | ||
|
|
6a74d771ee | ||
|
|
833fae57db | ||
|
|
5097656c83 | ||
|
|
5b733fb485 | ||
|
|
0b2f33d23a | ||
|
|
08382d866b | ||
|
|
8429dd67e6 | ||
|
|
0439dcfa7a | ||
|
|
00df097e5f | ||
|
|
fd4636b056 | ||
|
|
34d3f93868 | ||
|
|
57ab0a00b5 | ||
|
|
f0cec3b2f1 | ||
|
|
1c2b8417b9 | ||
|
|
ca29c2b906 | ||
|
|
7c785d0d7c | ||
|
|
0ae157a5c3 | ||
|
|
a6f59081cc | ||
|
|
201f1aaa39 | ||
|
|
ae73878c59 | ||
|
|
cfdc64d7cf | ||
|
|
95eb5e1862 | ||
|
|
dc0d5996e2 | ||
|
|
817d2339b8 | ||
|
|
008ff67ac2 | ||
|
|
b444196bf9 | ||
|
|
27703859e7 | ||
|
|
2ac1c2b433 | ||
|
|
118c25c0f0 | ||
|
|
7d163a45dc | ||
|
|
717f874767 | ||
|
|
681df58b61 | ||
|
|
f31ca2860f | ||
|
|
d702e736ca | ||
|
|
6156ff3eb7 | ||
|
|
04f1388860 | ||
|
|
c1c332f0b0 | ||
|
|
93780c25f7 | ||
|
|
a442d3fdb3 | ||
|
|
7bc163ee4c | ||
|
|
6bd0b850a0 | ||
|
|
1eece9b1fd | ||
|
|
859d18adb0 | ||
|
|
c4a9b73a66 | ||
|
|
8eb8c77886 | ||
|
|
ef3bc92b82 | ||
|
|
f7a4a94c3b | ||
|
|
3dc0714273 | ||
|
|
deb9e4ce3c | ||
|
|
4bc300e251 | ||
|
|
d65e208a99 | ||
|
|
f8fb1f6c7d | ||
|
|
db3b4dd396 | ||
|
|
b7335fdff5 | ||
|
|
d45556ec82 | ||
|
|
cebb9c6604 | ||
|
|
b7692b7bc1 | ||
|
|
327377cb2d | ||
|
|
75c4dbb0a1 | ||
|
|
f0b9506617 | ||
|
|
b4e1b3c1b1 | ||
|
|
02c487348a | ||
|
|
5db5e31140 | ||
|
|
4869a0d00e | ||
|
|
d9be0de269 | ||
|
|
0b18b36186 | ||
|
|
8d9dffcf84 | ||
|
|
2b8893dfca | ||
|
|
881cd4cfad | ||
|
|
067dbf299c | ||
|
|
8e9495f487 | ||
|
|
40dc6b1458 | ||
|
|
d5f981f5fc | ||
|
|
25de6b0a5f | ||
|
|
9af994ceb4 | ||
|
|
5549ff4c8a | ||
|
|
3730d46dad | ||
|
|
1507ed66a8 | ||
|
|
3a5a6c3637 | ||
|
|
4b2afc8f42 | ||
|
|
deef322b07 | ||
|
|
9456b83576 | ||
|
|
864844086e | ||
|
|
755849115e | ||
|
|
605ace7645 | ||
|
|
1a245234f1 | ||
|
|
20defb4844 | ||
|
|
8b909d5c17 | ||
|
|
4a3a40174e | ||
|
|
2fee75bfc1 | ||
|
|
6230204e42 | ||
|
|
5807ce2127 | ||
|
|
da43775d1b | ||
|
|
099a050c0b | ||
|
|
6fb2482886 | ||
|
|
b07da94c31 | ||
|
|
531e153144 | ||
|
|
079f346efd | ||
|
|
6d3b2b404d | ||
|
|
9685e756e6 | ||
|
|
8e365ea44a | ||
|
|
9a210cfda5 | ||
|
|
060692aad4 | ||
|
|
3e9e0c4b53 | ||
|
|
88570df135 | ||
|
|
c6a307fcd7 | ||
|
|
fd00e6e035 | ||
|
|
94c6a2a850 | ||
|
|
1c44c4a43e | ||
|
|
7e936187ac | ||
|
|
6328fabd5c | ||
|
|
125316f2a6 | ||
|
|
ed750a84dd | ||
|
|
e0ee58c92d | ||
|
|
6286a9708e | ||
|
|
5e4cb78208 | ||
|
|
a8481e369d | ||
|
|
35cc341544 | ||
|
|
f6013c1c37 | ||
|
|
992a390d75 | ||
|
|
ba43bfc646 | ||
|
|
cc9c976b76 | ||
|
|
eaff9a0e6a | ||
|
|
2a4eac6eb8 | ||
|
|
0ec66b3dbc | ||
|
|
718d217158 | ||
|
|
aeda2430cd | ||
|
|
819ea46bf0 | ||
|
|
2d5ddbf1bf | ||
|
|
76ad06ef47 | ||
|
|
49b5c42e85 | ||
|
|
d9337ad43a | ||
|
|
0c22e0262d | ||
|
|
593a53253c | ||
|
|
0c4f0fdd01 | ||
|
|
ecd1528197 | ||
|
|
cc0ce7163a | ||
|
|
259394029a | ||
|
|
a307d2d03f | ||
|
|
ad4ba44394 | ||
|
|
6b56426719 | ||
|
|
44e5e8bccf | ||
|
|
edf58820cf | ||
|
|
20cdb4dca0 | ||
|
|
d8bbcf21be | ||
|
|
7ff6d34a49 | ||
|
|
e3499b5df8 | ||
|
|
4e8c8deeaa | ||
|
|
92c987a6b4 | ||
|
|
5e4dac41a7 | ||
|
|
dc9e9f498a | ||
|
|
0d3ed84864 | ||
|
|
468b1e22f5 | ||
|
|
c89bb5f4b1 | ||
|
|
7d6c2229ab | ||
|
|
516a1b85d1 | ||
|
|
2836c20649 | ||
|
|
80050c110f | ||
|
|
d2fc4e3569 | ||
|
|
fbfb4bd74e | ||
|
|
8fff0fa6a9 | ||
|
|
d0dac38ea8 | ||
|
|
3d6ea6737c | ||
|
|
dc5f40bf62 | ||
|
|
1882bbdae7 | ||
|
|
855681a40b | ||
|
|
db066da443 | ||
|
|
090d813065 | ||
|
|
722917e9a6 | ||
|
|
8a02b76d73 | ||
|
|
3e483cfa4c | ||
|
|
c42ea14531 | ||
|
|
a30af2ac89 | ||
|
|
83dc45db62 | ||
|
|
3757829f8e | ||
|
|
db17ae8997 | ||
|
|
cd19246937 | ||
|
|
d61436cca5 | ||
|
|
4e6c8d8b35 | ||
|
|
16acba1636 | ||
|
|
50b35e2090 | ||
|
|
e8d02c1333 | ||
|
|
3523cee63d | ||
|
|
aa76632bb3 | ||
|
|
feb7582aca | ||
|
|
07e3f81b76 | ||
|
|
6ff5d3734f | ||
|
|
5fe65c5906 | ||
|
|
2c13d9eb57 | ||
|
|
b9fc9f6334 | ||
|
|
1853c0d678 | ||
|
|
6dc79c23ed | ||
|
|
5a9c3c797c | ||
|
|
a4a43a4de9 | ||
|
|
25b002b37f | ||
|
|
40c39c4afb | ||
|
|
f0e1024ad6 | ||
|
|
c11e186659 | ||
|
|
0a48916d98 | ||
|
|
dffb999efb | ||
|
|
044dd53513 | ||
|
|
02059a27d6 | ||
|
|
8f347a5333 | ||
|
|
bce9bca2ce | ||
|
|
cafe18c592 | ||
|
|
3e5490ef6d | ||
|
|
c76656cf7f | ||
|
|
c7c1b3cc3b | ||
|
|
39f9135104 | ||
|
|
dd52bdd2c4 | ||
|
|
7a0fa312ea | ||
|
|
cd2d52acdc | ||
|
|
62127d725d | ||
|
|
fc640504ba | ||
|
|
3c0b35092c | ||
|
|
89e8ea436a | ||
|
|
21dc05fc33 | ||
|
|
589570daa3 | ||
|
|
a02a469b20 | ||
|
|
be1f734845 | ||
|
|
98d7fa3fd9 | ||
|
|
74823cb7d1 | ||
|
|
e47bfa223f | ||
|
|
5c1ec051f0 | ||
|
|
65094d9c90 | ||
|
|
c00341a97e | ||
|
|
36423a5f77 | ||
|
|
60dd194b72 | ||
|
|
9ae717c433 | ||
|
|
d90a0647d6 | ||
|
|
35d81e65c1 | ||
|
|
cca574c9a9 | ||
|
|
c96c423afb | ||
|
|
463b154e3d | ||
|
|
3666948610 | ||
|
|
397410bac6 | ||
|
|
7aa838c091 | ||
|
|
458ac470aa | ||
|
|
a79cb95c85 | ||
|
|
5ad49454f1 | ||
|
|
1a56b9c5f2 | ||
|
|
efe3700f70 | ||
|
|
fc89d2e014 | ||
|
|
3c37539cee | ||
|
|
3d977aeacb | ||
|
|
4308b124c2 | ||
|
|
b23e9c207d | ||
|
|
c3a6b1600f | ||
|
|
138e1ba9a8 | ||
|
|
2858661bce | ||
|
|
afc791835e | ||
|
|
d981bff8ea | ||
|
|
b24d47c093 | ||
|
|
df086301b6 | ||
|
|
01b4d5cdd4 | ||
|
|
8c155dd875 | ||
|
|
3f9a38697d | ||
|
|
87742a5e6c | ||
|
|
5b9e8a77ca | ||
|
|
2821624ede | ||
|
|
ac1ab720c4 | ||
|
|
e0168b98d7 | ||
|
|
18801b81de | ||
|
|
1daefeb594 | ||
|
|
068048718e | ||
|
|
56946e8128 | ||
|
|
3dfb4a13f1 | ||
|
|
7ae3c91015 | ||
|
|
95f107d487 | ||
|
|
61316c7f95 | ||
|
|
49bdf2e72d | ||
|
|
f0f96bd1da | ||
|
|
3bfd9de677 | ||
|
|
f9b5ab4728 | ||
|
|
7abd70356d | ||
|
|
d8313288ad | ||
|
|
a89be5b269 | ||
|
|
7b0d482810 | ||
|
|
e81f3eb1d2 | ||
|
|
cd0a2d6ef3 | ||
|
|
d04d3d3c4a | ||
|
|
da7da5527c | ||
|
|
6f4bc30684 | ||
|
|
fa72795d84 | ||
|
|
68b8ffdb63 | ||
|
|
cb91d56d07 | ||
|
|
6e889e6a18 | ||
|
|
be9c3b218b | ||
|
|
a92f5b8e5a | ||
|
|
3eeb79ee12 | ||
|
|
24e1b9911a | ||
|
|
3a973ab719 | ||
|
|
6f10fe8502 | ||
|
|
d471e533b7 | ||
|
|
1a238048d5 | ||
|
|
aa2ff00485 | ||
|
|
f2787dc35c | ||
|
|
8002a13dd2 | ||
|
|
7dc2fe9ce7 | ||
|
|
5f37765292 | ||
|
|
a56d31910f | ||
|
|
24505a358a | ||
|
|
c570695aa1 | ||
|
|
208028a142 | ||
|
|
dceef25e2c | ||
|
|
256e58204a | ||
|
|
c1d64e1b1a | ||
|
|
1dbc5a57e6 | ||
|
|
9cc542fe67 | ||
|
|
f7a7f13287 | ||
|
|
96ece1b9f0 | ||
|
|
46004158a2 | ||
|
|
7e9ac16c22 | ||
|
|
2e5ab4e0e3 | ||
|
|
00c60d408a | ||
|
|
d5dc715d9c | ||
|
|
369909df84 | ||
|
|
2cd55ebf98 | ||
|
|
4e43e22a3a | ||
|
|
d8dea963fa | ||
|
|
84816d1c21 | ||
|
|
8430f9deff | ||
|
|
fcceb0aac1 | ||
|
|
2680b78b5b | ||
|
|
068889e5b1 | ||
|
|
3bd9772c04 | ||
|
|
af66c62814 | ||
|
|
5bc8f2e3e8 | ||
|
|
22c97ba801 | ||
|
|
026a249173 | ||
|
|
e52614ac81 | ||
|
|
10a7f5b933 | ||
|
|
c6b6d82a75 | ||
|
|
9a0249e793 | ||
|
|
e92760eec8 | ||
|
|
7b82051bdb | ||
|
|
aea54b7230 | ||
|
|
1a7a6f22e2 | ||
|
|
fab3ec0b56 | ||
|
|
2449f9c18d | ||
|
|
fee30262ac | ||
|
|
7cd4d78897 | ||
|
|
4ff40d4954 | ||
|
|
0d4fe469c6 | ||
|
|
8b43d67a73 | ||
|
|
128f7cefb1 | ||
|
|
09f9720ebb | ||
|
|
dbe74dffcb | ||
|
|
b958fa413e | ||
|
|
c453df927f | ||
|
|
1bb92d40aa | ||
|
|
15f969a469 | ||
|
|
bc5a74057d | ||
|
|
fc0d64f5ee | ||
|
|
885aaab8c8 | ||
|
|
9d4500cf69 | ||
|
|
9ff9fa0aea | ||
|
|
1d482eeecb | ||
|
|
b4e765362b | ||
|
|
c981eb81d9 | ||
|
|
95aebfc38c | ||
|
|
7265729446 | ||
|
|
846723d771 | ||
|
|
80d9b0464a | ||
|
|
09a1d1a593 | ||
|
|
aebcc2115d | ||
|
|
6fac038320 | ||
|
|
0df1b09a73 | ||
|
|
f432095532 | ||
|
|
e27a38939e | ||
|
|
ffa79ac6a5 | ||
|
|
2e632b1660 | ||
|
|
0b187a6a4e | ||
|
|
6cea5d0838 | ||
|
|
ffc7cf8f6c | ||
|
|
69bc58c5f6 | ||
|
|
f423181b94 | ||
|
|
112a863e73 | ||
|
|
cfde591ac9 | ||
|
|
0c97dda276 | ||
|
|
35f4698aed | ||
|
|
b7e2a3bd5f | ||
|
|
bb61b398a6 | ||
|
|
1e438f51c5 | ||
|
|
60416b18a5 | ||
|
|
4b0a0b0b85 | ||
|
|
f1377d5d30 | ||
|
|
30b6e4e2e5 | ||
|
|
5cf38bf88a | ||
|
|
9e3dadce0d | ||
|
|
73b4c818c5 | ||
|
|
2c2b0eb2f1 | ||
|
|
17726c2cac | ||
|
|
af79c9007e | ||
|
|
3de623bf66 | ||
|
|
7ec58cc554 | ||
|
|
3d6a1781e7 | ||
|
|
ce9238b389 | ||
|
|
2c6b0f3193 | ||
|
|
b4a16b165b | ||
|
|
a8cf5e0a5c | ||
|
|
2fcde0e0b6 | ||
|
|
b45f45dcef | ||
|
|
e823e60ca0 | ||
|
|
74977ab3db | ||
|
|
80dfb7d72d | ||
|
|
c30fe3066a | ||
|
|
0b605b3609 | ||
|
|
9bb337fb1f | ||
|
|
460dd8f186 | ||
|
|
6b0817b7ba | ||
|
|
7698477e86 | ||
|
|
8b60ef9db4 | ||
|
|
209fe8f7a9 | ||
|
|
b514f1aae9 | ||
|
|
f6a0345831 | ||
|
|
ce7e83f763 | ||
|
|
71b42dcec5 | ||
|
|
f5af8b03de | ||
|
|
e01f6e7455 | ||
|
|
b3eada1dc2 | ||
|
|
a3e3b9321e | ||
|
|
c652cf066d | ||
|
|
c218417d1a | ||
|
|
69db2ace58 | ||
|
|
79149b4c0c | ||
|
|
232ec62c75 | ||
|
|
7ca03d3bca | ||
|
|
15a30c745c | ||
|
|
8345475bc3 | ||
|
|
c7de7950c4 | ||
|
|
b6126f219f | ||
|
|
e05bf0844d | ||
|
|
fdff943262 | ||
|
|
a1a8ba7f53 | ||
|
|
d8a5f5b094 | ||
|
|
1ede09760e | ||
|
|
708fc6cd6f | ||
|
|
77999579b5 | ||
|
|
d24bb65639 | ||
|
|
d810f29e99 | ||
|
|
6e3e717876 | ||
|
|
2c87739d6c | ||
|
|
b00b81a861 | ||
|
|
a0a4eedc27 | ||
|
|
c0e9e3df49 | ||
|
|
7028579170 | ||
|
|
84ada74d53 | ||
|
|
be0fb67d8d | ||
|
|
fb60cc9b5b | ||
|
|
3c4d3b10c1 | ||
|
|
d9ef5ef98f | ||
|
|
be9c955506 | ||
|
|
1989b1028f | ||
|
|
0d577d9349 | ||
|
|
7536c53a48 | ||
|
|
e3ff30657c | ||
|
|
698ea58b39 | ||
|
|
a5500721db | ||
|
|
fd4ad29418 | ||
|
|
905c627043 | ||
|
|
8d8907e340 | ||
|
|
6724a63230 | ||
|
|
af4fe24939 | ||
|
|
c1c80dfc52 | ||
|
|
87273e21d8 | ||
|
|
610e51a162 | ||
|
|
e91aacc9a3 | ||
|
|
6e54461f4b | ||
|
|
ef23d72562 | ||
|
|
a1c0d15a1f | ||
|
|
b6a01ea41c | ||
|
|
8425e4558a | ||
|
|
5a688f9236 | ||
|
|
effd8c9737 | ||
|
|
a7c4d682d2 | ||
|
|
e00a6b0e5a | ||
|
|
dc3571184a | ||
|
|
22a375a5f4 | ||
|
|
3337d17fdd | ||
|
|
8ab2236cdd | ||
|
|
0cb6a0f961 | ||
|
|
28ae522ea2 | ||
|
|
c0cf7bd3c1 | ||
|
|
fd7a2835e4 | ||
|
|
3d0314c621 | ||
|
|
8d83aa5c07 | ||
|
|
7ff243ade9 | ||
|
|
2fd0540ed4 | ||
|
|
cdf470e68d | ||
|
|
7fc780dd70 | ||
|
|
4d7b1a3b61 | ||
|
|
9a9dffa4ff | ||
|
|
51e7f595bb | ||
|
|
293e520efc | ||
|
|
9e960ff6b8 | ||
|
|
0a8e690917 | ||
|
|
cf60d4c30e | ||
|
|
8f2480225b | ||
|
|
44167a6bcb | ||
|
|
db95808206 | ||
|
|
fd901f8081 | ||
|
|
b6ce0aa75a | ||
|
|
b712125bc0 | ||
|
|
d69b16895c | ||
|
|
d198b439fd | ||
|
|
83aa5517c0 | ||
|
|
5711e7caa9 | ||
|
|
8d0c93691d | ||
|
|
d8d0cb17ba | ||
|
|
47a919faf0 | ||
|
|
d572de769b | ||
|
|
810a6b0f30 | ||
|
|
665ad180cb | ||
|
|
361917e902 | ||
|
|
4b261b12a4 | ||
|
|
afd4b45036 | ||
|
|
47adc728db | ||
|
|
7e39d645b9 | ||
|
|
35504f1723 | ||
|
|
61d9dda4e0 | ||
|
|
38ca9d4a97 | ||
|
|
f37aa1d6c8 | ||
|
|
db13ddf844 | ||
|
|
bf642404c7 | ||
|
|
d53d5cfc42 | ||
|
|
bbf52056f9 | ||
|
|
b8cae2dfaf | ||
|
|
795ee8bb5e | ||
|
|
cfcd618aa6 | ||
|
|
19258cf980 | ||
|
|
cdaafeb4b6 | ||
|
|
7688a97d95 | ||
|
|
027b289c91 | ||
|
|
b55edfa8f0 | ||
|
|
7d46d153c6 | ||
|
|
96b17749af | ||
|
|
f27348c4d5 | ||
|
|
c6923dcf88 | ||
|
|
f456355da2 | ||
|
|
97806b42c4 | ||
|
|
ed02b0717e | ||
|
|
2963e91752 | ||
|
|
aa11effdd6 | ||
|
|
6e9c15af92 | ||
|
|
0ddeb29c35 | ||
|
|
98f878cf10 | ||
|
|
69b47890e6 | ||
|
|
41851022d3 | ||
|
|
a7630aaa55 | ||
|
|
1d15af6afd | ||
|
|
dd0075f2b8 | ||
|
|
4b0d8b630c | ||
|
|
b421559a47 | ||
|
|
05e7373086 | ||
|
|
bb0b97f46b | ||
|
|
3b639afac2 | ||
|
|
bd93ecbd6b | ||
|
|
79159ffd87 | ||
|
|
f05321d501 | ||
|
|
8734458cfb | ||
|
|
bdbb3caf47 | ||
|
|
076658e0f6 | ||
|
|
b2499c8fa0 | ||
|
|
231a5ae6fb | ||
|
|
45249e8746 | ||
|
|
e6ed9ae4d8 | ||
|
|
aca6db5601 | ||
|
|
8e9f9599b8 | ||
|
|
71d7d87bf3 | ||
|
|
7ffef30f1c | ||
|
|
7c90b9ef88 | ||
|
|
4bb74196c0 | ||
|
|
35fa20a110 | ||
|
|
ddaeae2855 | ||
|
|
9c8e3776de | ||
|
|
633cf86ad8 | ||
|
|
66ce8779e8 | ||
|
|
a9b3042d7e | ||
|
|
4df24c0e8e | ||
|
|
9a988963e9 | ||
|
|
5be33a650d | ||
|
|
5b09dc731f | ||
|
|
51d7e7336f | ||
|
|
ad9be4dbf6 | ||
|
|
87756b9324 | ||
|
|
e611a7a0f8 | ||
|
|
2f9a8440c2 | ||
|
|
a40dd2690a | ||
|
|
802c2395c1 | ||
|
|
8f97889176 | ||
|
|
104f12a9e2 | ||
|
|
e499743cdd | ||
|
|
241795cd73 | ||
|
|
411b2534ed | ||
|
|
253f138aff | ||
|
|
dadbab4c0f | ||
|
|
d9017a3f76 | ||
|
|
aedfaab93d | ||
|
|
8687f64429 | ||
|
|
1d08075c43 | ||
|
|
8a6c7f9208 | ||
|
|
fd061bba8a | ||
|
|
8f41817cb9 | ||
|
|
cf8b6be494 | ||
|
|
d263d4d449 | ||
|
|
b39e4817e5 | ||
|
|
4dfa250a34 | ||
|
|
8a6908c072 | ||
|
|
d8fe737ad7 | ||
|
|
61023c3f4a | ||
|
|
b607d47bd3 | ||
|
|
878c0f2a19 | ||
|
|
19dd983d2b | ||
|
|
c15751ced6 | ||
|
|
a55d9aa4c3 | ||
|
|
037d52114a | ||
|
|
68e123a8d6 | ||
|
|
b92a7d415e | ||
|
|
fc73fbd050 | ||
|
|
ab45c490d7 | ||
|
|
d8b85c00e8 | ||
|
|
e453c14b0a | ||
|
|
1c6e32ccc2 | ||
|
|
c4e581179c | ||
|
|
0d803e0fa2 | ||
|
|
c1b8efb7af | ||
|
|
b0704b47e8 | ||
|
|
2fa84e95b9 | ||
|
|
b02ec47b4f | ||
|
|
3ff56eb071 | ||
|
|
9e8a5a5765 | ||
|
|
461a8ea846 | ||
|
|
8d9c0daa9d | ||
|
|
1537527927 | ||
|
|
d51a2785ee | ||
|
|
e8a7ad4748 | ||
|
|
2ca18670d2 | ||
|
|
d4a56f223a | ||
|
|
2e7f5502bf | ||
|
|
4483079181 | ||
|
|
2f0b3bd427 | ||
|
|
d1ce07ef5d | ||
|
|
a252fefede | ||
|
|
e762d09e7e | ||
|
|
348e65074e | ||
|
|
64f2576fc8 | ||
|
|
9926d3188a | ||
|
|
cc8671b8b2 | ||
|
|
f5fcdd0b80 | ||
|
|
71a30a57cb | ||
|
|
f9fe2ef90f | ||
|
|
6c8673c7c3 | ||
|
|
11b64e049c | ||
|
|
33f153fc9a | ||
|
|
4758050444 | ||
|
|
a5589dcec6 | ||
|
|
08ea245101 | ||
|
|
3b58e36621 | ||
|
|
b343b0468a | ||
|
|
69b91065c5 | ||
|
|
e39316882e | ||
|
|
1ff972fbd3 | ||
|
|
8204d9524e | ||
|
|
07bf106cd3 | ||
|
|
225b5a1204 | ||
|
|
054d5de877 | ||
|
|
5349bcc1c5 | ||
|
|
17fd2ef2e2 | ||
|
|
e199c0555c | ||
|
|
42557b800c | ||
|
|
ef2330d477 | ||
|
|
cb7d0b508d | ||
|
|
cf72d70eca | ||
|
|
cf9d65f973 | ||
|
|
dd2feb8d1f | ||
|
|
d790c3b671 | ||
|
|
a56c43f3b3 | ||
|
|
6f3a35e8be | ||
|
|
c9d8fa9e96 | ||
|
|
b72724a4a4 | ||
|
|
f8a1ec0348 | ||
|
|
8375ae647e | ||
|
|
69da298aa7 | ||
|
|
6765507cc4 | ||
|
|
e2c67a1666 | ||
|
|
6397025435 | ||
|
|
2a448065da | ||
|
|
5c7130e4fd | ||
|
|
bbad20c66f | ||
|
|
e29163e922 | ||
|
|
2633949d5b | ||
|
|
16a38f3979 | ||
|
|
c4f8b38148 | ||
|
|
40678e9a78 | ||
|
|
8f5449dafb | ||
|
|
8c90ef810a | ||
|
|
177a52473a | ||
|
|
a22fa21ce4 | ||
|
|
beb9883705 | ||
|
|
654772a860 | ||
|
|
9cc80b7cb6 | ||
|
|
d46c21cc5f | ||
|
|
da18f7c053 | ||
|
|
0952ebfc1d | ||
|
|
a698104c55 | ||
|
|
f060820f3b | ||
|
|
119d5c1e47 | ||
|
|
2d53ee4051 | ||
|
|
66f0caa309 | ||
|
|
d88b63d4c8 | ||
|
|
63a5522406 | ||
|
|
d22eb0caa2 | ||
|
|
138cadc01c | ||
|
|
b590e2c96f | ||
|
|
c4c8a620c8 | ||
|
|
5dd8f28290 | ||
|
|
078436212c | ||
|
|
10521de2fc | ||
|
|
7d11471619 | ||
|
|
434855f500 | ||
|
|
11c4ca00d5 | ||
|
|
f16d701a2c | ||
|
|
34d590d93a | ||
|
|
a87f56448a | ||
|
|
bb61ad2afe | ||
|
|
57b8eb6ccd | ||
|
|
7f52249e40 | ||
|
|
321e2a94fe | ||
|
|
ceb01fb6a3 | ||
|
|
2206d0ef65 | ||
|
|
279c2a6f82 | ||
|
|
d1200224e2 | ||
|
|
fdd1f2ec36 | ||
|
|
7295d7f4bb | ||
|
|
05d98f4380 | ||
|
|
a187750b32 | ||
|
|
55377c12d3 | ||
|
|
cd11f3755e | ||
|
|
289c8c9f09 | ||
|
|
80a9a2bf5d | ||
|
|
1b0b8d7043 | ||
|
|
b81ec3545f | ||
|
|
999e2fa031 | ||
|
|
c060d08767 | ||
|
|
27ca1b2698 | ||
|
|
75af4ed9b5 | ||
|
|
1edc5e5ee0 | ||
|
|
28f90d17ac | ||
|
|
50b5dab5df | ||
|
|
8afdcb9e9f | ||
|
|
7e8f5401b2 | ||
|
|
5a0a47cbae | ||
|
|
bc2642f423 | ||
|
|
cd41a0decd | ||
|
|
803d145a5e | ||
|
|
8303266430 | ||
|
|
44e33121c7 | ||
|
|
8a6ff4803c | ||
|
|
abbf4b82b0 | ||
|
|
9752268308 | ||
|
|
1fe983948f | ||
|
|
39829a09cb | ||
|
|
3de738429f | ||
|
|
fa0ef25ffb | ||
|
|
a9e507da9b | ||
|
|
20dfecd2b6 | ||
|
|
eb7bd6a2f1 | ||
|
|
a570b74038 | ||
|
|
18c82465b2 | ||
|
|
d46db18a31 | ||
|
|
5cf4f4a5e2 | ||
|
|
e3ee23bcfd | ||
|
|
846cbf8c78 | ||
|
|
b14555c742 | ||
|
|
154e90b1ca | ||
|
|
97c89168f7 | ||
|
|
a039e7593a | ||
|
|
acebbf58eb | ||
|
|
84e3184106 | ||
|
|
3a1fa4a552 | ||
|
|
1cf518e82c | ||
|
|
951f479a1b | ||
|
|
a6e408510a | ||
|
|
f2f195f43e | ||
|
|
21c563f83a | ||
|
|
67b1acbf78 | ||
|
|
4ed6cbdd5b | ||
|
|
7e3dbce3d2 | ||
|
|
e38f01d1f4 | ||
|
|
32a01df0e1 | ||
|
|
814a8258fd | ||
|
|
f3b2153ba7 | ||
|
|
651fb45598 | ||
|
|
b5dc8eb9ce | ||
|
|
b12d1570a7 | ||
|
|
cd38492ceb | ||
|
|
411a12693d | ||
|
|
c0952e54db | ||
|
|
09c566a6eb | ||
|
|
97b1ac6eab | ||
|
|
2a8de0fd6b | ||
|
|
8921da91b8 | ||
|
|
2b69831f49 | ||
|
|
e9f924ca31 | ||
|
|
595912f82d | ||
|
|
ec1ffa2945 | ||
|
|
45ff08b6aa | ||
|
|
ab9e0c06b8 | ||
|
|
c549c9dff0 | ||
|
|
d7a778ce6a | ||
|
|
f45e279e06 | ||
|
|
4d19b8be07 | ||
|
|
2ae68923cc | ||
|
|
d197c9780a | ||
|
|
3d063edb72 | ||
|
|
f081e80c28 | ||
|
|
1c3ee48146 | ||
|
|
e499e908d2 | ||
|
|
e0956c36c1 | ||
|
|
2893f8c82a | ||
|
|
036c3098f3 | ||
|
|
24612eba4c | ||
|
|
6512b8894a | ||
|
|
1b44c9a3df | ||
|
|
8499cc9767 | ||
|
|
d49faa0f5c | ||
|
|
258cd2cb87 | ||
|
|
7eed701682 | ||
|
|
e62b9dc4c1 | ||
|
|
36ac1124f4 | ||
|
|
ddb34f1ed1 | ||
|
|
76b761d8e2 | ||
|
|
92b3cdb6f8 | ||
|
|
47eb7fcc2f | ||
|
|
6d8c73cc52 | ||
|
|
9e5e16c18d | ||
|
|
3af4cf0a28 | ||
|
|
d6903efc0c | ||
|
|
9390eb016c | ||
|
|
47dc31d8c2 | ||
|
|
f3c3e0bfff | ||
|
|
fbb5a753b1 | ||
|
|
a1951aff02 | ||
|
|
c28d36b500 | ||
|
|
0efb929898 | ||
|
|
3f84dd8cf9 | ||
|
|
5d9e53a37d | ||
|
|
2e2a7509cd | ||
|
|
7f97b7bc05 | ||
|
|
073ccf2705 | ||
|
|
6d8b25fdf8 | ||
|
|
22f62af9be | ||
|
|
2a014df60d | ||
|
|
6c8b4b2f8d | ||
|
|
8dad543671 | ||
|
|
cf0cea38fd | ||
|
|
db7b65ed42 | ||
|
|
61a8f7f078 | ||
|
|
e4f0b36f61 | ||
|
|
b7c34d8a96 | ||
|
|
b5dbd7942f | ||
|
|
5e5d5fdee4 | ||
|
|
89c05efe22 | ||
|
|
e5bf824c3b | ||
|
|
b509263ef5 | ||
|
|
13ec104154 | ||
|
|
4cfa1d5cd3 | ||
|
|
48396aebd1 | ||
|
|
7cfdab936c | ||
|
|
010444d77a | ||
|
|
1c8c3207fe | ||
|
|
ba7031cb3b | ||
|
|
7e88fdd0f1 | ||
|
|
af3d721f82 | ||
|
|
e09249abad | ||
|
|
0061f03cef | ||
|
|
53c82d54ea | ||
|
|
5602a24b22 | ||
|
|
f4cbb9d8e9 | ||
|
|
df82a734af | ||
|
|
2179ea85f8 | ||
|
|
f5299209d4 | ||
|
|
ca2384f230 | ||
|
|
9c88f76338 | ||
|
|
f07cd8ceb4 | ||
|
|
4469ff4b9a | ||
|
|
54f6f0ceba | ||
|
|
2cb3834bbb | ||
|
|
2e302a43aa | ||
|
|
5e8d028da2 | ||
|
|
8b62c23ab6 | ||
|
|
bcbe22c780 | ||
|
|
3461bafaa2 | ||
|
|
f25b448a49 | ||
|
|
874bbd0b8a | ||
|
|
73ddda4651 | ||
|
|
a433804ee6 | ||
|
|
08171dad5e | ||
|
|
f60eeaf08c | ||
|
|
7b3550c46e | ||
|
|
db8fb177b8 | ||
|
|
203739f7a4 | ||
|
|
735c341fae | ||
|
|
7bb9264c3d | ||
|
|
4b8d227922 | ||
|
|
4124850481 | ||
|
|
637fee5ecc | ||
|
|
47eb4da080 | ||
|
|
79ca82c078 | ||
|
|
d2a787805a | ||
|
|
d2071b7ea7 | ||
|
|
61ba1743ef | ||
|
|
d60426a19f | ||
|
|
a88bc564ee | ||
|
|
a5d5856638 | ||
|
|
4e64e3f1dd | ||
|
|
51850ded05 | ||
|
|
76d7c1c01a | ||
|
|
dabc5567f7 | ||
|
|
5c5ee6f763 | ||
|
|
06bfcad671 | ||
|
|
73e48e6595 | ||
|
|
64a005565d | ||
|
|
aa5098866c | ||
|
|
60ff83f280 | ||
|
|
8dbad62153 | ||
|
|
4a78b343d9 | ||
|
|
ab8102f927 | ||
|
|
fa02409c92 | ||
|
|
3a45ef0e65 | ||
|
|
f2cdeb7d9a | ||
|
|
ff7a2c63f2 | ||
|
|
efe4c9cae3 | ||
|
|
c37261858a | ||
|
|
ef3dc5bb58 | ||
|
|
968327d577 | ||
|
|
eedf724ccd | ||
|
|
bf3f33f8cb | ||
|
|
271feb02b8 | ||
|
|
f254ebb4ca | ||
|
|
c9f1966e08 | ||
|
|
095f85f159 | ||
|
|
fdd2740f8b | ||
|
|
8268162cac | ||
|
|
30eff2b520 | ||
|
|
d3962718aa | ||
|
|
388fd1262a | ||
|
|
7a4bd2278d | ||
|
|
b3f5986c83 | ||
|
|
48d28826d0 | ||
|
|
122a5cdf89 | ||
|
|
f3e93bbbeb | ||
|
|
6d2f7e46dd | ||
|
|
3d9589f010 | ||
|
|
906ef761ba | ||
|
|
6b87a67592 | ||
|
|
e16361826e | ||
|
|
a327cecee6 | ||
|
|
64d9f7c23e | ||
|
|
4f16a1cee9 | ||
|
|
8f83f69325 | ||
|
|
1d0ca51c88 | ||
|
|
ca70f4fab1 | ||
|
|
72cdf3f555 | ||
|
|
1c68fddad7 | ||
|
|
2f3b5f6d0a | ||
|
|
5663c45a0d | ||
|
|
172356d299 | ||
|
|
2323ea4493 | ||
|
|
d6a666f4e0 | ||
|
|
6e70a6c6f5 | ||
|
|
b82be0a9b0 | ||
|
|
94a47569d6 | ||
|
|
73df97f2d0 | ||
|
|
e8b75b80c2 | ||
|
|
f6bec473d5 | ||
|
|
9ab5611c65 | ||
|
|
92391332d7 | ||
|
|
8e26b187be | ||
|
|
79ce5901f3 | ||
|
|
29a4849024 | ||
|
|
0a1731c4c9 | ||
|
|
5cac2befb0 | ||
|
|
be60348f8f | ||
|
|
e6d4436e9d | ||
|
|
c4e9a464e7 | ||
|
|
16b1adfa86 | ||
|
|
404d58d77c | ||
|
|
6c712ff2df | ||
|
|
e3414bf042 | ||
|
|
308aaa6f78 | ||
|
|
eb62959216 | ||
|
|
70d5c4eca7 | ||
|
|
a025d365b8 | ||
|
|
89fa10b40b | ||
|
|
34e85ccb62 | ||
|
|
77a4218a9e | ||
|
|
93bcdf5318 | ||
|
|
d8ee487c19 | ||
|
|
bac303273f | ||
|
|
3605bf1f60 | ||
|
|
7c2e5f3ac8 | ||
|
|
d3b43bfa37 | ||
|
|
bf6079797f | ||
|
|
6366f62f11 | ||
|
|
427c33dbd7 | ||
|
|
675cbb72a6 | ||
|
|
f846b1a88f | ||
|
|
4bfcd12897 | ||
|
|
d736232142 | ||
|
|
9cb02028ed | ||
|
|
0703441ee7 | ||
|
|
2c3128d9ba | ||
|
|
7837eed21b | ||
|
|
db092449f9 | ||
|
|
d321b446db | ||
|
|
78ce7a08c0 | ||
|
|
15adb73a13 | ||
|
|
f15cc6c4f6 | ||
|
|
61e6e5694c | ||
|
|
66bc0bb424 | ||
|
|
25589bacea | ||
|
|
d721d35a2d | ||
|
|
ba84fc2c77 | ||
|
|
0f7dbc7bc0 | ||
|
|
137dd351b8 | ||
|
|
ba38bfad9d | ||
|
|
be71e8afa2 | ||
|
|
076a061997 | ||
|
|
de416adadd | ||
|
|
1fda99ba82 | ||
|
|
9f5b58c8ab | ||
|
|
a5131515ec | ||
|
|
8c11d24454 | ||
|
|
924b6b663e | ||
|
|
688452d971 | ||
|
|
2f94e16359 | ||
|
|
fbf736f169 | ||
|
|
f0624581d1 | ||
|
|
cb23352a35 | ||
|
|
9fea06ad84 | ||
|
|
2beeb9a293 | ||
|
|
1e92ac3cf5 | ||
|
|
acaf91a2f7 | ||
|
|
41125a0a34 | ||
|
|
35ed095dbf | ||
|
|
ce31e26f58 | ||
|
|
2b640532f2 | ||
|
|
c717006c44 | ||
|
|
fd33d693c4 | ||
|
|
31ecb4dcf3 | ||
|
|
5a4e900a21 | ||
|
|
94ed5b3a53 | ||
|
|
2eaf211e9b | ||
|
|
ed9f5639a8 | ||
|
|
8e842b5893 | ||
|
|
1b378172b6 | ||
|
|
0dc911c091 | ||
|
|
2be11874e3 | ||
|
|
5ac744ff66 | ||
|
|
57d6ab091c | ||
|
|
f13668371e | ||
|
|
c9486863c3 | ||
|
|
e9e0277b7c | ||
|
|
b69f0356ec | ||
|
|
4d72fc225a | ||
|
|
9786e432f8 | ||
|
|
040d7ebb46 | ||
|
|
f9f2b8124d | ||
|
|
dd5d938aa3 | ||
|
|
7c82adcc84 | ||
|
|
bdb1966573 | ||
|
|
a1582c610e | ||
|
|
2f9f217c11 | ||
|
|
278f679bb1 | ||
|
|
96bc727fcb | ||
|
|
7d2809eb27 | ||
|
|
5062e65277 | ||
|
|
bd44880d5a | ||
|
|
ad2383bd4b | ||
|
|
5b5a01989c | ||
|
|
c17f7e8b37 | ||
|
|
9b8133f65f | ||
|
|
77c0236cae | ||
|
|
07c4262392 | ||
|
|
10a5421987 | ||
|
|
06beddcee6 | ||
|
|
48f0e1f51d | ||
|
|
6701b7f1d0 | ||
|
|
9063953ee7 | ||
|
|
7315d9c300 | ||
|
|
05c248f297 | ||
|
|
b92a58d11e | ||
|
|
767d253593 | ||
|
|
046a8f443d | ||
|
|
78e59191ed | ||
|
|
958b3a1dc0 | ||
|
|
de4d872b7a | ||
|
|
921b34eafd | ||
|
|
77955c74bc | ||
|
|
555cd59a59 | ||
|
|
b4f8dc7abf | ||
|
|
14dde47173 | ||
|
|
4fb6bf3e67 | ||
|
|
f73c55a922 | ||
|
|
49c86768e6 | ||
|
|
0fca91c6c1 | ||
|
|
749b4adc7c | ||
|
|
a67e4ab9f1 | ||
|
|
e0b2a26805 | ||
|
|
6c5b23b317 | ||
|
|
8da2a724fb | ||
|
|
d5363d1a85 | ||
|
|
8f74ee1d96 | ||
|
|
796ee8e3de | ||
|
|
25f611d0ec | ||
|
|
08e518af73 | ||
|
|
5f4fe9fccb | ||
|
|
db9885e1fc | ||
|
|
27673c1c3f | ||
|
|
3394129894 | ||
|
|
57625e06ed | ||
|
|
bdfb5fa2bc | ||
|
|
b2c9179100 | ||
|
|
d7935192dd | ||
|
|
dd3e170e08 | ||
|
|
97d5325468 | ||
|
|
8433851652 | ||
|
|
f7b2b84ece | ||
|
|
8be67c1766 | ||
|
|
4d2e7ed404 | ||
|
|
e1018546ac | ||
|
|
44fcab1081 | ||
|
|
6dab1657b1 | ||
|
|
60ad21ae0d | ||
|
|
3974ddd8f7 | ||
|
|
8064e82774 | ||
|
|
e0af6ec567 | ||
|
|
0a96f3a249 | ||
|
|
40363f96a9 | ||
|
|
1c9577a1ac | ||
|
|
a7a30396be | ||
|
|
fee19390f5 | ||
|
|
ff6c9e329f | ||
|
|
f997384fca | ||
|
|
edbd3794e0 | ||
|
|
1f90b177a1 | ||
|
|
a064fcd8e5 | ||
|
|
457ad333b2 | ||
|
|
034e99562f | ||
|
|
b4d2f66d43 | ||
|
|
32fcf28e1f | ||
|
|
5fce652890 | ||
|
|
7728f69100 | ||
|
|
e78b8e4cf3 | ||
|
|
2c9c3f4b6e | ||
|
|
1e1aa76139 | ||
|
|
39b95903e3 | ||
|
|
1bce85d7b6 | ||
|
|
a5583de6e6 | ||
|
|
48e0466a2b | ||
|
|
1320898fbe | ||
|
|
90466d6cde | ||
|
|
3c6534dc91 | ||
|
|
889afd0cbd | ||
|
|
0141aadf3e | ||
|
|
0d6ad47051 | ||
|
|
95dcdf7ddc | ||
|
|
035b308d7c | ||
|
|
81a03285ec | ||
|
|
cb280b10c1 | ||
|
|
4f40e94c99 | ||
|
|
bb944466f2 | ||
|
|
2a97bd3848 | ||
|
|
e91f18946e | ||
|
|
6fd11db5a9 | ||
|
|
5185fa3a92 | ||
|
|
f26835e507 | ||
|
|
5423fa25d4 | ||
|
|
d17c8e235f | ||
|
|
754dea8d47 | ||
|
|
3fa2028eb2 | ||
|
|
d5c14755ce | ||
|
|
e86ff5daa1 | ||
|
|
bacf2605a4 | ||
|
|
382c9c68b8 | ||
|
|
bdd733bc0b | ||
|
|
05ac32064f | ||
|
|
bbe7457049 | ||
|
|
48ed44d117 | ||
|
|
0dbacedb58 | ||
|
|
493752e1c6 | ||
|
|
25fe66bafc | ||
|
|
496fea5995 | ||
|
|
810175ae95 | ||
|
|
45b07ff9ec | ||
|
|
469d5494ea | ||
|
|
e19e6c6b0a | ||
|
|
f6f4452231 | ||
|
|
a8cdd4f66d | ||
|
|
999701e384 | ||
|
|
4626992474 | ||
|
|
6066c254c8 | ||
|
|
f2dfde3ee1 | ||
|
|
2401b44bed | ||
|
|
3e5ec91977 | ||
|
|
108906cb20 | ||
|
|
880f354b90 | ||
|
|
0633ef1ba1 | ||
|
|
298ef4ac4d | ||
|
|
01c9baf8ca | ||
|
|
3c496b07f9 | ||
|
|
9f96d7ea38 | ||
|
|
d9905ec719 | ||
|
|
3a039fff66 | ||
|
|
c726377012 | ||
|
|
1601f6bbc9 | ||
|
|
b87eff2115 | ||
|
|
9c8204f945 | ||
|
|
289bc7deb3 | ||
|
|
f72b14ec36 | ||
|
|
f63867e958 | ||
|
|
fa05ded88e | ||
|
|
7bb4ff901e | ||
|
|
03516a14da | ||
|
|
0c67364e6c | ||
|
|
f00c09d9fc | ||
|
|
21a7b62c2b | ||
|
|
49c4a063c1 | ||
|
|
f8edc203e7 | ||
|
|
9a6a064307 | ||
|
|
22678b5cfa | ||
|
|
269008b311 | ||
|
|
0458d1910e | ||
|
|
98bdb9de68 | ||
|
|
aa4f347e7c | ||
|
|
0a0adaac6d | ||
|
|
124ea41d85 | ||
|
|
818130a8c0 | ||
|
|
41ff751cd2 | ||
|
|
a8cc9033b4 | ||
|
|
fdd012c420 | ||
|
|
3d2aae9ea5 | ||
|
|
3d5ff2b4cd | ||
|
|
d20f0d5014 | ||
|
|
b71ff4cb88 | ||
|
|
ca17adf7ec | ||
|
|
323164877c | ||
|
|
6dbbb7406c | ||
|
|
75bed5efcf | ||
|
|
45f00362db | ||
|
|
ded2a5c076 | ||
|
|
b6cb981a8b | ||
|
|
d0770cdb1a | ||
|
|
6464d1abc1 | ||
|
|
7d0d89faae | ||
|
|
9329aafe53 | ||
|
|
dc1276efa3 | ||
|
|
5707988155 | ||
|
|
382adcc93c | ||
|
|
656a6c5eb5 | ||
|
|
a8859b495b | ||
|
|
6700e44793 | ||
|
|
d6df73747f | ||
|
|
d8f265e8ac | ||
|
|
8db0094c73 | ||
|
|
d67d8c2ced | ||
|
|
4568c38597 | ||
|
|
e636669850 | ||
|
|
7149765892 | ||
|
|
c28c516b22 | ||
|
|
780a553662 | ||
|
|
c755a7ff9b | ||
|
|
8296d81edf | ||
|
|
0622e4fd44 | ||
|
|
3e8e2c2fee | ||
|
|
8296041f9e | ||
|
|
43a480f02d | ||
|
|
9154cbf8e1 | ||
|
|
66b55f91ba | ||
|
|
fe89c74e3b | ||
|
|
61e5359231 | ||
|
|
7373a26333 | ||
|
|
5ee94f8928 | ||
|
|
d4c4a03e42 | ||
|
|
caa4ed31de | ||
|
|
570bb2e139 | ||
|
|
b7c3b96516 | ||
|
|
0e7c8ce554 | ||
|
|
97feec6b5e | ||
|
|
9b80081122 | ||
|
|
ad8e9a76ed | ||
|
|
20f186d855 | ||
|
|
3af0c38315 | ||
|
|
6db0ceaf81 | ||
|
|
6f81d2e45d | ||
|
|
442ad4e445 | ||
|
|
9315d98aa9 | ||
|
|
19903674af | ||
|
|
434a63fa07 | ||
|
|
b44d68ea5d | ||
|
|
f424ae6942 | ||
|
|
333ba69d60 | ||
|
|
5b6cc3b036 | ||
|
|
8b8334af86 | ||
|
|
84c0ae1c6d | ||
|
|
caccee1d98 | ||
|
|
379110a8a2 | ||
|
|
8d37cd9169 | ||
|
|
b40ade5165 | ||
|
|
c475b23c7d | ||
|
|
d6b9cfcc34 | ||
|
|
0c05bd3def | ||
|
|
206cd3b529 | ||
|
|
8f7ab21423 | ||
|
|
07418cfb34 | ||
|
|
ac9816c01d | ||
|
|
bd3e4ac11c | ||
|
|
926d08db6f | ||
|
|
a23f6457dc | ||
|
|
4f9dba22c7 | ||
|
|
97e1a7db25 | ||
|
|
e03effd63b | ||
|
|
f9a65e4966 | ||
|
|
3c52fdfabe | ||
|
|
938b2fed7c | ||
|
|
d6875975ab | ||
|
|
92b2ca70b7 | ||
|
|
df6ac8f7f5 | ||
|
|
fa796a2eb5 | ||
|
|
c7b3153958 | ||
|
|
5bbb89753d | ||
|
|
654084d181 | ||
|
|
094f08211a | ||
|
|
74b0a7c633 | ||
|
|
8f09d3449d | ||
|
|
0c7a7903b6 | ||
|
|
6a8d24372e | ||
|
|
884dc11365 | ||
|
|
83830ef9c0 | ||
|
|
849e1ce5f4 | ||
|
|
4eb6020813 | ||
|
|
d655fdca56 | ||
|
|
b6df6748df | ||
|
|
269809dd1a | ||
|
|
65fdf1dc5e | ||
|
|
60002bf9bc | ||
|
|
dd94de2830 | ||
|
|
37bf76692d | ||
|
|
e1fc81f66f | ||
|
|
b2cf1e4c65 | ||
|
|
a65f692ab7 | ||
|
|
44e4a50050 | ||
|
|
ffbcb96eff | ||
|
|
eed1a891a7 | ||
|
|
9b787434c9 | ||
|
|
f4fe55caff | ||
|
|
8df88238cd | ||
|
|
ea0bd08660 | ||
|
|
c1f50ca7b3 | ||
|
|
a6f866b4d8 | ||
|
|
545b2fd6b1 | ||
|
|
b0a855a10e | ||
|
|
b5600e940a | ||
|
|
7f5d273e53 | ||
|
|
b0e6be93ff | ||
|
|
324c42ae09 | ||
|
|
acd03faee5 | ||
|
|
94af42da44 | ||
|
|
1e9624270d | ||
|
|
a50d67257c | ||
|
|
3759c553b0 | ||
|
|
332114c02a | ||
|
|
5d841c13b7 | ||
|
|
caecf78a6d | ||
|
|
408a62f7d0 | ||
|
|
b822d061ef | ||
|
|
020a112e77 | ||
|
|
8e33ae78f8 | ||
|
|
dbddc6b7f2 | ||
|
|
f32be2b28d | ||
|
|
0f05ebd834 | ||
|
|
26fc812e21 | ||
|
|
14db51e3e4 | ||
|
|
8f3bb286f2 | ||
|
|
258c93f8d8 | ||
|
|
88f885f2e7 | ||
|
|
91eee1a42d | ||
|
|
6a55f99ede | ||
|
|
0b457497d0 | ||
|
|
b7c9e33343 | ||
|
|
502d5689bf | ||
|
|
d015debe2b | ||
|
|
d8aab5a749 | ||
|
|
7ed2094a6a | ||
|
|
464410d8be | ||
|
|
aa0e17dd93 | ||
|
|
4e345b1c8a | ||
|
|
b2cb4df29a | ||
|
|
3d777f3f5d | ||
|
|
1842878c40 | ||
|
|
23f47adb60 | ||
|
|
377e3d479c | ||
|
|
d5193a776e | ||
|
|
ef51128270 | ||
|
|
9b15c88b0e | ||
|
|
f1c29ae20b | ||
|
|
6d2e3da306 | ||
|
|
7695ea2822 | ||
|
|
c729ceab20 | ||
|
|
e8643dd8cc | ||
|
|
7b69592fe1 | ||
|
|
12e11721f9 | ||
|
|
96c13f0d98 | ||
|
|
df728cd2cd | ||
|
|
0d7cad8d64 | ||
|
|
d69285f6ad | ||
|
|
b8e192e058 | ||
|
|
aeebfeab10 | ||
|
|
8aafebbb75 | ||
|
|
c3da2e1f03 | ||
|
|
c8c8003677 | ||
|
|
caab155a00 | ||
|
|
1b85b6eaba | ||
|
|
863add6a19 | ||
|
|
64b80e0573 | ||
|
|
ed902d9dea | ||
|
|
f38b373cb6 | ||
|
|
b8f2fdb6ac | ||
|
|
182f570f24 | ||
|
|
5b90ccf65d | ||
|
|
22a8e25538 | ||
|
|
d63aab6312 | ||
|
|
641ab8ddaf | ||
|
|
774dcad392 | ||
|
|
7b7b27ee9e | ||
|
|
c5adbc859a | ||
|
|
2cc12b2f2f | ||
|
|
13b33b5d4d | ||
|
|
c7dea3ed17 | ||
|
|
a7e6ecb5b3 | ||
|
|
5964710f73 | ||
|
|
262a61564c | ||
|
|
4cc4421c82 | ||
|
|
2786950c16 | ||
|
|
e45c1b238f | ||
|
|
d166e6a45e | ||
|
|
e759137f15 | ||
|
|
0bb570a36d | ||
|
|
38c6083a2f | ||
|
|
cfdf0d2f0a | ||
|
|
f0dc2bc425 | ||
|
|
b783e353c4 | ||
|
|
32ec3fe089 | ||
|
|
9e69bd5c56 | ||
|
|
ceeb36039e | ||
|
|
2bfae2f0ac | ||
|
|
b25f322c93 | ||
|
|
f77ecba896 | ||
|
|
5d2d88209f | ||
|
|
ecf1a3c69c | ||
|
|
3f0eacf5e7 | ||
|
|
d49f9ea109 | ||
|
|
2ec40cb6f1 | ||
|
|
3e342e4b71 | ||
|
|
147fee0272 | ||
|
|
fa900de548 | ||
|
|
1883b40083 | ||
|
|
8cd44c637d | ||
|
|
729caaacff | ||
|
|
2f5d721ec1 | ||
|
|
c15394c42a | ||
|
|
36a62f110c | ||
|
|
2d02b46253 | ||
|
|
6cf75f0fc2 | ||
|
|
1a3e2e3f36 | ||
|
|
645e32b19e | ||
|
|
fa0a61b5d7 | ||
|
|
2336fe2708 | ||
|
|
0cbd81146f | ||
|
|
a268c1a7ad | ||
|
|
3b7107b255 | ||
|
|
a2ea89c64e | ||
|
|
b44cb1a64c | ||
|
|
1dc3acb071 | ||
|
|
0cf58cc505 | ||
|
|
eb49e1bf47 | ||
|
|
0627d3487b | ||
|
|
5063839ce5 | ||
|
|
84161b86c7 | ||
|
|
110bbf3956 | ||
|
|
fad9998f9d | ||
|
|
b38a96ae82 | ||
|
|
e82d774d32 | ||
|
|
8d1b169f5a | ||
|
|
70ccdabf7c | ||
|
|
af36942e1f | ||
|
|
b1b98fa3b0 | ||
|
|
bb251063fc | ||
|
|
663742e0d1 | ||
|
|
16c89aee04 | ||
|
|
abe735102a | ||
|
|
70a37811bd | ||
|
|
edab96e973 | ||
|
|
e7a50e2a5a | ||
|
|
e18ba24670 | ||
|
|
f41fc87a33 | ||
|
|
5ec3534fea | ||
|
|
6bd39a316e | ||
|
|
8434203e71 | ||
|
|
59431c513a | ||
|
|
edc1bc35fd | ||
|
|
18ccdf8bd4 | ||
|
|
a0dcc4da8c | ||
|
|
2b91e62d5d | ||
|
|
bc5a25168a | ||
|
|
f453c58389 | ||
|
|
ad74606ab3 | ||
|
|
bb15295935 | ||
|
|
f0c1fbb098 | ||
|
|
692f224e1c | ||
|
|
5bd9cd2ee8 | ||
|
|
70fc091e74 | ||
|
|
1d09c54fdc | ||
|
|
c7ebe7205c | ||
|
|
1b6c707abb | ||
|
|
a0010effbc | ||
|
|
c094772bc0 | ||
|
|
7ce871f3b2 | ||
|
|
77b3ad5de1 | ||
|
|
a75a0c0b84 | ||
|
|
072fc53019 | ||
|
|
5bad2db667 | ||
|
|
7c2478480d | ||
|
|
761f218c0a | ||
|
|
163e8eb8fc | ||
|
|
6fccd07479 | ||
|
|
c86a40a361 | ||
|
|
362726de4a | ||
|
|
5962a4817a | ||
|
|
2e05471d72 | ||
|
|
94f13fb606 | ||
|
|
d998c6461e | ||
|
|
7edf783102 | ||
|
|
efc2159441 | ||
|
|
3078c6da12 | ||
|
|
de6f678de7 | ||
|
|
d8d51e8103 | ||
|
|
361f1da5b8 | ||
|
|
30e068ae17 | ||
|
|
3b751cc6e6 | ||
|
|
6d60f19d73 | ||
|
|
94235d4b4f | ||
|
|
367c3a5bfc | ||
|
|
f3b172b0c9 | ||
|
|
023715474c | ||
|
|
f5873bcad0 | ||
|
|
9f27801b8d | ||
|
|
9eb0c2964c | ||
|
|
73d64bbafc | ||
|
|
ea67a2d051 | ||
|
|
1e7588d0ab | ||
|
|
b6b3548c0c | ||
|
|
097a8ce640 | ||
|
|
6374aad9bc | ||
|
|
fed3f7b74b | ||
|
|
c079d9ae38 | ||
|
|
6a093b1b44 | ||
|
|
4dc573f195 | ||
|
|
b7f07aed00 | ||
|
|
cb791482a0 | ||
|
|
95eaf254c9 | ||
|
|
bd7eb94d69 | ||
|
|
223389a464 | ||
|
|
575f124fb8 | ||
|
|
483f768370 | ||
|
|
ab20ca95aa | ||
|
|
bf775036bc | ||
|
|
08bfd302fe | ||
|
|
3b6ea02920 | ||
|
|
26bfeb1319 | ||
|
|
72659d431e | ||
|
|
53dabe68ef | ||
|
|
ccd6b46995 | ||
|
|
91b3227a0f | ||
|
|
adebba94dc | ||
|
|
9d3b3f7a01 | ||
|
|
b354360bc0 | ||
|
|
8c24f7eb03 | ||
|
|
f473eade5a | ||
|
|
dc74a44b70 | ||
|
|
f96ac3db67 | ||
|
|
b11b9939f4 | ||
|
|
e595fd5e02 | ||
|
|
af52276cd9 | ||
|
|
2eec47415e | ||
|
|
4a2af70c2c | ||
|
|
6211065802 | ||
|
|
a338d9efe0 | ||
|
|
e2ef423624 | ||
|
|
0f8206e269 | ||
|
|
4ccc3751d6 | ||
|
|
7ef6e58024 | ||
|
|
57689c4e66 | ||
|
|
2fc8d70655 | ||
|
|
7ee9f8513c | ||
|
|
1a843fb4f6 | ||
|
|
9111ad1a9d | ||
|
|
a5a9242f4e | ||
|
|
3fcf4ae8b7 | ||
|
|
c3d34aaf4d | ||
|
|
e4f585b7fe | ||
|
|
874b685a83 | ||
|
|
e3ac1001be | ||
|
|
67f2a5d9d6 | ||
|
|
89b9fa0b35 | ||
|
|
4c0de726c8 | ||
|
|
7d96075e14 | ||
|
|
924a8cdd4b | ||
|
|
b27d078c67 | ||
|
|
c64ec9cfb9 | ||
|
|
3d6e76046c | ||
|
|
48d6a4ab6a | ||
|
|
f535304e1b | ||
|
|
2f485672fa | ||
|
|
63d438c979 | ||
|
|
ea5fe35b54 | ||
|
|
c955c03197 | ||
|
|
ceff6bc271 | ||
|
|
80a5f5878f | ||
|
|
1e6111c09c | ||
|
|
d468deee12 | ||
|
|
e7eb3aa63d | ||
|
|
749f31f69d | ||
|
|
2d6af1da1d | ||
|
|
6ec5fa9cae | ||
|
|
72832c0fa2 | ||
|
|
7d329570f4 | ||
|
|
c334093223 | ||
|
|
27274c9620 | ||
|
|
cd5e36045c | ||
|
|
3ed1382bbe | ||
|
|
0062a260b9 | ||
|
|
fdd2ea8feb | ||
|
|
fbc1768784 | ||
|
|
c53b9f3713 | ||
|
|
b3749e4d95 | ||
|
|
eb709f415b | ||
|
|
9dd08e4dab | ||
|
|
e1cd1e9e32 | ||
|
|
f875603525 | ||
|
|
e95ab65396 | ||
|
|
e0907ede4f | ||
|
|
17020ffc54 | ||
|
|
237b5e704f | ||
|
|
abd05a6378 | ||
|
|
189592938a | ||
|
|
4f34724c5a | ||
|
|
e958f72ba9 | ||
|
|
0fcd3da046 | ||
|
|
5c5b121b62 | ||
|
|
d21171b21e | ||
|
|
aead038215 | ||
|
|
a16c07c78a | ||
|
|
9930b12d9d | ||
|
|
3aebabce3d | ||
|
|
7239bcf0b7 | ||
|
|
623faa1550 | ||
|
|
60fad25476 | ||
|
|
d06e07ef0e | ||
|
|
ca800f9e8d | ||
|
|
4225b78bf5 | ||
|
|
8c68eff460 | ||
|
|
c2814308f1 | ||
|
|
f237187b0d | ||
|
|
187b4caf3c | ||
|
|
b8526f7894 | ||
|
|
b2b0377717 | ||
|
|
24ea1ab035 | ||
|
|
e980e69eca | ||
|
|
2904add428 | ||
|
|
babaac9305 | ||
|
|
9cdc06ce43 | ||
|
|
454d2f8c45 | ||
|
|
5d42d52660 | ||
|
|
a0e87c7aee | ||
|
|
49c4ec6f93 | ||
|
|
eb0ece417d | ||
|
|
7b5bf7f129 | ||
|
|
ab8ffc1a00 | ||
|
|
64c8335e22 | ||
|
|
4cfffdf76f | ||
|
|
8adc4c1e3c | ||
|
|
02c118981f | ||
|
|
4825cefbf8 | ||
|
|
4b91a18532 | ||
|
|
ff2453e42c | ||
|
|
269ad321e6 | ||
|
|
7382a0c142 | ||
|
|
8be4e7e65f | ||
|
|
c25184cc88 | ||
|
|
360e3fb81e | ||
|
|
06823349f9 | ||
|
|
d11510c34c | ||
|
|
e18c6f63cc | ||
|
|
36a864106d | ||
|
|
3028ffd083 | ||
|
|
a3d5a97df6 | ||
|
|
52879d964e | ||
|
|
aaf209485c | ||
|
|
4515ac0bca | ||
|
|
d7def5509d | ||
|
|
df26c08a34 | ||
|
|
4ff845ac91 | ||
|
|
e9d147f4b8 | ||
|
|
f1a1ef49d5 | ||
|
|
fd03c3297c | ||
|
|
ffd2e884f2 | ||
|
|
0d700d9833 | ||
|
|
dd902292ed | ||
|
|
1b4e0f5f48 | ||
|
|
31d352b3aa | ||
|
|
c26b8124e5 | ||
|
|
6bf7de2415 | ||
|
|
18c51f4e4a | ||
|
|
adf4860988 | ||
|
|
0dd6b95ac2 | ||
|
|
41a840e776 | ||
|
|
7d75041fb1 | ||
|
|
6675ee7f5c | ||
|
|
845c9f8a51 | ||
|
|
155fcdbcd0 | ||
|
|
52f298f150 | ||
|
|
860ab3523c | ||
|
|
36ac3bc672 | ||
|
|
fc9ab12bf9 | ||
|
|
b39c1eb92c | ||
|
|
6994423a49 | ||
|
|
172e967a73 | ||
|
|
6f5d8bba2d | ||
|
|
67b18e4bea | ||
|
|
9ad5644a8c | ||
|
|
e932ba591f | ||
|
|
f58399d2f3 | ||
|
|
730cd5d513 | ||
|
|
e838b30def | ||
|
|
dddcc09378 | ||
|
|
5adb68bba4 | ||
|
|
d6ef66646f | ||
|
|
cf1638e6de | ||
|
|
64ebd64d2b | ||
|
|
92799187ed | ||
|
|
2f3834359e | ||
|
|
399c43cae6 | ||
|
|
80acbe6f6b | ||
|
|
d90ba775e8 | ||
|
|
ea4161d880 | ||
|
|
172a060330 | ||
|
|
231efb5aa5 | ||
|
|
079475e491 | ||
|
|
aa775b4d3d | ||
|
|
216c8125e2 | ||
|
|
c61d0c663e | ||
|
|
0187c6a5a1 | ||
|
|
8289d4140a | ||
|
|
c7118a183a | ||
|
|
b1881e798b | ||
|
|
d44230b745 | ||
|
|
7b417b9d51 | ||
|
|
cc05e5727d | ||
|
|
764a8f2644 | ||
|
|
a15785eb64 | ||
|
|
688f8c5f3f | ||
|
|
dde5ccf7fa | ||
|
|
d5a6313c71 | ||
|
|
f030aab759 | ||
|
|
4393f98a2c | ||
|
|
c377d6c94b | ||
|
|
16aa015682 | ||
|
|
9cded76cf0 | ||
|
|
4ad07bb6b2 | ||
|
|
d0b28a6700 | ||
|
|
18299c3f7a | ||
|
|
ca07a1230b | ||
|
|
e0ad66d967 | ||
|
|
5615c4a2a7 | ||
|
|
d7fbef6764 | ||
|
|
e95bda3bdf | ||
|
|
c010a85ef5 | ||
|
|
798d36efcf | ||
|
|
2d44c8568f | ||
|
|
7232bdb40c | ||
|
|
45f092488a | ||
|
|
4244e1070d | ||
|
|
5a7fa8cfa9 | ||
|
|
daf4f8fcde | ||
|
|
d182d1455e | ||
|
|
dc2260adbe | ||
|
|
83a01e0c7d | ||
|
|
53c1269ebd | ||
|
|
f8bfe3a550 | ||
|
|
90bb53af20 | ||
|
|
ef1604a729 | ||
|
|
c77a2f335a | ||
|
|
8e34a1f6a7 | ||
|
|
2564b62f5c | ||
|
|
a7598c5610 | ||
|
|
8377f2516b | ||
|
|
7efd0ab0d6 | ||
|
|
14d38a1a8d | ||
|
|
c8447c190c | ||
|
|
aa5d16b3d8 | ||
|
|
fd1135315c | ||
|
|
98c915b2ca | ||
|
|
9114f3d2e6 | ||
|
|
5b0109055d | ||
|
|
5a3168c9ff | ||
|
|
a14f29f84f | ||
|
|
6c1190a361 | ||
|
|
100a76f0e8 | ||
|
|
47482acf83 | ||
|
|
1185103a3d | ||
|
|
54ef4ee6ef | ||
|
|
2389abc295 | ||
|
|
67c666b033 | ||
|
|
5ce3ed3555 | ||
|
|
d30b32fcde | ||
|
|
568e4cebda | ||
|
|
29d644e9d3 | ||
|
|
2dbb7301fb | ||
|
|
d2cba1c54f | ||
|
|
6a0c26a709 | ||
|
|
e44ae6af93 | ||
|
|
837b0799ac | ||
|
|
bc85a8b24f | ||
|
|
15d68649d5 | ||
|
|
e0d96ae807 | ||
|
|
3aa39ced60 | ||
|
|
1f1c0618e1 | ||
|
|
7788aa25b5 | ||
|
|
d5b460a85c | ||
|
|
9019f3a4f2 | ||
|
|
006020aef2 | ||
|
|
dfda0d566a | ||
|
|
99c2fac143 | ||
|
|
4c5308da8d | ||
|
|
4d0ed3d857 | ||
|
|
0b5582ed0d | ||
|
|
17734f833c | ||
|
|
98a9d5d424 | ||
|
|
6d74f36449 | ||
|
|
22d08b70ec | ||
|
|
47a5bf6aa5 | ||
|
|
2805e9eb3b | ||
|
|
72a1a86886 | ||
|
|
ec190bae33 | ||
|
|
83003e43d7 | ||
|
|
3b20dc2994 | ||
|
|
a7198298e7 | ||
|
|
f3d76d5780 | ||
|
|
e2305c3c5e | ||
|
|
ba737d7e58 | ||
|
|
88f69204c8 | ||
|
|
bb4561c2b8 | ||
|
|
4710f764e4 | ||
|
|
11a59a767e | ||
|
|
4cf3157aad | ||
|
|
b1f6cb349b | ||
|
|
0c134582ca | ||
|
|
acf2833362 | ||
|
|
20f9971096 | ||
|
|
cefeaceef0 | ||
|
|
1ba7c4b6ee | ||
|
|
1b49776819 | ||
|
|
41c68f4bbc | ||
|
|
56ac830405 | ||
|
|
ebcf821d81 | ||
|
|
e874a2624f | ||
|
|
03d1c0ed21 | ||
|
|
1b8c77eee0 | ||
|
|
d575cd50b1 | ||
|
|
2b040569e7 | ||
|
|
7a53f86fff | ||
|
|
a90bb53cd2 | ||
|
|
b450d62138 | ||
|
|
ab77e36c70 | ||
|
|
1a9d65c52a | ||
|
|
05f4746bbe | ||
|
|
a2530de06a | ||
|
|
1c587723fa | ||
|
|
b2a9c79de5 | ||
|
|
64259c7bcb | ||
|
|
a7efdb4e52 | ||
|
|
091ff0cce0 | ||
|
|
7e25a3a942 | ||
|
|
b3254e2b18 | ||
|
|
9a0fa79144 | ||
|
|
352db260b2 | ||
|
|
f072b5b679 | ||
|
|
c7c7084423 | ||
|
|
b4058a813b | ||
|
|
b27e152ead | ||
|
|
936e83759d | ||
|
|
18fdc175c6 | ||
|
|
47c6ab0ced | ||
|
|
4868135d47 | ||
|
|
5e70db651d | ||
|
|
1fedede771 | ||
|
|
00596f1436 | ||
|
|
db840b5604 | ||
|
|
45070d0e51 | ||
|
|
30121de963 | ||
|
|
8a1081f9ef | ||
|
|
fbf9c86c5c | ||
|
|
ac84e44161 | ||
|
|
836dfb6503 | ||
|
|
35a8ce2349 | ||
|
|
bb7d68b3b9 | ||
|
|
1979846e5e | ||
|
|
a61ffab3f9 | ||
|
|
698fe73608 | ||
|
|
0083c32629 | ||
|
|
f313caaa73 | ||
|
|
6e3f07ddce | ||
|
|
11d28c4856 | ||
|
|
e9394ca85a | ||
|
|
9445a30e72 | ||
|
|
185b1a3d36 | ||
|
|
1c2f5d60a5 | ||
|
|
2f32910bef | ||
|
|
8de1b20bb5 | ||
|
|
60a7abcef6 | ||
|
|
e44e75fa6b | ||
|
|
ff7dc0b446 | ||
|
|
f813cb2310 | ||
|
|
cba19d7e23 | ||
|
|
233127393f | ||
|
|
9479c0e12d | ||
|
|
65c9c45ec6 | ||
|
|
6d79004d4f | ||
|
|
97623d20c5 | ||
|
|
d37802a42f | ||
|
|
4a47ba9b35 | ||
|
|
9b837a24aa | ||
|
|
d0ef2f7dd8 | ||
|
|
44932b170f | ||
|
|
c7cfd23580 | ||
|
|
9708a12607 | ||
|
|
7cf1ec3f89 | ||
|
|
92812fe723 | ||
|
|
79417ac59a | ||
|
|
984f66e083 | ||
|
|
ef2a436769 | ||
|
|
7f1a95550f | ||
|
|
803f5b5613 | ||
|
|
8ca9fa1c26 | ||
|
|
3b3b897193 | ||
|
|
6c364f63cc | ||
|
|
6b9e842ddd | ||
|
|
8f88d915ba | ||
|
|
eaa1f47f00 | ||
|
|
cbeae85731 | ||
|
|
84e618b3f2 | ||
|
|
382a16ff07 | ||
|
|
7bd339b645 | ||
|
|
70d8b2c4b7 | ||
|
|
3764a83c6b | ||
|
|
c3d200ddcd | ||
|
|
44c5e337ab | ||
|
|
040982e321 | ||
|
|
6c81ea846c | ||
|
|
d082a0696d | ||
|
|
f999839e59 | ||
|
|
f1bc662a24 | ||
|
|
232693419a | ||
|
|
ed66b951c6 | ||
|
|
70c2854f7c | ||
|
|
e9381ddeb2 | ||
|
|
1b46e003c3 | ||
|
|
4611d5a35f | ||
|
|
2e59378ab7 | ||
|
|
fc8bf39043 | ||
|
|
0675c2b374 | ||
|
|
2cccd8ab28 | ||
|
|
bc5fcbbc88 | ||
|
|
d537ceedd6 | ||
|
|
ac7243b309 | ||
|
|
607e983f37 | ||
|
|
02f7326b7e | ||
|
|
b688f69031 | ||
|
|
df41329df9 | ||
|
|
0825bd7076 | ||
|
|
e9b7003cf5 | ||
|
|
c5d673c426 | ||
|
|
9cc8eec773 | ||
|
|
0b45535061 | ||
|
|
9f64ad8d89 | ||
|
|
e5b0b7e9a7 | ||
|
|
9c3522cb70 | ||
|
|
b357390215 | ||
|
|
c66fc2f656 | ||
|
|
64554aca6d | ||
|
|
f1df9a02fa | ||
|
|
f3725bdd2e | ||
|
|
cb92b94d55 | ||
|
|
da21c77ae3 | ||
|
|
ef01f82e0c | ||
|
|
4ba7ee8c92 | ||
|
|
c59633a588 | ||
|
|
f56e37398c | ||
|
|
e43ffa6f2b | ||
|
|
6991bc9723 | ||
|
|
9d6106a80b | ||
|
|
9e70404411 | ||
|
|
bc48d299b6 | ||
|
|
a8db5650a5 | ||
|
|
91871b418b | ||
|
|
aaf98082e9 | ||
|
|
ac228deeda | ||
|
|
fc661c83ef | ||
|
|
a2acffdfa3 | ||
|
|
79ce4ed226 | ||
|
|
e3a7aa0033 | ||
|
|
95973ba3e8 | ||
|
|
49673c33b4 | ||
|
|
fde6303ae6 | ||
|
|
c489975015 | ||
|
|
b4a1948951 | ||
|
|
b927028416 | ||
|
|
fe5d1ff6c5 | ||
|
|
1308656000 | ||
|
|
ec1e6b9385 | ||
|
|
315a8b6b60 | ||
|
|
558c6b621b | ||
|
|
6d91d02c62 | ||
|
|
436ded68b7 | ||
|
|
3ec88b3665 | ||
|
|
2caedb38a6 | ||
|
|
9bbcbd546b | ||
|
|
49378ab7fe | ||
|
|
7aa6b6b21d | ||
|
|
982dc6aa8c | ||
|
|
33175187b7 | ||
|
|
0339904920 | ||
|
|
8bda9487c6 | ||
|
|
617d84c0ef | ||
|
|
ac64731d55 | ||
|
|
5dc064e971 | ||
|
|
c24732ed4e | ||
|
|
ba710bee86 | ||
|
|
c20392ca80 | ||
|
|
8eb05d0950 | ||
|
|
0a0795328f | ||
|
|
b11ad375cd | ||
|
|
df89999891 | ||
|
|
7a6d533014 | ||
|
|
be44f75d2d | ||
|
|
ab14123aed | ||
|
|
a963a6d10d | ||
|
|
11c472d701 | ||
|
|
69b4cd22a2 | ||
|
|
e81d35c4db | ||
|
|
958325653f | ||
|
|
c5dc419f9e | ||
|
|
2a201f9525 | ||
|
|
b7ba509618 | ||
|
|
f946d7b447 | ||
|
|
33c5f98824 | ||
|
|
e2a5535ed6 | ||
|
|
0f94e2c0c3 | ||
|
|
a25508b98d | ||
|
|
e825433a38 | ||
|
|
d1c08889fe | ||
|
|
0b82b5a0d6 | ||
|
|
a33d0d4fb6 | ||
|
|
ba42334d36 | ||
|
|
dad460dcfc | ||
|
|
2e62641aa4 | ||
|
|
3ae23b6a54 | ||
|
|
97126f18b1 | ||
|
|
3838d222c2 | ||
|
|
96c3292210 | ||
|
|
b0fd92cb3f | ||
|
|
b70cd27bda | ||
|
|
62c5b5e570 | ||
|
|
feaa0871ac | ||
|
|
9f41976926 | ||
|
|
1784f24c5f | ||
|
|
fc47d9fc4d | ||
|
|
eade9f8f2b | ||
|
|
6276c55cc9 | ||
|
|
afa6ff7c4b | ||
|
|
f4dcbe3a84 | ||
|
|
9c02cc1b17 | ||
|
|
70a27b900a | ||
|
|
0cc3ef8f90 | ||
|
|
4cbbacc946 | ||
|
|
18c63a75fb | ||
|
|
9a0c71d4a7 | ||
|
|
d9aec19c87 | ||
|
|
0f1b831de7 | ||
|
|
bff5212386 | ||
|
|
37a7a2aacd | ||
|
|
635b157b11 | ||
|
|
c3ae4da83a | ||
|
|
c3809ece67 | ||
|
|
bfc436dccd | ||
|
|
3c32d0fbc3 | ||
|
|
71d6874236 | ||
|
|
9bf1f994ae | ||
|
|
bb4127a6fb | ||
|
|
a691632995 | ||
|
|
5d6ea3d75f | ||
|
|
43873b1b2c | ||
|
|
9430f3665b | ||
|
|
f3c1f63444 | ||
|
|
b5c7232d6f | ||
|
|
2f3677d593 | ||
|
|
1e0efaffe8 | ||
|
|
fc79754750 | ||
|
|
0e4de42be8 | ||
|
|
4e389127b5 | ||
|
|
47593730d6 | ||
|
|
e742da73bd | ||
|
|
890bf3cce1 | ||
|
|
60eb312e3b | ||
|
|
06207da185 | ||
|
|
4dc2cf8a6b | ||
|
|
44450bf644 | ||
|
|
312aec79ca | ||
|
|
a8578c73f8 | ||
|
|
c522ffa6db | ||
|
|
93b7599b1c | ||
|
|
3ccbd7c9b2 | ||
|
|
385a87db31 | ||
|
|
5530353eef | ||
|
|
d1193093ef | ||
|
|
b203db27a4 | ||
|
|
0a3e1af04c | ||
|
|
c6c8e5d70c | ||
|
|
fa354ec8d9 | ||
|
|
4699b17508 | ||
|
|
d0375f697d | ||
|
|
33c8257d25 | ||
|
|
b8c716a918 | ||
|
|
f389bc33c3 | ||
|
|
4d5dca71ce | ||
|
|
a9c44a1b9c | ||
|
|
4144f800a1 | ||
|
|
6ef9a81017 | ||
|
|
8c6722f3c5 | ||
|
|
34f0f9dcf1 | ||
|
|
40e138627b | ||
|
|
a470dda4e6 | ||
|
|
b725410623 | ||
|
|
a9dfb33126 | ||
|
|
8b848770dc | ||
|
|
8d1cfaabe7 | ||
|
|
94629edb9b | ||
|
|
2a3f2ca28d | ||
|
|
8ab1e7d432 | ||
|
|
b2ba6a0c85 | ||
|
|
cca5421aed | ||
|
|
f78269b02d | ||
|
|
799d9a73e6 | ||
|
|
b0781622b2 | ||
|
|
0d0eec6345 | ||
|
|
1af79f7960 | ||
|
|
15b570bbdd | ||
|
|
7aa5599cc2 | ||
|
|
676293ec42 | ||
|
|
e8c07717fc | ||
|
|
abc4fb81b1 | ||
|
|
9ca6740db3 | ||
|
|
53a16f354f | ||
|
|
6ab1ecd836 | ||
|
|
e7b16e7b47 | ||
|
|
92c9ebb0d6 | ||
|
|
14804f81a8 | ||
|
|
8432b9e29a | ||
|
|
9a61b8d77d | ||
|
|
f42c2763d5 | ||
|
|
98d4e0e1b5 | ||
|
|
9156633baf | ||
|
|
bcf4f836b4 | ||
|
|
dbc1d70f99 | ||
|
|
78bc190a85 | ||
|
|
02855d7fed | ||
|
|
6fdd5d32be | ||
|
|
d7f32b105b | ||
|
|
0ac480a0bd | ||
|
|
417996de02 | ||
|
|
6c2d60cec2 | ||
|
|
743bd6c917 | ||
|
|
ab61aa41d9 | ||
|
|
36396ae29e | ||
|
|
749e083e6e | ||
|
|
faf91d6697 | ||
|
|
67b9cf9e82 | ||
|
|
adc69e72df | ||
|
|
27fb20f3ab | ||
|
|
1c71b274f0 | ||
|
|
fcd20b63fe | ||
|
|
8ec344ac1b | ||
|
|
df966a9ac6 | ||
|
|
f634666dc6 | ||
|
|
e2f9f5d7e5 | ||
|
|
d078b0d143 | ||
|
|
0ccdea3cd8 | ||
|
|
df54b47cd0 | ||
|
|
c8ae3d1751 | ||
|
|
2e595830b3 | ||
|
|
96fbcc9a5a | ||
|
|
6283801981 | ||
|
|
9a3214d46e | ||
|
|
79f9cc534d | ||
|
|
9eb7c8344f | ||
|
|
4140bbb1f7 | ||
|
|
ea44497136 | ||
|
|
5100eadf12 | ||
|
|
07737c6e5b | ||
|
|
1d6721d345 | ||
|
|
98d5eefc86 | ||
|
|
4f2d93bb65 | ||
|
|
a5df3f1747 | ||
|
|
7f5f73887d | ||
|
|
91ce7807b9 | ||
|
|
d26fae9875 | ||
|
|
60bdc79ec4 | ||
|
|
253ddf2998 | ||
|
|
9fa15b390a | ||
|
|
e7d6fe6c8b | ||
|
|
9650b1aa70 | ||
|
|
eafa6f960f | ||
|
|
c62ccf4870 | ||
|
|
ef34439a79 | ||
|
|
b328ec2462 | ||
|
|
60f27178b8 | ||
|
|
c01b4e6baa | ||
|
|
e3fbb83ad0 | ||
|
|
28b70a7b9a | ||
|
|
dcdc341d0f | ||
|
|
fce77c9372 | ||
|
|
a360c481c2 | ||
|
|
c72db5fa5f | ||
|
|
fc9a23d6d4 | ||
|
|
167f4666e2 | ||
|
|
1cbcc7be21 | ||
|
|
8053598069 | ||
|
|
7cfac1a91a | ||
|
|
192cdd028e | ||
|
|
029c143922 | ||
|
|
00298cc68c | ||
|
|
d9c7db51af | ||
|
|
f12b15d22b | ||
|
|
409b8bac00 | ||
|
|
28b09bde4b | ||
|
|
2f6af906f4 | ||
|
|
16021591b2 | ||
|
|
628e3ac1eb | ||
|
|
fbf5785e35 | ||
|
|
eeea2b1ff8 | ||
|
|
32062e439f | ||
|
|
930a0beaf1 | ||
|
|
4a49fefdd9 | ||
|
|
8e792855e0 | ||
|
|
69f5c6987a | ||
|
|
85fc9e4ecf | ||
|
|
d5c3f0c9cf | ||
|
|
a48120e675 | ||
|
|
36f8e4f2ad | ||
|
|
1084a39a45 | ||
|
|
86df482842 | ||
|
|
b0d47ebcc6 | ||
|
|
a237f9d28c | ||
|
|
fffdf1dfba | ||
|
|
f1eb9d4f89 | ||
|
|
3273ed2616 | ||
|
|
aa7b0a31b0 | ||
|
|
fb0d44d403 | ||
|
|
cd8ec89cbb | ||
|
|
1da5e090d5 | ||
|
|
252f271dc5 | ||
|
|
62d400c3a9 | ||
|
|
f9aa3e0da5 | ||
|
|
5cde522d5e | ||
|
|
685fe5b0fb | ||
|
|
8aa4a027bb | ||
|
|
5180e71a0d | ||
|
|
55637f7508 | ||
|
|
7d72dfe0be | ||
|
|
02529a0fc2 | ||
|
|
b44974677e | ||
|
|
d4fd5e4fce | ||
|
|
d9c49386cb | ||
|
|
30123eaa4a | ||
|
|
454ec97d51 | ||
|
|
cd98d1c1f9 | ||
|
|
c2ac331e78 | ||
|
|
756ac603db | ||
|
|
be4a35af11 | ||
|
|
445b29ad0d | ||
|
|
64d0f7fffd | ||
|
|
baf0d09455 | ||
|
|
933a98b97c | ||
|
|
08a81a0ab9 | ||
|
|
b14751aad9 | ||
|
|
31110c7fd9 | ||
|
|
0e1dd92d9b | ||
|
|
a3204a4df7 | ||
|
|
2288ab48b9 | ||
|
|
670401884c | ||
|
|
37181c341e | ||
|
|
be7e677448 | ||
|
|
b2eeb49a45 | ||
|
|
f3ebd508d6 | ||
|
|
9aa040d917 | ||
|
|
5d33ce352e | ||
|
|
c2043a223b | ||
|
|
f24e859f17 | ||
|
|
737b33f9d1 | ||
|
|
00791d2151 | ||
|
|
b141598f9b | ||
|
|
d1618d79b0 | ||
|
|
00c84dfe5c | ||
|
|
95f31b98a8 | ||
|
|
10d74ed100 | ||
|
|
8a7f612d5b | ||
|
|
c1e070c042 | ||
|
|
0829ee9234 | ||
|
|
ade26e2c86 | ||
|
|
b22e33444b | ||
|
|
d115a12cbe | ||
|
|
b7b744de94 | ||
|
|
b668b79341 | ||
|
|
68e46e406a | ||
|
|
a46ae4efec | ||
|
|
62777a794e | ||
|
|
329a969761 | ||
|
|
7bc26c5ea0 | ||
|
|
30170bc394 | ||
|
|
f193302e15 | ||
|
|
5ece1fa568 | ||
|
|
7c4870d641 | ||
|
|
98ea17f7fc | ||
|
|
8b84a76d5d | ||
|
|
8d25cc3c92 | ||
|
|
a4cd761372 | ||
|
|
63d2cfd6ba | ||
|
|
bb44bdd047 | ||
|
|
6904e66384 | ||
|
|
15c1055ff4 | ||
|
|
fbffe2367e | ||
|
|
e442a2846d | ||
|
|
f6985586ea | ||
|
|
2bae5b0959 | ||
|
|
c930151a95 | ||
|
|
1e58809fcc | ||
|
|
3d7c6f831c | ||
|
|
6b1d213cc2 | ||
|
|
ef57b3954c | ||
|
|
42bec13a83 | ||
|
|
4415a179b3 | ||
|
|
878070084e | ||
|
|
5d42604efd | ||
|
|
ef5adc507a | ||
|
|
b134b7d3f6 | ||
|
|
788219fe05 | ||
|
|
9a7f66cfe9 | ||
|
|
daa4d16e61 | ||
|
|
cf05f87795 | ||
|
|
c2f2f83b7c | ||
|
|
b30b2a523f | ||
|
|
150a3810a8 | ||
|
|
ac0eaa912b | ||
|
|
05a04aa801 | ||
|
|
ea7013a34d | ||
|
|
e37d4043f6 | ||
|
|
d073425b44 | ||
|
|
825b18cf71 | ||
|
|
549ad3204f | ||
|
|
35f9499b67 | ||
|
|
db82c35c17 | ||
|
|
73c74f753c | ||
|
|
a38fb2a5dc | ||
|
|
38e99e01f9 | ||
|
|
a1f46e84b8 | ||
|
|
6540804571 | ||
|
|
eb64a4387d | ||
|
|
ffe6707595 | ||
|
|
68fe1a7c8f | ||
|
|
9b21740c9f | ||
|
|
bd12e2ab95 | ||
|
|
bffb5ef8b4 | ||
|
|
e4c9822d78 | ||
|
|
73187d8832 | ||
|
|
8101154d5e | ||
|
|
c02937fd6f | ||
|
|
3430be4075 | ||
|
|
320897bad6 | ||
|
|
3f2b6f771f | ||
|
|
6e39b49cc2 | ||
|
|
71c34ed4e0 | ||
|
|
477178675c | ||
|
|
dbdf68b248 | ||
|
|
2fd139b307 | ||
|
|
0b692080cd | ||
|
|
a6c2657062 | ||
|
|
eaa021c2e2 | ||
|
|
78a0bc0e2c | ||
|
|
d352a744a5 | ||
|
|
d7116d6867 | ||
|
|
edc15b9fa2 | ||
|
|
93d4b73b2f | ||
|
|
8e3849e591 | ||
|
|
14b439ce43 | ||
|
|
acaa1098f7 | ||
|
|
9e4c4ad8e5 | ||
|
|
c1a5e88752 | ||
|
|
74b99014d2 | ||
|
|
9cba944d21 | ||
|
|
8c1c2f5d05 | ||
|
|
bf0fa8c562 | ||
|
|
3e1fc9ba6c | ||
|
|
f5941041d4 | ||
|
|
4ceba603e4 | ||
|
|
6591c21ace | ||
|
|
e8d03c7b9b | ||
|
|
6fbce4c2f7 | ||
|
|
c168d54495 | ||
|
|
9ab4f7bcc6 | ||
|
|
2cce22052b | ||
|
|
4e19d5f625 | ||
|
|
5b667da526 | ||
|
|
f9fc9a3518 | ||
|
|
186ca9c235 | ||
|
|
e005cfd70e | ||
|
|
feb997481c | ||
|
|
2c8e90c9d8 | ||
|
|
fefdb32d08 | ||
|
|
ec96d5afa0 | ||
|
|
8be8853c33 | ||
|
|
c228f5a244 | ||
|
|
d4c8b4e3ac | ||
|
|
6564f6c164 | ||
|
|
1e37a5509c | ||
|
|
1e9503deaa | ||
|
|
ab1f36c565 | ||
|
|
5a212cd626 | ||
|
|
856fd9d69f | ||
|
|
4606d99951 | ||
|
|
dbd75169e5 | ||
|
|
3cd391daa6 | ||
|
|
f5b39ee911 | ||
|
|
88cb0a1f7a | ||
|
|
db5d52b4b2 | ||
|
|
dfeb9967b8 | ||
|
|
673e860c18 | ||
|
|
9deae34b20 | ||
|
|
ec92344fb4 | ||
|
|
44c68d6174 | ||
|
|
f0f082d3e3 | ||
|
|
5b7f172d03 | ||
|
|
65125eac87 | ||
|
|
761902864a | ||
|
|
4a8555b3bf | ||
|
|
af24d541d1 | ||
|
|
9d33e4bd7b | ||
|
|
3ad68a617e | ||
|
|
9e1a6589d4 | ||
|
|
da8ceed07e | ||
|
|
35935adc98 | ||
|
|
75c8d7aa57 | ||
|
|
5b4a501f68 | ||
|
|
5425a90f16 | ||
|
|
f034b02b92 | ||
|
|
7eaca149c1 | ||
|
|
4b5fd95657 | ||
|
|
96dedf553e | ||
|
|
23219f2662 | ||
|
|
af78ed608e | ||
|
|
51dc59e019 | ||
|
|
afc102e90a | ||
|
|
fc560179e0 | ||
|
|
d26241de0e | ||
|
|
96a3a34fa4 | ||
|
|
00310f4f10 | ||
|
|
e965b7c0da | ||
|
|
8caae219cf | ||
|
|
2264ae9247 | ||
|
|
29225bbe75 | ||
|
|
4b5625fd59 | ||
|
|
7c0c2419f7 | ||
|
|
5f59282ba1 | ||
|
|
7847ac3144 | ||
|
|
db03ce939c | ||
|
|
6708311a66 | ||
|
|
68bcbbb701 | ||
|
|
8bdf7b3983 | ||
|
|
4ab427d315 | ||
|
|
9a0a434dd8 | ||
|
|
33d1dda954 | ||
|
|
8e9efb4ceb | ||
|
|
8835af11d5 | ||
|
|
cfb6b678f1 | ||
|
|
365500da98 | ||
|
|
f14d75e798 | ||
|
|
0f71b4a378 | ||
|
|
b651e0146d | ||
|
|
a0dbbb2d84 | ||
|
|
a85fbf69e0 | ||
|
|
92b8c7961b | ||
|
|
225f8ac12f | ||
|
|
1161511207 | ||
|
|
ca8eda412e | ||
|
|
ec4ec48fb8 | ||
|
|
af7f0b5074 | ||
|
|
c0b69e8ef7 | ||
|
|
4241dbb600 | ||
|
|
f54280aaad | ||
|
|
6069400538 | ||
|
|
78dfb6bcf5 | ||
|
|
616be1d76c | ||
|
|
8e91ce67c5 | ||
|
|
c1ecd661c3 | ||
|
|
b27e2aad07 | ||
|
|
5ce508e09d | ||
|
|
3cfa5a41b1 | ||
|
|
6c072f37ef | ||
|
|
4640079f55 | ||
|
|
dbd993ed2b | ||
|
|
60330da25c | ||
|
|
45b5c4ba7a | ||
|
|
7933e5d1f9 | ||
|
|
01e52e6f9f | ||
|
|
40a955e192 | ||
|
|
a8296f7301 | ||
|
|
590c3b876b | ||
|
|
6dfc805eaa | ||
|
|
cd97b5beec | ||
|
|
5ce6068df5 | ||
|
|
bf9b8f4d1b | ||
|
|
d618581060 | ||
|
|
2936bbfae8 | ||
|
|
47b08bfc02 | ||
|
|
da4f77ca1f | ||
|
|
1c0a75d467 | ||
|
|
659cf0c221 | ||
|
|
430229fd84 | ||
|
|
81699a0971 | ||
|
|
c54aff74b3 | ||
|
|
7f43ab9097 | ||
|
|
d78f740250 | ||
|
|
cd1bd18a49 | ||
|
|
f81b084448 | ||
|
|
02d9c77402 | ||
|
|
a0c903c68c | ||
|
|
6aa325d3da | ||
|
|
041f874d4c | ||
|
|
526ecd6a81 | ||
|
|
30eb927ad4 | ||
|
|
d373054fc4 | ||
|
|
b6d9f1d4b2 | ||
|
|
3fef916972 | ||
|
|
89a51e5b91 | ||
|
|
f87a6ccc7a | ||
|
|
f65cea66ef | ||
|
|
4239880acb | ||
|
|
579b1e6f79 | ||
|
|
1dcd06a1c1 | ||
|
|
0f30191d10 | ||
|
|
8fb9d5daaa | ||
|
|
ed3c942ff1 | ||
|
|
80436d4a8b | ||
|
|
b5384cc964 | ||
|
|
cfc702c766 | ||
|
|
146d706343 | ||
|
|
88ae15ea8e | ||
|
|
b69ecfe75c | ||
|
|
6bafca7386 | ||
|
|
379e842080 | ||
|
|
c41ce469d0 | ||
|
|
a1ca68473d | ||
|
|
3345d03433 | ||
|
|
81a426608a | ||
|
|
2ad6f0a65e | ||
|
|
ee8bd8ddae | ||
|
|
319ac14e7d | ||
|
|
0215a7400d | ||
|
|
02d834e9bb | ||
|
|
79db0ca7a6 | ||
|
|
1a7eafb699 | ||
|
|
81a06ea6cd | ||
|
|
e4ecc762c6 | ||
|
|
de4be649ab | ||
|
|
4f515adafe | ||
|
|
d90ec5f06c | ||
|
|
32065ced6e | ||
|
|
b5224a2227 | ||
|
|
c55777738f | ||
|
|
c72dff5a24 | ||
|
|
6b09e49c08 | ||
|
|
413218c4c4 | ||
|
|
16c04b50ee | ||
|
|
56c18f7768 | ||
|
|
22ca13bc78 | ||
|
|
4c7fd18230 | ||
|
|
39730fc13e | ||
|
|
889c0a0d0f | ||
|
|
4f0a20ec68 | ||
|
|
624a803955 | ||
|
|
9f5c21f80e | ||
|
|
a3fe089367 | ||
|
|
85d5cd3118 | ||
|
|
61006e626d | ||
|
|
15aad1cb24 | ||
|
|
95c1c5f54e | ||
|
|
b12676f701 | ||
|
|
c65fb91878 | ||
|
|
d5a7e1331e | ||
|
|
b968821cc1 | ||
|
|
04bcd93ba3 | ||
|
|
f97ef7039a | ||
|
|
9160b46c1e | ||
|
|
aa4b116498 | ||
|
|
d81154bf6c | ||
|
|
612bb71165 | ||
|
|
5c67f99ef9 | ||
|
|
101a4808a0 | ||
|
|
1d38671f5e | ||
|
|
7f25d88f02 | ||
|
|
be830d3dad | ||
|
|
5bc949d70f | ||
|
|
43817bd722 | ||
|
|
61623d6d75 | ||
|
|
9aad60f56d | ||
|
|
e7cf3e8084 | ||
|
|
c7c9a725b8 | ||
|
|
e024e7c2ec | ||
|
|
6fc136ae9a | ||
|
|
2b69ded1ea | ||
|
|
8dd799aa6f | ||
|
|
83add658f9 | ||
|
|
7230ef41ee | ||
|
|
a86f0a743c | ||
|
|
af75b55ef7 | ||
|
|
9ecb37dd4f | ||
|
|
cb0e91c602 | ||
|
|
2e3784a914 | ||
|
|
019c1af435 | ||
|
|
97d87dff09 | ||
|
|
5322955f2b | ||
|
|
fe9d77734f | ||
|
|
a8ea4ce283 | ||
|
|
c12862f60d | ||
|
|
e889183fc5 | ||
|
|
7be695c6bd | ||
|
|
956901ae02 | ||
|
|
d562c5b2d5 | ||
|
|
d7b054c3f6 | ||
|
|
901ccad0cf | ||
|
|
8368798ad2 | ||
|
|
af7cd3cc04 | ||
|
|
9552551f9a | ||
|
|
1c73a0f649 | ||
|
|
e3698b2a07 | ||
|
|
8b59a2f6b6 | ||
|
|
c841f8b360 | ||
|
|
0857c6350d | ||
|
|
50f9b68d61 | ||
|
|
27b48bc16e | ||
|
|
bccdbaed2b | ||
|
|
398095a667 | ||
|
|
80095824b9 | ||
|
|
d91c1f96cc | ||
|
|
1c005a0292 | ||
|
|
c7ced496ac | ||
|
|
d4ff18834c | ||
|
|
f86d9fd626 | ||
|
|
854604f724 | ||
|
|
bf403a6142 | ||
|
|
5b8bb822ba | ||
|
|
df32f27762 | ||
|
|
ee570a49d0 | ||
|
|
6a1071ccd3 | ||
|
|
11d667c830 | ||
|
|
cc11b498cc | ||
|
|
ca71f18a6d | ||
|
|
6b79b5fc74 | ||
|
|
df24ae0fbb | ||
|
|
b74cdb2f9d | ||
|
|
bb730c00e9 | ||
|
|
7a92ac91d0 | ||
|
|
e68b989af5 | ||
|
|
fd27bcd7ee | ||
|
|
f5eb22253d | ||
|
|
0c5c901222 | ||
|
|
0a93f8db22 | ||
|
|
875f4c87ff | ||
|
|
7b4c705a3f | ||
|
|
b11e857148 | ||
|
|
0568a40d8d | ||
|
|
94dea7c06f | ||
|
|
8cd2ba48fc | ||
|
|
9d819b95bf | ||
|
|
d26dadd9d8 | ||
|
|
55ca9fb090 | ||
|
|
58ec5d5afe | ||
|
|
c00a976ff6 | ||
|
|
97a1af43ed | ||
|
|
558b914c64 | ||
|
|
dda5fd7390 | ||
|
|
ce8f56727e | ||
|
|
d9755d33d0 | ||
|
|
48d4fccc22 | ||
|
|
bfa8dec6f6 | ||
|
|
6e8230e1fb | ||
|
|
587a379b43 | ||
|
|
93021a054b | ||
|
|
bf4dd0cbde | ||
|
|
4ccc380a7b | ||
|
|
9efac86bb7 | ||
|
|
8be17cd60d | ||
|
|
caf5f7579e | ||
|
|
191f4496a7 | ||
|
|
df3f5e442d | ||
|
|
fdfcebd1cb | ||
|
|
8f5b4a6c96 | ||
|
|
a45b532664 | ||
|
|
c0dfbdc910 | ||
|
|
a4ef993282 | ||
|
|
6b0cec1189 | ||
|
|
4a3176e3a0 | ||
|
|
fd9206584f | ||
|
|
2ab7cfbf30 | ||
|
|
6b467e7e59 | ||
|
|
d64f5a387c | ||
|
|
cc6cd0bb8f | ||
|
|
3fbff6e620 | ||
|
|
5eb0aa2765 | ||
|
|
f63cf33118 | ||
|
|
0bb6171a85 | ||
|
|
e92dd73169 | ||
|
|
2d490f6e6a | ||
|
|
761affacc3 | ||
|
|
979c834ee0 | ||
|
|
aff0ec18b0 | ||
|
|
d32b91e0de | ||
|
|
8b659a6d32 | ||
|
|
18486169b3 | ||
|
|
d580e7c694 | ||
|
|
78ec5ccdbc | ||
|
|
d4a5c0353d | ||
|
|
6546c30e17 | ||
|
|
5478c540cb | ||
|
|
b5d81f4f92 | ||
|
|
2a99a8350f | ||
|
|
028935a254 | ||
|
|
6df466c692 | ||
|
|
956f2b98b8 | ||
|
|
4e3dcd1ce6 | ||
|
|
a690690b53 | ||
|
|
b9d0bf8822 | ||
|
|
bb02112752 | ||
|
|
8eddcfd3d5 | ||
|
|
78e1995365 | ||
|
|
c48b9244f2 | ||
|
|
e219008320 | ||
|
|
f603ae175b | ||
|
|
f62d034692 | ||
|
|
deb180cc83 | ||
|
|
17b970a387 | ||
|
|
d060eb498f | ||
|
|
c2bc7e2c30 | ||
|
|
eb5691e8fa | ||
|
|
864b20565b | ||
|
|
3e6818b407 | ||
|
|
aaced060bf | ||
|
|
af77ff3eed | ||
|
|
98162cec33 | ||
|
|
048a2d7bc3 | ||
|
|
307ad244b0 | ||
|
|
0c0fa877cf | ||
|
|
49bd8ac880 | ||
|
|
969ea98fd9 | ||
|
|
bd0f4b95ae | ||
|
|
dda419ddd6 | ||
|
|
1f9e2c920c | ||
|
|
43f38a240e | ||
|
|
705e629001 | ||
|
|
edc60e2e01 | ||
|
|
9f65b26288 | ||
|
|
496b337b27 | ||
|
|
3a895ccfaa | ||
|
|
eb19343f91 | ||
|
|
893b2d4587 | ||
|
|
370d98a858 | ||
|
|
d11983ae32 | ||
|
|
42692abd1c | ||
|
|
d1335a6efd | ||
|
|
61cfa6e37e | ||
|
|
f7aa4f9593 | ||
|
|
1dfd9e3c10 | ||
|
|
2f656e09c6 | ||
|
|
6c9d88bd6d | ||
|
|
045e38314a | ||
|
|
d346e6645a | ||
|
|
760f51910f | ||
|
|
9e5619ce99 | ||
|
|
b38dd98e71 | ||
|
|
71db1dfa06 | ||
|
|
08aa415c66 | ||
|
|
bf87614fa6 | ||
|
|
55045b5fe9 | ||
|
|
56c5c2ebaa | ||
|
|
a2c574fa15 | ||
|
|
b560f5a474 | ||
|
|
206169476f | ||
|
|
30648a1819 | ||
|
|
00575cf847 | ||
|
|
ef94f42b62 | ||
|
|
4ed36da458 | ||
|
|
68b5966fef | ||
|
|
7bae496257 | ||
|
|
dc591f8943 | ||
|
|
31089931d3 | ||
|
|
55dd5b5547 | ||
|
|
1f97a239dc | ||
|
|
8604e216eb | ||
|
|
f4120635e9 | ||
|
|
e8f1dd8421 | ||
|
|
2ec6050959 | ||
|
|
29c38ef0d4 | ||
|
|
74d616ac78 | ||
|
|
504a892887 | ||
|
|
30cf0f8d3a | ||
|
|
d794d7d30b | ||
|
|
b112b333bd | ||
|
|
0e7bac945f | ||
|
|
e5bb90fdfa | ||
|
|
ac0142a49e | ||
|
|
ef6e381de3 | ||
|
|
206e65cf05 | ||
|
|
695cc38b36 | ||
|
|
7b1e03a585 | ||
|
|
49bc04fa48 | ||
|
|
d5954fffa8 | ||
|
|
58da1065d6 | ||
|
|
fe58c1a383 | ||
|
|
2c02580c37 | ||
|
|
24c2315476 | ||
|
|
a3845f54e1 | ||
|
|
7442932b5e | ||
|
|
ed5a98f697 | ||
|
|
fcfa10d508 | ||
|
|
3cf0729878 | ||
|
|
55171f42f6 | ||
|
|
1311ca37e5 | ||
|
|
67d807d8fc | ||
|
|
ebf395ecc4 | ||
|
|
2c3ead339e | ||
|
|
6c7f5d093c | ||
|
|
93e9d8622e | ||
|
|
ca47d72aee | ||
|
|
c864e4d3db | ||
|
|
ff305e63b6 | ||
|
|
01fd05cb4b | ||
|
|
5831a53697 | ||
|
|
b60a7f3363 | ||
|
|
44445ff1b8 | ||
|
|
ac37c38133 | ||
|
|
8b7056b06c | ||
|
|
228b664ecf | ||
|
|
1dfd655959 | ||
|
|
ae22d5dc8a | ||
|
|
c67929ea39 | ||
|
|
2472a902dd | ||
|
|
f3d97c76df | ||
|
|
b0b8660132 | ||
|
|
ae551cde63 | ||
|
|
d0a0dbf430 | ||
|
|
0e46762962 | ||
|
|
a1ec423235 | ||
|
|
4f7dca3e5a | ||
|
|
4394594518 | ||
|
|
e5e0f527fe | ||
|
|
f07515eb88 | ||
|
|
d37dd46f65 | ||
|
|
3f6e7aa05a | ||
|
|
ad0064a310 | ||
|
|
0b7574ba00 | ||
|
|
cc05ce19f9 | ||
|
|
e132aabdae | ||
|
|
026b9268ae | ||
|
|
c807a4e383 | ||
|
|
2ff781b25f | ||
|
|
3acb474795 | ||
|
|
7e4c834c0e | ||
|
|
9c61a6df62 | ||
|
|
94e40dc554 | ||
|
|
38bf40884c | ||
|
|
1ef044d628 | ||
|
|
d5d37466e0 | ||
|
|
5f231d305f | ||
|
|
7b89bf6cc7 | ||
|
|
5c5de57290 | ||
|
|
9e18bb3c31 | ||
|
|
57703acf75 | ||
|
|
fbc247bf53 | ||
|
|
56496d8287 | ||
|
|
9d9c822efb | ||
|
|
1a3cddc002 | ||
|
|
373ca9cef0 | ||
|
|
9534516b42 | ||
|
|
755ab36f0d | ||
|
|
c0ca0373b6 | ||
|
|
7efb6a3ab8 | ||
|
|
69c26a180e | ||
|
|
40aa552489 | ||
|
|
7b1352d9c5 | ||
|
|
68cf7599d8 | ||
|
|
6501dea7a3 | ||
|
|
72fc42b60c | ||
|
|
2a164f0165 | ||
|
|
6a14f251ba | ||
|
|
92fd417962 | ||
|
|
ebbd9ff414 | ||
|
|
874b5240d2 | ||
|
|
14b34fc6ef | ||
|
|
34fffca202 | ||
|
|
4e59ab2261 | ||
|
|
327d7a6524 | ||
|
|
d5ece4e909 | ||
|
|
39f13beaf7 | ||
|
|
37624a7303 | ||
|
|
e82ec68820 | ||
|
|
90551a6eaf | ||
|
|
43ebbb1c70 | ||
|
|
f343941a96 | ||
|
|
001997e088 | ||
|
|
83b9d22ff0 | ||
|
|
77874ee518 | ||
|
|
2a04dcc334 | ||
|
|
50965ca9c0 | ||
|
|
277e32bb1e | ||
|
|
d94e4c2491 | ||
|
|
2dc25cec72 | ||
|
|
207ffdec8e | ||
|
|
1ad8ff9b64 | ||
|
|
1dd2836f1b | ||
|
|
a45fc47682 | ||
|
|
962a95d770 | ||
|
|
ca695fa6e1 | ||
|
|
e96ce99d3d | ||
|
|
550b8e55ee | ||
|
|
8e7e3b7256 | ||
|
|
f3dc7ce52c | ||
|
|
bfdda3212a | ||
|
|
02acf7d6d0 | ||
|
|
84ef06e35c | ||
|
|
f0acc9c901 | ||
|
|
55447b05ac | ||
|
|
41eb8a1e29 | ||
|
|
9eda4bc6fa | ||
|
|
6eda7772eb | ||
|
|
8c522aa758 | ||
|
|
057344e1af | ||
|
|
ee728e3dbc | ||
|
|
ae324fba94 | ||
|
|
43e6d345e4 | ||
|
|
27307fca0c | ||
|
|
8b1b6050e7 | ||
|
|
da925ee5cc | ||
|
|
4676db126a | ||
|
|
d8ea4f9b06 | ||
|
|
d2d946204c | ||
|
|
2b132ae892 | ||
|
|
34b7599df6 | ||
|
|
270ceb7ceb | ||
|
|
200c935228 | ||
|
|
f0c57cf95c | ||
|
|
19d05b8024 | ||
|
|
2a362a99da | ||
|
|
497c8aeabf | ||
|
|
c35843fda5 | ||
|
|
88af355028 | ||
|
|
10958459a3 | ||
|
|
5f6e2ee026 | ||
|
|
7a7514fa0c | ||
|
|
637eafedee | ||
|
|
3f74cb76e9 | ||
|
|
f79b34b2c9 | ||
|
|
85ced3dbf7 | ||
|
|
718569d6a1 | ||
|
|
a56c01d044 | ||
|
|
04a4219a75 | ||
|
|
16113e783f | ||
|
|
63b0a1c9e0 | ||
|
|
a386b458fb | ||
|
|
8017b18039 | ||
|
|
981f6a8972 | ||
|
|
429deb959c | ||
|
|
86793468de | ||
|
|
04d039eddd | ||
|
|
201221253d | ||
|
|
aa2773e483 | ||
|
|
25f29a2287 | ||
|
|
b0503691c5 | ||
|
|
457c3262d7 | ||
|
|
de2c4cc7b8 | ||
|
|
81e5b59060 | ||
|
|
96587dc68c | ||
|
|
d9d291abcb | ||
|
|
38516ef793 | ||
|
|
5acd433080 | ||
|
|
5c2da08c13 | ||
|
|
3c79ebda17 | ||
|
|
46e5dc2f5c | ||
|
|
0aa7e871d1 | ||
|
|
34527fbbe4 | ||
|
|
9fcab37445 | ||
|
|
5c0ee3d9a8 | ||
|
|
f3327e6dca | ||
|
|
0e6e22ac3d | ||
|
|
5002ab2169 | ||
|
|
db05b9ff04 | ||
|
|
04f9270772 | ||
|
|
29feaba22f | ||
|
|
dd3fc7a084 | ||
|
|
c5130e3eb3 | ||
|
|
b4855b6ac9 | ||
|
|
b09e975b4c | ||
|
|
ac9c02f73b | ||
|
|
52ff45549d | ||
|
|
325a265a33 | ||
|
|
918950ba49 | ||
|
|
34dfcee2e8 | ||
|
|
95cb192209 | ||
|
|
c1bef9b35c | ||
|
|
005672e8af | ||
|
|
e52e7d15dc | ||
|
|
dda53a96cc | ||
|
|
35f53516c7 | ||
|
|
14f8ed8dd2 | ||
|
|
21b78adfee | ||
|
|
503b8047b1 | ||
|
|
d959af430e | ||
|
|
4e908d3e96 | ||
|
|
3db2b7d6a6 | ||
|
|
4615297b00 | ||
|
|
6108aca055 | ||
|
|
068cb83803 | ||
|
|
22b4e17fad | ||
|
|
7333d13dd4 | ||
|
|
77268845a6 | ||
|
|
93d490bc8f | ||
|
|
e1d0bc83f4 | ||
|
|
0ac3f826e1 | ||
|
|
2ef937a9dc | ||
|
|
52b0f65bb3 | ||
|
|
0c92204927 | ||
|
|
8632d43748 | ||
|
|
9bf8c3765b | ||
|
|
5b691224f0 | ||
|
|
9cdf27cbf5 | ||
|
|
d1621692dc | ||
|
|
cc133ccc4c | ||
|
|
69f0eb109f | ||
|
|
a3ab23a36a | ||
|
|
5e5b49d4e2 | ||
|
|
377c983ecb | ||
|
|
69b20b52cc | ||
|
|
e4a68d9962 | ||
|
|
21f0d63507 | ||
|
|
e7b008c6d5 | ||
|
|
7735187d36 | ||
|
|
85f4d7d025 | ||
|
|
e0eaa08597 | ||
|
|
43c065c5b6 | ||
|
|
df154e43b1 | ||
|
|
ba21367b40 | ||
|
|
c420f60259 | ||
|
|
b13f35645a | ||
|
|
68560c9ea7 | ||
|
|
1a9019f5f5 | ||
|
|
969eeec717 | ||
|
|
1f59e38dc7 | ||
|
|
b202b82f5a | ||
|
|
d0bdafff71 | ||
|
|
685af493a4 | ||
|
|
e8ad5a0e6b | ||
|
|
000b5a2b7c | ||
|
|
88ffd3cdfb | ||
|
|
98352429c2 | ||
|
|
5171a00569 | ||
|
|
01af51308e | ||
|
|
65d4440d0d | ||
|
|
37276f357c | ||
|
|
e0b6620df2 | ||
|
|
ebabeb6fbd | ||
|
|
ab6c138a7c | ||
|
|
33e7c124a3 | ||
|
|
11ff62e120 | ||
|
|
155a6a09b6 | ||
|
|
74156b6b89 | ||
|
|
9387e7dd2d | ||
|
|
9aaaa6aef0 | ||
|
|
cc9358ee95 | ||
|
|
06ed133ae3 | ||
|
|
75b778924f | ||
|
|
fe902db322 | ||
|
|
0c00335627 | ||
|
|
5e3548fc00 | ||
|
|
c8837d07e7 | ||
|
|
fd14957072 | ||
|
|
1df03b67e7 | ||
|
|
6d9131084f | ||
|
|
66b96b90d5 | ||
|
|
03baeccda5 | ||
|
|
91b0c1cd0e | ||
|
|
6d974daaf2 | ||
|
|
849d0c1c34 | ||
|
|
63dc75fb81 | ||
|
|
f07732a9ca | ||
|
|
9702446d91 | ||
|
|
d3a07234cd | ||
|
|
cf2c43e7ab | ||
|
|
83c3beb2ed | ||
|
|
52133569f5 | ||
|
|
1c39721ff7 | ||
|
|
57b2c3c2e4 | ||
|
|
ed82643faf | ||
|
|
5131752402 | ||
|
|
1b44479311 | ||
|
|
4c987d04d6 | ||
|
|
728ace79c5 | ||
|
|
a937b97a61 | ||
|
|
35d2ea862b | ||
|
|
1c502948f5 | ||
|
|
45f321a3a2 | ||
|
|
85f5672280 | ||
|
|
62c1b02eb1 | ||
|
|
67af5ccda8 | ||
|
|
bd49b0edf8 | ||
|
|
3126654d33 | ||
|
|
1b55d39997 | ||
|
|
51372c01f2 | ||
|
|
7008db7dda | ||
|
|
47456a1723 | ||
|
|
933ba3c7d6 | ||
|
|
08ff5f02b1 | ||
|
|
2bf39203e8 | ||
|
|
d323a84dd9 | ||
|
|
2e402ba654 | ||
|
|
f0afa04037 | ||
|
|
b9290acb85 | ||
|
|
cb47146b3b | ||
|
|
04fadc84a6 | ||
|
|
18333eac29 | ||
|
|
abd3668b65 | ||
|
|
9064af3b1c | ||
|
|
2f7b42b13b | ||
|
|
56755c278b | ||
|
|
7266111b68 | ||
|
|
810954014b | ||
|
|
3248a1b57f | ||
|
|
4edf1fd8fa | ||
|
|
67f22e602e | ||
|
|
114012fab2 | ||
|
|
c50fc88827 | ||
|
|
f5e4b3aeb3 | ||
|
|
76e0d4c770 | ||
|
|
ed8d9b1ed3 | ||
|
|
c825fce0cf | ||
|
|
0f5b35f408 | ||
|
|
ae0cd50840 | ||
|
|
9a7c5b02d4 | ||
|
|
66c5b4ed01 | ||
|
|
f125c3a3c8 | ||
|
|
e36f027a9a | ||
|
|
dc7035ed19 | ||
|
|
d25fe19d87 | ||
|
|
dc52a31814 | ||
|
|
2f45613017 | ||
|
|
8d881d3b6f | ||
|
|
ce6f051551 | ||
|
|
b3b188061a | ||
|
|
49f70c083d | ||
|
|
ed392300b4 | ||
|
|
a3af6404b0 | ||
|
|
312b7352b2 | ||
|
|
23e4bc4f9a | ||
|
|
8208bb25ba | ||
|
|
a90ea340d2 | ||
|
|
e2fd51c282 | ||
|
|
0008193a20 | ||
|
|
5c691c0883 | ||
|
|
e363cbe542 | ||
|
|
d8bec0a43c | ||
|
|
e1c176ceb7 | ||
|
|
a1289eb502 | ||
|
|
4a00e8feed | ||
|
|
60e0e5c38f | ||
|
|
93ef4f2301 | ||
|
|
ccda3068ef | ||
|
|
ebad05a9df | ||
|
|
4f19ea4a8e | ||
|
|
8e2722da95 | ||
|
|
b5fbcfaa8e | ||
|
|
d0ea813515 | ||
|
|
932bc382dc | ||
|
|
bdfb19fe38 | ||
|
|
d798330f44 | ||
|
|
caa3a5d0bb | ||
|
|
d54a5c49c1 | ||
|
|
9e75075dc4 | ||
|
|
6a833e19aa | ||
|
|
941ac2ae5e | ||
|
|
34f4b3cad4 | ||
|
|
03948cd685 | ||
|
|
3c993884cd | ||
|
|
9e99aed182 | ||
|
|
66edf2822c | ||
|
|
9c9ba18619 | ||
|
|
485d048415 | ||
|
|
10a0db9160 | ||
|
|
8260b75586 | ||
|
|
8365ed7408 | ||
|
|
d4298d1bd2 | ||
|
|
75736f547a | ||
|
|
e84b524fc4 | ||
|
|
7eb80615c7 | ||
|
|
030c763549 | ||
|
|
57d0e556d8 | ||
|
|
3fea8a4202 | ||
|
|
ca1eda2df1 | ||
|
|
386fea5e71 | ||
|
|
e7bda30506 | ||
|
|
6dcf61669c | ||
|
|
1832463010 | ||
|
|
a0baaeafd1 | ||
|
|
c5a113ca80 | ||
|
|
e6b3ded33f | ||
|
|
aa66af151a | ||
|
|
ab57495e29 | ||
|
|
afb5d161e3 | ||
|
|
1fdaafb30b | ||
|
|
9328e6fdec | ||
|
|
98ac0697a9 | ||
|
|
b658f82510 | ||
|
|
b50894fa70 | ||
|
|
e002000764 | ||
|
|
9182c1558c | ||
|
|
ded7eca60f | ||
|
|
74e8c881f7 | ||
|
|
f1eac72d20 | ||
|
|
6d13ddd43a | ||
|
|
94e9632234 | ||
|
|
3699b74ebb | ||
|
|
4eeab3bc3e | ||
|
|
0d1ded5278 | ||
|
|
86142ecdf1 | ||
|
|
8cdc00230d | ||
|
|
d3d674ba4b | ||
|
|
6d961d87f8 | ||
|
|
5a28c54505 | ||
|
|
9968101d96 | ||
|
|
d0a309e6da | ||
|
|
f2d84f0a90 | ||
|
|
d81345d8f6 | ||
|
|
97b6260c9a | ||
|
|
48cf78af68 |
91
.clang-format
Normal file
91
.clang-format
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlinesLeft: true
|
||||||
|
AlignOperands: false
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: All
|
||||||
|
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:'
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
ForEachMacros: [ Q_FOREACH, BOOST_FOREACH ]
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<(test)/'
|
||||||
|
Priority: 0
|
||||||
|
- Regex: '^<(xrpld)/'
|
||||||
|
Priority: 1
|
||||||
|
- Regex: '^<(xrpl)/'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^<(boost)/'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 4
|
||||||
|
IncludeIsMainRegex: '$'
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentFunctionDeclarationAfterType: false
|
||||||
|
IndentRequiresClause: true
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: false
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReflowComments: true
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
SortIncludes: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
37
.codecov.yml
Normal file
37
.codecov.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
codecov:
|
||||||
|
require_ci_to_pass: true
|
||||||
|
|
||||||
|
comment:
|
||||||
|
behavior: default
|
||||||
|
layout: reach,diff,flags,tree,reach
|
||||||
|
show_carryforward_flags: false
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
range: "60..80"
|
||||||
|
precision: 1
|
||||||
|
round: nearest
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
target: 60%
|
||||||
|
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/"
|
||||||
|
- "include/xrpl/beast/test/"
|
||||||
|
- "include/xrpl/beast/unit_test/"
|
||||||
13
.git-blame-ignore-revs
Normal file
13
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# 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
|
||||||
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: Create a report to help us improve rippled
|
||||||
|
title: "[Title with short description] (Version: [rippled 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 './rippled --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.
|
||||||
21
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
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?-->
|
||||||
34
.github/actions/build/action.yml
vendored
Normal file
34
.github/actions/build/action.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: build
|
||||||
|
inputs:
|
||||||
|
generator:
|
||||||
|
default: null
|
||||||
|
configuration:
|
||||||
|
required: true
|
||||||
|
cmake-args:
|
||||||
|
default: null
|
||||||
|
cmake-target:
|
||||||
|
default: all
|
||||||
|
# An implicit input is the environment variable `build_dir`.
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: configure
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd ${build_dir}
|
||||||
|
cmake \
|
||||||
|
${{ inputs.generator && format('-G "{0}"', inputs.generator) || '' }} \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ inputs.configuration }} \
|
||||||
|
-Dtests=TRUE \
|
||||||
|
-Dxrpld=TRUE \
|
||||||
|
${{ inputs.cmake-args }} \
|
||||||
|
..
|
||||||
|
- name: build
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cmake \
|
||||||
|
--build ${build_dir} \
|
||||||
|
--config ${{ inputs.configuration }} \
|
||||||
|
--parallel ${NUM_PROCESSORS:-$(nproc)} \
|
||||||
|
--target ${{ inputs.cmake-target }}
|
||||||
61
.github/actions/dependencies/action.yml
vendored
Normal file
61
.github/actions/dependencies/action.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
name: dependencies
|
||||||
|
inputs:
|
||||||
|
configuration:
|
||||||
|
required: true
|
||||||
|
# An implicit input is the environment variable `build_dir`.
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: unlock Conan
|
||||||
|
shell: bash
|
||||||
|
run: conan remove --locks
|
||||||
|
- name: export custom recipes
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
conan config set general.revisions_enabled=1
|
||||||
|
conan export external/snappy snappy/1.1.10@
|
||||||
|
conan export external/rocksdb rocksdb/6.29.5@
|
||||||
|
conan export external/soci soci/4.0.3@
|
||||||
|
conan export external/nudb nudb/2.0.8@
|
||||||
|
- name: add Ripple Conan remote
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
conan remote list
|
||||||
|
conan remote remove ripple || true
|
||||||
|
# Do not quote the URL. An empty string will be accepted (with
|
||||||
|
# a non-fatal warning), but a missing argument will not.
|
||||||
|
conan remote add ripple ${{ env.CONAN_URL }} --insert 0
|
||||||
|
- name: try to authenticate to Ripple Conan remote
|
||||||
|
id: remote
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# `conan user` implicitly uses the environment variables
|
||||||
|
# CONAN_LOGIN_USERNAME_<REMOTE> and CONAN_PASSWORD_<REMOTE>.
|
||||||
|
# https://docs.conan.io/1/reference/commands/misc/user.html#using-environment-variables
|
||||||
|
# https://docs.conan.io/1/reference/env_vars.html#conan-login-username-conan-login-username-remote-name
|
||||||
|
# https://docs.conan.io/1/reference/env_vars.html#conan-password-conan-password-remote-name
|
||||||
|
echo outcome=$(conan user --remote ripple --password >&2 \
|
||||||
|
&& echo success || echo failure) | tee ${GITHUB_OUTPUT}
|
||||||
|
- name: list missing binaries
|
||||||
|
id: binaries
|
||||||
|
shell: bash
|
||||||
|
# Print the list of dependencies that would need to be built locally.
|
||||||
|
# A non-empty list means we have "failed" to cache binaries remotely.
|
||||||
|
run: |
|
||||||
|
echo missing=$(conan info . --build missing --settings build_type=${{ inputs.configuration }} --json 2>/dev/null | grep '^\[') | tee ${GITHUB_OUTPUT}
|
||||||
|
- name: install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir ${build_dir}
|
||||||
|
cd ${build_dir}
|
||||||
|
conan install \
|
||||||
|
--output-folder . \
|
||||||
|
--build missing \
|
||||||
|
--options tests=True \
|
||||||
|
--options xrpld=True \
|
||||||
|
--settings build_type=${{ inputs.configuration }} \
|
||||||
|
..
|
||||||
|
- name: upload dependencies to remote
|
||||||
|
if: (steps.binaries.outputs.missing != '[]') && (steps.remote.outputs.outcome == 'success')
|
||||||
|
shell: bash
|
||||||
|
run: conan upload --remote ripple '*' --all --parallel --confirm
|
||||||
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.
|
||||||
|
-->
|
||||||
59
.github/workflows/clang-format.yml
vendored
Normal file
59
.github/workflows/clang-format.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
name: clang-format
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
env:
|
||||||
|
CLANG_VERSION: 18
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install clang-format
|
||||||
|
run: |
|
||||||
|
codename=$( lsb_release --codename --short )
|
||||||
|
sudo tee /etc/apt/sources.list.d/llvm.list >/dev/null <<EOF
|
||||||
|
deb http://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-${CLANG_VERSION} main
|
||||||
|
deb-src http://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-${CLANG_VERSION} main
|
||||||
|
EOF
|
||||||
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install clang-format-${CLANG_VERSION}
|
||||||
|
- name: Format first-party sources
|
||||||
|
run: find include src -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format-${CLANG_VERSION} -i {} +
|
||||||
|
- name: Check for differences
|
||||||
|
id: assert
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
git diff --exit-code | tee "clang-format.patch"
|
||||||
|
- name: Upload patch
|
||||||
|
if: failure() && steps.assert.outcome == 'failure'
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
name: clang-format.patch
|
||||||
|
if-no-files-found: ignore
|
||||||
|
path: clang-format.patch
|
||||||
|
- name: What happened?
|
||||||
|
if: failure() && steps.assert.outcome == 'failure'
|
||||||
|
env:
|
||||||
|
PREAMBLE: |
|
||||||
|
If you are reading this, you are looking at a failed Github Actions
|
||||||
|
job. That means you pushed one or more files that did not conform
|
||||||
|
to the formatting specified in .clang-format. That may be because
|
||||||
|
you neglected to run 'git clang-format' or 'clang-format' before
|
||||||
|
committing, or that your version of clang-format has an
|
||||||
|
incompatibility with the one on this
|
||||||
|
machine, which is:
|
||||||
|
SUGGESTION: |
|
||||||
|
|
||||||
|
To fix it, you can do one of two things:
|
||||||
|
1. Download and apply the patch generated as an artifact of this
|
||||||
|
job to your repo, commit, and push.
|
||||||
|
2. Run 'git-clang-format --extensions cpp,h,hpp,ipp develop'
|
||||||
|
in your repo, commit, and push.
|
||||||
|
run: |
|
||||||
|
echo "${PREAMBLE}"
|
||||||
|
clang-format-${CLANG_VERSION} --version
|
||||||
|
echo "${SUGGESTION}"
|
||||||
|
exit 1
|
||||||
37
.github/workflows/doxygen.yml
vendored
Normal file
37
.github/workflows/doxygen.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Build and publish Doxygen documentation
|
||||||
|
# To test this workflow, push your changes to your fork's `develop` branch.
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
- doxygen
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
container: rippleci/rippled-build-ubuntu:aaf5e3e
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
echo ${PATH} | tr ':' '\n'
|
||||||
|
cmake --version
|
||||||
|
doxygen --version
|
||||||
|
env | sort
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -Donly_docs=TRUE ..
|
||||||
|
cmake --build . --target docs --parallel $(nproc)
|
||||||
|
- name: publish
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: build/docs/html
|
||||||
49
.github/workflows/levelization.yml
vendored
Normal file
49
.github/workflows/levelization.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: levelization
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CLANG_VERSION: 10
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check levelization
|
||||||
|
run: Builds/levelization/levelization.sh
|
||||||
|
- name: Check for differences
|
||||||
|
id: assert
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
git diff --exit-code | tee "levelization.patch"
|
||||||
|
- name: Upload patch
|
||||||
|
if: failure() && steps.assert.outcome == 'failure'
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
name: levelization.patch
|
||||||
|
if-no-files-found: ignore
|
||||||
|
path: levelization.patch
|
||||||
|
- name: What happened?
|
||||||
|
if: failure() && steps.assert.outcome == 'failure'
|
||||||
|
env:
|
||||||
|
MESSAGE: |
|
||||||
|
If you are reading this, you are looking at a failed Github
|
||||||
|
Actions job. That means you changed the dependency relationships
|
||||||
|
between the modules in rippled. That may be an improvement or a
|
||||||
|
regression. This check doesn't judge.
|
||||||
|
|
||||||
|
A rule of thumb, though, is that if your changes caused
|
||||||
|
something to be removed from loops.txt, that's probably an
|
||||||
|
improvement. If something was added, it's probably a regression.
|
||||||
|
|
||||||
|
To fix it, you can do one of two things:
|
||||||
|
1. Download and apply the patch generated as an artifact of this
|
||||||
|
job to your repo, commit, and push.
|
||||||
|
2. Run './Builds/levelization/levelization.sh' in your repo,
|
||||||
|
commit, and push.
|
||||||
|
|
||||||
|
See Builds/levelization/README.md for more info.
|
||||||
|
run: |
|
||||||
|
echo "${MESSAGE}"
|
||||||
|
exit 1
|
||||||
88
.github/workflows/libxrpl.yml
vendored
Normal file
88
.github/workflows/libxrpl.yml
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
name: Check libXRPL compatibility with Clio
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
CONAN_LOGIN_USERNAME_RIPPLE: ${{ secrets.CONAN_USERNAME }}
|
||||||
|
CONAN_PASSWORD_RIPPLE: ${{ secrets.CONAN_TOKEN }}
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/libxrpl/protocol/BuildInfo.cpp'
|
||||||
|
- '.github/workflows/libxrpl.yml'
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
name: Publish libXRPL
|
||||||
|
outputs:
|
||||||
|
outcome: ${{ steps.upload.outputs.outcome }}
|
||||||
|
version: ${{ steps.version.outputs.version }}
|
||||||
|
channel: ${{ steps.channel.outputs.channel }}
|
||||||
|
runs-on: [self-hosted, heavy]
|
||||||
|
container: rippleci/rippled-build-ubuntu:aaf5e3e
|
||||||
|
steps:
|
||||||
|
- name: Wait for essential checks to succeed
|
||||||
|
uses: lewagon/wait-on-check-action@v1.3.4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
running-workflow-name: wait-for-check-regexp
|
||||||
|
check-regexp: '(dependencies|test).*linux.*' # Ignore windows and mac tests but make sure linux passes
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
wait-interval: 10
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Generate channel
|
||||||
|
id: channel
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo channel="clio/pr_${{ github.event.pull_request.number }}" | tee ${GITHUB_OUTPUT}
|
||||||
|
- name: Export new package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
conan export . ${{ steps.channel.outputs.channel }}
|
||||||
|
- name: Add Ripple Conan remote
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
conan remote list
|
||||||
|
conan remote remove ripple || true
|
||||||
|
# Do not quote the URL. An empty string will be accepted (with a non-fatal warning), but a missing argument will not.
|
||||||
|
conan remote add ripple ${{ env.CONAN_URL }} --insert 0
|
||||||
|
- name: Parse new version
|
||||||
|
id: version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo version="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" \
|
||||||
|
| awk -F '"' '{print $2}')" | tee ${GITHUB_OUTPUT}
|
||||||
|
- name: Try to authenticate to Ripple Conan remote
|
||||||
|
id: remote
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# `conan user` implicitly uses the environment variables CONAN_LOGIN_USERNAME_<REMOTE> and CONAN_PASSWORD_<REMOTE>.
|
||||||
|
# https://docs.conan.io/1/reference/commands/misc/user.html#using-environment-variables
|
||||||
|
# https://docs.conan.io/1/reference/env_vars.html#conan-login-username-conan-login-username-remote-name
|
||||||
|
# https://docs.conan.io/1/reference/env_vars.html#conan-password-conan-password-remote-name
|
||||||
|
echo outcome=$(conan user --remote ripple --password >&2 \
|
||||||
|
&& echo success || echo failure) | tee ${GITHUB_OUTPUT}
|
||||||
|
- name: Upload new package
|
||||||
|
id: upload
|
||||||
|
if: (steps.remote.outputs.outcome == 'success')
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "conan upload version ${{ steps.version.outputs.version }} on channel ${{ steps.channel.outputs.channel }}"
|
||||||
|
echo outcome=$(conan upload xrpl/${{ steps.version.outputs.version }}@${{ steps.channel.outputs.channel }} --remote ripple --confirm >&2 \
|
||||||
|
&& echo success || echo failure) | tee ${GITHUB_OUTPUT}
|
||||||
|
notify_clio:
|
||||||
|
name: Notify Clio
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: publish
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.CLIO_NOTIFY_TOKEN }}
|
||||||
|
steps:
|
||||||
|
- name: Notify Clio about new version
|
||||||
|
if: (needs.publish.outputs.outcome == 'success')
|
||||||
|
shell: bash
|
||||||
|
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[version]=${{ needs.publish.outputs.version }}@${{ needs.publish.outputs.channel }}"
|
||||||
95
.github/workflows/macos.yml
vendored
Normal file
95
.github/workflows/macos.yml
vendored
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
name: macos
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
# If the branches list is ever changed, be sure to change it on all
|
||||||
|
# build/test jobs (nix, macos, windows, instrumentation)
|
||||||
|
branches:
|
||||||
|
# Always build the package branches
|
||||||
|
- develop
|
||||||
|
- release
|
||||||
|
- master
|
||||||
|
# Branches that opt-in to running
|
||||||
|
- 'ci/**'
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
- macos
|
||||||
|
generator:
|
||||||
|
- Ninja
|
||||||
|
configuration:
|
||||||
|
- Release
|
||||||
|
runs-on: [self-hosted, macOS]
|
||||||
|
env:
|
||||||
|
# The `build` action requires these variables.
|
||||||
|
build_dir: .build
|
||||||
|
NUM_PROCESSORS: 12
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: install Conan
|
||||||
|
run: |
|
||||||
|
brew install conan@1
|
||||||
|
echo '/opt/homebrew/opt/conan@1/bin' >> $GITHUB_PATH
|
||||||
|
- name: install Ninja
|
||||||
|
if: matrix.generator == 'Ninja'
|
||||||
|
run: brew install ninja
|
||||||
|
- name: install python
|
||||||
|
run: |
|
||||||
|
if which python > /dev/null 2>&1; then
|
||||||
|
echo "Python executable exists"
|
||||||
|
else
|
||||||
|
brew install python@3.13
|
||||||
|
ln -s /opt/homebrew/bin/python3 /opt/homebrew/bin/python
|
||||||
|
fi
|
||||||
|
- name: install cmake
|
||||||
|
run: |
|
||||||
|
if which cmake > /dev/null 2>&1; then
|
||||||
|
echo "cmake executable exists"
|
||||||
|
else
|
||||||
|
brew install cmake
|
||||||
|
fi
|
||||||
|
- name: install nproc
|
||||||
|
run: |
|
||||||
|
brew install coreutils
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
env | sort
|
||||||
|
echo ${PATH} | tr ':' '\n'
|
||||||
|
python --version
|
||||||
|
conan --version
|
||||||
|
cmake --version
|
||||||
|
nproc --version
|
||||||
|
echo -n "nproc returns: "
|
||||||
|
nproc
|
||||||
|
- name: configure Conan
|
||||||
|
run : |
|
||||||
|
conan profile new default --detect || true
|
||||||
|
conan profile update settings.compiler.cppstd=20 default
|
||||||
|
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_DISABLE_CONCEPTS"]' default
|
||||||
|
- name: build dependencies
|
||||||
|
uses: ./.github/actions/dependencies
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
CONAN_LOGIN_USERNAME_RIPPLE: ${{ secrets.CONAN_USERNAME }}
|
||||||
|
CONAN_PASSWORD_RIPPLE: ${{ secrets.CONAN_TOKEN }}
|
||||||
|
with:
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
- name: build
|
||||||
|
uses: ./.github/actions/build
|
||||||
|
with:
|
||||||
|
generator: ${{ matrix.generator }}
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}"
|
||||||
|
- name: test
|
||||||
|
run: |
|
||||||
|
n=$(nproc)
|
||||||
|
echo "Using $n test jobs"
|
||||||
|
${build_dir}/rippled --unittest --unittest-jobs $n
|
||||||
60
.github/workflows/missing-commits.yml
vendored
Normal file
60
.github/workflows/missing-commits.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: missing-commits
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
# Only check that the branches are up to date when updating the
|
||||||
|
# relevant branches.
|
||||||
|
- develop
|
||||||
|
- release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
up_to_date:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Check for missing commits
|
||||||
|
id: commits
|
||||||
|
env:
|
||||||
|
SUGGESTION: |
|
||||||
|
|
||||||
|
If you are reading this, then the commits indicated above are
|
||||||
|
missing from "develop" and/or "release". Do a reverse-merge
|
||||||
|
as soon as possible. See CONTRIBUTING.md for instructions.
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
# Branches ordered by how "canonical" they are. Every commit in
|
||||||
|
# one branch should be in all the branches behind it
|
||||||
|
order=( master release develop )
|
||||||
|
branches=()
|
||||||
|
for branch in "${order[@]}"
|
||||||
|
do
|
||||||
|
# Check that the branches exist so that this job will work on
|
||||||
|
# forked repos, which don't necessarily have master and
|
||||||
|
# release branches.
|
||||||
|
if git ls-remote --exit-code --heads origin \
|
||||||
|
refs/heads/${branch} > /dev/null
|
||||||
|
then
|
||||||
|
branches+=( origin/${branch} )
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
prior=()
|
||||||
|
for branch in "${branches[@]}"
|
||||||
|
do
|
||||||
|
if [[ ${#prior[@]} -ne 0 ]]
|
||||||
|
then
|
||||||
|
echo "Checking ${prior[@]} for commits missing from ${branch}"
|
||||||
|
git log --oneline --no-merges "${prior[@]}" \
|
||||||
|
^$branch | tee -a "missing-commits.txt"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
prior+=( "${branch}" )
|
||||||
|
done
|
||||||
|
if [[ $( cat missing-commits.txt | wc -l ) -ne 0 ]]
|
||||||
|
then
|
||||||
|
echo "${SUGGESTION}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
386
.github/workflows/nix.yml
vendored
Normal file
386
.github/workflows/nix.yml
vendored
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
name: nix
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
# If the branches list is ever changed, be sure to change it on all
|
||||||
|
# build/test jobs (nix, macos, windows)
|
||||||
|
branches:
|
||||||
|
# Always build the package branches
|
||||||
|
- develop
|
||||||
|
- release
|
||||||
|
- master
|
||||||
|
# Branches that opt-in to running
|
||||||
|
- "ci/**"
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# This workflow has multiple job matrixes.
|
||||||
|
# They can be considered phases because most of the matrices ("test",
|
||||||
|
# "coverage", "conan", ) depend on the first ("dependencies").
|
||||||
|
#
|
||||||
|
# The first phase has a job in the matrix for each combination of
|
||||||
|
# variables that affects dependency ABI:
|
||||||
|
# platform, compiler, and configuration.
|
||||||
|
# It creates a GitHub artifact holding the Conan profile,
|
||||||
|
# and builds and caches binaries for all the dependencies.
|
||||||
|
# If an Artifactory remote is configured, they are cached there.
|
||||||
|
# If not, they are added to the GitHub artifact.
|
||||||
|
# GitHub's "cache" action has a size limit (10 GB) that is too small
|
||||||
|
# to hold the binaries if they are built locally.
|
||||||
|
# We must use the "{upload,download}-artifact" actions instead.
|
||||||
|
#
|
||||||
|
# The remaining phases have a job in the matrix for each test
|
||||||
|
# configuration. They install dependency binaries from the cache,
|
||||||
|
# whichever was used, and build and test rippled.
|
||||||
|
#
|
||||||
|
# "instrumentation" is independent, but is included here because it also
|
||||||
|
# builds on linux in the same "on:" conditions.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependencies:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
- linux
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
configuration:
|
||||||
|
- Debug
|
||||||
|
- Release
|
||||||
|
include:
|
||||||
|
- compiler: gcc
|
||||||
|
profile:
|
||||||
|
version: 11
|
||||||
|
cc: /usr/bin/gcc
|
||||||
|
cxx: /usr/bin/g++
|
||||||
|
- compiler: clang
|
||||||
|
profile:
|
||||||
|
version: 14
|
||||||
|
cc: /usr/bin/clang-14
|
||||||
|
cxx: /usr/bin/clang++-14
|
||||||
|
runs-on: [self-hosted, heavy]
|
||||||
|
container: rippleci/rippled-build-ubuntu:aaf5e3e
|
||||||
|
env:
|
||||||
|
build_dir: .build
|
||||||
|
steps:
|
||||||
|
- name: upgrade conan
|
||||||
|
run: |
|
||||||
|
pip install --upgrade "conan<2"
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
echo ${PATH} | tr ':' '\n'
|
||||||
|
lsb_release -a || true
|
||||||
|
${{ matrix.profile.cc }} --version
|
||||||
|
conan --version
|
||||||
|
cmake --version
|
||||||
|
env | sort
|
||||||
|
- name: configure Conan
|
||||||
|
run: |
|
||||||
|
conan profile new default --detect
|
||||||
|
conan profile update settings.compiler.cppstd=20 default
|
||||||
|
conan profile update settings.compiler=${{ matrix.compiler }} default
|
||||||
|
conan profile update settings.compiler.version=${{ matrix.profile.version }} default
|
||||||
|
conan profile update settings.compiler.libcxx=libstdc++11 default
|
||||||
|
conan profile update env.CC=${{ matrix.profile.cc }} default
|
||||||
|
conan profile update env.CXX=${{ matrix.profile.cxx }} default
|
||||||
|
conan profile update conf.tools.build:compiler_executables='{"c": "${{ matrix.profile.cc }}", "cpp": "${{ matrix.profile.cxx }}"}' default
|
||||||
|
- name: archive profile
|
||||||
|
# Create this archive before dependencies are added to the local cache.
|
||||||
|
run: tar -czf conan.tar -C ~/.conan .
|
||||||
|
- name: build dependencies
|
||||||
|
uses: ./.github/actions/dependencies
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
CONAN_LOGIN_USERNAME_RIPPLE: ${{ secrets.CONAN_USERNAME }}
|
||||||
|
CONAN_PASSWORD_RIPPLE: ${{ secrets.CONAN_TOKEN }}
|
||||||
|
with:
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
- name: upload archive
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }}
|
||||||
|
path: conan.tar
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
test:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
- linux
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
configuration:
|
||||||
|
- Debug
|
||||||
|
- Release
|
||||||
|
cmake-args:
|
||||||
|
-
|
||||||
|
- "-Dunity=ON"
|
||||||
|
needs: dependencies
|
||||||
|
runs-on: [self-hosted, heavy]
|
||||||
|
container: rippleci/rippled-build-ubuntu:aaf5e3e
|
||||||
|
env:
|
||||||
|
build_dir: .build
|
||||||
|
steps:
|
||||||
|
- name: upgrade conan
|
||||||
|
run: |
|
||||||
|
pip install --upgrade "conan<2"
|
||||||
|
- name: download cache
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }}
|
||||||
|
- name: extract cache
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.conan
|
||||||
|
tar -xzf conan.tar -C ~/.conan
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
env | sort
|
||||||
|
echo ${PATH} | tr ':' '\n'
|
||||||
|
conan --version
|
||||||
|
cmake --version
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: dependencies
|
||||||
|
uses: ./.github/actions/dependencies
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
with:
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
- name: build
|
||||||
|
uses: ./.github/actions/build
|
||||||
|
with:
|
||||||
|
generator: Ninja
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}"
|
||||||
|
- name: test
|
||||||
|
run: |
|
||||||
|
${build_dir}/rippled --unittest --unittest-jobs $(nproc)
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform:
|
||||||
|
- linux
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
configuration:
|
||||||
|
- Debug
|
||||||
|
needs: dependencies
|
||||||
|
runs-on: [self-hosted, heavy]
|
||||||
|
container: rippleci/rippled-build-ubuntu:aaf5e3e
|
||||||
|
env:
|
||||||
|
build_dir: .build
|
||||||
|
steps:
|
||||||
|
- name: upgrade conan
|
||||||
|
run: |
|
||||||
|
pip install --upgrade "conan<2"
|
||||||
|
- name: download cache
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }}
|
||||||
|
- name: extract cache
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.conan
|
||||||
|
tar -xzf conan.tar -C ~/.conan
|
||||||
|
- name: install gcovr
|
||||||
|
run: pip install "gcovr>=7,<8"
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
echo ${PATH} | tr ':' '\n'
|
||||||
|
conan --version
|
||||||
|
cmake --version
|
||||||
|
gcovr --version
|
||||||
|
env | sort
|
||||||
|
ls ~/.conan
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: dependencies
|
||||||
|
uses: ./.github/actions/dependencies
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
with:
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
- name: build
|
||||||
|
uses: ./.github/actions/build
|
||||||
|
with:
|
||||||
|
generator: Ninja
|
||||||
|
configuration: ${{ matrix.configuration }}
|
||||||
|
cmake-args: >-
|
||||||
|
-Dassert=TRUE
|
||||||
|
-Dwerr=TRUE
|
||||||
|
-Dcoverage=ON
|
||||||
|
-Dcoverage_format=xml
|
||||||
|
-DCODE_COVERAGE_VERBOSE=ON
|
||||||
|
-DCMAKE_CXX_FLAGS="-O0"
|
||||||
|
-DCMAKE_C_FLAGS="-O0"
|
||||||
|
cmake-target: coverage
|
||||||
|
- name: move coverage report
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mv "${build_dir}/coverage.xml" ./
|
||||||
|
- name: archive coverage report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: coverage.xml
|
||||||
|
path: coverage.xml
|
||||||
|
retention-days: 30
|
||||||
|
- name: upload coverage report
|
||||||
|
uses: wandalen/wretry.action@v1.4.10
|
||||||
|
with:
|
||||||
|
action: codecov/codecov-action@v4.5.0
|
||||||
|
with: |
|
||||||
|
files: coverage.xml
|
||||||
|
fail_ci_if_error: true
|
||||||
|
disable_search: true
|
||||||
|
verbose: true
|
||||||
|
plugin: noop
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
attempt_limit: 5
|
||||||
|
attempt_delay: 210000 # in milliseconds
|
||||||
|
|
||||||
|
conan:
|
||||||
|
needs: dependencies
|
||||||
|
runs-on: [self-hosted, heavy]
|
||||||
|
container: rippleci/rippled-build-ubuntu:aaf5e3e
|
||||||
|
env:
|
||||||
|
build_dir: .build
|
||||||
|
configuration: Release
|
||||||
|
steps:
|
||||||
|
- name: upgrade conan
|
||||||
|
run: |
|
||||||
|
pip install --upgrade "conan<2"
|
||||||
|
- name: download cache
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: linux-gcc-${{ env.configuration }}
|
||||||
|
- name: extract cache
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.conan
|
||||||
|
tar -xzf conan.tar -C ~/.conan
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
env | sort
|
||||||
|
echo ${PATH} | tr ':' '\n'
|
||||||
|
conan --version
|
||||||
|
cmake --version
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: dependencies
|
||||||
|
uses: ./.github/actions/dependencies
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
with:
|
||||||
|
configuration: ${{ env.configuration }}
|
||||||
|
- name: export
|
||||||
|
run: |
|
||||||
|
version=$(conan inspect --raw version .)
|
||||||
|
reference="xrpl/${version}@local/test"
|
||||||
|
conan remove -f ${reference} || true
|
||||||
|
conan export . local/test
|
||||||
|
echo "reference=${reference}" >> "${GITHUB_ENV}"
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
cd examples/example
|
||||||
|
mkdir ${build_dir}
|
||||||
|
cd ${build_dir}
|
||||||
|
conan install .. --output-folder . \
|
||||||
|
--require-override ${reference} --build missing
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=./build/${configuration}/generators/conan_toolchain.cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=${configuration}
|
||||||
|
cmake --build .
|
||||||
|
./example | grep '^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+'
|
||||||
|
|
||||||
|
# NOTE we are not using dependencies built above because it lags with
|
||||||
|
# compiler versions. Instrumentation requires clang version 16 or
|
||||||
|
# later
|
||||||
|
|
||||||
|
instrumentation-build:
|
||||||
|
env:
|
||||||
|
CLANG_RELEASE: 16
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: [self-hosted, heavy]
|
||||||
|
container: debian:bookworm
|
||||||
|
steps:
|
||||||
|
- name: install prerequisites
|
||||||
|
env:
|
||||||
|
DEBIAN_FRONTEND: noninteractive
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install --yes --no-install-recommends \
|
||||||
|
clang-${CLANG_RELEASE} clang++-${CLANG_RELEASE} \
|
||||||
|
python3-pip python-is-python3 make cmake git wget
|
||||||
|
apt-get clean
|
||||||
|
update-alternatives --install \
|
||||||
|
/usr/bin/clang clang /usr/bin/clang-${CLANG_RELEASE} 100 \
|
||||||
|
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-${CLANG_RELEASE}
|
||||||
|
update-alternatives --auto clang
|
||||||
|
pip install --no-cache --break-system-packages "conan<2"
|
||||||
|
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: prepare environment
|
||||||
|
run: |
|
||||||
|
mkdir ${GITHUB_WORKSPACE}/.build
|
||||||
|
echo "SOURCE_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||||
|
echo "BUILD_DIR=$GITHUB_WORKSPACE/.build" >> $GITHUB_ENV
|
||||||
|
echo "CC=/usr/bin/clang" >> $GITHUB_ENV
|
||||||
|
echo "CXX=/usr/bin/clang++" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: configure Conan
|
||||||
|
run: |
|
||||||
|
conan profile new --detect default
|
||||||
|
conan profile update settings.compiler=clang default
|
||||||
|
conan profile update settings.compiler.version=${CLANG_RELEASE} default
|
||||||
|
conan profile update settings.compiler.libcxx=libstdc++11 default
|
||||||
|
conan profile update settings.compiler.cppstd=20 default
|
||||||
|
conan profile update options.rocksdb=False default
|
||||||
|
conan profile update \
|
||||||
|
'conf.tools.build:compiler_executables={"c": "/usr/bin/clang", "cpp": "/usr/bin/clang++"}' default
|
||||||
|
conan profile update 'env.CXXFLAGS="-DBOOST_ASIO_DISABLE_CONCEPTS"' default
|
||||||
|
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_DISABLE_CONCEPTS"]' default
|
||||||
|
conan export external/snappy snappy/1.1.10@
|
||||||
|
conan export external/soci soci/4.0.3@
|
||||||
|
|
||||||
|
- name: build dependencies
|
||||||
|
run: |
|
||||||
|
cd ${BUILD_DIR}
|
||||||
|
conan install ${SOURCE_DIR} \
|
||||||
|
--output-folder ${BUILD_DIR} \
|
||||||
|
--install-folder ${BUILD_DIR} \
|
||||||
|
--build missing \
|
||||||
|
--settings build_type=Debug
|
||||||
|
|
||||||
|
- name: build with instrumentation
|
||||||
|
run: |
|
||||||
|
cd ${BUILD_DIR}
|
||||||
|
cmake -S ${SOURCE_DIR} -B ${BUILD_DIR} \
|
||||||
|
-Dvoidstar=ON \
|
||||||
|
-Dtests=ON \
|
||||||
|
-Dxrpld=ON \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DSECP256K1_BUILD_BENCHMARK=OFF \
|
||||||
|
-DSECP256K1_BUILD_TESTS=OFF \
|
||||||
|
-DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/build/generators/conan_toolchain.cmake
|
||||||
|
cmake --build . --parallel $(nproc)
|
||||||
|
|
||||||
|
- name: verify instrumentation enabled
|
||||||
|
run: |
|
||||||
|
cd ${BUILD_DIR}
|
||||||
|
./rippled --version | grep libvoidstar
|
||||||
|
|
||||||
|
- name: run unit tests
|
||||||
|
run: |
|
||||||
|
cd ${BUILD_DIR}
|
||||||
|
./rippled -u --unittest-jobs $(( $(nproc)/4 ))
|
||||||
97
.github/workflows/windows.yml
vendored
Normal file
97
.github/workflows/windows.yml
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
name: windows
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
# If the branches list is ever changed, be sure to change it on all
|
||||||
|
# build/test jobs (nix, macos, windows, instrumentation)
|
||||||
|
branches:
|
||||||
|
# Always build the package branches
|
||||||
|
- develop
|
||||||
|
- release
|
||||||
|
- master
|
||||||
|
# Branches that opt-in to running
|
||||||
|
- 'ci/**'
|
||||||
|
|
||||||
|
# https://docs.github.com/en/actions/using-jobs/using-concurrency
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
test:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
version:
|
||||||
|
- generator: Visual Studio 17 2022
|
||||||
|
runs-on: windows-2022
|
||||||
|
configuration:
|
||||||
|
- type: Release
|
||||||
|
tests: true
|
||||||
|
- type: Debug
|
||||||
|
# Skip running unit tests on debug builds, because they
|
||||||
|
# take an unreasonable amount of time
|
||||||
|
tests: false
|
||||||
|
runtime: d
|
||||||
|
runs-on: ${{ matrix.version.runs-on }}
|
||||||
|
env:
|
||||||
|
build_dir: .build
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: choose Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.9
|
||||||
|
- name: learn Python cache directory
|
||||||
|
id: pip-cache
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
echo "dir=$(pip cache dir)" | tee ${GITHUB_OUTPUT}
|
||||||
|
- name: restore Python cache directory
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pip-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-${{ hashFiles('.github/workflows/windows.yml') }}
|
||||||
|
- name: install Conan
|
||||||
|
run: pip install wheel 'conan<2'
|
||||||
|
- name: check environment
|
||||||
|
run: |
|
||||||
|
dir env:
|
||||||
|
$env:PATH -split ';'
|
||||||
|
python --version
|
||||||
|
conan --version
|
||||||
|
cmake --version
|
||||||
|
- name: configure Conan
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
conan profile new default --detect
|
||||||
|
conan profile update settings.compiler.cppstd=20 default
|
||||||
|
conan profile update \
|
||||||
|
settings.compiler.runtime=MT${{ matrix.configuration.runtime }} \
|
||||||
|
default
|
||||||
|
- name: build dependencies
|
||||||
|
uses: ./.github/actions/dependencies
|
||||||
|
env:
|
||||||
|
CONAN_URL: http://18.143.149.228:8081/artifactory/api/conan/conan-non-prod
|
||||||
|
CONAN_LOGIN_USERNAME_RIPPLE: ${{ secrets.CONAN_USERNAME }}
|
||||||
|
CONAN_PASSWORD_RIPPLE: ${{ secrets.CONAN_TOKEN }}
|
||||||
|
with:
|
||||||
|
configuration: ${{ matrix.configuration.type }}
|
||||||
|
- name: build
|
||||||
|
uses: ./.github/actions/build
|
||||||
|
with:
|
||||||
|
generator: '${{ matrix.version.generator }}'
|
||||||
|
configuration: ${{ matrix.configuration.type }}
|
||||||
|
# Hard code for now. Move to the matrix if varied options are needed
|
||||||
|
cmake-args: '-Dassert=TRUE -Dwerr=TRUE -Dreporting=OFF -Dunity=ON'
|
||||||
|
cmake-target: install
|
||||||
|
- name: test
|
||||||
|
shell: bash
|
||||||
|
if: ${{ matrix.configuration.tests }}
|
||||||
|
run: |
|
||||||
|
${build_dir}/${{ matrix.configuration.type }}/rippled --unittest \
|
||||||
|
--unittest-jobs $(nproc)
|
||||||
56
.gitignore
vendored
56
.gitignore
vendored
@@ -1,5 +1,9 @@
|
|||||||
# .gitignore
|
# .gitignore
|
||||||
|
|
||||||
|
bin/boostbook_catalog.xml
|
||||||
|
bin/config.log
|
||||||
|
bin/project-cache.jam
|
||||||
|
|
||||||
# Ignore vim swap files.
|
# Ignore vim swap files.
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
@@ -17,20 +21,32 @@
|
|||||||
|
|
||||||
# Ignore object files.
|
# Ignore object files.
|
||||||
*.o
|
*.o
|
||||||
build
|
.nih_c
|
||||||
tags
|
tags
|
||||||
TAGS
|
TAGS
|
||||||
|
GTAGS
|
||||||
|
GRTAGS
|
||||||
|
GPATH
|
||||||
bin/rippled
|
bin/rippled
|
||||||
Debug/*.*
|
Debug/*.*
|
||||||
Release/*.*
|
Release/*.*
|
||||||
|
|
||||||
# Ignore locally installed node_modules
|
# Ignore coverage files.
|
||||||
/node_modules
|
*.gcno
|
||||||
|
*.gcda
|
||||||
|
*.gcov
|
||||||
|
|
||||||
|
# Levelization checking
|
||||||
|
Builds/levelization/results/rawincludes.txt
|
||||||
|
Builds/levelization/results/paths.txt
|
||||||
|
Builds/levelization/results/includes/
|
||||||
|
Builds/levelization/results/includedby/
|
||||||
|
|
||||||
# Ignore tmp directory.
|
# Ignore tmp directory.
|
||||||
tmp
|
tmp
|
||||||
|
|
||||||
# Ignore database directory.
|
# Ignore database directory.
|
||||||
|
db/
|
||||||
db/*.db
|
db/*.db
|
||||||
db/*.db-*
|
db/*.db-*
|
||||||
|
|
||||||
@@ -40,15 +56,15 @@ debug_log.txt
|
|||||||
# Ignore customized configs
|
# Ignore customized configs
|
||||||
rippled.cfg
|
rippled.cfg
|
||||||
validators.txt
|
validators.txt
|
||||||
test/config.js
|
|
||||||
|
|
||||||
# Doxygen generated documentation output
|
# Doxygen generated documentation output
|
||||||
HtmlDocumentation
|
HtmlDocumentation
|
||||||
|
docs/html_doc
|
||||||
|
|
||||||
# Xcode user-specific project settings
|
# Xcode user-specific project settings
|
||||||
# Xcode
|
# Xcode
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*/build/*
|
/build/
|
||||||
*.pbxuser
|
*.pbxuser
|
||||||
!default.pbxuser
|
!default.pbxuser
|
||||||
*.mode1v3
|
*.mode1v3
|
||||||
@@ -67,12 +83,32 @@ DerivedData
|
|||||||
# Intel Parallel Studio 2013 XE
|
# Intel Parallel Studio 2013 XE
|
||||||
My Amplifier XE Results - RippleD
|
My Amplifier XE Results - RippleD
|
||||||
|
|
||||||
# KeyvaDB files
|
|
||||||
*.key
|
|
||||||
*.val
|
|
||||||
|
|
||||||
# Compiler intermediate output
|
# Compiler intermediate output
|
||||||
/out.txt
|
/out.txt
|
||||||
|
|
||||||
# Build Log
|
# Build Log
|
||||||
rippled-build.log
|
rippled-build.log
|
||||||
|
|
||||||
|
# Profiling data
|
||||||
|
gmon.out
|
||||||
|
|
||||||
|
Builds/VisualStudio2015/*.db
|
||||||
|
Builds/VisualStudio2015/*.user
|
||||||
|
Builds/VisualStudio2015/*.opendb
|
||||||
|
Builds/VisualStudio2015/*.sdf
|
||||||
|
|
||||||
|
# MSVC
|
||||||
|
*.pdb
|
||||||
|
.vs/
|
||||||
|
CMakeSettings.json
|
||||||
|
compile_commands.json
|
||||||
|
.clangd
|
||||||
|
packages
|
||||||
|
pkg_out
|
||||||
|
pkg
|
||||||
|
CMakeUserPresets.json
|
||||||
|
bld.rippled/
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Suggested in-tree build directory
|
||||||
|
/.build/
|
||||||
|
|||||||
6
.pre-commit-config.yaml
Normal file
6
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# .pre-commit-config.yaml
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v18.1.3
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
61
.travis.yml
61
.travis.yml
@@ -1,61 +0,0 @@
|
|||||||
language: cpp
|
|
||||||
compiler:
|
|
||||||
- clang
|
|
||||||
- gcc
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- sudo apt-get install -qq python-software-properties
|
|
||||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
|
||||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- sudo apt-get install -qq g++-4.8
|
|
||||||
- sudo apt-get install -qq libboost1.55-all-dev
|
|
||||||
# We want debug symbols for boost as we install gdb later
|
|
||||||
- sudo apt-get install -qq libboost1.55-dbg
|
|
||||||
- | # Setup the BOOST_ROOT
|
|
||||||
export BOOST_ROOT=$HOME/boost_root
|
|
||||||
mkdir -p $BOOST_ROOT/stage
|
|
||||||
ln -s /usr/lib/x86_64-linux-gnu $BOOST_ROOT/stage/lib
|
|
||||||
ln -s /usr/include/boost $BOOST_ROOT/boost
|
|
||||||
- | # Try to patch boost
|
|
||||||
sudo patch /usr/include/boost/bimap/detail/debug/static_error.hpp Builds/travis/static_error.boost.patch
|
|
||||||
sudo patch /usr/include/boost/config/compiler/clang.hpp Builds/travis/clang.boost.patch
|
|
||||||
- sudo apt-get install -qq mlocate
|
|
||||||
- sudo updatedb
|
|
||||||
- sudo locate libboost | grep /lib | grep -e ".a$"
|
|
||||||
- sudo apt-get install -qq protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags
|
|
||||||
# We need gcc >= 4.8 for some c++11 features
|
|
||||||
- sudo apt-get install -qq gcc-4.8
|
|
||||||
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
|
|
||||||
- sudo update-alternatives --set gcc /usr/bin/gcc-4.8
|
|
||||||
# Stuff is gold. Nuff said ;)
|
|
||||||
- sudo apt-get -y install binutils-gold
|
|
||||||
# We can get a backtrace if the guy crashes
|
|
||||||
- sudo apt-get -y install gdb
|
|
||||||
# What versions are we ACTUALLY running?
|
|
||||||
- g++ -v
|
|
||||||
- clang -v
|
|
||||||
|
|
||||||
script:
|
|
||||||
# Set so any failing command will abort the build
|
|
||||||
- set -e
|
|
||||||
# If only we could do -j12 ;)
|
|
||||||
- scons
|
|
||||||
# See what we've actually built
|
|
||||||
- ldd ./build/rippled
|
|
||||||
# Run unittests (under gdb)
|
|
||||||
- | # create gdb script
|
|
||||||
echo "set env MALLOC_CHECK_=3" > script.gdb
|
|
||||||
echo "run" >> script.gdb
|
|
||||||
echo "backtrace full" >> script.gdb
|
|
||||||
# gdb --help
|
|
||||||
- cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args ./build/rippled --unittest
|
|
||||||
# Run integration tests
|
|
||||||
- npm install
|
|
||||||
- npm test
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
false
|
|
||||||
irc:
|
|
||||||
channels:
|
|
||||||
- "chat.freenode.net#ripple-dev"
|
|
||||||
217
API-CHANGELOG.md
Normal file
217
API-CHANGELOG.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
# API Changelog
|
||||||
|
|
||||||
|
This changelog is intended to list all updates to the [public API methods](https://xrpl.org/public-api-methods.html).
|
||||||
|
|
||||||
|
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
|
||||||
|
|
||||||
|
The API version controls the API behavior you see. This includes what properties you see in responses, what parameters you're permitted to send in requests, and so on. You specify the API version in each of your requests. When a breaking change is introduced to the `rippled` API, a new version is released. To avoid breaking your code, you should set (or increase) your version when you're ready to upgrade.
|
||||||
|
|
||||||
|
For a log of breaking changes, see the **API Version [number]** headings. In general, breaking changes are associated with a particular API Version number. For non-breaking changes, scroll to the **XRP Ledger version [x.y.z]** headings. Non-breaking changes are associated with a particular XRP Ledger (`rippled`) release.
|
||||||
|
|
||||||
|
## API Version 2
|
||||||
|
|
||||||
|
API version 2 is available in `rippled` version 2.0.0 and later. To use this API, clients specify `"api_version" : 2` in each request.
|
||||||
|
|
||||||
|
#### Removed methods
|
||||||
|
|
||||||
|
In API version 2, the following deprecated methods are no longer available: (https://github.com/XRPLF/rippled/pull/4759)
|
||||||
|
|
||||||
|
- `tx_history` - Instead, use other methods such as `account_tx` or `ledger` with the `transactions` field set to `true`.
|
||||||
|
- `ledger_header` - Instead, use the `ledger` method.
|
||||||
|
|
||||||
|
#### Modifications to JSON transaction element in V2
|
||||||
|
|
||||||
|
In API version 2, JSON elements for transaction output have been changed and made consistent for all methods which output transactions. (https://github.com/XRPLF/rippled/pull/4775)
|
||||||
|
This helps to unify the JSON serialization format of transactions. (https://github.com/XRPLF/clio/issues/722, https://github.com/XRPLF/rippled/issues/4727)
|
||||||
|
|
||||||
|
- JSON transaction element is named `tx_json`
|
||||||
|
- Binary transaction element is named `tx_blob`
|
||||||
|
- JSON transaction metadata element is named `meta`
|
||||||
|
- Binary transaction metadata element is named `meta_blob`
|
||||||
|
|
||||||
|
Additionally, these elements are now consistently available next to `tx_json` (i.e. sibling elements), where possible:
|
||||||
|
|
||||||
|
- `hash` - Transaction ID. This data was stored inside transaction output in API version 1, but in API version 2 is a sibling element.
|
||||||
|
- `ledger_index` - Ledger index (only set on validated ledgers)
|
||||||
|
- `ledger_hash` - Ledger hash (only set on closed or validated ledgers)
|
||||||
|
- `close_time_iso` - Ledger close time expressed in ISO 8601 time format (only set on validated ledgers)
|
||||||
|
- `validated` - Bool element set to `true` if the transaction is in a validated ledger, otherwise `false`
|
||||||
|
|
||||||
|
This change affects the following methods:
|
||||||
|
|
||||||
|
- `tx` - Transaction data moved into element `tx_json` (was inline inside `result`) or, if binary output was requested, moved from `tx` to `tx_blob`. Renamed binary transaction metadata element (if it was requested) from `meta` to `meta_blob`. Changed location of `hash` and added new elements
|
||||||
|
- `account_tx` - Renamed transaction element from `tx` to `tx_json`. Renamed binary transaction metadata element (if it was requested) from `meta` to `meta_blob`. Changed location of `hash` and added new elements
|
||||||
|
- `transaction_entry` - Renamed transaction metadata element from `metadata` to `meta`. Changed location of `hash` and added new elements
|
||||||
|
- `subscribe` - Renamed transaction element from `transaction` to `tx_json`. Changed location of `hash` and added new elements
|
||||||
|
- `sign`, `sign_for`, `submit` and `submit_multisigned` - Changed location of `hash` element.
|
||||||
|
|
||||||
|
#### Modification to `Payment` transaction JSON schema
|
||||||
|
|
||||||
|
When reading Payments, the `Amount` field should generally **not** be used. Instead, use [delivered_amount](https://xrpl.org/partial-payments.html#the-delivered_amount-field) to see the amount that the Payment delivered. To clarify its meaning, the `Amount` field is being renamed to `DeliverMax`. (https://github.com/XRPLF/rippled/pull/4733)
|
||||||
|
|
||||||
|
- In `Payment` transaction type, JSON RPC field `Amount` is renamed to `DeliverMax`. To enable smooth client transition, `Amount` is still handled, as described below: (https://github.com/XRPLF/rippled/pull/4733)
|
||||||
|
- On JSON RPC input (e.g. `submit_multisigned` etc. methods), `Amount` is recognized as an alias to `DeliverMax` for both API version 1 and version 2 clients.
|
||||||
|
- On JSON RPC input, submitting both `Amount` and `DeliverMax` fields is allowed _only_ if they are identical; otherwise such input is rejected with `rpcINVALID_PARAMS` error.
|
||||||
|
- On JSON RPC output (e.g. `subscribe`, `account_tx` etc. methods), `DeliverMax` is present in both API version 1 and version 2.
|
||||||
|
- On JSON RPC output, `Amount` is only present in API version 1 and _not_ in version 2.
|
||||||
|
|
||||||
|
#### Modifications to account_info response
|
||||||
|
|
||||||
|
- `signer_lists` is returned in the root of the response. (In API version 1, it was nested under `account_data`.) (https://github.com/XRPLF/rippled/pull/3770)
|
||||||
|
- When using an invalid `signer_lists` value, the API now returns an "invalidParams" error. (https://github.com/XRPLF/rippled/pull/4585)
|
||||||
|
- (`signer_lists` must be a boolean. In API version 1, strings were accepted and may return a normal response - i.e. as if `signer_lists` were `true`.)
|
||||||
|
|
||||||
|
#### Modifications to [account_tx](https://xrpl.org/account_tx.html#account_tx) response
|
||||||
|
|
||||||
|
- Using `ledger_index_min`, `ledger_index_max`, and `ledger_index` returns `invalidParams` because if you use `ledger_index_min` or `ledger_index_max`, then it does not make sense to also specify `ledger_index`. In API version 1, no error was returned. (https://github.com/XRPLF/rippled/pull/4571)
|
||||||
|
- The same applies for `ledger_index_min`, `ledger_index_max`, and `ledger_hash`. (https://github.com/XRPLF/rippled/issues/4545#issuecomment-1565065579)
|
||||||
|
- Using a `ledger_index_min` or `ledger_index_max` beyond the range of ledgers that the server has:
|
||||||
|
- returns `lgrIdxMalformed` in API version 2. Previously, in API version 1, no error was returned. (https://github.com/XRPLF/rippled/issues/4288)
|
||||||
|
- Attempting to use a non-boolean value (such as a string) for the `binary` or `forward` parameters returns `invalidParams` (`rpcINVALID_PARAMS`). Previously, in API version 1, no error was returned. (https://github.com/XRPLF/rippled/pull/4620)
|
||||||
|
|
||||||
|
#### Modifications to [noripple_check](https://xrpl.org/noripple_check.html#noripple_check) response
|
||||||
|
|
||||||
|
- Attempting to use a non-boolean value (such as a string) for the `transactions` parameter returns `invalidParams` (`rpcINVALID_PARAMS`). Previously, in API version 1, no error was returned. (https://github.com/XRPLF/rippled/pull/4620)
|
||||||
|
|
||||||
|
## API Version 1
|
||||||
|
|
||||||
|
This version is supported by all `rippled` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
|
||||||
|
|
||||||
|
The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conventions/request-formatting/#commandline-format) always uses the latest API version. The command line is intended for ad-hoc usage by humans, not programs or automated scripts. The command line is not meant for use in production code.
|
||||||
|
|
||||||
|
### Inconsistency: server_info - network_id
|
||||||
|
|
||||||
|
The `network_id` field was added in the `server_info` response in version 1.5.0 (2019), but it is not returned in [reporting mode](https://xrpl.org/rippled-server-modes.html#reporting-mode). However, use of reporting mode is now discouraged, in favor of using [Clio](https://github.com/XRPLF/clio) instead.
|
||||||
|
|
||||||
|
## XRP Ledger server version 2.4.0
|
||||||
|
|
||||||
|
As of 2025-01-28, version 2.4.0 is in development. You can use a pre-release version by building from source or [using the `nightly` package](https://xrpl.org/docs/infrastructure/installation/install-rippled-on-ubuntu).
|
||||||
|
|
||||||
|
### Additions and bugfixes in 2.4.0
|
||||||
|
|
||||||
|
- `ledger_entry`: `state` is added an alias for `ripple_state`.
|
||||||
|
- `ledger_entry`: Enables case-insensitive filtering by canonical name in addition to case-sensitive filtering by RPC name.
|
||||||
|
- `validators`: Added new field `validator_list_threshold` in response.
|
||||||
|
- `simulate`: A new RPC that executes a [dry run of a transaction submission](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0069d-simulate#2-rpc-simulate)
|
||||||
|
- Signing methods autofill fees better and properly handle transactions that don't have a base fee, and will also autofill the `NetworkID` field.
|
||||||
|
|
||||||
|
## XRP Ledger server version 2.3.0
|
||||||
|
|
||||||
|
[Version 2.3.0](https://github.com/XRPLF/rippled/releases/tag/2.3.0) was released on Nov 25, 2024.
|
||||||
|
|
||||||
|
### Breaking changes in 2.3.0
|
||||||
|
|
||||||
|
- `book_changes`: If the requested ledger version is not available on this node, a `ledgerNotFound` error is returned and the node does not attempt to acquire the ledger from the p2p network (as with other non-admin RPCs).
|
||||||
|
|
||||||
|
Admins can still attempt to retrieve old ledgers with the `ledger_request` RPC.
|
||||||
|
|
||||||
|
### Additions and bugfixes in 2.3.0
|
||||||
|
|
||||||
|
- `book_changes`: Returns a `validated` field in its response, which was missing in prior versions.
|
||||||
|
|
||||||
|
## XRP Ledger server version 2.2.0
|
||||||
|
|
||||||
|
[Version 2.2.0](https://github.com/XRPLF/rippled/releases/tag/2.2.0) was released on Jun 5, 2024. The following additions are non-breaking (because they are purely additive):
|
||||||
|
|
||||||
|
- The `feature` method now has a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781))
|
||||||
|
|
||||||
|
## XRP Ledger server version 2.0.0
|
||||||
|
|
||||||
|
[Version 2.0.0](https://github.com/XRPLF/rippled/releases/tag/2.0.0) was released on Jan 9, 2024. The following additions are non-breaking (because they are purely additive):
|
||||||
|
|
||||||
|
- `server_definitions`: A new RPC that generates a `definitions.json`-like output that can be used in XRPL libraries.
|
||||||
|
- In `Payment` transactions, `DeliverMax` has been added. This is a replacement for the `Amount` field, which should not be used. Typically, the `delivered_amount` (in transaction metadata) should be used. To ease the transition, `DeliverMax` is present regardless of API version, since adding a field is non-breaking.
|
||||||
|
- API version 2 has been moved from beta to supported, meaning that it is generally available (regardless of the `beta_rpc_api` setting).
|
||||||
|
|
||||||
|
## XRP Ledger server version 2.2.0
|
||||||
|
|
||||||
|
The following is a non-breaking addition to the API.
|
||||||
|
|
||||||
|
- The `feature` method now has a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781))
|
||||||
|
|
||||||
|
## XRP Ledger server version 1.12.0
|
||||||
|
|
||||||
|
[Version 1.12.0](https://github.com/XRPLF/rippled/releases/tag/1.12.0) was released on Sep 6, 2023. The following additions are non-breaking (because they are purely additive).
|
||||||
|
|
||||||
|
- `server_info`: Added `ports`, an array which advertises the RPC and WebSocket ports. This information is also included in the `/crawl` endpoint (which calls `server_info` internally). `grpc` and `peer` ports are also included. (https://github.com/XRPLF/rippled/pull/4427)
|
||||||
|
- `ports` contains objects, each containing a `port` for the listening port (a number string), and a `protocol` array listing the supported protocols on that port.
|
||||||
|
- This allows crawlers to build a more detailed topology without needing to port-scan nodes.
|
||||||
|
- (For peers and other non-admin clients, the info about admin ports is excluded.)
|
||||||
|
- Clawback: The following additions are gated by the Clawback amendment (`featureClawback`). (https://github.com/XRPLF/rippled/pull/4553)
|
||||||
|
- Adds an [AccountRoot flag](https://xrpl.org/accountroot.html#accountroot-flags) called `lsfAllowTrustLineClawback` (https://github.com/XRPLF/rippled/pull/4617)
|
||||||
|
- Adds the corresponding `asfAllowTrustLineClawback` [AccountSet Flag](https://xrpl.org/accountset.html#accountset-flags) as well.
|
||||||
|
- Clawback is disabled by default, so if an issuer desires the ability to claw back funds, they must use an `AccountSet` transaction to set the AllowTrustLineClawback flag. They must do this before creating any trust lines, offers, escrows, payment channels, or checks.
|
||||||
|
- Adds the [Clawback transaction type](https://github.com/XRPLF/XRPL-Standards/blob/master/XLS-39d-clawback/README.md#331-clawback-transaction), containing these fields:
|
||||||
|
- `Account`: The issuer of the asset being clawed back. Must also be the sender of the transaction.
|
||||||
|
- `Amount`: The amount being clawed back, with the `Amount.issuer` being the token holder's address.
|
||||||
|
- Adds [AMM](https://github.com/XRPLF/XRPL-Standards/discussions/78) ([#4294](https://github.com/XRPLF/rippled/pull/4294), [#4626](https://github.com/XRPLF/rippled/pull/4626)) feature:
|
||||||
|
- Adds `amm_info` API to retrieve AMM information for a given tokens pair.
|
||||||
|
- Adds `AMMCreate` transaction type to create `AMM` instance.
|
||||||
|
- Adds `AMMDeposit` transaction type to deposit funds into `AMM` instance.
|
||||||
|
- Adds `AMMWithdraw` transaction type to withdraw funds from `AMM` instance.
|
||||||
|
- Adds `AMMVote` transaction type to vote for the trading fee of `AMM` instance.
|
||||||
|
- Adds `AMMBid` transaction type to bid for the Auction Slot of `AMM` instance.
|
||||||
|
- Adds `AMMDelete` transaction type to delete `AMM` instance.
|
||||||
|
- Adds `sfAMMID` to `AccountRoot` to indicate that the account is `AMM`'s account. `AMMID` is used to fetch `ltAMM`.
|
||||||
|
- Adds `lsfAMMNode` `TrustLine` flag to indicate that one side of the `TrustLine` is `AMM` account.
|
||||||
|
- Adds `tfLPToken`, `tfSingleAsset`, `tfTwoAsset`, `tfOneAssetLPToken`, `tfLimitLPToken`, `tfTwoAssetIfEmpty`,
|
||||||
|
`tfWithdrawAll`, `tfOneAssetWithdrawAll` which allow a trader to specify different fields combination
|
||||||
|
for `AMMDeposit` and `AMMWithdraw` transactions.
|
||||||
|
- Adds new transaction result codes:
|
||||||
|
- tecUNFUNDED_AMM: insufficient balance to fund AMM. The account does not have funds for liquidity provision.
|
||||||
|
- tecAMM_BALANCE: AMM has invalid balance. Calculated balances greater than the current pool balances.
|
||||||
|
- tecAMM_FAILED: AMM transaction failed. Fails due to a processing failure.
|
||||||
|
- tecAMM_INVALID_TOKENS: AMM invalid LP tokens. Invalid input values, format, or calculated values.
|
||||||
|
- tecAMM_EMPTY: AMM is in empty state. Transaction requires AMM in non-empty state (LP tokens > 0).
|
||||||
|
- tecAMM_NOT_EMPTY: AMM is not in empty state. Transaction requires AMM in empty state (LP tokens == 0).
|
||||||
|
- tecAMM_ACCOUNT: AMM account. Clawback of AMM account.
|
||||||
|
- tecINCOMPLETE: Some work was completed, but more submissions required to finish. AMMDelete partially deletes the trustlines.
|
||||||
|
|
||||||
|
## XRP Ledger server version 1.11.0
|
||||||
|
|
||||||
|
[Version 1.11.0](https://github.com/XRPLF/rippled/releases/tag/1.11.0) was released on Jun 20, 2023.
|
||||||
|
|
||||||
|
### Breaking changes in 1.11
|
||||||
|
|
||||||
|
- Added the ability to mark amendments as obsolete. For the `feature` admin API, there is a new possible value for the `vetoed` field. (https://github.com/XRPLF/rippled/pull/4291)
|
||||||
|
- The value of `vetoed` can now be `true`, `false`, or `"Obsolete"`.
|
||||||
|
- Removed the acceptance of seeds or public keys in place of account addresses. (https://github.com/XRPLF/rippled/pull/4404)
|
||||||
|
- This simplifies the API and encourages better security practices (i.e. seeds should never be sent over the network).
|
||||||
|
- For the `ledger_data` method, when all entries are filtered out, the `state` field of the response is now an empty list (in other words, an empty array, `[]`). (Previously, it would return `null`.) While this is technically a breaking change, the new behavior is consistent with the documentation, so this is considered only a bug fix. (https://github.com/XRPLF/rippled/pull/4398)
|
||||||
|
- If and when the `fixNFTokenRemint` amendment activates, there will be a new AccountRoot field, `FirstNFTSequence`. This field is set to the current account sequence when the account issues their first NFT. If an account has not issued any NFTs, then the field is not set. ([#4406](https://github.com/XRPLF/rippled/pull/4406))
|
||||||
|
- There is a new account deletion restriction: an account can only be deleted if `FirstNFTSequence` + `MintedNFTokens` + `256` is less than the current ledger sequence.
|
||||||
|
- This is potentially a breaking change if clients have logic for determining whether an account can be deleted.
|
||||||
|
- NetworkID
|
||||||
|
- For sidechains and networks with a network ID greater than 1024, there is a new [transaction common field](https://xrpl.org/transaction-common-fields.html), `NetworkID`. (https://github.com/XRPLF/rippled/pull/4370)
|
||||||
|
- This field helps to prevent replay attacks and is now required for chains whose network ID is 1025 or higher.
|
||||||
|
- The field must be omitted for Mainnet, so there is no change for Mainnet users.
|
||||||
|
- There are three new local error codes:
|
||||||
|
- `telNETWORK_ID_MAKES_TX_NON_CANONICAL`: a `NetworkID` is present but the chain's network ID is less than 1025. Remove the field from the transaction, and try again.
|
||||||
|
- `telREQUIRES_NETWORK_ID`: a `NetworkID` is required, but is not present. Add the field to the transaction, and try again.
|
||||||
|
- `telWRONG_NETWORK`: a `NetworkID` is specified, but it is for a different network. Submit the transaction to a different server which is connected to the correct network.
|
||||||
|
|
||||||
|
### Additions and bug fixes in 1.11
|
||||||
|
|
||||||
|
- Added `nftoken_id`, `nftoken_ids` and `offer_id` meta fields into NFT `tx` and `account_tx` responses. (https://github.com/XRPLF/rippled/pull/4447)
|
||||||
|
- Added an `account_flags` object to the `account_info` method response. (https://github.com/XRPLF/rippled/pull/4459)
|
||||||
|
- Added `NFTokenPages` to the `account_objects` RPC. (https://github.com/XRPLF/rippled/pull/4352)
|
||||||
|
- Fixed: `marker` returned from the `account_lines` command would not work on subsequent commands. (https://github.com/XRPLF/rippled/pull/4361)
|
||||||
|
|
||||||
|
## XRP Ledger server version 1.10.0
|
||||||
|
|
||||||
|
[Version 1.10.0](https://github.com/XRPLF/rippled/releases/tag/1.10.0)
|
||||||
|
was released on Mar 14, 2023.
|
||||||
|
|
||||||
|
### Breaking changes in 1.10
|
||||||
|
|
||||||
|
- If the `XRPFees` feature is enabled, the `fee_ref` field will be
|
||||||
|
removed from the [ledger subscription stream](https://xrpl.org/subscribe.html#ledger-stream), because it will no longer
|
||||||
|
have any meaning.
|
||||||
|
|
||||||
|
# Unit tests for API changes
|
||||||
|
|
||||||
|
The following information is useful to developers contributing to this project:
|
||||||
|
|
||||||
|
The purpose of unit tests is to catch bugs and prevent regressions. In general, it often makes sense to create a test function when there is a breaking change to the API. For APIs that have changed in a new API version, the tests should be modified so that both the prior version and the new version are properly tested.
|
||||||
|
|
||||||
|
To take one example: for `account_info` version 1, WebSocket and JSON-RPC behavior should be tested. The latest API version, i.e. API version 2, should be tested over WebSocket, JSON-RPC, and command line.
|
||||||
500
BUILD.md
Normal file
500
BUILD.md
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
| :warning: **WARNING** :warning:
|
||||||
|
|---|
|
||||||
|
| These instructions assume you have a C++ development environment ready with Git, Python, Conan, CMake, and a C++ compiler. For help setting one up on Linux, macOS, or Windows, [see this guide](./docs/build/environment.md). |
|
||||||
|
|
||||||
|
> These instructions also assume a basic familiarity with Conan and CMake.
|
||||||
|
> If you are unfamiliar with Conan,
|
||||||
|
> you can read our [crash course](./docs/build/conan.md)
|
||||||
|
> or the official [Getting Started][3] walkthrough.
|
||||||
|
|
||||||
|
## Branches
|
||||||
|
|
||||||
|
For a stable release, choose the `master` branch or one of the [tagged
|
||||||
|
releases](https://github.com/ripple/rippled/releases).
|
||||||
|
|
||||||
|
```
|
||||||
|
git checkout master
|
||||||
|
```
|
||||||
|
|
||||||
|
For the latest release candidate, choose the `release` branch.
|
||||||
|
|
||||||
|
```
|
||||||
|
git checkout release
|
||||||
|
```
|
||||||
|
|
||||||
|
For the latest set of untested features, or to contribute, choose the `develop`
|
||||||
|
branch.
|
||||||
|
|
||||||
|
```
|
||||||
|
git checkout develop
|
||||||
|
```
|
||||||
|
|
||||||
|
## Minimum Requirements
|
||||||
|
|
||||||
|
See [System Requirements](https://xrpl.org/system-requirements.html).
|
||||||
|
|
||||||
|
Building rippled generally requires git, Python, Conan, CMake, and a C++ compiler. Some guidance on setting up such a [C++ development environment can be found here](./docs/build/environment.md).
|
||||||
|
|
||||||
|
- [Python 3.7](https://www.python.org/downloads/)
|
||||||
|
- [Conan 1.60](https://conan.io/downloads.html)[^1]
|
||||||
|
- [CMake 3.16](https://cmake.org/download/)
|
||||||
|
|
||||||
|
[^1]: It is possible to build with Conan 2.x,
|
||||||
|
but the instructions are significantly different,
|
||||||
|
which is why we are not recommending it yet.
|
||||||
|
Notably, the `conan profile update` command is removed in 2.x.
|
||||||
|
Profiles must be edited by hand.
|
||||||
|
|
||||||
|
`rippled` is written in the C++20 dialect and includes the `<concepts>` header.
|
||||||
|
The [minimum compiler versions][2] required are:
|
||||||
|
|
||||||
|
| Compiler | Version |
|
||||||
|
|-------------|---------|
|
||||||
|
| GCC | 11 |
|
||||||
|
| Clang | 13 |
|
||||||
|
| Apple Clang | 13.1.6 |
|
||||||
|
| MSVC | 19.23 |
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
The Ubuntu operating system has received the highest level of
|
||||||
|
quality assurance, testing, and support.
|
||||||
|
|
||||||
|
Here are [sample instructions for setting up a C++ development environment on Linux](./docs/build/environment.md#linux).
|
||||||
|
|
||||||
|
### Mac
|
||||||
|
|
||||||
|
Many rippled engineers use macOS for development.
|
||||||
|
|
||||||
|
Here are [sample instructions for setting up a C++ development environment on macOS](./docs/build/environment.md#macos).
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
Windows is not recommended for production use at this time.
|
||||||
|
|
||||||
|
- Additionally, 32-bit Windows development is not supported.
|
||||||
|
|
||||||
|
[Boost]: https://www.boost.org/
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
### Set Up Conan
|
||||||
|
|
||||||
|
After you have a [C++ development environment](./docs/build/environment.md) ready with Git, Python, Conan, CMake, and a C++ compiler, you may need to set up your Conan profile.
|
||||||
|
|
||||||
|
These instructions assume a basic familiarity with Conan and CMake.
|
||||||
|
|
||||||
|
If you are unfamiliar with Conan, then please read [this crash course](./docs/build/conan.md) or the official [Getting Started][3] walkthrough.
|
||||||
|
|
||||||
|
You'll need at least one Conan profile:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile new default --detect
|
||||||
|
```
|
||||||
|
|
||||||
|
Update the compiler settings:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile update settings.compiler.cppstd=20 default
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure Conan (1.x only) to use recipe revisions:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan config set general.revisions_enabled=1
|
||||||
|
```
|
||||||
|
|
||||||
|
**Linux** developers will commonly have a default Conan [profile][] that compiles
|
||||||
|
with GCC and links with libstdc++.
|
||||||
|
If you are linking with libstdc++ (see profile setting `compiler.libcxx`),
|
||||||
|
then you will need to choose the `libstdc++11` ABI:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile update settings.compiler.libcxx=libstdc++11 default
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Ensure inter-operability between `boost::string_view` and `std::string_view` types:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_BEAST_USE_STD_STRING_VIEW"]' default
|
||||||
|
conan profile update 'env.CXXFLAGS="-DBOOST_BEAST_USE_STD_STRING_VIEW"' default
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have other flags in the `conf.tools.build` or `env.CXXFLAGS` sections, make sure to retain the existing flags and append the new ones. You can check them with:
|
||||||
|
```
|
||||||
|
conan profile show default
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
**Windows** developers may need to use the x64 native build tools.
|
||||||
|
An easy way to do that is to run the shortcut "x64 Native Tools Command
|
||||||
|
Prompt" for the version of Visual Studio that you have installed.
|
||||||
|
|
||||||
|
Windows developers must also build `rippled` and its dependencies for the x64
|
||||||
|
architecture:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile update settings.arch=x86_64 default
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple compilers
|
||||||
|
|
||||||
|
When `/usr/bin/g++` exists on a platform, it is the default cpp compiler. This
|
||||||
|
default works for some users.
|
||||||
|
|
||||||
|
However, if this compiler cannot build rippled or its dependencies, then you can
|
||||||
|
install another compiler and set Conan and CMake to use it.
|
||||||
|
Update the `conf.tools.build:compiler_executables` setting in order to set the correct variables (`CMAKE_<LANG>_COMPILER`) in the
|
||||||
|
generated CMake toolchain file.
|
||||||
|
For example, on Ubuntu 20, you may have gcc at `/usr/bin/gcc` and g++ at `/usr/bin/g++`; if that is the case, you can select those compilers with:
|
||||||
|
```
|
||||||
|
conan profile update 'conf.tools.build:compiler_executables={"c": "/usr/bin/gcc", "cpp": "/usr/bin/g++"}' default
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `/usr/bin/gcc` and `/usr/bin/g++` with paths to the desired compilers.
|
||||||
|
|
||||||
|
It should choose the compiler for dependencies as well,
|
||||||
|
but not all of them have a Conan recipe that respects this setting (yet).
|
||||||
|
For the rest, you can set these environment variables.
|
||||||
|
Replace `<path>` with paths to the desired compilers:
|
||||||
|
|
||||||
|
- `conan profile update env.CC=<path> default`
|
||||||
|
- `conan profile update env.CXX=<path> default`
|
||||||
|
|
||||||
|
Export our [Conan recipe for Snappy](./external/snappy).
|
||||||
|
It does not explicitly link the C++ standard library,
|
||||||
|
which allows you to statically link it with GCC, if you want.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Conan 1.x
|
||||||
|
conan export external/snappy snappy/1.1.10@
|
||||||
|
# Conan 2.x
|
||||||
|
conan export --version 1.1.10 external/snappy
|
||||||
|
```
|
||||||
|
|
||||||
|
Export our [Conan recipe for RocksDB](./external/rocksdb).
|
||||||
|
It does not override paths to dependencies when building with Visual Studio.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Conan 1.x
|
||||||
|
conan export external/rocksdb rocksdb/6.29.5@
|
||||||
|
# Conan 2.x
|
||||||
|
conan export --version 6.29.5 external/rocksdb
|
||||||
|
```
|
||||||
|
|
||||||
|
Export our [Conan recipe for SOCI](./external/soci).
|
||||||
|
It patches their CMake to correctly import its dependencies.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Conan 1.x
|
||||||
|
conan export external/soci soci/4.0.3@
|
||||||
|
# Conan 2.x
|
||||||
|
conan export --version 4.0.3 external/soci
|
||||||
|
```
|
||||||
|
|
||||||
|
Export our [Conan recipe for NuDB](./external/nudb).
|
||||||
|
It fixes some source files to add missing `#include`s.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
# Conan 1.x
|
||||||
|
conan export external/nudb nudb/2.0.8@
|
||||||
|
# Conan 2.x
|
||||||
|
conan export --version 2.0.8 external/nudb
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build and Test
|
||||||
|
|
||||||
|
1. Create a build directory and move into it.
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir .build
|
||||||
|
cd .build
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use any directory name. Conan treats your working directory as an
|
||||||
|
install folder and generates files with implementation details.
|
||||||
|
You don't need to worry about these files, but make sure to change
|
||||||
|
your working directory to your build directory before calling Conan.
|
||||||
|
|
||||||
|
**Note:** You can specify a directory for the installation files by adding
|
||||||
|
the `install-folder` or `-if` option to every `conan install` command
|
||||||
|
in the next step.
|
||||||
|
|
||||||
|
2. Use conan to generate CMake files for every configuration you want to build:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan install .. --output-folder . --build missing --settings build_type=Release
|
||||||
|
conan install .. --output-folder . --build missing --settings build_type=Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
To build Debug, in the next step, be sure to set `-DCMAKE_BUILD_TYPE=Debug`
|
||||||
|
|
||||||
|
For a single-configuration generator, e.g. `Unix Makefiles` or `Ninja`,
|
||||||
|
you only need to run this command once.
|
||||||
|
For a multi-configuration generator, e.g. `Visual Studio`, you may want to
|
||||||
|
run it more than once.
|
||||||
|
|
||||||
|
Each of these commands should also have a different `build_type` setting.
|
||||||
|
A second command with the same `build_type` setting will overwrite the files
|
||||||
|
generated by the first. You can pass the build type on the command line with
|
||||||
|
`--settings build_type=$BUILD_TYPE` or in the profile itself,
|
||||||
|
under the section `[settings]` with the key `build_type`.
|
||||||
|
|
||||||
|
If you are using a Microsoft Visual C++ compiler,
|
||||||
|
then you will need to ensure consistency between the `build_type` setting
|
||||||
|
and the `compiler.runtime` setting.
|
||||||
|
|
||||||
|
When `build_type` is `Release`, `compiler.runtime` should be `MT`.
|
||||||
|
|
||||||
|
When `build_type` is `Debug`, `compiler.runtime` should be `MTd`.
|
||||||
|
|
||||||
|
```
|
||||||
|
conan install .. --output-folder . --build missing --settings build_type=Release --settings compiler.runtime=MT
|
||||||
|
conan install .. --output-folder . --build missing --settings build_type=Debug --settings compiler.runtime=MTd
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Configure CMake and pass the toolchain file generated by Conan, located at
|
||||||
|
`$OUTPUT_FOLDER/build/generators/conan_toolchain.cmake`.
|
||||||
|
|
||||||
|
Single-config generators:
|
||||||
|
|
||||||
|
Pass the CMake variable [`CMAKE_BUILD_TYPE`][build_type]
|
||||||
|
and make sure it matches the one of the `build_type` settings
|
||||||
|
you chose in the previous step.
|
||||||
|
|
||||||
|
For example, to build Debug, in the next command, replace "Release" with "Debug"
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -Dxrpld=ON -Dtests=ON ..
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Multi-config generators:
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -Dxrpld=ON -Dtests=ON ..
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** You can pass build options for `rippled` in this step.
|
||||||
|
|
||||||
|
5. Build `rippled`.
|
||||||
|
|
||||||
|
For a single-configuration generator, it will build whatever configuration
|
||||||
|
you passed for `CMAKE_BUILD_TYPE`. For a multi-configuration generator,
|
||||||
|
you must pass the option `--config` to select the build configuration.
|
||||||
|
|
||||||
|
Single-config generators:
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
Multi-config generators:
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake --build . --config Release
|
||||||
|
cmake --build . --config Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Test rippled.
|
||||||
|
|
||||||
|
Single-config generators:
|
||||||
|
|
||||||
|
```
|
||||||
|
./rippled --unittest
|
||||||
|
```
|
||||||
|
|
||||||
|
Multi-config generators:
|
||||||
|
|
||||||
|
```
|
||||||
|
./Release/rippled --unittest
|
||||||
|
./Debug/rippled --unittest
|
||||||
|
```
|
||||||
|
|
||||||
|
The location of `rippled` in your build directory depends on your CMake
|
||||||
|
generator. Pass `--help` to see the rest of the command line options.
|
||||||
|
|
||||||
|
|
||||||
|
## Coverage report
|
||||||
|
|
||||||
|
The coverage report is intended for developers using compilers GCC
|
||||||
|
or Clang (including Apple Clang). It is generated by the build target `coverage`,
|
||||||
|
which is only enabled when the `coverage` option is set, e.g. with
|
||||||
|
`--options coverage=True` in `conan` or `-Dcoverage=ON` variable in `cmake`
|
||||||
|
|
||||||
|
Prerequisites for the coverage report:
|
||||||
|
|
||||||
|
- [gcovr tool][gcovr] (can be installed e.g. with [pip][python-pip])
|
||||||
|
- `gcov` for GCC (installed with the compiler by default) or
|
||||||
|
- `llvm-cov` for Clang (installed with the compiler by default)
|
||||||
|
- `Debug` build type
|
||||||
|
|
||||||
|
A coverage report is created when the following steps are completed, in order:
|
||||||
|
|
||||||
|
1. `rippled` binary built with instrumentation data, enabled by the `coverage`
|
||||||
|
option mentioned above
|
||||||
|
2. completed run of unit tests, which populates coverage capture data
|
||||||
|
3. completed run of the `gcovr` tool (which internally invokes either `gcov` or `llvm-cov`)
|
||||||
|
to assemble both instrumentation data and the coverage capture data into a coverage report
|
||||||
|
|
||||||
|
The above steps are automated into a single target `coverage`. The instrumented
|
||||||
|
`rippled` binary can also be used for regular development or testing work, at
|
||||||
|
the cost of extra disk space utilization and a small performance hit
|
||||||
|
(to store coverage capture). In case of a spurious failure of unit tests, it is
|
||||||
|
possible to re-run the `coverage` target without rebuilding the `rippled` binary
|
||||||
|
(since it is simply a dependency of the coverage report target). It is also possible
|
||||||
|
to select only specific tests for the purpose of the coverage report, by setting
|
||||||
|
the `coverage_test` variable in `cmake`
|
||||||
|
|
||||||
|
The default coverage report format is `html-details`, but the user
|
||||||
|
can override it to any of the formats listed in `Builds/CMake/CodeCoverage.cmake`
|
||||||
|
by setting the `coverage_format` variable in `cmake`. It is also possible
|
||||||
|
to generate more than one format at a time by setting the `coverage_extra_args`
|
||||||
|
variable in `cmake`. The specific command line used to run the `gcovr` tool will be
|
||||||
|
displayed if the `CODE_COVERAGE_VERBOSE` variable is set.
|
||||||
|
|
||||||
|
By default, the code coverage tool runs parallel unit tests with `--unittest-jobs`
|
||||||
|
set to the number of available CPU cores. This may cause spurious test
|
||||||
|
errors on Apple. Developers can override the number of unit test jobs with
|
||||||
|
the `coverage_test_parallelism` variable in `cmake`.
|
||||||
|
|
||||||
|
Example use with some cmake variables set:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd .build
|
||||||
|
conan install .. --output-folder . --build missing --settings build_type=Debug
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Debug -Dcoverage=ON -Dxrpld=ON -Dtests=ON -Dcoverage_test_parallelism=2 -Dcoverage_format=html-details -Dcoverage_extra_args="--json coverage.json" -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake ..
|
||||||
|
cmake --build . --target coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
After the `coverage` target is completed, the generated coverage report will be
|
||||||
|
stored inside the build directory, as either of:
|
||||||
|
|
||||||
|
- file named `coverage.`_extension_ , with a suitable extension for the report format, or
|
||||||
|
- directory named `coverage`, with the `index.html` and other files inside, for the `html-details` or `html-nested` report formats.
|
||||||
|
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
| Option | Default Value | Description |
|
||||||
|
| --- | ---| ---|
|
||||||
|
| `assert` | OFF | Enable assertions.
|
||||||
|
| `coverage` | OFF | Prepare the coverage report. |
|
||||||
|
| `san` | N/A | Enable a sanitizer with Clang. Choices are `thread` and `address`. |
|
||||||
|
| `tests` | OFF | Build tests. |
|
||||||
|
| `unity` | ON | Configure a unity build. |
|
||||||
|
| `xrpld` | OFF | Build the xrpld (`rippled`) application, and not just the libxrpl library. |
|
||||||
|
|
||||||
|
[Unity builds][5] may be faster for the first build
|
||||||
|
(at the cost of much more memory) since they concatenate sources into fewer
|
||||||
|
translation units. Non-unity builds may be faster for incremental builds,
|
||||||
|
and can be helpful for detecting `#include` omissions.
|
||||||
|
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
|
||||||
|
### Conan
|
||||||
|
|
||||||
|
After any updates or changes to dependencies, you may need to do the following:
|
||||||
|
|
||||||
|
1. Remove your build directory.
|
||||||
|
2. Remove the Conan cache:
|
||||||
|
```
|
||||||
|
rm -rf ~/.conan/data
|
||||||
|
```
|
||||||
|
4. Re-run [conan install](#build-and-test).
|
||||||
|
|
||||||
|
|
||||||
|
### 'protobuf/port_def.inc' file not found
|
||||||
|
|
||||||
|
If `cmake --build .` results in an error due to a missing a protobuf file, then you might have generated CMake files for a different `build_type` than the `CMAKE_BUILD_TYPE` you passed to conan.
|
||||||
|
|
||||||
|
```
|
||||||
|
/rippled/.build/pb-xrpl.libpb/xrpl/proto/ripple.pb.h:10:10: fatal error: 'google/protobuf/port_def.inc' file not found
|
||||||
|
10 | #include <google/protobuf/port_def.inc>
|
||||||
|
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
1 error generated.
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, if you want to build Debug:
|
||||||
|
|
||||||
|
1. For conan install, pass `--settings build_type=Debug`
|
||||||
|
2. For cmake, pass `-DCMAKE_BUILD_TYPE=Debug`
|
||||||
|
|
||||||
|
|
||||||
|
### no std::result_of
|
||||||
|
|
||||||
|
If your compiler version is recent enough to have removed `std::result_of` as
|
||||||
|
part of C++20, e.g. Apple Clang 15.0, then you might need to add a preprocessor
|
||||||
|
definition to your build.
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile update 'options.boost:extra_b2_flags="define=BOOST_ASIO_HAS_STD_INVOKE_RESULT"' default
|
||||||
|
conan profile update 'env.CFLAGS="-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"' default
|
||||||
|
conan profile update 'env.CXXFLAGS="-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"' default
|
||||||
|
conan profile update 'conf.tools.build:cflags+=["-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"]' default
|
||||||
|
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"]' default
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### call to 'async_teardown' is ambiguous
|
||||||
|
|
||||||
|
If you are compiling with an early version of Clang 16, then you might hit
|
||||||
|
a [regression][6] when compiling C++20 that manifests as an [error in a Boost
|
||||||
|
header][7]. You can workaround it by adding this preprocessor definition:
|
||||||
|
|
||||||
|
```
|
||||||
|
conan profile update 'env.CXXFLAGS="-DBOOST_ASIO_DISABLE_CONCEPTS"' default
|
||||||
|
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_DISABLE_CONCEPTS"]' default
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### recompile with -fPIC
|
||||||
|
|
||||||
|
If you get a linker error suggesting that you recompile Boost with
|
||||||
|
position-independent code, such as:
|
||||||
|
|
||||||
|
```
|
||||||
|
/usr/bin/ld.gold: error: /home/username/.conan/data/boost/1.77.0/_/_/package/.../lib/libboost_container.a(alloc_lib.o):
|
||||||
|
requires unsupported dynamic reloc 11; recompile with -fPIC
|
||||||
|
```
|
||||||
|
|
||||||
|
Conan most likely downloaded a bad binary distribution of the dependency.
|
||||||
|
This seems to be a [bug][1] in Conan just for Boost 1.77.0 compiled with GCC
|
||||||
|
for Linux. The solution is to build the dependency locally by passing
|
||||||
|
`--build boost` when calling `conan install`.
|
||||||
|
|
||||||
|
```
|
||||||
|
conan install --build boost ...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Add a Dependency
|
||||||
|
|
||||||
|
If you want to experiment with a new package, follow these steps:
|
||||||
|
|
||||||
|
1. Search for the package on [Conan Center](https://conan.io/center/).
|
||||||
|
2. Modify [`conanfile.py`](./conanfile.py):
|
||||||
|
- Add a version of the package to the `requires` property.
|
||||||
|
- Change any default options for the package by adding them to the
|
||||||
|
`default_options` property (with syntax `'$package:$option': $value`).
|
||||||
|
3. Modify [`CMakeLists.txt`](./CMakeLists.txt):
|
||||||
|
- Add a call to `find_package($package REQUIRED)`.
|
||||||
|
- Link a library from the package to the target `ripple_libs`
|
||||||
|
(search for the existing call to `target_link_libraries(ripple_libs INTERFACE ...)`).
|
||||||
|
4. Start coding! Don't forget to include whatever headers you need from the package.
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://github.com/conan-io/conan-center-index/issues/13168
|
||||||
|
[2]: https://en.cppreference.com/w/cpp/compiler_support/20
|
||||||
|
[3]: https://docs.conan.io/en/latest/getting_started.html
|
||||||
|
[5]: https://en.wikipedia.org/wiki/Unity_build
|
||||||
|
[6]: https://github.com/boostorg/beast/issues/2648
|
||||||
|
[7]: https://github.com/boostorg/beast/issues/2661
|
||||||
|
[gcovr]: https://gcovr.com/en/stable/getting-started.html
|
||||||
|
[python-pip]: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/
|
||||||
|
[build_type]: https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
|
||||||
|
[profile]: https://docs.conan.io/en/latest/reference/profiles.html
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Maintainer: Roberto Catini <roberto.catini@gmail.com>
|
|
||||||
|
|
||||||
pkgname=rippled
|
|
||||||
pkgrel=1
|
|
||||||
pkgver=0
|
|
||||||
pkgdesc="Ripple peer-to-peer network daemon"
|
|
||||||
arch=('i686' 'x86_64')
|
|
||||||
url="https://github.com/ripple/rippled"
|
|
||||||
license=('custom:ISC')
|
|
||||||
depends=('protobuf' 'openssl' 'boost-libs')
|
|
||||||
makedepends=('git' 'scons' 'boost')
|
|
||||||
checkdepends=('nodejs')
|
|
||||||
backup=("etc/$pkgname/rippled.cfg")
|
|
||||||
source=("git://github.com/ripple/rippled.git#branch=master")
|
|
||||||
sha512sums=('SKIP')
|
|
||||||
|
|
||||||
pkgver() {
|
|
||||||
cd "$srcdir/$pkgname"
|
|
||||||
git describe --long --tags | sed -r 's/([^-]*-g)/r\1/;s/-/./g'
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "$srcdir/$pkgname"
|
|
||||||
scons build/rippled
|
|
||||||
}
|
|
||||||
|
|
||||||
check() {
|
|
||||||
cd "$srcdir/$pkgname"
|
|
||||||
npm install
|
|
||||||
npm test
|
|
||||||
build/rippled --unittest
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "$srcdir/$pkgname"
|
|
||||||
install -D -m644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
|
||||||
install -D build/rippled "$pkgdir/usr/bin/rippled"
|
|
||||||
install -D -m644 doc/rippled-example.cfg "$pkgdir/etc/$pkgname/rippled.cfg"
|
|
||||||
mkdir -p "$pkgdir/var/lib/$pkgname/db"
|
|
||||||
mkdir -p "$pkgdir/var/log/$pkgname"
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# rippled
|
|
||||||
|
|
||||||
# use the ubuntu base image
|
|
||||||
FROM ubuntu
|
|
||||||
MAINTAINER Roberto Catini roberto.catini@gmail.com
|
|
||||||
|
|
||||||
# make sure the package repository is up to date
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get -y upgrade
|
|
||||||
|
|
||||||
# install the dependencies
|
|
||||||
RUN apt-get -y install git scons pkg-config protobuf-compiler libprotobuf-dev libssl-dev libboost1.55-all-dev
|
|
||||||
|
|
||||||
# download source code from official repository
|
|
||||||
RUN git clone https://github.com/ripple/rippled.git src; cd src/; git checkout master
|
|
||||||
|
|
||||||
# compile
|
|
||||||
RUN cd src/; scons build/rippled
|
|
||||||
|
|
||||||
# move to root directory and strip
|
|
||||||
RUN cp src/build/rippled rippled; strip rippled
|
|
||||||
|
|
||||||
# copy default config
|
|
||||||
RUN cp src/doc/rippled-example.cfg rippled.cfg
|
|
||||||
|
|
||||||
# clean source
|
|
||||||
RUN rm -r src
|
|
||||||
|
|
||||||
# launch rippled when launching the container
|
|
||||||
ENTRYPOINT ./rippled
|
|
||||||
5
Builds/QtCreator/.gitignore
vendored
5
Builds/QtCreator/.gitignore
vendored
@@ -1,5 +0,0 @@
|
|||||||
# QTCreator
|
|
||||||
|
|
||||||
Makefile
|
|
||||||
*.user
|
|
||||||
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
|
|
||||||
# Ripple protocol buffers
|
|
||||||
|
|
||||||
PROTOS = ../../src/ripple_data/protocol/ripple.proto
|
|
||||||
PROTOS_DIR = ../../build/proto
|
|
||||||
|
|
||||||
# Google Protocol Buffers support
|
|
||||||
|
|
||||||
protobuf_h.name = protobuf header
|
|
||||||
protobuf_h.input = PROTOS
|
|
||||||
protobuf_h.output = $${PROTOS_DIR}/${QMAKE_FILE_BASE}.pb.h
|
|
||||||
protobuf_h.depends = ${QMAKE_FILE_NAME}
|
|
||||||
protobuf_h.commands = protoc --cpp_out=$${PROTOS_DIR} --proto_path=${QMAKE_FILE_PATH} ${QMAKE_FILE_NAME}
|
|
||||||
protobuf_h.variable_out = HEADERS
|
|
||||||
QMAKE_EXTRA_COMPILERS += protobuf_h
|
|
||||||
|
|
||||||
protobuf_cc.name = protobuf implementation
|
|
||||||
protobuf_cc.input = PROTOS
|
|
||||||
protobuf_cc.output = $${PROTOS_DIR}/${QMAKE_FILE_BASE}.pb.cc
|
|
||||||
protobuf_cc.depends = $${PROTOS_DIR}/${QMAKE_FILE_BASE}.pb.h
|
|
||||||
protobuf_cc.commands = $$escape_expand(\\n)
|
|
||||||
#protobuf_cc.variable_out = SOURCES
|
|
||||||
QMAKE_EXTRA_COMPILERS += protobuf_cc
|
|
||||||
|
|
||||||
# Ripple compilation
|
|
||||||
|
|
||||||
DESTDIR = ../../build/QtCreator
|
|
||||||
OBJECTS_DIR = ../../build/QtCreator/obj
|
|
||||||
|
|
||||||
TEMPLATE = app
|
|
||||||
CONFIG += console thread warn_off
|
|
||||||
CONFIG -= qt gui
|
|
||||||
|
|
||||||
DEFINES += _DEBUG
|
|
||||||
|
|
||||||
linux-g++:QMAKE_CXXFLAGS += \
|
|
||||||
-Wall \
|
|
||||||
-Wno-sign-compare \
|
|
||||||
-Wno-char-subscripts \
|
|
||||||
-Wno-invalid-offsetof \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-Wformat \
|
|
||||||
-O0 \
|
|
||||||
-std=c++11 \
|
|
||||||
-pthread
|
|
||||||
|
|
||||||
INCLUDEPATH += \
|
|
||||||
"../../src/leveldb/" \
|
|
||||||
"../../src/leveldb/port" \
|
|
||||||
"../../src/leveldb/include" \
|
|
||||||
$${PROTOS_DIR}
|
|
||||||
|
|
||||||
OTHER_FILES += \
|
|
||||||
# $$files(../../src/*, true) \
|
|
||||||
# $$files(../../src/beast/*) \
|
|
||||||
# $$files(../../src/beast/modules/beast_basics/diagnostic/*)
|
|
||||||
# $$files(../../src/beast/modules/beast_core/, true)
|
|
||||||
|
|
||||||
UI_HEADERS_DIR += ../../src/ripple_basics
|
|
||||||
|
|
||||||
# ---------
|
|
||||||
# New style
|
|
||||||
#
|
|
||||||
SOURCES += \
|
|
||||||
../../src/ripple/beast/ripple_beast.unity.cpp \
|
|
||||||
../../src/ripple/beast/ripple_beastc.c \
|
|
||||||
../../src/ripple/common/ripple_common.unity.cpp \
|
|
||||||
../../src/ripple/http/ripple_http.unity.cpp \
|
|
||||||
../../src/ripple/json/ripple_json.unity.cpp \
|
|
||||||
../../src/ripple/peerfinder/ripple_peerfinder.unity.cpp \
|
|
||||||
../../src/ripple/radmap/ripple_radmap.unity.cpp \
|
|
||||||
../../src/ripple/resource/ripple_resource.unity.cpp \
|
|
||||||
../../src/ripple/sitefiles/ripple_sitefiles.unity.cpp \
|
|
||||||
../../src/ripple/sslutil/ripple_sslutil.unity.cpp \
|
|
||||||
../../src/ripple/testoverlay/ripple_testoverlay.unity.cpp \
|
|
||||||
../../src/ripple/types/ripple_types.unity.cpp \
|
|
||||||
../../src/ripple/validators/ripple_validators.unity.cpp
|
|
||||||
|
|
||||||
# ---------
|
|
||||||
# Old style
|
|
||||||
#
|
|
||||||
SOURCES += \
|
|
||||||
../../src/ripple_app/ripple_app.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt1.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt2.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt3.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt4.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt5.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt6.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt7.unity.cpp \
|
|
||||||
../../src/ripple_app/ripple_app_pt8.unity.cpp \
|
|
||||||
../../src/ripple_basics/ripple_basics.unity.cpp \
|
|
||||||
../../src/ripple_core/ripple_core.unity.cpp \
|
|
||||||
../../src/ripple_data/ripple_data.unity.cpp \
|
|
||||||
../../src/ripple_hyperleveldb/ripple_hyperleveldb.unity.cpp \
|
|
||||||
../../src/ripple_leveldb/ripple_leveldb.unity.cpp \
|
|
||||||
../../src/ripple_net/ripple_net.unity.cpp \
|
|
||||||
../../src/ripple_overlay/ripple_overlay.unity.cpp \
|
|
||||||
../../src/ripple_rpc/ripple_rpc.unity.cpp \
|
|
||||||
../../src/ripple_websocket/ripple_websocket.unity.cpp
|
|
||||||
|
|
||||||
LIBS += \
|
|
||||||
-lboost_date_time-mt\
|
|
||||||
-lboost_filesystem-mt \
|
|
||||||
-lboost_program_options-mt \
|
|
||||||
-lboost_regex-mt \
|
|
||||||
-lboost_system-mt \
|
|
||||||
-lboost_thread-mt \
|
|
||||||
-lboost_random-mt \
|
|
||||||
-lprotobuf \
|
|
||||||
-lssl \
|
|
||||||
-lrt
|
|
||||||
4
Builds/VisualStudio2013/.gitattributes
vendored
4
Builds/VisualStudio2013/.gitattributes
vendored
@@ -1,4 +0,0 @@
|
|||||||
RippleD.vcxproj -text
|
|
||||||
RippleD.vcxproj.filters -text
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Express 2013 for Windows Desktop
|
|
||||||
VisualStudioVersion = 12.0.30110.0
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|Win32.ActiveCfg = debug|x64
|
|
||||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.ActiveCfg = debug|x64
|
|
||||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.Build.0 = debug|x64
|
|
||||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|Win32.ActiveCfg = release|x64
|
|
||||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.ActiveCfg = release|x64
|
|
||||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.Build.0 = release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Place XCode project file here!
|
|
||||||
114
Builds/levelization/README.md
Normal file
114
Builds/levelization/README.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# 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/rippled` (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` folder of any level
|
||||||
|
other than it's own.
|
||||||
|
|
||||||
|
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
|
||||||
|
state of the rippled code when it was created. 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.
|
||||||
|
|
||||||
|
| Level / Tier | Module(s) |
|
||||||
|
|--------------|-----------------------------------------------|
|
||||||
|
| 01 | ripple/beast ripple/unity
|
||||||
|
| 02 | ripple/basics
|
||||||
|
| 03 | ripple/json ripple/crypto
|
||||||
|
| 04 | ripple/protocol
|
||||||
|
| 05 | ripple/core ripple/conditions ripple/consensus ripple/resource ripple/server
|
||||||
|
| 06 | ripple/peerfinder ripple/ledger ripple/nodestore ripple/net
|
||||||
|
| 07 | ripple/shamap ripple/overlay
|
||||||
|
| 08 | ripple/app
|
||||||
|
| 09 | ripple/rpc
|
||||||
|
| 10 | ripple/perflog
|
||||||
|
| 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 `ripple` levelization, other than the requirement
|
||||||
|
that `test` code should *never* be included in `ripple` code.)
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
The [levelization.sh](levelization.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, deduped, 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_.
|
||||||
|
* `includedby/`: 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](../../.github/workflows/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](../../.github/workflows/levelization.yml) to validate
|
||||||
|
that nothing changed.
|
||||||
|
* [`levelization.yml`](../../.github/workflows/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 Builds/levelization/results/paths.txt | grep -w B`
|
||||||
130
Builds/levelization/levelization.sh
Executable file
130
Builds/levelization/levelization.sh
Executable file
@@ -0,0 +1,130 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Usage: levelization.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 includedby
|
||||||
|
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 dedup 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 includedby/${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
|
||||||
42
Builds/levelization/results/loops.txt
Normal file
42
Builds/levelization/results/loops.txt
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
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.ledger
|
||||||
|
xrpld.app > xrpld.ledger
|
||||||
|
|
||||||
|
Loop: xrpld.app xrpld.net
|
||||||
|
xrpld.app > xrpld.net
|
||||||
|
|
||||||
|
Loop: xrpld.app xrpld.overlay
|
||||||
|
xrpld.overlay == xrpld.app
|
||||||
|
|
||||||
|
Loop: xrpld.app xrpld.peerfinder
|
||||||
|
xrpld.app > xrpld.peerfinder
|
||||||
|
|
||||||
|
Loop: xrpld.app xrpld.rpc
|
||||||
|
xrpld.rpc > xrpld.app
|
||||||
|
|
||||||
|
Loop: xrpld.app xrpld.shamap
|
||||||
|
xrpld.app > xrpld.shamap
|
||||||
|
|
||||||
|
Loop: xrpld.core xrpld.net
|
||||||
|
xrpld.net > xrpld.core
|
||||||
|
|
||||||
|
Loop: xrpld.core xrpld.perflog
|
||||||
|
xrpld.perflog == xrpld.core
|
||||||
|
|
||||||
|
Loop: xrpld.net xrpld.rpc
|
||||||
|
xrpld.rpc ~= xrpld.net
|
||||||
|
|
||||||
|
Loop: xrpld.overlay xrpld.rpc
|
||||||
|
xrpld.rpc ~= xrpld.overlay
|
||||||
|
|
||||||
|
Loop: xrpld.perflog xrpld.rpc
|
||||||
|
xrpld.rpc ~= xrpld.perflog
|
||||||
|
|
||||||
197
Builds/levelization/results/ordering.txt
Normal file
197
Builds/levelization/results/ordering.txt
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
libxrpl.basics > xrpl.basics
|
||||||
|
libxrpl.crypto > xrpl.basics
|
||||||
|
libxrpl.json > xrpl.basics
|
||||||
|
libxrpl.json > xrpl.json
|
||||||
|
libxrpl.protocol > xrpl.basics
|
||||||
|
libxrpl.protocol > xrpl.json
|
||||||
|
libxrpl.protocol > xrpl.protocol
|
||||||
|
libxrpl.resource > xrpl.basics
|
||||||
|
libxrpl.resource > xrpl.resource
|
||||||
|
libxrpl.server > xrpl.basics
|
||||||
|
libxrpl.server > xrpl.json
|
||||||
|
libxrpl.server > xrpl.protocol
|
||||||
|
libxrpl.server > xrpl.server
|
||||||
|
test.app > test.jtx
|
||||||
|
test.app > test.rpc
|
||||||
|
test.app > test.toplevel
|
||||||
|
test.app > test.unit_test
|
||||||
|
test.app > xrpl.basics
|
||||||
|
test.app > xrpld.app
|
||||||
|
test.app > xrpld.core
|
||||||
|
test.app > xrpld.ledger
|
||||||
|
test.app > xrpld.nodestore
|
||||||
|
test.app > xrpld.overlay
|
||||||
|
test.app > xrpld.rpc
|
||||||
|
test.app > xrpl.json
|
||||||
|
test.app > xrpl.protocol
|
||||||
|
test.app > xrpl.resource
|
||||||
|
test.basics > test.jtx
|
||||||
|
test.basics > test.unit_test
|
||||||
|
test.basics > xrpl.basics
|
||||||
|
test.basics > xrpld.perflog
|
||||||
|
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 > xrpld.ledger
|
||||||
|
test.core > test.jtx
|
||||||
|
test.core > test.toplevel
|
||||||
|
test.core > test.unit_test
|
||||||
|
test.core > xrpl.basics
|
||||||
|
test.core > xrpld.core
|
||||||
|
test.core > xrpld.perflog
|
||||||
|
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.consensus
|
||||||
|
test.jtx > xrpld.core
|
||||||
|
test.jtx > xrpld.ledger
|
||||||
|
test.jtx > xrpld.net
|
||||||
|
test.jtx > xrpld.rpc
|
||||||
|
test.jtx > xrpl.json
|
||||||
|
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 > xrpld.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 > xrpld.nodestore
|
||||||
|
test.nodestore > xrpld.unity
|
||||||
|
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 > xrpld.shamap
|
||||||
|
test.overlay > xrpl.protocol
|
||||||
|
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 > xrpld.app
|
||||||
|
test.rpc > xrpld.core
|
||||||
|
test.rpc > xrpld.net
|
||||||
|
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 > xrpld.nodestore
|
||||||
|
test.shamap > xrpld.shamap
|
||||||
|
test.shamap > xrpl.protocol
|
||||||
|
test.toplevel > test.csf
|
||||||
|
test.toplevel > xrpl.json
|
||||||
|
test.unit_test > xrpl.basics
|
||||||
|
xrpl.json > xrpl.basics
|
||||||
|
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
|
||||||
|
xrpld.app > test.unit_test
|
||||||
|
xrpld.app > xrpl.basics
|
||||||
|
xrpld.app > xrpld.conditions
|
||||||
|
xrpld.app > xrpld.consensus
|
||||||
|
xrpld.app > xrpld.nodestore
|
||||||
|
xrpld.app > xrpld.perflog
|
||||||
|
xrpld.app > xrpl.json
|
||||||
|
xrpld.app > xrpl.protocol
|
||||||
|
xrpld.app > xrpl.resource
|
||||||
|
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.json
|
||||||
|
xrpld.core > xrpl.protocol
|
||||||
|
xrpld.ledger > xrpl.basics
|
||||||
|
xrpld.ledger > xrpld.core
|
||||||
|
xrpld.ledger > xrpl.json
|
||||||
|
xrpld.ledger > xrpl.protocol
|
||||||
|
xrpld.net > xrpl.basics
|
||||||
|
xrpld.net > xrpl.json
|
||||||
|
xrpld.net > xrpl.protocol
|
||||||
|
xrpld.net > xrpl.resource
|
||||||
|
xrpld.nodestore > xrpl.basics
|
||||||
|
xrpld.nodestore > xrpld.core
|
||||||
|
xrpld.nodestore > xrpld.unity
|
||||||
|
xrpld.nodestore > xrpl.json
|
||||||
|
xrpld.nodestore > xrpl.protocol
|
||||||
|
xrpld.overlay > xrpl.basics
|
||||||
|
xrpld.overlay > xrpld.core
|
||||||
|
xrpld.overlay > xrpld.peerfinder
|
||||||
|
xrpld.overlay > xrpld.perflog
|
||||||
|
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.json
|
||||||
|
xrpld.perflog > xrpl.protocol
|
||||||
|
xrpld.rpc > xrpl.basics
|
||||||
|
xrpld.rpc > xrpld.core
|
||||||
|
xrpld.rpc > xrpld.ledger
|
||||||
|
xrpld.rpc > xrpld.nodestore
|
||||||
|
xrpld.rpc > xrpl.json
|
||||||
|
xrpld.rpc > xrpl.protocol
|
||||||
|
xrpld.rpc > xrpl.resource
|
||||||
|
xrpld.rpc > xrpl.server
|
||||||
|
xrpld.shamap > xrpl.basics
|
||||||
|
xrpld.shamap > xrpld.nodestore
|
||||||
|
xrpld.shamap > xrpl.protocol
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
Name: rippled
|
|
||||||
Version: 0.26.2
|
|
||||||
Release: 1%{?dist}
|
|
||||||
Summary: Ripple peer-to-peer network daemon
|
|
||||||
|
|
||||||
Group: Applications/Internet
|
|
||||||
License: ISC
|
|
||||||
URL: https://github.com/ripple/rippled
|
|
||||||
|
|
||||||
# curl -L -o SOURCES/rippled-release.zip https://github.com/ripple/rippled/archive/release.zip
|
|
||||||
Source0: rippled-release.zip
|
|
||||||
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
|
||||||
|
|
||||||
BuildRequires: gcc-c++ scons openssl-devel protobuf-devel
|
|
||||||
Requires: protobuf openssl
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
|
||||||
Rippled is the server component of the Ripple network.
|
|
||||||
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%setup -n rippled-release
|
|
||||||
|
|
||||||
|
|
||||||
%build
|
|
||||||
# Assume boost is manually installed
|
|
||||||
export RIPPLED_BOOST_HOME=/usr/local/boost_1_55_0
|
|
||||||
scons -j `grep -c processor /proc/cpuinfo` build/rippled
|
|
||||||
|
|
||||||
|
|
||||||
%install
|
|
||||||
rm -rf %{buildroot}
|
|
||||||
mkdir -p %{buildroot}/usr/share/%{name}
|
|
||||||
cp LICENSE %{buildroot}/usr/share/%{name}/
|
|
||||||
mkdir -p %{buildroot}/usr/bin
|
|
||||||
cp build/rippled %{buildroot}/usr/bin/rippled
|
|
||||||
mkdir -p %{buildroot}/etc/%{name}
|
|
||||||
cp doc/rippled-example.cfg %{buildroot}/etc/%{name}/rippled.cfg
|
|
||||||
mkdir -p %{buildroot}/var/lib/%{name}/db
|
|
||||||
mkdir -p %{buildroot}/var/log/%{name}
|
|
||||||
|
|
||||||
|
|
||||||
%clean
|
|
||||||
rm -rf %{buildroot}
|
|
||||||
|
|
||||||
|
|
||||||
%files
|
|
||||||
%defattr(-,root,root,-)
|
|
||||||
/usr/bin/rippled
|
|
||||||
/usr/share/rippled/LICENSE
|
|
||||||
/etc/rippled/rippled-example.cfg
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
--- /usr/include/boost/config/compiler/clang.hpp 2013-07-20 13:17:10.000000000 -0400
|
|
||||||
+++ /usr/include/boost/config/compiler/clang.rippled.hpp 2014-03-11 16:40:51.000000000 -0400
|
|
||||||
@@ -39,6 +39,10 @@
|
|
||||||
// Clang supports "long long" in all compilation modes.
|
|
||||||
#define BOOST_HAS_LONG_LONG
|
|
||||||
|
|
||||||
+#if defined(__SIZEOF_INT128__)
|
|
||||||
+# define BOOST_HAS_INT128
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
//
|
|
||||||
// Dynamic shared object (DSO) and dynamic-link library (DLL) support
|
|
||||||
//
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
--- /usr/include/boost/bimap/detail/debug/static_error.hpp 2008-03-22 17:45:55.000000000 -0400
|
|
||||||
+++ /usr/include/boost/bimap/detail/debug/static_error.rippled.hpp 2014-03-12 19:40:05.000000000 -0400
|
|
||||||
@@ -25,7 +25,6 @@
|
|
||||||
// a static error.
|
|
||||||
/*===========================================================================*/
|
|
||||||
#define BOOST_BIMAP_STATIC_ERROR(MESSAGE,VARIABLES) \
|
|
||||||
- struct BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE) {}; \
|
|
||||||
BOOST_MPL_ASSERT_MSG(false, \
|
|
||||||
BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE), \
|
|
||||||
VARIABLES)
|
|
||||||
134
CMakeLists.txt
Normal file
134
CMakeLists.txt
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
if(POLICY CMP0074)
|
||||||
|
cmake_policy(SET CMP0074 NEW)
|
||||||
|
endif()
|
||||||
|
if(POLICY CMP0077)
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Fix "unrecognized escape" issues when passing CMAKE_MODULE_PATH on Windows.
|
||||||
|
file(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH)
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
project(xrpl)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# make GIT_COMMIT_HASH define available to all sources
|
||||||
|
find_package(Git)
|
||||||
|
if(Git_FOUND)
|
||||||
|
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse HEAD
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gch)
|
||||||
|
if(gch)
|
||||||
|
set(GIT_COMMIT_HASH "${gch}")
|
||||||
|
message(STATUS gch: ${GIT_COMMIT_HASH})
|
||||||
|
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse --abbrev-ref HEAD
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gb)
|
||||||
|
if(gb)
|
||||||
|
set(GIT_BRANCH "${gb}")
|
||||||
|
message(STATUS gb: ${GIT_BRANCH})
|
||||||
|
add_definitions(-DGIT_BRANCH="${GIT_BRANCH}")
|
||||||
|
endif()
|
||||||
|
endif() #git
|
||||||
|
|
||||||
|
if(thread_safety_analysis)
|
||||||
|
add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -DRIPPLE_ENABLE_THREAD_SAFETY_ANNOTATIONS)
|
||||||
|
add_compile_options("-stdlib=libc++")
|
||||||
|
add_link_options("-stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include (CheckCXXCompilerFlag)
|
||||||
|
include (FetchContent)
|
||||||
|
include (ExternalProject)
|
||||||
|
include (CMakeFuncs) # must come *after* ExternalProject b/c it overrides one function in EP
|
||||||
|
if (target)
|
||||||
|
message (FATAL_ERROR "The target option has been removed - use native cmake options to control build")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
include(RippledSanity)
|
||||||
|
include(RippledVersion)
|
||||||
|
include(RippledSettings)
|
||||||
|
# this check has to remain in the top-level cmake
|
||||||
|
# because of the early return statement
|
||||||
|
if (packages_only)
|
||||||
|
if (NOT TARGET rpm)
|
||||||
|
message (FATAL_ERROR "packages_only requested, but targets were not created - is docker installed?")
|
||||||
|
endif()
|
||||||
|
return ()
|
||||||
|
endif ()
|
||||||
|
include(RippledCompiler)
|
||||||
|
include(RippledInterface)
|
||||||
|
|
||||||
|
option(only_docs "Include only the docs target?" FALSE)
|
||||||
|
include(RippledDocs)
|
||||||
|
if(only_docs)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
include(deps/Boost)
|
||||||
|
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||||
|
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||||
|
INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
|
||||||
|
)
|
||||||
|
set(SECP256K1_INSTALL TRUE)
|
||||||
|
add_subdirectory(external/secp256k1)
|
||||||
|
add_library(secp256k1::secp256k1 ALIAS secp256k1)
|
||||||
|
add_subdirectory(external/ed25519-donna)
|
||||||
|
add_subdirectory(external/antithesis-sdk)
|
||||||
|
find_package(gRPC REQUIRED)
|
||||||
|
find_package(lz4 REQUIRED)
|
||||||
|
# Target names with :: are not allowed in a generator expression.
|
||||||
|
# We need to pull the include directories and imported location properties
|
||||||
|
# from separate targets.
|
||||||
|
find_package(LibArchive REQUIRED)
|
||||||
|
find_package(SOCI REQUIRED)
|
||||||
|
find_package(SQLite3 REQUIRED)
|
||||||
|
|
||||||
|
option(rocksdb "Enable RocksDB" ON)
|
||||||
|
if(rocksdb)
|
||||||
|
find_package(RocksDB REQUIRED)
|
||||||
|
set_target_properties(RocksDB::rocksdb PROPERTIES
|
||||||
|
INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1
|
||||||
|
)
|
||||||
|
target_link_libraries(ripple_libs INTERFACE RocksDB::rocksdb)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(nudb REQUIRED)
|
||||||
|
find_package(date REQUIRED)
|
||||||
|
find_package(xxHash REQUIRED)
|
||||||
|
|
||||||
|
target_link_libraries(ripple_libs INTERFACE
|
||||||
|
ed25519::ed25519
|
||||||
|
lz4::lz4
|
||||||
|
OpenSSL::Crypto
|
||||||
|
OpenSSL::SSL
|
||||||
|
secp256k1::secp256k1
|
||||||
|
soci::soci
|
||||||
|
SQLite::SQLite3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Work around changes to Conan recipe for now.
|
||||||
|
if(TARGET nudb::core)
|
||||||
|
set(nudb nudb::core)
|
||||||
|
elseif(TARGET NuDB::nudb)
|
||||||
|
set(nudb NuDB::nudb)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "unknown nudb target")
|
||||||
|
endif()
|
||||||
|
target_link_libraries(ripple_libs INTERFACE ${nudb})
|
||||||
|
|
||||||
|
if(coverage)
|
||||||
|
include(RippledCov)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PROJECT_EXPORT_SET RippleExports)
|
||||||
|
include(RippledCore)
|
||||||
|
include(RippledInstall)
|
||||||
|
include(RippledValidatorKeys)
|
||||||
1021
CONTRIBUTING.md
Normal file
1021
CONTRIBUTING.md
Normal file
File diff suppressed because it is too large
Load Diff
17
LICENSE.md
Normal file
17
LICENSE.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (c) 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant.
|
||||||
|
Copyright (c) 2012-2020, the XRP Ledger developers.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
84
README.md
84
README.md
@@ -1,41 +1,69 @@
|
|||||||
#rippled - Ripple P2P server
|
# The XRP Ledger
|
||||||
|
|
||||||
##[](https://travis-ci.org/ripple/rippled)
|
The [XRP Ledger](https://xrpl.org/) is a decentralized cryptographic ledger powered by a network of peer-to-peer nodes. The XRP Ledger uses a novel Byzantine Fault Tolerant consensus algorithm to settle and record transactions in a secure distributed database without a central operator.
|
||||||
|
|
||||||
This is the repository for Ripple's `rippled`, reference P2P server.
|
## XRP
|
||||||
|
[XRP](https://xrpl.org/xrp.html) is a public, counterparty-free asset native to the XRP Ledger, and is designed to bridge the many different currencies in use worldwide. XRP is traded on the open-market and is available for anyone to access. The XRP Ledger was created in 2012 with a finite supply of 100 billion units of XRP.
|
||||||
|
|
||||||
###Build instructions:
|
## rippled
|
||||||
* https://ripple.com/wiki/Rippled_build_instructions
|
The server software that powers the XRP Ledger is called `rippled` and is available in this repository under the permissive [ISC open-source license](LICENSE.md). The `rippled` server software is written primarily in C++ and runs on a variety of platforms. The `rippled` server software can run in several modes depending on its [configuration](https://xrpl.org/rippled-server-modes.html).
|
||||||
|
|
||||||
###Setup instructions:
|
If you are interested in running an **API Server** (including a **Full History Server**), take a look at [Clio](https://github.com/XRPLF/clio). (rippled Reporting Mode has been replaced by Clio.)
|
||||||
* https://ripple.com/wiki/Rippled_setup_instructions
|
|
||||||
|
### Build from Source
|
||||||
|
|
||||||
|
* [Read the build instructions in `BUILD.md`](BUILD.md)
|
||||||
|
* If you encounter any issues, please [open an issue](https://github.com/XRPLF/rippled/issues)
|
||||||
|
|
||||||
|
## Key Features of the XRP Ledger
|
||||||
|
|
||||||
|
- **[Censorship-Resistant Transaction Processing][]:** No single party decides which transactions succeed or fail, and no one can "roll back" a transaction after it completes. As long as those who choose to participate in the network keep it healthy, they can settle transactions in seconds.
|
||||||
|
- **[Fast, Efficient Consensus Algorithm][]:** The XRP Ledger's consensus algorithm settles transactions in 4 to 5 seconds, processing at a throughput of up to 1500 transactions per second. These properties put XRP at least an order of magnitude ahead of other top digital assets.
|
||||||
|
- **[Finite XRP Supply][]:** When the XRP Ledger began, 100 billion XRP were created, and no more XRP will ever be created. The available supply of XRP decreases slowly over time as small amounts are destroyed to pay transaction costs.
|
||||||
|
- **[Responsible Software Governance][]:** A team of full-time, world-class developers at Ripple maintain and continually improve the XRP Ledger's underlying software with contributions from the open-source community. Ripple acts as a steward for the technology and an advocate for its interests, and builds constructive relationships with governments and financial institutions worldwide.
|
||||||
|
- **[Secure, Adaptable Cryptography][]:** The XRP Ledger relies on industry standard digital signature systems like ECDSA (the same scheme used by Bitcoin) but also supports modern, efficient algorithms like Ed25519. The extensible nature of the XRP Ledger's software makes it possible to add and disable algorithms as the state of the art in cryptography advances.
|
||||||
|
- **[Modern Features for Smart Contracts][]:** Features like Escrow, Checks, and Payment Channels support cutting-edge financial applications including the [Interledger Protocol](https://interledger.org/). This toolbox of advanced features comes with safety features like a process for amending the network and separate checks against invariant constraints.
|
||||||
|
- **[On-Ledger Decentralized Exchange][]:** In addition to all the features that make XRP useful on its own, the XRP Ledger also has a fully-functional accounting system for tracking and trading obligations denominated in any way users want, and an exchange built into the protocol. The XRP Ledger can settle long, cross-currency payment paths and exchanges of multiple currencies in atomic transactions, bridging gaps of trust with XRP.
|
||||||
|
|
||||||
|
[Censorship-Resistant Transaction Processing]: https://xrpl.org/xrp-ledger-overview.html#censorship-resistant-transaction-processing
|
||||||
|
[Fast, Efficient Consensus Algorithm]: https://xrpl.org/xrp-ledger-overview.html#fast-efficient-consensus-algorithm
|
||||||
|
[Finite XRP Supply]: https://xrpl.org/xrp-ledger-overview.html#finite-xrp-supply
|
||||||
|
[Responsible Software Governance]: https://xrpl.org/xrp-ledger-overview.html#responsible-software-governance
|
||||||
|
[Secure, Adaptable Cryptography]: https://xrpl.org/xrp-ledger-overview.html#secure-adaptable-cryptography
|
||||||
|
[Modern Features for Smart Contracts]: https://xrpl.org/xrp-ledger-overview.html#modern-features-for-smart-contracts
|
||||||
|
[On-Ledger Decentralized Exchange]: https://xrpl.org/xrp-ledger-overview.html#on-ledger-decentralized-exchange
|
||||||
|
|
||||||
|
|
||||||
|
## Source Code
|
||||||
|
|
||||||
|
Here are some good places to start learning the source code:
|
||||||
|
|
||||||
|
- Read the markdown files in the source tree: `src/ripple/**/*.md`.
|
||||||
|
- Read [the levelization document](./Builds/levelization) to get an idea of the internal dependency graph.
|
||||||
|
- In the big picture, the `main` function constructs an `ApplicationImp` object, which implements the `Application` virtual interface. Almost every component in the application takes an `Application&` parameter in its constructor, typically named `app` and stored as a member variable `app_`. This allows most components to depend on any other component.
|
||||||
|
|
||||||
### Repository Contents
|
### Repository Contents
|
||||||
|
|
||||||
#### ./bin
|
| Folder | Contents |
|
||||||
Scripts and data files for Ripple integrators.
|
|:-----------|:-------------------------------------------------|
|
||||||
|
| `./bin` | Scripts and data files for Ripple integrators. |
|
||||||
|
| `./Builds` | Platform-specific guides for building `rippled`. |
|
||||||
|
| `./docs` | Source documentation files and doxygen config. |
|
||||||
|
| `./cfg` | Example configuration files. |
|
||||||
|
| `./src` | Source code. |
|
||||||
|
|
||||||
#### ./build
|
Some of the directories under `src` are external repositories included using
|
||||||
Intermediate and final build outputs.
|
git-subtree. See those directories' README files for more details.
|
||||||
|
|
||||||
#### ./Builds
|
|
||||||
Platform or IDE-specific project files.
|
|
||||||
|
|
||||||
#### ./doc
|
## Additional Documentation
|
||||||
Documentation and example configuration files.
|
|
||||||
|
|
||||||
#### ./src
|
* [XRP Ledger Dev Portal](https://xrpl.org/)
|
||||||
Source code directory. Some of the directories contained here are
|
* [Setup and Installation](https://xrpl.org/install-rippled.html)
|
||||||
external repositories inlined via git-subtree, see the corresponding
|
* [Source Documentation (Doxygen)](https://xrplf.github.io/rippled/)
|
||||||
README for more details.
|
|
||||||
|
|
||||||
#### ./test
|
## See Also
|
||||||
Javascript / Mocha tests.
|
|
||||||
|
|
||||||
## License
|
* [Clio API Server for the XRP Ledger](https://github.com/XRPLF/clio)
|
||||||
Ripple is open source and permissively licensed under the ISC license. See the
|
* [Mailing List for Release Announcements](https://groups.google.com/g/ripple-server)
|
||||||
LICENSE file for more details.
|
* [Learn more about the XRP Ledger (YouTube)](https://www.youtube.com/playlist?list=PLJQ55Tj1hIVZtJ_JdTvSum2qMTsedWkNi)
|
||||||
|
|
||||||
###For more information:
|
|
||||||
* https://ripple.com
|
|
||||||
* https://ripple.com/wiki
|
|
||||||
|
|||||||
4817
RELEASENOTES.md
Normal file
4817
RELEASENOTES.md
Normal file
File diff suppressed because it is too large
Load Diff
615
SConstruct
615
SConstruct
@@ -1,615 +0,0 @@
|
|||||||
# rippled SConstruct
|
|
||||||
#
|
|
||||||
'''
|
|
||||||
|
|
||||||
Target Builds
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
<none> Same as 'install'
|
|
||||||
install Default target and copies it to build/rippled (default)
|
|
||||||
|
|
||||||
all All available variants
|
|
||||||
debug All available debug variants
|
|
||||||
release All available release variants
|
|
||||||
|
|
||||||
clang All clang variants
|
|
||||||
clang.debug clang debug variant
|
|
||||||
clang.release clang release variant
|
|
||||||
|
|
||||||
gcc All gcc variants
|
|
||||||
gcc.debug gcc debug variant
|
|
||||||
gcc.release gcc release variant
|
|
||||||
|
|
||||||
msvc All msvc variants
|
|
||||||
msvc.debug MSVC debug variant
|
|
||||||
msvc.release MSVC release variant
|
|
||||||
|
|
||||||
vcxproj Generate Visual Studio 2013 project file
|
|
||||||
|
|
||||||
If the clang toolchain is detected, then the default target will use it, else
|
|
||||||
the gcc toolchain will be used. On Windows environments, the MSVC toolchain is
|
|
||||||
also detected.
|
|
||||||
|
|
||||||
'''
|
|
||||||
#
|
|
||||||
'''
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
- Fix git-describe support
|
|
||||||
- Fix printing exemplar command lines
|
|
||||||
- Fix toolchain detection
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
import collections
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import textwrap
|
|
||||||
import time
|
|
||||||
import SCons.Action
|
|
||||||
|
|
||||||
sys.path.append(os.path.join('src', 'beast', 'site_scons'))
|
|
||||||
|
|
||||||
import Beast
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def parse_time(t):
|
|
||||||
return time.strptime(t, '%a %b %d %H:%M:%S %Z %Y')
|
|
||||||
|
|
||||||
CHECK_PLATFORMS = 'Debian', 'Ubuntu'
|
|
||||||
CHECK_COMMAND = 'openssl version -a'
|
|
||||||
CHECK_LINE = 'built on: '
|
|
||||||
BUILD_TIME = 'Mon Apr 7 20:33:19 UTC 2014'
|
|
||||||
OPENSSL_ERROR = ('Your openSSL was built on %s; '
|
|
||||||
'rippled needs a version built on or after %s.')
|
|
||||||
|
|
||||||
def check_openssl():
|
|
||||||
if Beast.system.platform in CHECK_PLATFORMS:
|
|
||||||
for line in subprocess.check_output(CHECK_COMMAND.split()).splitlines():
|
|
||||||
if line.startswith(CHECK_LINE):
|
|
||||||
line = line[len(CHECK_LINE):]
|
|
||||||
if parse_time(line) < parse_time(BUILD_TIME):
|
|
||||||
raise Exception(OPENSSL_ERROR % (line, BUILD_TIME))
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
raise Exception("Didn't find any '%s' line in '$ %s'" %
|
|
||||||
(CHECK_LINE, CHECK_COMMAND))
|
|
||||||
|
|
||||||
|
|
||||||
def import_environ(env):
|
|
||||||
'''Imports environment settings into the construction environment'''
|
|
||||||
def set(keys):
|
|
||||||
if type(keys) == list:
|
|
||||||
for key in keys:
|
|
||||||
set(key)
|
|
||||||
return
|
|
||||||
if keys in os.environ:
|
|
||||||
value = os.environ[keys]
|
|
||||||
env[keys] = value
|
|
||||||
set(['GNU_CC', 'GNU_CXX', 'GNU_LINK'])
|
|
||||||
set(['CLANG_CC', 'CLANG_CXX', 'CLANG_LINK'])
|
|
||||||
|
|
||||||
def detect_toolchains(env):
|
|
||||||
def is_compiler(comp_from, comp_to):
|
|
||||||
return comp_from and comp_to in comp_from
|
|
||||||
|
|
||||||
def detect_clang(env):
|
|
||||||
n = sum(x in env for x in ['CLANG_CC', 'CLANG_CXX', 'CLANG_LINK'])
|
|
||||||
if n > 0:
|
|
||||||
if n == 3:
|
|
||||||
return True
|
|
||||||
raise ValueError('CLANG_CC, CLANG_CXX, and CLANG_LINK must be set together')
|
|
||||||
cc = env.get('CC')
|
|
||||||
cxx = env.get('CXX')
|
|
||||||
link = env.subst(env.get('LINK'))
|
|
||||||
if (cc and cxx and link and
|
|
||||||
is_compiler(cc, 'clang') and
|
|
||||||
is_compiler(cxx, 'clang') and
|
|
||||||
is_compiler(link, 'clang')):
|
|
||||||
env['CLANG_CC'] = cc
|
|
||||||
env['CLANG_CXX'] = cxx
|
|
||||||
env['CLANG_LINK'] = link
|
|
||||||
return True
|
|
||||||
cc = env.WhereIs('clang')
|
|
||||||
cxx = env.WhereIs('clang++')
|
|
||||||
link = cxx
|
|
||||||
if (is_compiler(cc, 'clang') and
|
|
||||||
is_compiler(cxx, 'clang') and
|
|
||||||
is_compiler(link, 'clang')):
|
|
||||||
env['CLANG_CC'] = cc
|
|
||||||
env['CLANG_CXX'] = cxx
|
|
||||||
env['CLANG_LINK'] = link
|
|
||||||
return True
|
|
||||||
env['CLANG_CC'] = 'clang'
|
|
||||||
env['CLANG_CXX'] = 'clang++'
|
|
||||||
env['CLANG_LINK'] = env['LINK']
|
|
||||||
return False
|
|
||||||
|
|
||||||
def detect_gcc(env):
|
|
||||||
n = sum(x in env for x in ['GNU_CC', 'GNU_CXX', 'GNU_LINK'])
|
|
||||||
if n > 0:
|
|
||||||
if n == 3:
|
|
||||||
return True
|
|
||||||
raise ValueError('GNU_CC, GNU_CXX, and GNU_LINK must be set together')
|
|
||||||
cc = env.get('CC')
|
|
||||||
cxx = env.get('CXX')
|
|
||||||
link = env.subst(env.get('LINK'))
|
|
||||||
if (cc and cxx and link and
|
|
||||||
is_compiler(cc, 'gcc') and
|
|
||||||
is_compiler(cxx, 'g++') and
|
|
||||||
is_compiler(link, 'g++')):
|
|
||||||
env['GNU_CC'] = cc
|
|
||||||
env['GNU_CXX'] = cxx
|
|
||||||
env['GNU_LINK'] = link
|
|
||||||
return True
|
|
||||||
cc = env.WhereIs('gcc')
|
|
||||||
cxx = env.WhereIs('g++')
|
|
||||||
link = cxx
|
|
||||||
if (is_compiler(cc, 'gcc') and
|
|
||||||
is_compiler(cxx, 'g++') and
|
|
||||||
is_compiler(link, 'g++')):
|
|
||||||
env['GNU_CC'] = cc
|
|
||||||
env['GNU_CXX'] = cxx
|
|
||||||
env['GNU_LINK'] = link
|
|
||||||
return True
|
|
||||||
env['GNU_CC'] = 'gcc'
|
|
||||||
env['GNU_CXX'] = 'g++'
|
|
||||||
env['GNU_LINK'] = env['LINK']
|
|
||||||
return False
|
|
||||||
|
|
||||||
toolchains = []
|
|
||||||
if detect_clang(env):
|
|
||||||
toolchains.append('clang')
|
|
||||||
if detect_gcc(env):
|
|
||||||
toolchains.append('gcc')
|
|
||||||
if env.Detect('cl'):
|
|
||||||
toolchains.append('msvc')
|
|
||||||
return toolchains
|
|
||||||
|
|
||||||
def files(base):
|
|
||||||
def _iter(base):
|
|
||||||
for parent, _, files in os.walk(base):
|
|
||||||
for path in files:
|
|
||||||
path = os.path.join(parent, path)
|
|
||||||
yield os.path.normpath(path)
|
|
||||||
return list(_iter(base))
|
|
||||||
|
|
||||||
def print_coms(target, source, env):
|
|
||||||
'''Display command line exemplars for an environment'''
|
|
||||||
print ('Target: ' + Beast.yellow(str(target[0])))
|
|
||||||
# TODO Add 'PROTOCCOM' to this list and make it work
|
|
||||||
Beast.print_coms(['CXXCOM', 'CCCOM', 'LINKCOM'], env)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Set construction variables for the base environment
|
|
||||||
def config_base(env):
|
|
||||||
if False:
|
|
||||||
env.Replace(
|
|
||||||
CCCOMSTR='Compiling ' + Beast.blue('$SOURCES'),
|
|
||||||
CXXCOMSTR='Compiling ' + Beast.blue('$SOURCES'),
|
|
||||||
LINKCOMSTR='Linking ' + Beast.blue('$TARGET'),
|
|
||||||
)
|
|
||||||
check_openssl()
|
|
||||||
|
|
||||||
env.Append(CPPDEFINES=['OPENSSL_NO_SSL2'])
|
|
||||||
|
|
||||||
#git = Beast.Git(env) # TODO(TOM)
|
|
||||||
if False: #git.exists:
|
|
||||||
env.Append(CPPDEFINES={'GIT_COMMIT_ID' : '"%s"' % git.commit_id})
|
|
||||||
|
|
||||||
try:
|
|
||||||
BOOST_ROOT = os.path.normpath(os.environ['BOOST_ROOT'])
|
|
||||||
env.Append(CPPPATH=[
|
|
||||||
BOOST_ROOT,
|
|
||||||
])
|
|
||||||
env.Append(LIBPATH=[
|
|
||||||
os.path.join(BOOST_ROOT, 'stage', 'lib'),
|
|
||||||
])
|
|
||||||
env['BOOST_ROOT'] = BOOST_ROOT
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if Beast.system.windows:
|
|
||||||
try:
|
|
||||||
OPENSSL_ROOT = os.path.normpath(os.environ['OPENSSL_ROOT'])
|
|
||||||
env.Append(CPPPATH=[
|
|
||||||
os.path.join(OPENSSL_ROOT, 'include'),
|
|
||||||
])
|
|
||||||
env.Append(LIBPATH=[
|
|
||||||
os.path.join(OPENSSL_ROOT, 'lib', 'VC', 'static'),
|
|
||||||
])
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
elif Beast.system.osx:
|
|
||||||
OSX_OPENSSL_ROOT = '/usr/local/Cellar/openssl/'
|
|
||||||
most_recent = sorted(os.listdir(OSX_OPENSSL_ROOT))[-1]
|
|
||||||
openssl = os.path.join(OSX_OPENSSL_ROOT, most_recent)
|
|
||||||
env.Prepend(CPPPATH='%s/include' % openssl)
|
|
||||||
env.Prepend(LIBPATH=['%s/lib' % openssl])
|
|
||||||
|
|
||||||
# Set toolchain and variant specific construction variables
|
|
||||||
def config_env(toolchain, variant, env):
|
|
||||||
if variant == 'debug':
|
|
||||||
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
|
|
||||||
|
|
||||||
elif variant == 'release':
|
|
||||||
env.Append(CPPDEFINES=['NDEBUG'])
|
|
||||||
|
|
||||||
if toolchain in Split('clang gcc'):
|
|
||||||
if Beast.system.linux:
|
|
||||||
env.ParseConfig('pkg-config --static --cflags --libs openssl')
|
|
||||||
env.ParseConfig('pkg-config --static --cflags --libs protobuf')
|
|
||||||
|
|
||||||
env.Prepend(CFLAGS=['-Wall'])
|
|
||||||
env.Prepend(CXXFLAGS=['-Wall'])
|
|
||||||
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'-Wno-sign-compare',
|
|
||||||
'-Wno-char-subscripts',
|
|
||||||
'-Wno-format',
|
|
||||||
])
|
|
||||||
|
|
||||||
if toolchain == 'clang':
|
|
||||||
env.Append(CCFLAGS=['-Wno-redeclared-class-member'])
|
|
||||||
|
|
||||||
env.Append(CXXFLAGS=[
|
|
||||||
'-frtti',
|
|
||||||
'-std=c++11',
|
|
||||||
'-Wno-invalid-offsetof'])
|
|
||||||
|
|
||||||
if Beast.system.osx:
|
|
||||||
env.Append(CPPDEFINES={
|
|
||||||
'BEAST_COMPILE_OBJECTIVE_CPP': 1,
|
|
||||||
})
|
|
||||||
|
|
||||||
# These should be the same regardless of platform...
|
|
||||||
if Beast.system.osx:
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'-Wno-deprecated',
|
|
||||||
'-Wno-deprecated-declarations',
|
|
||||||
'-Wno-unused-variable',
|
|
||||||
'-Wno-unused-function',
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
if toolchain == 'gcc':
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'-Wno-unused-but-set-variable'
|
|
||||||
])
|
|
||||||
|
|
||||||
boost_libs = [
|
|
||||||
'boost_date_time',
|
|
||||||
'boost_filesystem',
|
|
||||||
'boost_program_options',
|
|
||||||
'boost_regex',
|
|
||||||
'boost_system',
|
|
||||||
'boost_thread'
|
|
||||||
]
|
|
||||||
# We prefer static libraries for boost
|
|
||||||
if env.get('BOOST_ROOT'):
|
|
||||||
static_libs = ['%s/stage/lib/lib%s.a' % (env['BOOST_ROOT'], l) for
|
|
||||||
l in boost_libs]
|
|
||||||
if all(os.path.exists(f) for f in static_libs):
|
|
||||||
boost_libs = [File(f) for f in static_libs]
|
|
||||||
|
|
||||||
env.Append(LIBS=boost_libs)
|
|
||||||
env.Append(LIBS=['dl'])
|
|
||||||
|
|
||||||
if Beast.system.osx:
|
|
||||||
env.Append(LIBS=[
|
|
||||||
'crypto',
|
|
||||||
'protobuf',
|
|
||||||
'ssl',
|
|
||||||
])
|
|
||||||
env.Append(FRAMEWORKS=[
|
|
||||||
'AppKit',
|
|
||||||
'Foundation'
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
env.Append(LIBS=['rt'])
|
|
||||||
|
|
||||||
env.Append(LINKFLAGS=[
|
|
||||||
'-rdynamic'
|
|
||||||
])
|
|
||||||
|
|
||||||
if variant == 'debug':
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'-g'
|
|
||||||
])
|
|
||||||
elif variant == 'release':
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'-O3',
|
|
||||||
'-fno-strict-aliasing'
|
|
||||||
])
|
|
||||||
|
|
||||||
if toolchain == 'clang':
|
|
||||||
if Beast.system.osx:
|
|
||||||
env.Replace(CC='clang', CXX='clang++', LINK='clang++')
|
|
||||||
elif 'CLANG_CC' in env and 'CLANG_CXX' in env and 'CLANG_LINK' in env:
|
|
||||||
env.Replace(CC=env['CLANG_CC'],
|
|
||||||
CXX=env['CLANG_CXX'],
|
|
||||||
LINK=env['CLANG_LINK'])
|
|
||||||
# C and C++
|
|
||||||
# Add '-Wshorten-64-to-32'
|
|
||||||
env.Append(CCFLAGS=[])
|
|
||||||
# C++ only
|
|
||||||
env.Append(CXXFLAGS=[
|
|
||||||
'-Wno-mismatched-tags',
|
|
||||||
'-Wno-deprecated-register',
|
|
||||||
])
|
|
||||||
|
|
||||||
elif toolchain == 'gcc':
|
|
||||||
if 'GNU_CC' in env and 'GNU_CXX' in env and 'GNU_LINK' in env:
|
|
||||||
env.Replace(CC=env['GNU_CC'],
|
|
||||||
CXX=env['GNU_CXX'],
|
|
||||||
LINK=env['GNU_LINK'])
|
|
||||||
# Why is this only for gcc?!
|
|
||||||
env.Append(CCFLAGS=['-Wno-unused-local-typedefs'])
|
|
||||||
|
|
||||||
elif toolchain == 'msvc':
|
|
||||||
env.Append (CPPPATH=[
|
|
||||||
os.path.join('src', 'protobuf', 'src'),
|
|
||||||
os.path.join('src', 'protobuf', 'vsprojects'),
|
|
||||||
])
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'/bigobj', # Increase object file max size
|
|
||||||
'/EHa', # ExceptionHandling all
|
|
||||||
'/fp:precise', # Floating point behavior
|
|
||||||
'/Gd', # __cdecl calling convention
|
|
||||||
'/Gm-', # Minimal rebuild: disabled
|
|
||||||
'/GR', # Enable RTTI
|
|
||||||
'/Gy-', # Function level linking: disabled
|
|
||||||
'/FS',
|
|
||||||
'/MP', # Multiprocessor compilation
|
|
||||||
'/openmp-', # pragma omp: disabled
|
|
||||||
'/Zc:forScope', # Language extension: for scope
|
|
||||||
'/Zi', # Generate complete debug info
|
|
||||||
'/errorReport:none', # No error reporting to Internet
|
|
||||||
'/nologo', # Suppress login banner
|
|
||||||
#'/Fd${TARGET}.pdb', # Path: Program Database (.pdb)
|
|
||||||
'/W3', # Warning level 3
|
|
||||||
'/WX-', # Disable warnings as errors
|
|
||||||
'/wd"4018"',
|
|
||||||
'/wd"4244"',
|
|
||||||
'/wd"4267"',
|
|
||||||
'/wd"4800"', # Disable C4800 (int to bool performance)
|
|
||||||
])
|
|
||||||
env.Append(CPPDEFINES={
|
|
||||||
'_WIN32_WINNT' : '0x6000',
|
|
||||||
})
|
|
||||||
env.Append(CPPDEFINES=[
|
|
||||||
'_SCL_SECURE_NO_WARNINGS',
|
|
||||||
'_CRT_SECURE_NO_WARNINGS',
|
|
||||||
'WIN32_CONSOLE',
|
|
||||||
])
|
|
||||||
env.Append(LIBS=[
|
|
||||||
'ssleay32MT.lib',
|
|
||||||
'libeay32MT.lib',
|
|
||||||
'Shlwapi.lib',
|
|
||||||
'kernel32.lib',
|
|
||||||
'user32.lib',
|
|
||||||
'gdi32.lib',
|
|
||||||
'winspool.lib',
|
|
||||||
'comdlg32.lib',
|
|
||||||
'advapi32.lib',
|
|
||||||
'shell32.lib',
|
|
||||||
'ole32.lib',
|
|
||||||
'oleaut32.lib',
|
|
||||||
'uuid.lib',
|
|
||||||
'odbc32.lib',
|
|
||||||
'odbccp32.lib',
|
|
||||||
])
|
|
||||||
env.Append(LINKFLAGS=[
|
|
||||||
'/DEBUG',
|
|
||||||
'/DYNAMICBASE',
|
|
||||||
'/ERRORREPORT:NONE',
|
|
||||||
#'/INCREMENTAL',
|
|
||||||
'/MACHINE:X64',
|
|
||||||
'/MANIFEST',
|
|
||||||
#'''/MANIFESTUAC:"level='asInvoker' uiAccess='false'"''',
|
|
||||||
'/nologo',
|
|
||||||
'/NXCOMPAT',
|
|
||||||
'/SUBSYSTEM:CONSOLE',
|
|
||||||
'/TLBID:1',
|
|
||||||
])
|
|
||||||
|
|
||||||
if variant == 'debug':
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'/GS', # Buffers security check: enable
|
|
||||||
'/MTd', # Language: Multi-threaded Debug CRT
|
|
||||||
'/Od', # Optimization: Disabled
|
|
||||||
'/RTC1', # Run-time error checks:
|
|
||||||
])
|
|
||||||
env.Append(CPPDEFINES=[
|
|
||||||
'_CRTDBG_MAP_ALLOC'
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
env.Append(CCFLAGS=[
|
|
||||||
'/MT', # Language: Multi-threaded CRT
|
|
||||||
'/Ox', # Optimization: Full
|
|
||||||
])
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise SCons.UserError('Unknown toolchain == "%s"' % toolchain)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def addSource(path, env, variant_dirs, CPPPATH=[]):
|
|
||||||
if CPPPATH:
|
|
||||||
env = env.Clone()
|
|
||||||
env.Prepend(CPPPATH=CPPPATH)
|
|
||||||
return env.Object(Beast.variantFile(path, variant_dirs))
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Configure the base construction environment
|
|
||||||
root_dir = Dir('#').srcnode().get_abspath() # Path to this SConstruct file
|
|
||||||
build_dir = os.path.join('build')
|
|
||||||
base = Environment(
|
|
||||||
toolpath=[os.path.join ('src', 'beast', 'site_scons', 'site_tools')],
|
|
||||||
tools=['default', 'Protoc', 'VSProject'],
|
|
||||||
ENV=os.environ,
|
|
||||||
TARGET_ARCH='x86_64')
|
|
||||||
import_environ(base)
|
|
||||||
config_base(base)
|
|
||||||
base.Append(CPPPATH=[
|
|
||||||
'src',
|
|
||||||
os.path.join('src', 'beast'),
|
|
||||||
os.path.join(build_dir, 'proto'),
|
|
||||||
])
|
|
||||||
|
|
||||||
# Configure the toolchains, variants, default toolchain, and default target
|
|
||||||
variants = ['debug', 'release']
|
|
||||||
all_toolchains = ['clang', 'gcc', 'msvc']
|
|
||||||
if Beast.system.osx:
|
|
||||||
toolchains = ['clang']
|
|
||||||
default_toolchain = 'clang'
|
|
||||||
else:
|
|
||||||
toolchains = detect_toolchains(base)
|
|
||||||
if not toolchains:
|
|
||||||
raise ValueError('No toolchains detected!')
|
|
||||||
if 'msvc' in toolchains:
|
|
||||||
default_toolchain = 'msvc'
|
|
||||||
elif 'gcc' in toolchains:
|
|
||||||
if 'clang' in toolchains:
|
|
||||||
cxx = os.environ.get('CXX', 'g++')
|
|
||||||
default_toolchain = 'clang' if 'clang' in cxx else 'gcc'
|
|
||||||
else:
|
|
||||||
default_toolchain = 'gcc'
|
|
||||||
elif 'clang' in toolchains:
|
|
||||||
default_toolchain = 'clang'
|
|
||||||
else:
|
|
||||||
raise ValueError("Don't understand toolchains in " + str(toolchains))
|
|
||||||
default_variant = 'debug'
|
|
||||||
default_target = None
|
|
||||||
|
|
||||||
for source in [
|
|
||||||
'src/ripple/proto/ripple.proto',
|
|
||||||
]:
|
|
||||||
base.Protoc([],
|
|
||||||
source,
|
|
||||||
PROTOCPROTOPATH=[os.path.dirname(source)],
|
|
||||||
PROTOCOUTDIR=os.path.join(build_dir, 'proto'),
|
|
||||||
PROTOCPYTHONOUTDIR=None)
|
|
||||||
|
|
||||||
# Declare the targets
|
|
||||||
aliases = collections.defaultdict(list)
|
|
||||||
msvc_configs = []
|
|
||||||
for toolchain in all_toolchains:
|
|
||||||
for variant in variants:
|
|
||||||
# Configure this variant's construction environment
|
|
||||||
env = base.Clone()
|
|
||||||
config_env(toolchain, variant, env)
|
|
||||||
variant_name = '%s.%s' % (toolchain, variant)
|
|
||||||
variant_dir = os.path.join(build_dir, variant_name)
|
|
||||||
variant_dirs = {
|
|
||||||
os.path.join(variant_dir, 'src') :
|
|
||||||
'src',
|
|
||||||
os.path.join(variant_dir, 'proto') :
|
|
||||||
os.path.join (build_dir, 'proto'),
|
|
||||||
}
|
|
||||||
for dest, source in variant_dirs.iteritems():
|
|
||||||
env.VariantDir(dest, source, duplicate=0)
|
|
||||||
objects = []
|
|
||||||
objects.append(addSource('src/ripple/unity/app.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app1.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app2.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app3.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app4.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app5.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app6.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app7.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app8.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/app9.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/basics.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/beast.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/beastc.c', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/common.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/core.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/data.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/http.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/json.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/net.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/overlay.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/peerfinder.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/protobuf.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/ripple.proto.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/radmap.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/resource.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/rpcx.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/sitefiles.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/sslutil.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/testoverlay.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/types.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/validators.cpp', env, variant_dirs))
|
|
||||||
objects.append(addSource('src/ripple/unity/websocket.cpp', env, variant_dirs))
|
|
||||||
|
|
||||||
objects.append(addSource('src/ripple/unity/nodestore.cpp', env, variant_dirs, [
|
|
||||||
'src/leveldb/include',
|
|
||||||
#'src/hyperleveldb/include', # hyper
|
|
||||||
'src/rocksdb/include',
|
|
||||||
]))
|
|
||||||
|
|
||||||
objects.append(addSource('src/ripple/unity/leveldb.cpp', env, variant_dirs, [
|
|
||||||
'src/leveldb/',
|
|
||||||
'src/leveldb/include',
|
|
||||||
'src/snappy/snappy',
|
|
||||||
'src/snappy/config',
|
|
||||||
]))
|
|
||||||
|
|
||||||
objects.append(addSource('src/ripple/unity/hyperleveldb.cpp', env, variant_dirs, [
|
|
||||||
'src/hyperleveldb',
|
|
||||||
'src/snappy/snappy',
|
|
||||||
'src/snappy/config',
|
|
||||||
]))
|
|
||||||
|
|
||||||
objects.append(addSource('src/ripple/unity/rocksdb.cpp', env, variant_dirs, [
|
|
||||||
'src/rocksdb',
|
|
||||||
'src/rocksdb/include',
|
|
||||||
'src/snappy/snappy',
|
|
||||||
'src/snappy/config',
|
|
||||||
]))
|
|
||||||
|
|
||||||
objects.append(addSource('src/ripple/unity/snappy.cpp', env, variant_dirs, [
|
|
||||||
'src/snappy/snappy',
|
|
||||||
'src/snappy/config',
|
|
||||||
]))
|
|
||||||
|
|
||||||
if toolchain == "clang" and Beast.system.osx:
|
|
||||||
objects.append(addSource('src/ripple/unity/beastobjc.mm', env, variant_dirs))
|
|
||||||
|
|
||||||
target = env.Program(
|
|
||||||
target = os.path.join(variant_dir, 'rippled'),
|
|
||||||
source = objects
|
|
||||||
)
|
|
||||||
|
|
||||||
if toolchain == default_toolchain and variant == default_variant:
|
|
||||||
default_target = target
|
|
||||||
install_target = env.Install (build_dir, source = default_target)
|
|
||||||
env.Alias ('install', install_target)
|
|
||||||
env.Default (install_target)
|
|
||||||
aliases['all'].extend(install_target)
|
|
||||||
if toolchain == 'msvc':
|
|
||||||
config = env.VSProjectConfig(variant, 'x64', target, env)
|
|
||||||
msvc_configs.append(config)
|
|
||||||
if toolchain in toolchains:
|
|
||||||
aliases['all'].extend(target)
|
|
||||||
aliases[variant].extend(target)
|
|
||||||
aliases[toolchain].extend(target)
|
|
||||||
env.Alias(variant_name, target)
|
|
||||||
|
|
||||||
for key, value in aliases.iteritems():
|
|
||||||
env.Alias(key, value)
|
|
||||||
|
|
||||||
vcxproj = base.VSProject(
|
|
||||||
os.path.join('Builds', 'VisualStudio2013', 'RippleD'),
|
|
||||||
source = [],
|
|
||||||
VSPROJECT_ROOT_DIRS = ['src/beast', 'src', '.'],
|
|
||||||
VSPROJECT_CONFIGS = msvc_configs)
|
|
||||||
base.Alias('vcxproj', vcxproj)
|
|
||||||
149
SECURITY.md
Normal file
149
SECURITY.md
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
### Operating an XRP Ledger server securely
|
||||||
|
|
||||||
|
For more details on operating an XRP Ledger server securely, please visit https://xrpl.org/manage-the-rippled-server.html.
|
||||||
|
|
||||||
|
|
||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
Software constantly evolves. In order to focus resources, we only generally only accept vulnerability reports that affect recent and current versions of the software. We always accept reports for issues present in the **master**, **release** or **develop** branches, and with proposed, [open pull requests](https://github.com/ripple/rippled/pulls).
|
||||||
|
|
||||||
|
## Identifying and Reporting Vulnerabilities
|
||||||
|
|
||||||
|
We take security seriously and we do our best to ensure that all our releases are bug free. But we aren't perfect and sometimes things will slip through.
|
||||||
|
|
||||||
|
### Responsible Investigation
|
||||||
|
|
||||||
|
We urge you to examine our code carefully and responsibly, and to disclose any issues that you identify in a responsible fashion.
|
||||||
|
|
||||||
|
Responsible investigation includes, but isn't limited to, the following:
|
||||||
|
|
||||||
|
- Not performing tests on the main network. If testing is necessary, use the [Testnet or Devnet](https://xrpl.org/xrp-testnet-faucet.html).
|
||||||
|
- Not targeting physical security measures, or attempting to use social engineering, spam, distributed denial of service (DDOS) attacks, etc.
|
||||||
|
- Investigating bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to the XRP Ledger and the broader ecosystem.
|
||||||
|
|
||||||
|
### Responsible Disclosure
|
||||||
|
|
||||||
|
If you discover a vulnerability or potential threat, or if you _think_
|
||||||
|
you have, please reach out by dropping an email using the contact
|
||||||
|
information below.
|
||||||
|
|
||||||
|
Your report should include the following:
|
||||||
|
|
||||||
|
- Your contact information (typically, an email address);
|
||||||
|
- The description of the vulnerability;
|
||||||
|
- The attack scenario (if any);
|
||||||
|
- The steps to reproduce the vulnerability;
|
||||||
|
- Any other relevant details or artifacts, including code, scripts or patches.
|
||||||
|
|
||||||
|
In your email, please describe the issue or potential threat. If possible, include a "repro" (code that can reproduce the issue) or describe the best way to reproduce and replicate the issue. Please make your report as detailed and comprehensive as possible.
|
||||||
|
|
||||||
|
For more information on responsible disclosure, please read this [Wikipedia article](https://en.wikipedia.org/wiki/Responsible_disclosure).
|
||||||
|
|
||||||
|
## Report Handling Process
|
||||||
|
|
||||||
|
Please report the bug directly to us and limit further disclosure. If you want to prove that you knew the bug as of a given time, consider using a cryptographic precommitment: hash the content of your report and publish the hash on a medium of your choice (e.g. on Twitter or as a memo in a transaction) as "proof" that you had written the text at a given point in time.
|
||||||
|
|
||||||
|
Once we receive a report, we:
|
||||||
|
|
||||||
|
1. Assign two people to independently evaluate the report;
|
||||||
|
2. Consider their recommendations;
|
||||||
|
3. If action is necessary, formulate a plan to address the issue;
|
||||||
|
4. Communicate privately with the reporter to explain our plan.
|
||||||
|
5. Prepare, test and release a version which fixes the issue; and
|
||||||
|
6. Announce the vulnerability publicly.
|
||||||
|
|
||||||
|
We will triage and respond to your disclosure within 24 hours. Beyond that, we will work to analyze the issue in more detail, formulate, develop and test a fix.
|
||||||
|
|
||||||
|
While we commit to responding with 24 hours of your initial report with our triage assessment, we cannot guarantee a response time for the remaining steps. We will communicate with you throughout this process, letting you know where we are and keeping you updated on the timeframe.
|
||||||
|
|
||||||
|
## Bug Bounty Program
|
||||||
|
|
||||||
|
[Ripple](https://ripple.com) is generously sponsoring a bug bounty program for vulnerabilities in [`rippled`](https://github.com/XRPLF/rippled) (and other related projects, like [`xrpl.js`](https://github.com/XRPLF/xrpl.js), [`xrpl-py`](https://github.com/XRPLF/xrpl-py), [`xrpl4j`](https://github.com/XRPLF/xrpl4j)).
|
||||||
|
|
||||||
|
This program allows us to recognize and reward individuals or groups that identify and report bugs. In summary, in order to qualify for a bounty, the bug must be:
|
||||||
|
|
||||||
|
1. **In scope**. Only bugs in software under the scope of the program qualify. Currently, that means `rippled`, `xrpl.js`, `xrpl-py`, `xrpl4j`.
|
||||||
|
2. **Relevant**. A security issue, posing a danger to user funds, privacy, or the operation of the XRP Ledger.
|
||||||
|
3. **Original and previously unknown**. Bugs that are already known and discussed in public do not qualify. Previously reported bugs, even if publicly unknown, are not eligible.
|
||||||
|
4. **Specific**. We welcome general security advice or recommendations, but we cannot pay bounties for that.
|
||||||
|
5. **Fixable**. There has to be something we can do to permanently fix the problem. Note that bugs in other people’s software may still qualify in some cases. For example, if you find a bug in a library that we use which can compromise the security of software that is in scope and we can get it fixed, you may qualify for a bounty.
|
||||||
|
6. **Unused**. If you use the exploit to attack the XRP Ledger, you do not qualify for a bounty. If you report a vulnerability used in an ongoing or past attack and there is specific, concrete evidence that suggests you are the attacker we reserve the right not to pay a bounty.
|
||||||
|
|
||||||
|
The amount paid varies dramatically. Vulnerabilities that are harmless on their own, but could form part of a critical exploit will usually receive a bounty. Full-blown exploits can receive much higher bounties. Please don’t hold back partial vulnerabilities while trying to construct a full-blown exploit. We will pay a bounty to anyone who reports a complete chain of vulnerabilities even if they have reported each component of the exploit separately and those vulnerabilities have been fixed in the meantime. However, to qualify for a the full bounty, you must to have been the first to report each of the partial exploits.
|
||||||
|
|
||||||
|
### Contacting Us
|
||||||
|
|
||||||
|
To report a qualifying bug, please send a detailed report to:
|
||||||
|
|
||||||
|
|Email Address|bugs@ripple.com |
|
||||||
|
|:-----------:|:----------------------------------------------------|
|
||||||
|
|Short Key ID | `0xC57929BE` |
|
||||||
|
|Long Key ID | `0xCD49A0AFC57929BE` |
|
||||||
|
|Fingerprint | `24E6 3B02 37E0 FA9C 5E96 8974 CD49 A0AF C579 29BE` |
|
||||||
|
|
||||||
|
The full PGP key for this address, which is also available on several key servers (e.g. on [keys.gnupg.net](https://keys.gnupg.net)), is:
|
||||||
|
```
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
mQINBFUwGHYBEAC0wpGpBPkd8W1UdQjg9+cEFzeIEJRaoZoeuJD8mofwI5Ejnjdt
|
||||||
|
kCpUYEDal0ygkKobu8SzOoATcDl18iCrScX39VpTm96vISFZMhmOryYCIp4QLJNN
|
||||||
|
4HKc2ZdBj6W4igNi6vj5Qo6JMyGpLY2mz4CZskbt0TNuUxWrGood+UrCzpY8x7/N
|
||||||
|
a93fcvNw+prgCr0rCH3hAPmAFfsOBbtGzNnmq7xf3jg5r4Z4sDiNIF1X1y53DAfV
|
||||||
|
rWDx49IKsuCEJfPMp1MnBSvDvLaQ2hKXs+cOpx1BCZgHn3skouEUxxgqbtTzBLt1
|
||||||
|
xXpmuijsaltWngPnGO7mOAzbpZSdBm82/Emrk9bPMuD0QaLQjWr7HkTSUs6ZsKt4
|
||||||
|
7CLPdWqxyY/QVw9UaxeHEtWGQGMIQGgVJGh1fjtUr5O1sC9z9jXcQ0HuIHnRCTls
|
||||||
|
GP7hklJmfH5V4SyAJQ06/hLuEhUJ7dn+BlqCsT0tLmYTgZYNzNcLHcqBFMEZHvHw
|
||||||
|
9GENMx/tDXgajKql4bJnzuTK0iGU/YepanANLd1JHECJ4jzTtmKOus9SOGlB2/l1
|
||||||
|
0t0ADDYAS3eqOdOcUvo9ElSLCI5vSVHhShSte/n2FMWU+kMUboTUisEG8CgQnrng
|
||||||
|
g2CvvQvqDkeOtZeqMcC7HdiZS0q3LJUWtwA/ViwxrVlBDCxiTUXCotyBWwARAQAB
|
||||||
|
tDBSaXBwbGUgTGFicyBCdWcgQm91bnR5IFByb2dyYW0gPGJ1Z3NAcmlwcGxlLmNv
|
||||||
|
bT6JAjcEEwEKACEFAlUwGHYCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
|
||||||
|
zUmgr8V5Kb6R0g//SwY/mVJY59k87iL26/KayauSoOcz7xjcST26l4ZHVVX85gOY
|
||||||
|
HYZl8k0+m8X3zxeYm9a3QAoAml8sfoaFRFQP8ynnefRrLUPaZ2MjbJ0SACMwZNef
|
||||||
|
T6o7Mi8LBAaiNZdYVyIfX1oM6YXtqYkuJdav6ZCyvVYqc9OvMJPY2ZzJYuI/ZtvQ
|
||||||
|
/lTndxCeg9ALNX/iezOLGdfMpf4HuIFVwcPPlwGi+HDlB9/bggDEHC8z434SXVFc
|
||||||
|
aQatXAPcDkjMUweU7y0CZtYEj00HITd4pSX6MqGiHrxlDZTqinCOPs1Ieqp7qufs
|
||||||
|
MzlM6irLGucxj1+wa16ieyYvEtGaPIsksUKkywx0O7cf8N2qKg+eIkUk6O0Uc6eO
|
||||||
|
CszizmiXIXy4O6OiLlVHGKkXHMSW9Nwe9GE95O8G9WR8OZCEuDv+mHPAutO+IjdP
|
||||||
|
PDAAUvy+3XnkceO+HGWRpVvJZfFP2YH4A33InFL5yqlJmSoR/yVingGLxk55bZDM
|
||||||
|
+HYGR3VeMb8Xj1rf/02qERsZyccMCFdAvKDbTwmvglyHdVLu5sPmktxbBYiemfyJ
|
||||||
|
qxMxmYXCc9S0hWrWZW7edktBa9NpE58z1mx+hRIrDNbS2sDHrib9PULYCySyVYcF
|
||||||
|
P+PWEe1CAS5jqkR2ker5td2/pHNnJIycynBEs7l6zbc9fu+nktFJz0q2B+GJAhwE
|
||||||
|
EAEKAAYFAlUwGaQACgkQ+tiY1qQ2QkjMFw//f2hNY3BPNe+1qbhzumMDCnbTnGif
|
||||||
|
kLuAGl9OKt81VHG1f6RnaGiLpR696+6Ja45KzH15cQ5JJl5Bgs1YkR/noTGX8IAD
|
||||||
|
c70eNwiFu8JXTaaeeJrsmFkF9Tueufb364risYkvPP8tNUD3InBFEZT3WN7JKwix
|
||||||
|
coD4/BwekUwOZVDd/uCFEyhlhZsROxdKNisNo3VtAq2s+3tIBAmTrriFUl0K+ZC5
|
||||||
|
zgavcpnPN57zMtW9aK+VO3wXqAKYLYmtgxkVzSLUZt2M7JuwOaAdyuYWAneKZPCu
|
||||||
|
1AXkmyo+d84sd5mZaKOr5xArAFiNMWPUcZL4rkS1Fq4dKtGAqzzR7a7hWtA5o27T
|
||||||
|
6vynuxZ1n0PPh0er2O/zF4znIjm5RhTlfjp/VmhZdQfpulFEQ/dMxxGkQ9z5IYbX
|
||||||
|
mTlSDbCSb+FMsanRBJ7Drp5EmBIudVGY6SHI5Re1RQiEh7GoDfUMUwZO+TVDII5R
|
||||||
|
Ra7WyuimYleJgDo/+7HyfuIyGDaUCVj6pwVtYtYIdOI3tTw1R1Mr0V8yaNVnJghL
|
||||||
|
CHcEJQL+YHSmiMM3ySil3O6tm1By6lFz8bVe/rgG/5uklQrnjMR37jYboi1orCC4
|
||||||
|
yeIoQeV0ItlxeTyBwYIV/o1DBNxDevTZvJabC93WiGLw2XFjpZ0q/9+zI2rJUZJh
|
||||||
|
qxmKP+D4e27lCI65Ag0EVTAYdgEQAMvttYNqeRNBRpSX8fk45WVIV8Fb21fWdwk6
|
||||||
|
2SkZnJURbiC0LxQnOi7wrtii7DeFZtwM2kFHihS1VHekBnIKKZQSgGoKuFAQMGyu
|
||||||
|
a426H4ZsSmA9Ufd7kRbvdtEcp7/RTAanhrSL4lkBhaKJrXlxBJ27o3nd7/rh7r3a
|
||||||
|
OszbPY6DJ5bWClX3KooPTDl/RF2lHn+fweFk58UvuunHIyo4BWJUdilSXIjLun+P
|
||||||
|
Qaik4ZAsZVwNhdNz05d+vtai4AwbYoO7adboMLRkYaXSQwGytkm+fM6r7OpXHYuS
|
||||||
|
cR4zB/OK5hxCVEpWfiwN71N2NMvnEMaWd/9uhqxJzyvYgkVUXV9274TUe16pzXnW
|
||||||
|
ZLfmitjwc91e7mJBBfKNenDdhaLEIlDRwKTLj7k58f9srpMnyZFacntu5pUMNblB
|
||||||
|
cjXwWxz5ZaQikLnKYhIvrIEwtWPyjqOzNXNvYfZamve/LJ8HmWGCKao3QHoAIDvB
|
||||||
|
9XBxrDyTJDpxbog6Qu4SY8AdgVlan6c/PsLDc7EUegeYiNTzsOK+eq3G5/E92eIu
|
||||||
|
TsUXlciypFcRm1q8vLRr+HYYe2mJDo4GetB1zLkAFBcYJm/x9iJQbu0hn5NxJvZO
|
||||||
|
R0Y5nOJQdyi+muJzKYwhkuzaOlswzqVXkq/7+QCjg7QsycdcwDjiQh3OrsgXHrwl
|
||||||
|
M7gyafL9ABEBAAGJAh8EGAEKAAkFAlUwGHYCGwwACgkQzUmgr8V5Kb50BxAAhj9T
|
||||||
|
TwmNrgRldTHszj+Qc+v8RWqV6j+R+zc0cn5XlUa6XFaXI1OFFg71H4dhCPEiYeN0
|
||||||
|
IrnocyMNvCol+eKIlPKbPTmoixjQ4udPTR1DC1Bx1MyW5FqOrsgBl5t0e1VwEViM
|
||||||
|
NspSStxu5Hsr6oWz2GD48lXZWJOgoL1RLs+uxjcyjySD/em2fOKASwchYmI+ezRv
|
||||||
|
plfhAFIMKTSCN2pgVTEOaaz13M0U+MoprThqF1LWzkGkkC7n/1V1f5tn83BWiagG
|
||||||
|
2N2Q4tHLfyouzMUKnX28kQ9sXfxwmYb2sA9FNIgxy+TdKU2ofLxivoWT8zS189z/
|
||||||
|
Yj9fErmiMjns2FzEDX+bipAw55X4D/RsaFgC+2x2PDbxeQh6JalRA2Wjq32Ouubx
|
||||||
|
u+I4QhEDJIcVwt9x6LPDuos1F+M5QW0AiUhKrZJ17UrxOtaquh/nPUL9T3l2qPUn
|
||||||
|
1ChrZEEEhHO6vA8+jn0+cV9n5xEz30Str9iHnDQ5QyR5LyV4UBPgTdWyQzNVKA69
|
||||||
|
KsSr9lbHEtQFRzGuBKwt6UlSFv9vPWWJkJit5XDKAlcKuGXj0J8OlltToocGElkF
|
||||||
|
+gEBZfoOWi/IBjRLrFW2cT3p36DTR5O1Ud/1DLnWRqgWNBLrbs2/KMKE6EnHttyD
|
||||||
|
7Tz8SQkuxltX/yBXMV3Ddy0t6nWV2SZEfuxJAQI=
|
||||||
|
=spg4
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
```
|
||||||
150
bin/getRippledInfo
Executable file
150
bin/getRippledInfo
Executable file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This script generates information about your rippled installation
|
||||||
|
# and system. It can be used to help debug issues that you may face
|
||||||
|
# in your installation. While this script endeavors to not display any
|
||||||
|
# sensitive information, it is recommended that you read the output
|
||||||
|
# before sharing with any third parties.
|
||||||
|
|
||||||
|
|
||||||
|
rippled_exe=/opt/ripple/bin/rippled
|
||||||
|
conf_file=/etc/opt/ripple/rippled.cfg
|
||||||
|
|
||||||
|
while getopts ":e:c:" opt; do
|
||||||
|
case $opt in
|
||||||
|
e)
|
||||||
|
rippled_exe=${OPTARG}
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
conf_file=${OPTARG}
|
||||||
|
;;
|
||||||
|
\?)
|
||||||
|
echo "Invalid option: -$OPTARG"
|
||||||
|
exit -1
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
tmp_loc=$(mktemp -d --tmpdir ripple_info.XXXXX)
|
||||||
|
chmod 751 ${tmp_loc}
|
||||||
|
awk_prog=${tmp_loc}/cfg.awk
|
||||||
|
summary_out=${tmp_loc}/rippled_info.md
|
||||||
|
printf "# rippled report info\n\n> generated at %s\n" "$(date -R)" > ${summary_out}
|
||||||
|
|
||||||
|
function log_section {
|
||||||
|
printf "\n## %s\n" "$*" >> ${summary_out}
|
||||||
|
|
||||||
|
while read -r l; do
|
||||||
|
echo " $l" >> ${summary_out}
|
||||||
|
done </dev/stdin
|
||||||
|
}
|
||||||
|
|
||||||
|
function join_by {
|
||||||
|
local IFS="$1"; shift; echo "$*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -f ${conf_file} ]] ; then
|
||||||
|
exclude=( ips ips_fixed node_seed validation_seed validator_token )
|
||||||
|
cleaned_conf=${tmp_loc}/cleaned_rippled_cfg.txt
|
||||||
|
cat << 'EOP' >> ${awk_prog}
|
||||||
|
BEGIN {FS="[[:space:]]*=[[:space:]]*"; skip=0; db_path=""; print > OUT_FILE; split(exl,exa,"|")}
|
||||||
|
/^#/ {next}
|
||||||
|
save==2 && /^[[:space:]]*$/ {next}
|
||||||
|
/^\[.+\]$/ {
|
||||||
|
section=tolower(gensub(/^\[[[:space:]]*([a-zA-Z_]+)[[:space:]]*\]$/, "\\1", "g"))
|
||||||
|
skip = 0
|
||||||
|
for (i in exa) {
|
||||||
|
if (section == exa[i])
|
||||||
|
skip = 1
|
||||||
|
}
|
||||||
|
if (section == "database_path")
|
||||||
|
save = 1
|
||||||
|
}
|
||||||
|
skip==1 {next}
|
||||||
|
save==2 {save=0; db_path=$0}
|
||||||
|
save==1 {save=2}
|
||||||
|
$1 ~ /password/ {$0=$1"=<redacted>"}
|
||||||
|
{print >> OUT_FILE}
|
||||||
|
END {print db_path}
|
||||||
|
EOP
|
||||||
|
|
||||||
|
db=$(\
|
||||||
|
sed -r -e 's/\<s[[:alnum:]]{28}\>/<redactedsecret>/g;s/^[[:space:]]*//;s/[[:space:]]*$//' ${conf_file} |\
|
||||||
|
awk -v OUT_FILE=${cleaned_conf} -v exl="$(join_by '|' "${exclude[@]}")" -f ${awk_prog})
|
||||||
|
rm ${awk_prog}
|
||||||
|
cat ${cleaned_conf} | log_section "cleaned config file"
|
||||||
|
rm ${cleaned_conf}
|
||||||
|
echo "${db}" | log_section "database path"
|
||||||
|
df ${db} | log_section "df: database"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Send output from this script to a log file
|
||||||
|
## this captures any messages
|
||||||
|
## or errors from the script itself
|
||||||
|
|
||||||
|
log_file=${tmp_loc}/get_info.log
|
||||||
|
exec 3>&1 1>>${log_file} 2>&1
|
||||||
|
|
||||||
|
## Send all stdout files to /tmp
|
||||||
|
|
||||||
|
if [[ -x ${rippled_exe} ]] ; then
|
||||||
|
pgrep rippled && \
|
||||||
|
${rippled_exe} --conf ${conf_file} \
|
||||||
|
-- server_info | log_section "server info"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat /proc/meminfo | log_section "meminfo"
|
||||||
|
cat /proc/swaps | log_section "swap space"
|
||||||
|
ulimit -a | log_section "ulimit"
|
||||||
|
|
||||||
|
if command -v lshw >/dev/null 2>&1 ; then
|
||||||
|
lshw 2>/dev/null | log_section "hardware info"
|
||||||
|
else
|
||||||
|
lscpu > ${tmp_loc}/hw_info.txt
|
||||||
|
hwinfo >> ${tmp_loc}/hw_info.txt
|
||||||
|
lspci >> ${tmp_loc}/hw_info.txt
|
||||||
|
lsblk >> ${tmp_loc}/hw_info.txt
|
||||||
|
cat ${tmp_loc}/hw_info.txt | log_section "hardware info"
|
||||||
|
rm ${tmp_loc}/hw_info.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v iostat >/dev/null 2>&1 ; then
|
||||||
|
iostat -t -d -x 2 6 | log_section "iostat"
|
||||||
|
fi
|
||||||
|
|
||||||
|
df -h | log_section "free disk space"
|
||||||
|
drives=($(df | awk '$1 ~ /^\/dev\// {print $1}' | xargs -n 1 basename))
|
||||||
|
block_devs=($(ls /sys/block/))
|
||||||
|
for d in "${drives[@]}"; do
|
||||||
|
for dev in "${block_devs[@]}"; do
|
||||||
|
#echo "D: [$d], DEV: [$dev]"
|
||||||
|
if [[ $d =~ $dev ]]; then
|
||||||
|
# this file (if exists) has 0 for SSD and 1 for HDD
|
||||||
|
if [[ "$(cat /sys/block/${dev}/queue/rotational 2>/dev/null)" == 0 ]] ; then
|
||||||
|
echo "${d} : SSD" >> ${tmp_loc}/is_ssd.txt
|
||||||
|
else
|
||||||
|
echo "${d} : NO SSD" >> ${tmp_loc}/is_ssd.txt
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -f ${tmp_loc}/is_ssd.txt ]] ; then
|
||||||
|
cat ${tmp_loc}/is_ssd.txt | log_section "SSD"
|
||||||
|
rm ${tmp_loc}/is_ssd.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat ${log_file} | log_section "script log"
|
||||||
|
|
||||||
|
cat << MSG | tee /dev/fd/3
|
||||||
|
####################################################
|
||||||
|
rippled info has been gathered. Please copy the
|
||||||
|
contents of ${summary_out}
|
||||||
|
to a github gist at https://gist.github.com/
|
||||||
|
|
||||||
|
PLEASE REVIEW THIS FILE FOR ANY SENSITIVE DATA
|
||||||
|
BEFORE POSTING! We have tried our best to omit
|
||||||
|
any sensitive information from this file, but you
|
||||||
|
should verify before posting.
|
||||||
|
####################################################
|
||||||
|
MSG
|
||||||
|
|
||||||
86
bin/git/setup-upstreams.sh
Executable file
86
bin/git/setup-upstreams.sh
Executable file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ $# -ne 1 || "$1" == "--help" || "$1" == "-h" ]]
|
||||||
|
then
|
||||||
|
name=$( basename $0 )
|
||||||
|
cat <<- USAGE
|
||||||
|
Usage: $name <username>
|
||||||
|
|
||||||
|
Where <username> is the Github username of the upstream repo. e.g. XRPLF
|
||||||
|
USAGE
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create upstream remotes based on origin
|
||||||
|
shift
|
||||||
|
user="$1"
|
||||||
|
# Get the origin URL. Expect it be an SSH-style URL
|
||||||
|
origin=$( git remote get-url origin )
|
||||||
|
if [[ "${origin}" == "" ]]
|
||||||
|
then
|
||||||
|
echo Invalid origin remote >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# echo "Origin: ${origin}"
|
||||||
|
# Parse the origin
|
||||||
|
ifs_orig="${IFS}"
|
||||||
|
IFS=':' read remote originpath <<< "${origin}"
|
||||||
|
# echo "Remote: ${remote}, Originpath: ${originpath}"
|
||||||
|
IFS='@' read sshuser server <<< "${remote}"
|
||||||
|
# echo "SSHUser: ${sshuser}, Server: ${server}"
|
||||||
|
IFS='/' read originuser repo <<< "${originpath}"
|
||||||
|
# echo "Originuser: ${originuser}, Repo: ${repo}"
|
||||||
|
if [[ "${sshuser}" == "" || "${server}" == "" || "${originuser}" == ""
|
||||||
|
|| "${repo}" == "" ]]
|
||||||
|
then
|
||||||
|
echo "Can't parse origin URL: ${origin}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
upstream="https://${server}/${user}/${repo}"
|
||||||
|
upstreampush="${remote}:${user}/${repo}"
|
||||||
|
upstreamgroup="upstream upstream-push"
|
||||||
|
current=$( git remote get-url upstream 2>/dev/null )
|
||||||
|
currentpush=$( git remote get-url upstream-push 2>/dev/null )
|
||||||
|
currentgroup=$( git config remotes.upstreams )
|
||||||
|
if [[ "${current}" == "${upstream}" ]]
|
||||||
|
then
|
||||||
|
echo "Upstream already set up correctly. Skip"
|
||||||
|
elif [[ -n "${current}" && "${current}" != "${upstream}" &&
|
||||||
|
"${current}" != "${upstreampush}" ]]
|
||||||
|
then
|
||||||
|
echo "Upstream already set up as: ${current}. Skip"
|
||||||
|
else
|
||||||
|
if [[ "${current}" == "${upstreampush}" ]]
|
||||||
|
then
|
||||||
|
echo "Upstream set to dangerous push URL. Update."
|
||||||
|
_run git remote rename upstream upstream-push || \
|
||||||
|
_run git remote remove upstream
|
||||||
|
currentpush=$( git remote get-url upstream-push 2>/dev/null )
|
||||||
|
fi
|
||||||
|
_run git remote add upstream "${upstream}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${currentpush}" == "${upstreampush}" ]]
|
||||||
|
then
|
||||||
|
echo "upstream-push already set up correctly. Skip"
|
||||||
|
elif [[ -n "${currentpush}" && "${currentpush}" != "${upstreampush}" ]]
|
||||||
|
then
|
||||||
|
echo "upstream-push already set up as: ${currentpush}. Skip"
|
||||||
|
else
|
||||||
|
_run git remote add upstream-push "${upstreampush}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${currentgroup}" == "${upstreamgroup}" ]]
|
||||||
|
then
|
||||||
|
echo "Upstreams group already set up correctly. Skip"
|
||||||
|
elif [[ -n "${currentgroup}" && "${currentgroup}" != "${upstreamgroup}" ]]
|
||||||
|
then
|
||||||
|
echo "Upstreams group already set up as: ${currentgroup}. Skip"
|
||||||
|
else
|
||||||
|
_run git config --add remotes.upstreams "${upstreamgroup}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_run git fetch --jobs=$(nproc) upstreams
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
69
bin/git/squash-branches.sh
Executable file
69
bin/git/squash-branches.sh
Executable file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ $# -lt 3 || "$1" == "--help" || "$1" = "-h" ]]
|
||||||
|
then
|
||||||
|
name=$( basename $0 )
|
||||||
|
cat <<- USAGE
|
||||||
|
Usage: $name workbranch base/branch user/branch [user/branch [...]]
|
||||||
|
|
||||||
|
* workbranch will be created locally from base/branch
|
||||||
|
* base/branch and user/branch may be specified as user:branch to allow
|
||||||
|
easy copying from Github PRs
|
||||||
|
* Remotes for each user must already be set up
|
||||||
|
USAGE
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
work="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
branches=( $( echo "${@}" | sed "s/:/\//" ) )
|
||||||
|
base="${branches[0]}"
|
||||||
|
unset branches[0]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
users=()
|
||||||
|
for b in "${branches[@]}"
|
||||||
|
do
|
||||||
|
users+=( $( echo $b | cut -d/ -f1 ) )
|
||||||
|
done
|
||||||
|
|
||||||
|
users=( $( printf '%s\n' "${users[@]}" | sort -u ) )
|
||||||
|
|
||||||
|
git fetch --multiple upstreams "${users[@]}"
|
||||||
|
git checkout -B "$work" --no-track "$base"
|
||||||
|
|
||||||
|
for b in "${branches[@]}"
|
||||||
|
do
|
||||||
|
git merge --squash "${b}"
|
||||||
|
git commit -S # Use the commit message provided on the PR
|
||||||
|
done
|
||||||
|
|
||||||
|
# Make sure the commits look right
|
||||||
|
git log --show-signature "$base..HEAD"
|
||||||
|
|
||||||
|
parts=( $( echo $base | sed "s/\// /" ) )
|
||||||
|
repo="${parts[0]}"
|
||||||
|
b="${parts[1]}"
|
||||||
|
push=$repo
|
||||||
|
if [[ "$push" == "upstream" ]]
|
||||||
|
then
|
||||||
|
push="upstream-push"
|
||||||
|
fi
|
||||||
|
if [[ "$repo" == "upstream" ]]
|
||||||
|
then
|
||||||
|
repo="upstreams"
|
||||||
|
fi
|
||||||
|
cat << PUSH
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
This script will not push. Verify everything is correct, then push
|
||||||
|
to your repo, and create a PR if necessary. Once the PR is approved,
|
||||||
|
run:
|
||||||
|
|
||||||
|
git push $push HEAD:$b
|
||||||
|
git fetch $repo
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
PUSH
|
||||||
|
|
||||||
58
bin/git/update-version.sh
Executable file
58
bin/git/update-version.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ $# -ne 3 || "$1" == "--help" || "$1" = "-h" ]]
|
||||||
|
then
|
||||||
|
name=$( basename $0 )
|
||||||
|
cat <<- USAGE
|
||||||
|
Usage: $name workbranch base/branch version
|
||||||
|
|
||||||
|
* workbranch will be created locally from base/branch. If it exists,
|
||||||
|
it will be reused, so make sure you don't overwrite any work.
|
||||||
|
* base/branch may be specified as user:branch to allow easy copying
|
||||||
|
from Github PRs.
|
||||||
|
USAGE
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
work="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
base=$( echo "$1" | sed "s/:/\//" )
|
||||||
|
shift
|
||||||
|
|
||||||
|
version=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
git fetch upstreams
|
||||||
|
|
||||||
|
git checkout -B "${work}" --no-track "${base}"
|
||||||
|
|
||||||
|
push=$( git rev-parse --abbrev-ref --symbolic-full-name '@{push}' \
|
||||||
|
2>/dev/null ) || true
|
||||||
|
if [[ "${push}" != "" ]]
|
||||||
|
then
|
||||||
|
echo "Warning: ${push} may already exist."
|
||||||
|
fi
|
||||||
|
|
||||||
|
build=$( find -name BuildInfo.cpp )
|
||||||
|
sed 's/\(^.*versionString =\).*$/\1 "'${version}'"/' ${build} > version.cpp && \
|
||||||
|
diff "${build}" version.cpp && exit 1 || \
|
||||||
|
mv -vi version.cpp ${build}
|
||||||
|
|
||||||
|
git diff
|
||||||
|
|
||||||
|
git add ${build}
|
||||||
|
|
||||||
|
git commit -S -m "Set version to ${version}"
|
||||||
|
|
||||||
|
git log --oneline --first-parent ${base}^..
|
||||||
|
|
||||||
|
cat << PUSH
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
This script will not push. Verify everything is correct, then push
|
||||||
|
to your repo, and create a PR as described in CONTRIBUTING.md.
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
PUSH
|
||||||
218
bin/physical.sh
Executable file
218
bin/physical.sh
Executable file
@@ -0,0 +1,218 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
|
||||||
|
marker_base=985c80fbc6131f3a8cedd0da7e8af98dfceb13c7
|
||||||
|
marker_commit=${1:-${marker_base}}
|
||||||
|
|
||||||
|
if [ $(git merge-base ${marker_commit} ${marker_base}) != ${marker_base} ]; then
|
||||||
|
echo "first marker commit not an ancestor: ${marker_commit}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $(git merge-base ${marker_commit} HEAD) != $(git rev-parse --verify ${marker_commit}) ]; then
|
||||||
|
echo "given marker commit not an ancestor: ${marker_commit}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e Builds/CMake ]; then
|
||||||
|
echo move CMake
|
||||||
|
git mv Builds/CMake cmake
|
||||||
|
git add --update .
|
||||||
|
git commit -m 'Move CMake directory' --author 'Pretty Printer <cpp@ripple.com>'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e src/ripple ]; then
|
||||||
|
|
||||||
|
echo move protocol buffers
|
||||||
|
mkdir -p include/xrpl
|
||||||
|
if [ -e src/ripple/proto ]; then
|
||||||
|
git mv src/ripple/proto include/xrpl
|
||||||
|
fi
|
||||||
|
|
||||||
|
extract_list() {
|
||||||
|
git show ${marker_commit}:Builds/CMake/RippledCore.cmake | \
|
||||||
|
awk "/END ${1}/ { p = 0 } p && /src\/ripple/; /BEGIN ${1}/ { p = 1 }" | \
|
||||||
|
sed -e 's#src/ripple/##' -e 's#[^a-z]\+$##'
|
||||||
|
}
|
||||||
|
|
||||||
|
move_files() {
|
||||||
|
oldroot="$1"; shift
|
||||||
|
newroot="$1"; shift
|
||||||
|
detail="$1"; shift
|
||||||
|
files=("$@")
|
||||||
|
for file in ${files[@]}; do
|
||||||
|
if [ ! -e ${oldroot}/${file} ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
dir=$(dirname ${file})
|
||||||
|
if [ $(basename ${dir}) == 'details' ]; then
|
||||||
|
dir=$(dirname ${dir})
|
||||||
|
fi
|
||||||
|
if [ $(basename ${dir}) == 'impl' ]; then
|
||||||
|
dir="$(dirname ${dir})/${detail}"
|
||||||
|
fi
|
||||||
|
mkdir -p ${newroot}/${dir}
|
||||||
|
git mv ${oldroot}/${file} ${newroot}/${dir}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
echo move libxrpl headers
|
||||||
|
files=$(extract_list 'LIBXRPL HEADERS')
|
||||||
|
files+=(
|
||||||
|
basics/SlabAllocator.h
|
||||||
|
|
||||||
|
beast/asio/io_latency_probe.h
|
||||||
|
beast/container/aged_container.h
|
||||||
|
beast/container/aged_container_utility.h
|
||||||
|
beast/container/aged_map.h
|
||||||
|
beast/container/aged_multimap.h
|
||||||
|
beast/container/aged_multiset.h
|
||||||
|
beast/container/aged_set.h
|
||||||
|
beast/container/aged_unordered_map.h
|
||||||
|
beast/container/aged_unordered_multimap.h
|
||||||
|
beast/container/aged_unordered_multiset.h
|
||||||
|
beast/container/aged_unordered_set.h
|
||||||
|
beast/container/detail/aged_associative_container.h
|
||||||
|
beast/container/detail/aged_container_iterator.h
|
||||||
|
beast/container/detail/aged_ordered_container.h
|
||||||
|
beast/container/detail/aged_unordered_container.h
|
||||||
|
beast/container/detail/empty_base_optimization.h
|
||||||
|
beast/core/LockFreeStack.h
|
||||||
|
beast/insight/Collector.h
|
||||||
|
beast/insight/Counter.h
|
||||||
|
beast/insight/CounterImpl.h
|
||||||
|
beast/insight/Event.h
|
||||||
|
beast/insight/EventImpl.h
|
||||||
|
beast/insight/Gauge.h
|
||||||
|
beast/insight/GaugeImpl.h
|
||||||
|
beast/insight/Group.h
|
||||||
|
beast/insight/Groups.h
|
||||||
|
beast/insight/Hook.h
|
||||||
|
beast/insight/HookImpl.h
|
||||||
|
beast/insight/Insight.h
|
||||||
|
beast/insight/Meter.h
|
||||||
|
beast/insight/MeterImpl.h
|
||||||
|
beast/insight/NullCollector.h
|
||||||
|
beast/insight/StatsDCollector.h
|
||||||
|
beast/test/fail_counter.h
|
||||||
|
beast/test/fail_stream.h
|
||||||
|
beast/test/pipe_stream.h
|
||||||
|
beast/test/sig_wait.h
|
||||||
|
beast/test/string_iostream.h
|
||||||
|
beast/test/string_istream.h
|
||||||
|
beast/test/string_ostream.h
|
||||||
|
beast/test/test_allocator.h
|
||||||
|
beast/test/yield_to.h
|
||||||
|
beast/utility/hash_pair.h
|
||||||
|
beast/utility/maybe_const.h
|
||||||
|
beast/utility/temp_dir.h
|
||||||
|
|
||||||
|
# included by only json/impl/json_assert.h
|
||||||
|
json/json_errors.h
|
||||||
|
|
||||||
|
protocol/PayChan.h
|
||||||
|
protocol/RippleLedgerHash.h
|
||||||
|
protocol/messages.h
|
||||||
|
protocol/st.h
|
||||||
|
)
|
||||||
|
files+=(
|
||||||
|
basics/README.md
|
||||||
|
crypto/README.md
|
||||||
|
json/README.md
|
||||||
|
protocol/README.md
|
||||||
|
resource/README.md
|
||||||
|
)
|
||||||
|
move_files src/ripple include/xrpl detail ${files[@]}
|
||||||
|
|
||||||
|
echo move libxrpl sources
|
||||||
|
files=$(extract_list 'LIBXRPL SOURCES')
|
||||||
|
move_files src/ripple src/libxrpl "" ${files[@]}
|
||||||
|
|
||||||
|
echo check leftovers
|
||||||
|
dirs=$(cd include/xrpl; ls -d */)
|
||||||
|
dirs=$(cd src/ripple; ls -d ${dirs} 2>/dev/null || true)
|
||||||
|
files="$(cd src/ripple; find ${dirs} -type f)"
|
||||||
|
if [ -n "${files}" ]; then
|
||||||
|
echo "leftover files:"
|
||||||
|
echo ${files}
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo remove empty directories
|
||||||
|
empty_dirs="$(cd src/ripple; find ${dirs} -depth -type d)"
|
||||||
|
for dir in ${empty_dirs[@]}; do
|
||||||
|
if [ -e ${dir} ]; then
|
||||||
|
rmdir ${dir}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo move xrpld sources
|
||||||
|
files=$(
|
||||||
|
extract_list 'XRPLD SOURCES'
|
||||||
|
cd src/ripple
|
||||||
|
find * -regex '.*\.\(h\|ipp\|md\|pu\|uml\|png\)'
|
||||||
|
)
|
||||||
|
move_files src/ripple src/xrpld detail ${files[@]}
|
||||||
|
|
||||||
|
files="$(cd src/ripple; find . -type f)"
|
||||||
|
if [ -n "${files}" ]; then
|
||||||
|
echo "leftover files:"
|
||||||
|
echo ${files}
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf src/ripple
|
||||||
|
|
||||||
|
echo rename .hpp to .h
|
||||||
|
find include src -name '*.hpp' -exec bash -c 'f="{}"; git mv "${f}" "${f%hpp}h"' \;
|
||||||
|
|
||||||
|
echo move PerfLog.h
|
||||||
|
if [ -e include/xrpl/basics/PerfLog.h ]; then
|
||||||
|
git mv include/xrpl/basics/PerfLog.h src/xrpld/perflog
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure all protobuf includes have the correct prefix.
|
||||||
|
protobuf_replace='s:^#include\s*["<].*org/xrpl\([^">]\+\)[">]:#include <xrpl/proto/org/xrpl\1>:'
|
||||||
|
# Make sure first-party includes use angle brackets and .h extension.
|
||||||
|
ripple_replace='s:include\s*["<]ripple/\(.*\)\.h\(pp\)\?[">]:include <ripple/\1.h>:'
|
||||||
|
beast_replace='s:include\s*<beast/:include <xrpl/beast/:'
|
||||||
|
# Rename impl directories to detail.
|
||||||
|
impl_rename='s:\(<xrpl.*\)/impl\(/details\)\?/:\1/detail/:'
|
||||||
|
|
||||||
|
echo rewrite includes in libxrpl
|
||||||
|
find include/xrpl src/libxrpl -type f -exec sed -i \
|
||||||
|
-e "${protobuf_replace}" \
|
||||||
|
-e "${ripple_replace}" \
|
||||||
|
-e "${beast_replace}" \
|
||||||
|
-e 's:^#include <ripple/:#include <xrpl/:' \
|
||||||
|
-e "${impl_rename}" \
|
||||||
|
{} +
|
||||||
|
|
||||||
|
echo rewrite includes in xrpld
|
||||||
|
# # https://www.baeldung.com/linux/join-multiple-lines
|
||||||
|
libxrpl_dirs="$(cd include/xrpl; ls -d1 */ | sed 's:/$::')"
|
||||||
|
# libxrpl_dirs='a\nb\nc\n'
|
||||||
|
readarray -t libxrpl_dirs <<< "${libxrpl_dirs}"
|
||||||
|
# libxrpl_dirs=(a b c)
|
||||||
|
libxrpl_dirs=$(printf -v txt '%s\\|' "${libxrpl_dirs[@]}"; echo "${txt%\\|}")
|
||||||
|
# libxrpl_dirs='a\|b\|c'
|
||||||
|
find src/xrpld src/test -type f -exec sed -i \
|
||||||
|
-e "${protobuf_replace}" \
|
||||||
|
-e "${ripple_replace}" \
|
||||||
|
-e "${beast_replace}" \
|
||||||
|
-e "s:^#include <ripple/basics/PerfLog.h>:#include <xrpld/perflog/PerfLog.h>:" \
|
||||||
|
-e "s:^#include <ripple/\(${libxrpl_dirs}\)/:#include <xrpl/\1/:" \
|
||||||
|
-e 's:^#include <ripple/:#include <xrpld/:' \
|
||||||
|
-e "${impl_rename}" \
|
||||||
|
{} +
|
||||||
|
|
||||||
|
git commit -m 'Rearrange sources' --author 'Pretty Printer <cpp@ripple.com>'
|
||||||
|
find include src -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format-10 -i {} +
|
||||||
|
git add --update .
|
||||||
|
git commit -m 'Rewrite includes' --author 'Pretty Printer <cpp@ripple.com>'
|
||||||
|
./Builds/levelization/levelization.sh
|
||||||
|
git add --update .
|
||||||
|
git commit -m 'Recompute loops' --author 'Pretty Printer <cpp@ripple.com>'
|
||||||
51
bin/sh/install-vcpkg.sh
Executable file
51
bin/sh/install-vcpkg.sh
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -exu
|
||||||
|
|
||||||
|
: ${TRAVIS_BUILD_DIR:=""}
|
||||||
|
: ${VCPKG_DIR:=".vcpkg"}
|
||||||
|
export VCPKG_ROOT=${VCPKG_DIR}
|
||||||
|
: ${VCPKG_DEFAULT_TRIPLET:="x64-windows-static"}
|
||||||
|
|
||||||
|
export VCPKG_DEFAULT_TRIPLET
|
||||||
|
|
||||||
|
EXE="vcpkg"
|
||||||
|
if [[ -z ${COMSPEC:-} ]]; then
|
||||||
|
EXE="${EXE}.exe"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "${VCPKG_DIR}" && -x "${VCPKG_DIR}/${EXE}" && -d "${VCPKG_DIR}/installed" ]] ; then
|
||||||
|
echo "Using cached vcpkg at ${VCPKG_DIR}"
|
||||||
|
${VCPKG_DIR}/${EXE} list
|
||||||
|
else
|
||||||
|
if [[ -d "${VCPKG_DIR}" ]] ; then
|
||||||
|
rm -rf "${VCPKG_DIR}"
|
||||||
|
fi
|
||||||
|
git clone --branch 2021.04.30 https://github.com/Microsoft/vcpkg.git ${VCPKG_DIR}
|
||||||
|
pushd ${VCPKG_DIR}
|
||||||
|
BSARGS=()
|
||||||
|
if [[ "$(uname)" == "Darwin" ]] ; then
|
||||||
|
BSARGS+=(--allowAppleClang)
|
||||||
|
fi
|
||||||
|
if [[ -z ${COMSPEC:-} ]]; then
|
||||||
|
chmod +x ./bootstrap-vcpkg.sh
|
||||||
|
time ./bootstrap-vcpkg.sh "${BSARGS[@]}"
|
||||||
|
else
|
||||||
|
time ./bootstrap-vcpkg.bat
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: bring boost in this way as well ?
|
||||||
|
# NOTE: can pin specific ports to a commit/version like this:
|
||||||
|
# git checkout <SOME COMMIT HASH> ports/boost
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "No extra packages specified..."
|
||||||
|
PKGS=()
|
||||||
|
else
|
||||||
|
PKGS=( "$@" )
|
||||||
|
fi
|
||||||
|
for LIB in "${PKGS[@]}"; do
|
||||||
|
time ${VCPKG_DIR}/${EXE} --clean-after-build install ${LIB}
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
40
bin/sh/setup-msvc.sh
Executable file
40
bin/sh/setup-msvc.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
# NOTE: must be sourced from a shell so it can export vars
|
||||||
|
|
||||||
|
cat << BATCH > ./getenv.bat
|
||||||
|
CALL %*
|
||||||
|
ENV
|
||||||
|
BATCH
|
||||||
|
|
||||||
|
while read line ; do
|
||||||
|
IFS='"' read x path arg <<<"${line}"
|
||||||
|
if [ -f "${path}" ] ; then
|
||||||
|
echo "FOUND: $path"
|
||||||
|
export VCINSTALLDIR=$(./getenv.bat "${path}" ${arg} | grep "^VCINSTALLDIR=" | sed -E "s/^VCINSTALLDIR=//g")
|
||||||
|
if [ "${VCINSTALLDIR}" != "" ] ; then
|
||||||
|
echo "USING ${VCINSTALLDIR}"
|
||||||
|
export LIB=$(./getenv.bat "${path}" ${arg} | grep "^LIB=" | sed -E "s/^LIB=//g")
|
||||||
|
export LIBPATH=$(./getenv.bat "${path}" ${arg} | grep "^LIBPATH=" | sed -E "s/^LIBPATH=//g")
|
||||||
|
export INCLUDE=$(./getenv.bat "${path}" ${arg} | grep "^INCLUDE=" | sed -E "s/^INCLUDE=//g")
|
||||||
|
ADDPATH=$(./getenv.bat "${path}" ${arg} | grep "^PATH=" | sed -E "s/^PATH=//g")
|
||||||
|
export PATH="${ADDPATH}:${PATH}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done <<EOL
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat" x86_amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio 15.0/VC/vcvarsall.bat" amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat" amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio 13.0/VC/vcvarsall.bat" amd64
|
||||||
|
"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat" amd64
|
||||||
|
EOL
|
||||||
|
# TODO: update the list above as needed to support newer versions of msvc tools
|
||||||
|
|
||||||
|
rm -f getenv.bat
|
||||||
|
|
||||||
|
if [ "${VCINSTALLDIR}" = "" ] ; then
|
||||||
|
echo "No compatible visual studio found!"
|
||||||
|
fi
|
||||||
246
bin/start_sync_stop.py
Normal file
246
bin/start_sync_stop.py
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""A script to test rippled in an infinite loop of start-sync-stop.
|
||||||
|
|
||||||
|
- Requires Python 3.7+.
|
||||||
|
- Can be stopped with SIGINT.
|
||||||
|
- Has no dependencies outside the standard library.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
assert sys.version_info.major == 3 and sys.version_info.minor >= 7
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import asyncio
|
||||||
|
import configparser
|
||||||
|
import contextlib
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
import urllib.error
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
# Enable asynchronous subprocesses on Windows. The default changed in 3.8.
|
||||||
|
# https://docs.python.org/3.7/library/asyncio-platforms.html#subprocess-support-on-windows
|
||||||
|
if (platform.system() == 'Windows' and sys.version_info.major == 3
|
||||||
|
and sys.version_info.minor < 8):
|
||||||
|
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
||||||
|
|
||||||
|
DEFAULT_EXE = 'rippled'
|
||||||
|
DEFAULT_CONFIGURATION_FILE = 'rippled.cfg'
|
||||||
|
# Number of seconds to wait before forcefully terminating.
|
||||||
|
PATIENCE = 120
|
||||||
|
# Number of contiguous seconds in a sync state to be considered synced.
|
||||||
|
DEFAULT_SYNC_DURATION = 60
|
||||||
|
# Number of seconds between polls of state.
|
||||||
|
DEFAULT_POLL_INTERVAL = 5
|
||||||
|
SYNC_STATES = ('full', 'validating', 'proposing')
|
||||||
|
|
||||||
|
|
||||||
|
def read_config(config_file):
|
||||||
|
# strict = False: Allow duplicate keys, e.g. [rpc_startup].
|
||||||
|
# allow_no_value = True: Allow keys with no values. Generally, these
|
||||||
|
# instances use the "key" as the value, and the section name is the key,
|
||||||
|
# e.g. [debug_logfile].
|
||||||
|
# delimiters = ('='): Allow ':' as a character in Windows paths. Some of
|
||||||
|
# our "keys" are actually values, and we don't want to split them on ':'.
|
||||||
|
config = configparser.ConfigParser(
|
||||||
|
strict=False,
|
||||||
|
allow_no_value=True,
|
||||||
|
delimiters=('='),
|
||||||
|
)
|
||||||
|
config.read(config_file)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def to_list(value, separator=','):
|
||||||
|
"""Parse a list from a delimited string value."""
|
||||||
|
return [s.strip() for s in value.split(separator) if s]
|
||||||
|
|
||||||
|
|
||||||
|
def find_log_file(config_file):
|
||||||
|
"""Try to figure out what log file the user has chosen. Raises all kinds
|
||||||
|
of exceptions if there is any possibility of ambiguity."""
|
||||||
|
config = read_config(config_file)
|
||||||
|
values = list(config['debug_logfile'].keys())
|
||||||
|
if len(values) < 1:
|
||||||
|
raise ValueError(
|
||||||
|
f'no [debug_logfile] in configuration file: {config_file}')
|
||||||
|
if len(values) > 1:
|
||||||
|
raise ValueError(
|
||||||
|
f'too many [debug_logfile] in configuration file: {config_file}')
|
||||||
|
return values[0]
|
||||||
|
|
||||||
|
|
||||||
|
def find_http_port(config_file):
|
||||||
|
config = read_config(config_file)
|
||||||
|
names = list(config['server'].keys())
|
||||||
|
for name in names:
|
||||||
|
server = config[name]
|
||||||
|
if 'http' in to_list(server.get('protocol', '')):
|
||||||
|
return int(server['port'])
|
||||||
|
raise ValueError(f'no server in [server] for "http" protocol')
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.asynccontextmanager
|
||||||
|
async def rippled(exe=DEFAULT_EXE, config_file=DEFAULT_CONFIGURATION_FILE):
|
||||||
|
"""A context manager for a rippled process."""
|
||||||
|
# Start the server.
|
||||||
|
process = await asyncio.create_subprocess_exec(
|
||||||
|
str(exe),
|
||||||
|
'--conf',
|
||||||
|
str(config_file),
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
)
|
||||||
|
logging.info(f'rippled started with pid {process.pid}')
|
||||||
|
try:
|
||||||
|
yield process
|
||||||
|
finally:
|
||||||
|
# Ask it to stop.
|
||||||
|
logging.info(f'asking rippled (pid: {process.pid}) to stop')
|
||||||
|
start = time.time()
|
||||||
|
process.terminate()
|
||||||
|
|
||||||
|
# Wait nicely.
|
||||||
|
try:
|
||||||
|
await asyncio.wait_for(process.wait(), PATIENCE)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
# Ask the operating system to kill it.
|
||||||
|
logging.warning(f'killing rippled ({process.pid})')
|
||||||
|
try:
|
||||||
|
process.kill()
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
code = await process.wait()
|
||||||
|
end = time.time()
|
||||||
|
logging.info(
|
||||||
|
f'rippled stopped after {end - start:.1f} seconds with code {code}'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def sync(
|
||||||
|
port,
|
||||||
|
*,
|
||||||
|
duration=DEFAULT_SYNC_DURATION,
|
||||||
|
interval=DEFAULT_POLL_INTERVAL,
|
||||||
|
):
|
||||||
|
"""Poll rippled on an interval until it has been synced for a duration."""
|
||||||
|
start = time.perf_counter()
|
||||||
|
while (time.perf_counter() - start) < duration:
|
||||||
|
await asyncio.sleep(interval)
|
||||||
|
|
||||||
|
request = urllib.request.Request(
|
||||||
|
f'http://127.0.0.1:{port}',
|
||||||
|
data=json.dumps({
|
||||||
|
'method': 'server_state'
|
||||||
|
}).encode(),
|
||||||
|
headers={'Content-Type': 'application/json'},
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(request) as response:
|
||||||
|
try:
|
||||||
|
body = json.loads(response.read())
|
||||||
|
except urllib.error.HTTPError as cause:
|
||||||
|
logging.warning(f'server_state returned not JSON: {cause}')
|
||||||
|
start = time.perf_counter()
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
state = body['result']['state']['server_state']
|
||||||
|
except KeyError as cause:
|
||||||
|
logging.warning(f'server_state response missing key: {cause.key}')
|
||||||
|
start = time.perf_counter()
|
||||||
|
continue
|
||||||
|
logging.info(f'server_state: {state}')
|
||||||
|
if state not in SYNC_STATES:
|
||||||
|
# Require a contiguous sync state.
|
||||||
|
start = time.perf_counter()
|
||||||
|
|
||||||
|
|
||||||
|
async def loop(test,
|
||||||
|
*,
|
||||||
|
exe=DEFAULT_EXE,
|
||||||
|
config_file=DEFAULT_CONFIGURATION_FILE):
|
||||||
|
"""
|
||||||
|
Start-test-stop rippled in an infinite loop.
|
||||||
|
|
||||||
|
Moves log to a different file after each iteration.
|
||||||
|
"""
|
||||||
|
log_file = find_log_file(config_file)
|
||||||
|
id = 0
|
||||||
|
while True:
|
||||||
|
logging.info(f'iteration: {id}')
|
||||||
|
async with rippled(exe, config_file) as process:
|
||||||
|
start = time.perf_counter()
|
||||||
|
exited = asyncio.create_task(process.wait())
|
||||||
|
tested = asyncio.create_task(test())
|
||||||
|
# Try to sync as long as the process is running.
|
||||||
|
done, pending = await asyncio.wait(
|
||||||
|
{exited, tested},
|
||||||
|
return_when=asyncio.FIRST_COMPLETED,
|
||||||
|
)
|
||||||
|
if done == {exited}:
|
||||||
|
code = exited.result()
|
||||||
|
logging.warning(
|
||||||
|
f'server halted for unknown reason with code {code}')
|
||||||
|
else:
|
||||||
|
assert done == {tested}
|
||||||
|
assert tested.exception() is None
|
||||||
|
end = time.perf_counter()
|
||||||
|
logging.info(f'synced after {end - start:.0f} seconds')
|
||||||
|
os.replace(log_file, f'debug.{id}.log')
|
||||||
|
id += 1
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
format='%(asctime)s %(levelname)-8s %(message)s',
|
||||||
|
level=logging.INFO,
|
||||||
|
datefmt='%Y-%m-%d %H:%M:%S',
|
||||||
|
)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
|
parser.add_argument(
|
||||||
|
'rippled',
|
||||||
|
type=Path,
|
||||||
|
nargs='?',
|
||||||
|
default=DEFAULT_EXE,
|
||||||
|
help='Path to rippled.',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--conf',
|
||||||
|
type=Path,
|
||||||
|
default=DEFAULT_CONFIGURATION_FILE,
|
||||||
|
help='Path to configuration file.',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--duration',
|
||||||
|
type=int,
|
||||||
|
default=DEFAULT_SYNC_DURATION,
|
||||||
|
help='Number of contiguous seconds required in a synchronized state.',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--interval',
|
||||||
|
type=int,
|
||||||
|
default=DEFAULT_POLL_INTERVAL,
|
||||||
|
help='Number of seconds to wait between polls of state.',
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
port = find_http_port(args.conf)
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
return sync(port, duration=args.duration, interval=args.interval)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
asyncio.run(loop(test, exe=args.rippled, config_file=args.conf))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
# Squelch the message. This is a normal mode of exit.
|
||||||
|
pass
|
||||||
133
bin/stop-test.js
Normal file
133
bin/stop-test.js
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/* -------------------------------- REQUIRES -------------------------------- */
|
||||||
|
|
||||||
|
var child = require("child_process");
|
||||||
|
var assert = require("assert");
|
||||||
|
|
||||||
|
/* --------------------------------- CONFIG --------------------------------- */
|
||||||
|
|
||||||
|
if (process.argv[2] == null) {
|
||||||
|
[
|
||||||
|
'Usage: ',
|
||||||
|
'',
|
||||||
|
' `node bin/stop-test.js i,j [rippled_path] [rippled_conf]`',
|
||||||
|
'',
|
||||||
|
' Launch rippled and stop it after n seconds for all n in [i, j}',
|
||||||
|
' For all even values of n launch rippled with `--fg`',
|
||||||
|
' For values of n where n % 3 == 0 launch rippled with `--fg`\n',
|
||||||
|
'Examples: ',
|
||||||
|
'',
|
||||||
|
' $ node bin/stop-test.js 5,10',
|
||||||
|
(' $ node bin/stop-test.js 1,4 ' +
|
||||||
|
'build/clang.debug/rippled $HOME/.confs/rippled.cfg')
|
||||||
|
]
|
||||||
|
.forEach(function(l){console.log(l)});
|
||||||
|
|
||||||
|
process.exit();
|
||||||
|
} else {
|
||||||
|
var testRange = process.argv[2].split(',').map(Number);
|
||||||
|
var rippledPath = process.argv[3] || 'build/rippled'
|
||||||
|
var rippledConf = process.argv[4] || 'rippled.cfg'
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
env: process.env,
|
||||||
|
stdio: 'ignore' // we could dump the child io when it fails abnormally
|
||||||
|
};
|
||||||
|
|
||||||
|
// default args
|
||||||
|
var conf_args = ['--conf='+rippledConf];
|
||||||
|
var start_args = conf_args.concat([/*'--net'*/])
|
||||||
|
var stop_args = conf_args.concat(['stop']);
|
||||||
|
|
||||||
|
/* --------------------------------- HELPERS -------------------------------- */
|
||||||
|
|
||||||
|
function start(args) {
|
||||||
|
return child.spawn(rippledPath, args, options);
|
||||||
|
}
|
||||||
|
function stop(rippled) { child.execFile(rippledPath, stop_args, options)}
|
||||||
|
function secs_l8r(ms, f) {setTimeout(f, ms * 1000); }
|
||||||
|
|
||||||
|
function show_results_and_exit(results) {
|
||||||
|
console.log(JSON.stringify(results, undefined, 2));
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeTakes = function (range) {
|
||||||
|
function sumRange(n) {return (n+1) * n /2}
|
||||||
|
var ret = sumRange(range[1]);
|
||||||
|
if (range[0] > 1) {
|
||||||
|
ret = ret - sumRange(range[0] - 1)
|
||||||
|
}
|
||||||
|
var stopping = (range[1] - range[0]) * 0.5;
|
||||||
|
return ret + stopping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------- TEST ---------------------------------- */
|
||||||
|
|
||||||
|
console.log("Test will take ~%s seconds", timeTakes(testRange));
|
||||||
|
|
||||||
|
(function oneTest(n /* seconds */, results) {
|
||||||
|
if (n >= testRange[1]) {
|
||||||
|
// show_results_and_exit(results);
|
||||||
|
console.log(JSON.stringify(results, undefined, 2));
|
||||||
|
oneTest(testRange[0], []);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = start_args;
|
||||||
|
if (n % 2 == 0) {args = args.concat(['--fg'])}
|
||||||
|
if (n % 3 == 0) {args = args.concat(['--net'])}
|
||||||
|
|
||||||
|
var result = {args: args, alive_for: n};
|
||||||
|
results.push(result);
|
||||||
|
|
||||||
|
console.log("\nLaunching `%s` with `%s` for %d seconds",
|
||||||
|
rippledPath, JSON.stringify(args), n);
|
||||||
|
|
||||||
|
rippled = start(args);
|
||||||
|
console.log("Rippled pid: %d", rippled.pid);
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
var b4StopSent = false;
|
||||||
|
var stopSent = false;
|
||||||
|
var stop_took = null;
|
||||||
|
|
||||||
|
rippled.once('exit', function(){
|
||||||
|
if (!stopSent && !b4StopSent) {
|
||||||
|
console.warn('\nRippled exited itself b4 stop issued');
|
||||||
|
process.exit();
|
||||||
|
};
|
||||||
|
|
||||||
|
// The io handles close AFTER exit, may have implications for
|
||||||
|
// `stdio:'inherit'` option to `child.spawn`.
|
||||||
|
rippled.once('close', function() {
|
||||||
|
result.stop_took = (+new Date() - stop_took) / 1000; // seconds
|
||||||
|
console.log("Stopping after %d seconds took %s seconds",
|
||||||
|
n, result.stop_took);
|
||||||
|
oneTest(n+1, results);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
secs_l8r(n, function(){
|
||||||
|
console.log("Stopping rippled after %d seconds", n);
|
||||||
|
|
||||||
|
// possible race here ?
|
||||||
|
// seems highly unlikely, but I was having issues at one point
|
||||||
|
b4StopSent=true;
|
||||||
|
stop_took = (+new Date());
|
||||||
|
// when does `exit` actually get sent?
|
||||||
|
stop();
|
||||||
|
stopSent=true;
|
||||||
|
|
||||||
|
// Sometimes we want to attach with a debugger.
|
||||||
|
if (process.env.ABORT_TESTS_ON_STALL != null) {
|
||||||
|
// We wait 30 seconds, and if it hasn't stopped, we abort the process
|
||||||
|
secs_l8r(30, function() {
|
||||||
|
if (result.stop_took == null) {
|
||||||
|
console.log("rippled has stalled");
|
||||||
|
process.exit();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}(testRange[0], []));
|
||||||
1506
cfg/rippled-example.cfg
Normal file
1506
cfg/rippled-example.cfg
Normal file
File diff suppressed because it is too large
Load Diff
90
cfg/validators-example.txt
Normal file
90
cfg/validators-example.txt
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#
|
||||||
|
# Default validators.txt
|
||||||
|
#
|
||||||
|
# This file is located in the same folder as your rippled.cfg file
|
||||||
|
# and defines which validators your server trusts not to collude.
|
||||||
|
#
|
||||||
|
# This file is UTF-8 with DOS, UNIX, or Mac style line endings.
|
||||||
|
# Blank lines and lines starting with a '#' are ignored.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# [validators]
|
||||||
|
#
|
||||||
|
# List of the validation public keys of nodes to always accept as validators.
|
||||||
|
#
|
||||||
|
# Manually listing validator keys is not recommended for production networks.
|
||||||
|
# See validator_list_sites and validator_list_keys below.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
||||||
|
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt
|
||||||
|
#
|
||||||
|
# [validator_list_sites]
|
||||||
|
#
|
||||||
|
# List of URIs serving lists of recommended validators.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# https://vl.ripple.com
|
||||||
|
# https://vl.xrplf.org
|
||||||
|
# http://127.0.0.1:8000
|
||||||
|
# file:///etc/opt/ripple/vl.txt
|
||||||
|
#
|
||||||
|
# [validator_list_keys]
|
||||||
|
#
|
||||||
|
# List of keys belonging to trusted validator list publishers.
|
||||||
|
# Validator lists fetched from configured sites will only be considered
|
||||||
|
# if the list is accompanied by a valid signature from a trusted
|
||||||
|
# publisher key.
|
||||||
|
# Validator list keys should be hex-encoded.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
|
||||||
|
# ED307A760EE34F2D0CAA103377B1969117C38B8AA0AA1E2A24DAC1F32FC97087ED
|
||||||
|
#
|
||||||
|
|
||||||
|
# The default validator list publishers that the rippled instance
|
||||||
|
# trusts.
|
||||||
|
#
|
||||||
|
# WARNING: Changing these values can cause your rippled instance to see a
|
||||||
|
# validated ledger that contradicts other rippled instances'
|
||||||
|
# validated ledgers (aka a ledger fork) if your validator list(s)
|
||||||
|
# do not sufficiently overlap with the list(s) used by others.
|
||||||
|
# See: https://arxiv.org/pdf/1802.07242.pdf
|
||||||
|
|
||||||
|
[validator_list_sites]
|
||||||
|
https://vl.ripple.com
|
||||||
|
https://unl.xrplf.org
|
||||||
|
|
||||||
|
[validator_list_keys]
|
||||||
|
#vl.ripple.com
|
||||||
|
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
|
||||||
|
#unl.xrplf.org
|
||||||
|
ED42AEC58B701EEBB77356FFFEC26F83C1F0407263530F068C7C73D392C7E06FD1
|
||||||
|
|
||||||
|
# To use the test network (see https://xrpl.org/connect-your-rippled-to-the-xrp-test-net.html),
|
||||||
|
# use the following configuration instead:
|
||||||
|
#
|
||||||
|
# [validator_list_sites]
|
||||||
|
# https://vl.altnet.rippletest.net
|
||||||
|
#
|
||||||
|
# [validator_list_keys]
|
||||||
|
# ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860
|
||||||
|
|
||||||
|
|
||||||
|
# [validator_list_threshold]
|
||||||
|
#
|
||||||
|
# Minimum number of validator lists on which a validator must be listed in
|
||||||
|
# order to be used.
|
||||||
|
#
|
||||||
|
# This can be set explicitly to any positive integer number not greater than
|
||||||
|
# the size of [validator_list_keys]. If it is not set, or set to 0, the
|
||||||
|
# value will be calculated at startup from the size of [validator_list_keys],
|
||||||
|
# where the calculation is:
|
||||||
|
#
|
||||||
|
# threshold = size(validator_list_keys) < 3
|
||||||
|
# ? 1
|
||||||
|
# : floor(size(validator_list_keys) / 2) + 1
|
||||||
|
|
||||||
|
[validator_list_threshold]
|
||||||
|
0
|
||||||
48
cmake/CMakeFuncs.cmake
Normal file
48
cmake/CMakeFuncs.cmake
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
macro(group_sources_in source_dir curdir)
|
||||||
|
file(GLOB children RELATIVE ${source_dir}/${curdir}
|
||||||
|
${source_dir}/${curdir}/*)
|
||||||
|
foreach (child ${children})
|
||||||
|
if (IS_DIRECTORY ${source_dir}/${curdir}/${child})
|
||||||
|
group_sources_in(${source_dir} ${curdir}/${child})
|
||||||
|
else()
|
||||||
|
string(REPLACE "/" "\\" groupname ${curdir})
|
||||||
|
source_group(${groupname} FILES
|
||||||
|
${source_dir}/${curdir}/${child})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(group_sources curdir)
|
||||||
|
group_sources_in(${PROJECT_SOURCE_DIR} ${curdir})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro (exclude_from_default target_)
|
||||||
|
set_target_properties (${target_} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||||
|
set_target_properties (${target_} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
macro (exclude_if_included target_)
|
||||||
|
get_directory_property(has_parent PARENT_DIRECTORY)
|
||||||
|
if (has_parent)
|
||||||
|
exclude_from_default (${target_})
|
||||||
|
endif ()
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
find_package(Git)
|
||||||
|
|
||||||
|
function (git_branch branch_val)
|
||||||
|
if (NOT GIT_FOUND)
|
||||||
|
return ()
|
||||||
|
endif ()
|
||||||
|
set (_branch "")
|
||||||
|
execute_process (COMMAND ${GIT_EXECUTABLE} "rev-parse" "--abbrev-ref" "HEAD"
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
RESULT_VARIABLE _git_exit_code
|
||||||
|
OUTPUT_VARIABLE _temp_branch
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET)
|
||||||
|
if (_git_exit_code EQUAL 0)
|
||||||
|
set (_branch ${_temp_branch})
|
||||||
|
endif ()
|
||||||
|
set (${branch_val} "${_branch}" PARENT_SCOPE)
|
||||||
|
endfunction ()
|
||||||
453
cmake/CodeCoverage.cmake
Normal file
453
cmake/CodeCoverage.cmake
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
# Copyright (c) 2012 - 2017, Lars Bilke
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
# are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# CHANGES:
|
||||||
|
#
|
||||||
|
# 2012-01-31, Lars Bilke
|
||||||
|
# - Enable Code Coverage
|
||||||
|
#
|
||||||
|
# 2013-09-17, Joakim Söderberg
|
||||||
|
# - Added support for Clang.
|
||||||
|
# - Some additional usage instructions.
|
||||||
|
#
|
||||||
|
# 2016-02-03, Lars Bilke
|
||||||
|
# - Refactored functions to use named parameters
|
||||||
|
#
|
||||||
|
# 2017-06-02, Lars Bilke
|
||||||
|
# - Merged with modified version from github.com/ufz/ogs
|
||||||
|
#
|
||||||
|
# 2019-05-06, Anatolii Kurotych
|
||||||
|
# - Remove unnecessary --coverage flag
|
||||||
|
#
|
||||||
|
# 2019-12-13, FeRD (Frank Dana)
|
||||||
|
# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor
|
||||||
|
# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments.
|
||||||
|
# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY
|
||||||
|
# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list
|
||||||
|
# - Set lcov basedir with -b argument
|
||||||
|
# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be
|
||||||
|
# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().)
|
||||||
|
# - Delete output dir, .info file on 'make clean'
|
||||||
|
# - Remove Python detection, since version mismatches will break gcovr
|
||||||
|
# - Minor cleanup (lowercase function names, update examples...)
|
||||||
|
#
|
||||||
|
# 2019-12-19, FeRD (Frank Dana)
|
||||||
|
# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets
|
||||||
|
#
|
||||||
|
# 2020-01-19, Bob Apthorpe
|
||||||
|
# - Added gfortran support
|
||||||
|
#
|
||||||
|
# 2020-02-17, FeRD (Frank Dana)
|
||||||
|
# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters
|
||||||
|
# in EXCLUDEs, and remove manual escaping from gcovr targets
|
||||||
|
#
|
||||||
|
# 2021-01-19, Robin Mueller
|
||||||
|
# - Add CODE_COVERAGE_VERBOSE option which will allow to print out commands which are run
|
||||||
|
# - Added the option for users to set the GCOVR_ADDITIONAL_ARGS variable to supply additional
|
||||||
|
# flags to the gcovr command
|
||||||
|
#
|
||||||
|
# 2020-05-04, Mihchael Davis
|
||||||
|
# - Add -fprofile-abs-path to make gcno files contain absolute paths
|
||||||
|
# - Fix BASE_DIRECTORY not working when defined
|
||||||
|
# - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines
|
||||||
|
#
|
||||||
|
# 2021-05-10, Martin Stump
|
||||||
|
# - Check if the generator is multi-config before warning about non-Debug builds
|
||||||
|
#
|
||||||
|
# 2022-02-22, Marko Wehle
|
||||||
|
# - Change gcovr output from -o <filename> for --xml <filename> and --html <filename> output respectively.
|
||||||
|
# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt".
|
||||||
|
#
|
||||||
|
# 2022-09-28, Sebastian Mueller
|
||||||
|
# - fix append_coverage_compiler_flags_to_target to correctly add flags
|
||||||
|
# - replace "-fprofile-arcs -ftest-coverage" with "--coverage" (equivalent)
|
||||||
|
#
|
||||||
|
# 2024-01-04, Bronek Kozicki
|
||||||
|
# - remove setup_target_for_coverage_lcov (slow) and setup_target_for_coverage_fastcov (no support for Clang)
|
||||||
|
# - fix Clang support by adding find_program( ... llvm-cov )
|
||||||
|
# - add Apple Clang support by adding execute_process( COMMAND xcrun -f llvm-cov ... )
|
||||||
|
# - add CODE_COVERAGE_GCOV_TOOL to explicitly select gcov tool and disable find_program
|
||||||
|
# - replace both functions setup_target_for_coverage_gcovr_* with a single setup_target_for_coverage_gcovr
|
||||||
|
# - add support for all gcovr output formats
|
||||||
|
#
|
||||||
|
# 2024-04-03, Bronek Kozicki
|
||||||
|
# - add support for output formats: jacoco, clover, lcov
|
||||||
|
#
|
||||||
|
# USAGE:
|
||||||
|
#
|
||||||
|
# 1. Copy this file into your cmake modules path.
|
||||||
|
#
|
||||||
|
# 2. Add the following line to your CMakeLists.txt (best inside an if-condition
|
||||||
|
# using a CMake option() to enable it just optionally):
|
||||||
|
# include(CodeCoverage)
|
||||||
|
#
|
||||||
|
# 3. Append necessary compiler flags for all supported source files:
|
||||||
|
# append_coverage_compiler_flags()
|
||||||
|
# Or for specific target:
|
||||||
|
# append_coverage_compiler_flags_to_target(YOUR_TARGET_NAME)
|
||||||
|
#
|
||||||
|
# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og
|
||||||
|
#
|
||||||
|
# 4. If you need to exclude additional directories from the report, specify them
|
||||||
|
# using full paths in the COVERAGE_EXCLUDES variable before calling
|
||||||
|
# setup_target_for_coverage_*().
|
||||||
|
# Example:
|
||||||
|
# set(COVERAGE_EXCLUDES
|
||||||
|
# '${PROJECT_SOURCE_DIR}/src/dir1/*'
|
||||||
|
# '/path/to/my/src/dir2/*')
|
||||||
|
# Or, use the EXCLUDE argument to setup_target_for_coverage_*().
|
||||||
|
# Example:
|
||||||
|
# setup_target_for_coverage_gcovr(
|
||||||
|
# NAME coverage
|
||||||
|
# EXECUTABLE testrunner
|
||||||
|
# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*")
|
||||||
|
#
|
||||||
|
# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set
|
||||||
|
# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR)
|
||||||
|
# Example:
|
||||||
|
# set(COVERAGE_EXCLUDES "dir1/*")
|
||||||
|
# setup_target_for_coverage_gcovr(
|
||||||
|
# NAME coverage
|
||||||
|
# EXECUTABLE testrunner
|
||||||
|
# FORMAT html-details
|
||||||
|
# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src"
|
||||||
|
# EXCLUDE "dir2/*")
|
||||||
|
#
|
||||||
|
# 4.b If you need to pass specific options to gcovr, specify them in
|
||||||
|
# GCOVR_ADDITIONAL_ARGS variable.
|
||||||
|
# Example:
|
||||||
|
# set (GCOVR_ADDITIONAL_ARGS --exclude-throw-branches --exclude-noncode-lines -s)
|
||||||
|
# setup_target_for_coverage_gcovr(
|
||||||
|
# NAME coverage
|
||||||
|
# EXECUTABLE testrunner
|
||||||
|
# EXCLUDE "src/dir1" "src/dir2")
|
||||||
|
#
|
||||||
|
# 5. Use the functions described below to create a custom make target which
|
||||||
|
# runs your test executable and produces a code coverage report.
|
||||||
|
#
|
||||||
|
# 6. Build a Debug build:
|
||||||
|
# cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
# make
|
||||||
|
# make my_coverage_target
|
||||||
|
|
||||||
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
|
option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE)
|
||||||
|
|
||||||
|
# Check prereqs
|
||||||
|
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
||||||
|
|
||||||
|
if(DEFINED CODE_COVERAGE_GCOV_TOOL)
|
||||||
|
set(GCOV_TOOL "${CODE_COVERAGE_GCOV_TOOL}")
|
||||||
|
elseif(DEFINED ENV{CODE_COVERAGE_GCOV_TOOL})
|
||||||
|
set(GCOV_TOOL "$ENV{CODE_COVERAGE_GCOV_TOOL}")
|
||||||
|
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||||
|
if(APPLE)
|
||||||
|
execute_process( COMMAND xcrun -f llvm-cov
|
||||||
|
OUTPUT_VARIABLE LLVMCOV_PATH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
find_program( LLVMCOV_PATH llvm-cov )
|
||||||
|
endif()
|
||||||
|
if(LLVMCOV_PATH)
|
||||||
|
set(GCOV_TOOL "${LLVMCOV_PATH} gcov")
|
||||||
|
endif()
|
||||||
|
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||||
|
find_program( GCOV_PATH gcov )
|
||||||
|
set(GCOV_TOOL "${GCOV_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check supported compiler (Clang, GNU and Flang)
|
||||||
|
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||||
|
foreach(LANG ${LANGUAGES})
|
||||||
|
if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||||
|
if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3)
|
||||||
|
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
|
||||||
|
endif()
|
||||||
|
elseif(NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU"
|
||||||
|
AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang")
|
||||||
|
message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(COVERAGE_COMPILER_FLAGS "-g --coverage"
|
||||||
|
CACHE INTERNAL "")
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
|
||||||
|
if(HAVE_cxx_fprofile_abs_path)
|
||||||
|
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
|
||||||
|
endif()
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
|
||||||
|
if(HAVE_c_fprofile_abs_path)
|
||||||
|
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_Fortran_FLAGS_COVERAGE
|
||||||
|
${COVERAGE_COMPILER_FLAGS}
|
||||||
|
CACHE STRING "Flags used by the Fortran compiler during coverage builds."
|
||||||
|
FORCE )
|
||||||
|
set(CMAKE_CXX_FLAGS_COVERAGE
|
||||||
|
${COVERAGE_COMPILER_FLAGS}
|
||||||
|
CACHE STRING "Flags used by the C++ compiler during coverage builds."
|
||||||
|
FORCE )
|
||||||
|
set(CMAKE_C_FLAGS_COVERAGE
|
||||||
|
${COVERAGE_COMPILER_FLAGS}
|
||||||
|
CACHE STRING "Flags used by the C compiler during coverage builds."
|
||||||
|
FORCE )
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||||
|
""
|
||||||
|
CACHE STRING "Flags used for linking binaries during coverage builds."
|
||||||
|
FORCE )
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||||
|
""
|
||||||
|
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
|
||||||
|
FORCE )
|
||||||
|
mark_as_advanced(
|
||||||
|
CMAKE_Fortran_FLAGS_COVERAGE
|
||||||
|
CMAKE_CXX_FLAGS_COVERAGE
|
||||||
|
CMAKE_C_FLAGS_COVERAGE
|
||||||
|
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||||
|
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
|
||||||
|
|
||||||
|
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
|
||||||
|
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
|
||||||
|
endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
|
||||||
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
|
||||||
|
link_libraries(gcov)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Defines a target for running and collection code coverage information
|
||||||
|
# Builds dependencies, runs the given executable and outputs reports.
|
||||||
|
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||||
|
# the coverage generation will not complete.
|
||||||
|
#
|
||||||
|
# setup_target_for_coverage_gcovr(
|
||||||
|
# NAME ctest_coverage # New target name
|
||||||
|
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||||
|
# DEPENDENCIES executable_target # Dependencies to build first
|
||||||
|
# BASE_DIRECTORY "../" # Base directory for report
|
||||||
|
# # (defaults to PROJECT_SOURCE_DIR)
|
||||||
|
# FORMAT "cobertura" # Output format, one of:
|
||||||
|
# # xml cobertura sonarqube jacoco clover
|
||||||
|
# # json-summary json-details coveralls csv
|
||||||
|
# # txt html-single html-nested html-details
|
||||||
|
# # lcov (xml is an alias to cobertura;
|
||||||
|
# # if no format is set, defaults to xml)
|
||||||
|
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
|
||||||
|
# # to BASE_DIRECTORY, with CMake 3.4+)
|
||||||
|
# )
|
||||||
|
# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the
|
||||||
|
# GCVOR command.
|
||||||
|
function(setup_target_for_coverage_gcovr)
|
||||||
|
set(options NONE)
|
||||||
|
set(oneValueArgs BASE_DIRECTORY NAME FORMAT)
|
||||||
|
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||||
|
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||||
|
|
||||||
|
if(NOT GCOV_TOOL)
|
||||||
|
message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT GCOVR_PATH)
|
||||||
|
message(FATAL_ERROR "Could not find gcovr tool! Aborting...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
|
||||||
|
if(DEFINED Coverage_BASE_DIRECTORY)
|
||||||
|
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
|
||||||
|
else()
|
||||||
|
set(BASEDIR ${PROJECT_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED Coverage_FORMAT)
|
||||||
|
set(Coverage_FORMAT xml)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if("--output" IN_LIST GCOVR_ADDITIONAL_ARGS)
|
||||||
|
message(FATAL_ERROR "Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting...")
|
||||||
|
else()
|
||||||
|
if((Coverage_FORMAT STREQUAL "html-details")
|
||||||
|
OR (Coverage_FORMAT STREQUAL "html-nested"))
|
||||||
|
set(GCOVR_OUTPUT_FILE ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html)
|
||||||
|
set(GCOVR_CREATE_FOLDER ${PROJECT_BINARY_DIR}/${Coverage_NAME})
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "html-single")
|
||||||
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html)
|
||||||
|
elseif((Coverage_FORMAT STREQUAL "json-summary")
|
||||||
|
OR (Coverage_FORMAT STREQUAL "json-details")
|
||||||
|
OR (Coverage_FORMAT STREQUAL "coveralls"))
|
||||||
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "txt")
|
||||||
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "csv")
|
||||||
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "lcov")
|
||||||
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.lcov)
|
||||||
|
else()
|
||||||
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if((Coverage_FORMAT STREQUAL "cobertura")
|
||||||
|
OR (Coverage_FORMAT STREQUAL "xml"))
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty )
|
||||||
|
set(Coverage_FORMAT cobertura) # overwrite xml
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "sonarqube")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "jacoco")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco-pretty )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "clover")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --clover "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --clover-pretty )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "lcov")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --lcov "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "json-summary")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary-pretty)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "json-details")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json-pretty)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "coveralls")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls-pretty)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "csv")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --csv "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "txt")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --txt "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "html-single")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html-self-contained)
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "html-nested")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html-nested "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
elseif(Coverage_FORMAT STREQUAL "html-details")
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html-details "${GCOVR_OUTPUT_FILE}" )
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported output style ${Coverage_FORMAT}! Aborting...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Collect excludes (CMake 3.4+: Also compute absolute paths)
|
||||||
|
set(GCOVR_EXCLUDES "")
|
||||||
|
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
|
||||||
|
if(CMAKE_VERSION VERSION_GREATER 3.4)
|
||||||
|
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
||||||
|
endif()
|
||||||
|
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||||
|
endforeach()
|
||||||
|
list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
|
||||||
|
|
||||||
|
# Combine excludes to several -e arguments
|
||||||
|
set(GCOVR_EXCLUDE_ARGS "")
|
||||||
|
foreach(EXCLUDE ${GCOVR_EXCLUDES})
|
||||||
|
list(APPEND GCOVR_EXCLUDE_ARGS "-e")
|
||||||
|
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Set up commands which will be run to generate coverage data
|
||||||
|
# Run tests
|
||||||
|
set(GCOVR_EXEC_TESTS_CMD
|
||||||
|
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create folder
|
||||||
|
if(DEFINED GCOVR_CREATE_FOLDER)
|
||||||
|
set(GCOVR_FOLDER_CMD
|
||||||
|
${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER})
|
||||||
|
else()
|
||||||
|
set(GCOVR_FOLDER_CMD echo) # dummy
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Running gcovr
|
||||||
|
set(GCOVR_CMD
|
||||||
|
${GCOVR_PATH}
|
||||||
|
--gcov-executable ${GCOV_TOOL}
|
||||||
|
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file
|
||||||
|
-r ${BASEDIR}
|
||||||
|
${GCOVR_ADDITIONAL_ARGS}
|
||||||
|
${GCOVR_EXCLUDE_ARGS}
|
||||||
|
--object-directory=${PROJECT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(CODE_COVERAGE_VERBOSE)
|
||||||
|
message(STATUS "Executed command report")
|
||||||
|
|
||||||
|
message(STATUS "Command to run tests: ")
|
||||||
|
string(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}")
|
||||||
|
message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}")
|
||||||
|
|
||||||
|
if(NOT GCOVR_FOLDER_CMD STREQUAL "echo")
|
||||||
|
message(STATUS "Command to create a folder: ")
|
||||||
|
string(REPLACE ";" " " GCOVR_FOLDER_CMD_SPACED "${GCOVR_FOLDER_CMD}")
|
||||||
|
message(STATUS "${GCOVR_FOLDER_CMD_SPACED}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Command to generate gcovr coverage data: ")
|
||||||
|
string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}")
|
||||||
|
message(STATUS "${GCOVR_CMD_SPACED}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_target(${Coverage_NAME}
|
||||||
|
COMMAND ${GCOVR_EXEC_TESTS_CMD}
|
||||||
|
COMMAND ${GCOVR_FOLDER_CMD}
|
||||||
|
COMMAND ${GCOVR_CMD}
|
||||||
|
|
||||||
|
BYPRODUCTS ${GCOVR_OUTPUT_FILE}
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
DEPENDS ${Coverage_DEPENDENCIES}
|
||||||
|
VERBATIM # Protect arguments to commands
|
||||||
|
COMMENT "Running gcovr to produce code coverage report."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Show info where to find the report
|
||||||
|
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||||
|
COMMAND ;
|
||||||
|
COMMENT "Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}"
|
||||||
|
)
|
||||||
|
endfunction() # setup_target_for_coverage_gcovr
|
||||||
|
|
||||||
|
function(append_coverage_compiler_flags)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||||
|
message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
|
||||||
|
endfunction() # append_coverage_compiler_flags
|
||||||
|
|
||||||
|
# Setup coverage for specific library
|
||||||
|
function(append_coverage_compiler_flags_to_target name)
|
||||||
|
separate_arguments(_flag_list NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}")
|
||||||
|
target_compile_options(${name} PRIVATE ${_flag_list})
|
||||||
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_libraries(${name} PRIVATE gcov)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
56
cmake/RippleConfig.cmake
Normal file
56
cmake/RippleConfig.cmake
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
include (CMakeFindDependencyMacro)
|
||||||
|
# need to represent system dependencies of the lib here
|
||||||
|
#[=========================================================[
|
||||||
|
Boost
|
||||||
|
#]=========================================================]
|
||||||
|
if (static OR APPLE OR MSVC)
|
||||||
|
set (Boost_USE_STATIC_LIBS ON)
|
||||||
|
endif ()
|
||||||
|
set (Boost_USE_MULTITHREADED ON)
|
||||||
|
if (static OR MSVC)
|
||||||
|
set (Boost_USE_STATIC_RUNTIME ON)
|
||||||
|
else ()
|
||||||
|
set (Boost_USE_STATIC_RUNTIME OFF)
|
||||||
|
endif ()
|
||||||
|
find_dependency (Boost 1.70
|
||||||
|
COMPONENTS
|
||||||
|
chrono
|
||||||
|
container
|
||||||
|
context
|
||||||
|
coroutine
|
||||||
|
date_time
|
||||||
|
filesystem
|
||||||
|
program_options
|
||||||
|
regex
|
||||||
|
system
|
||||||
|
thread)
|
||||||
|
#[=========================================================[
|
||||||
|
OpenSSL
|
||||||
|
#]=========================================================]
|
||||||
|
if (NOT DEFINED OPENSSL_ROOT_DIR)
|
||||||
|
if (DEFINED ENV{OPENSSL_ROOT})
|
||||||
|
set (OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT})
|
||||||
|
elseif (APPLE)
|
||||||
|
find_program (homebrew brew)
|
||||||
|
if (homebrew)
|
||||||
|
execute_process (COMMAND ${homebrew} --prefix openssl
|
||||||
|
OUTPUT_VARIABLE OPENSSL_ROOT_DIR
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
file (TO_CMAKE_PATH "${OPENSSL_ROOT_DIR}" OPENSSL_ROOT_DIR)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (static OR APPLE OR MSVC)
|
||||||
|
set (OPENSSL_USE_STATIC_LIBS ON)
|
||||||
|
endif ()
|
||||||
|
set (OPENSSL_MSVC_STATIC_RT ON)
|
||||||
|
find_dependency (OpenSSL 1.1.1 REQUIRED)
|
||||||
|
find_dependency (ZLIB)
|
||||||
|
find_dependency (date)
|
||||||
|
if (TARGET ZLIB::ZLIB)
|
||||||
|
set_target_properties(OpenSSL::Crypto PROPERTIES
|
||||||
|
INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
include ("${CMAKE_CURRENT_LIST_DIR}/RippleTargets.cmake")
|
||||||
202
cmake/RippledCompiler.cmake
Normal file
202
cmake/RippledCompiler.cmake
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
setup project-wide compiler settings
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
#[=========================================================[
|
||||||
|
TODO some/most of these common settings belong in a
|
||||||
|
toolchain file, especially the ABI-impacting ones
|
||||||
|
#]=========================================================]
|
||||||
|
add_library (common INTERFACE)
|
||||||
|
add_library (Ripple::common ALIAS common)
|
||||||
|
# add a single global dependency on this interface lib
|
||||||
|
link_libraries (Ripple::common)
|
||||||
|
set_target_properties (common
|
||||||
|
PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
target_compile_definitions (common
|
||||||
|
INTERFACE
|
||||||
|
$<$<CONFIG:Debug>:DEBUG _DEBUG>
|
||||||
|
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>)
|
||||||
|
# ^^^^ NOTE: CMAKE release builds already have NDEBUG
|
||||||
|
# defined, so no need to add it explicitly except for
|
||||||
|
# this special case of (profile ON) and (assert OFF)
|
||||||
|
# -- presumably this is because we don't want profile
|
||||||
|
# builds asserting unless asserts were specifically
|
||||||
|
# requested
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# remove existing exception flag since we set it to -EHa
|
||||||
|
string (REGEX REPLACE "[-/]EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
|
foreach (var_
|
||||||
|
CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||||
|
CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE)
|
||||||
|
|
||||||
|
# also remove dynamic runtime
|
||||||
|
string (REGEX REPLACE "[-/]MD[d]*" " " ${var_} "${${var_}}")
|
||||||
|
|
||||||
|
# /ZI (Edit & Continue debugging information) is incompatible with Gy-
|
||||||
|
string (REPLACE "/ZI" "/Zi" ${var_} "${${var_}}")
|
||||||
|
|
||||||
|
# omit debug info completely under CI (not needed)
|
||||||
|
if (is_ci)
|
||||||
|
string (REPLACE "/Zi" " " ${var_} "${${var_}}")
|
||||||
|
endif ()
|
||||||
|
endforeach ()
|
||||||
|
|
||||||
|
target_compile_options (common
|
||||||
|
INTERFACE
|
||||||
|
-bigobj # Increase object file max size
|
||||||
|
-fp:precise # Floating point behavior
|
||||||
|
-Gd # __cdecl calling convention
|
||||||
|
-Gm- # Minimal rebuild: disabled
|
||||||
|
-Gy- # Function level linking: disabled
|
||||||
|
-MP # Multiprocessor compilation
|
||||||
|
-openmp- # pragma omp: disabled
|
||||||
|
-errorReport:none # No error reporting to Internet
|
||||||
|
-nologo # Suppress login banner
|
||||||
|
-wd4018 # Disable signed/unsigned comparison warnings
|
||||||
|
-wd4244 # Disable float to int possible loss of data warnings
|
||||||
|
-wd4267 # Disable size_t to T possible loss of data warnings
|
||||||
|
-wd4800 # Disable C4800(int to bool performance)
|
||||||
|
-wd4503 # Decorated name length exceeded, name was truncated
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:
|
||||||
|
-EHa
|
||||||
|
-GR
|
||||||
|
>
|
||||||
|
$<$<CONFIG:Release>:-Ox>
|
||||||
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:
|
||||||
|
-GS
|
||||||
|
-Zc:forScope
|
||||||
|
>
|
||||||
|
# static runtime
|
||||||
|
$<$<CONFIG:Debug>:-MTd>
|
||||||
|
$<$<NOT:$<CONFIG:Debug>>:-MT>
|
||||||
|
$<$<BOOL:${werr}>:-WX>
|
||||||
|
)
|
||||||
|
target_compile_definitions (common
|
||||||
|
INTERFACE
|
||||||
|
_WIN32_WINNT=0x6000
|
||||||
|
_SCL_SECURE_NO_WARNINGS
|
||||||
|
_CRT_SECURE_NO_WARNINGS
|
||||||
|
WIN32_CONSOLE
|
||||||
|
WIN32_LEAN_AND_MEAN
|
||||||
|
NOMINMAX
|
||||||
|
# TODO: Resolve these warnings, don't just silence them
|
||||||
|
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
|
||||||
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>)
|
||||||
|
target_link_libraries (common
|
||||||
|
INTERFACE
|
||||||
|
-errorreport:none
|
||||||
|
-machine:X64)
|
||||||
|
else ()
|
||||||
|
# HACK : because these need to come first, before any warning demotion
|
||||||
|
string (APPEND CMAKE_CXX_FLAGS " -Wall -Wdeprecated")
|
||||||
|
if (wextra)
|
||||||
|
string (APPEND CMAKE_CXX_FLAGS " -Wextra -Wno-unused-parameter")
|
||||||
|
endif ()
|
||||||
|
# not MSVC
|
||||||
|
target_compile_options (common
|
||||||
|
INTERFACE
|
||||||
|
$<$<BOOL:${werr}>:-Werror>
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:
|
||||||
|
-frtti
|
||||||
|
-Wnon-virtual-dtor
|
||||||
|
>
|
||||||
|
-Wno-sign-compare
|
||||||
|
-Wno-char-subscripts
|
||||||
|
-Wno-format
|
||||||
|
-Wno-unused-local-typedefs
|
||||||
|
-fstack-protector
|
||||||
|
$<$<BOOL:${is_gcc}>:
|
||||||
|
-Wno-unused-but-set-variable
|
||||||
|
-Wno-deprecated
|
||||||
|
>
|
||||||
|
$<$<NOT:$<CONFIG:Debug>>:-fno-strict-aliasing>
|
||||||
|
# tweak gcc optimization for debug
|
||||||
|
$<$<AND:$<BOOL:${is_gcc}>,$<CONFIG:Debug>>:-O0>
|
||||||
|
# Add debug symbols to release config
|
||||||
|
$<$<CONFIG:Release>:-g>)
|
||||||
|
target_link_libraries (common
|
||||||
|
INTERFACE
|
||||||
|
-rdynamic
|
||||||
|
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
|
||||||
|
# link to static libc/c++ iff:
|
||||||
|
# * static option set and
|
||||||
|
# * NOT APPLE (AppleClang does not support static libc/c++) and
|
||||||
|
# * NOT san (sanitizers typically don't work with static libc/c++)
|
||||||
|
$<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>,$<NOT:$<BOOL:${san}>>>:
|
||||||
|
-static-libstdc++
|
||||||
|
-static-libgcc
|
||||||
|
>)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Antithesis instrumentation will only be built and deployed using machines running Linux.
|
||||||
|
if (voidstar)
|
||||||
|
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message(FATAL_ERROR "Antithesis instrumentation requires Debug build type, aborting...")
|
||||||
|
elseif (NOT is_linux)
|
||||||
|
message(FATAL_ERROR "Antithesis instrumentation requires Linux, aborting...")
|
||||||
|
elseif (NOT (is_clang AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0))
|
||||||
|
message(FATAL_ERROR "Antithesis instrumentation requires Clang version 16 or later, aborting...")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (use_mold)
|
||||||
|
# use mold linker if available
|
||||||
|
execute_process (
|
||||||
|
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=mold -Wl,--version
|
||||||
|
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
|
if ("${LD_VERSION}" MATCHES "mold")
|
||||||
|
target_link_libraries (common INTERFACE -fuse-ld=mold)
|
||||||
|
endif ()
|
||||||
|
unset (LD_VERSION)
|
||||||
|
elseif (use_gold AND is_gcc)
|
||||||
|
# use gold linker if available
|
||||||
|
execute_process (
|
||||||
|
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version
|
||||||
|
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
|
#[=========================================================[
|
||||||
|
NOTE: THE gold linker inserts -rpath as DT_RUNPATH by
|
||||||
|
default intead of DT_RPATH, so you might have slightly
|
||||||
|
unexpected runtime ld behavior if you were expecting
|
||||||
|
DT_RPATH. Specify --disable-new-dtags to gold if you do
|
||||||
|
not want the default DT_RUNPATH behavior. This rpath
|
||||||
|
treatment as well as static/dynamic selection means that
|
||||||
|
gold does not currently have ideal default behavior when
|
||||||
|
we are using jemalloc. Thus for simplicity we don't use
|
||||||
|
it when jemalloc is requested. An alternative to
|
||||||
|
disabling would be to figure out all the settings
|
||||||
|
required to make gold play nicely with jemalloc.
|
||||||
|
#]=========================================================]
|
||||||
|
if (("${LD_VERSION}" MATCHES "GNU gold") AND (NOT jemalloc))
|
||||||
|
target_link_libraries (common
|
||||||
|
INTERFACE
|
||||||
|
-fuse-ld=gold
|
||||||
|
-Wl,--no-as-needed
|
||||||
|
#[=========================================================[
|
||||||
|
see https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1253638/comments/5
|
||||||
|
DT_RUNPATH does not work great for transitive
|
||||||
|
dependencies (of which boost has a few) - so just
|
||||||
|
switch to DT_RPATH if doing dynamic linking with gold
|
||||||
|
#]=========================================================]
|
||||||
|
$<$<NOT:$<BOOL:${static}>>:-Wl,--disable-new-dtags>)
|
||||||
|
endif ()
|
||||||
|
unset (LD_VERSION)
|
||||||
|
elseif (use_lld)
|
||||||
|
# use lld linker if available
|
||||||
|
execute_process (
|
||||||
|
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=lld -Wl,--version
|
||||||
|
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
|
if ("${LD_VERSION}" MATCHES "LLD")
|
||||||
|
target_link_libraries (common INTERFACE -fuse-ld=lld)
|
||||||
|
endif ()
|
||||||
|
unset (LD_VERSION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if (assert)
|
||||||
|
foreach (var_ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE)
|
||||||
|
STRING (REGEX REPLACE "[-/]DNDEBUG" "" ${var_} "${${var_}}")
|
||||||
|
endforeach ()
|
||||||
|
endif ()
|
||||||
191
cmake/RippledCore.cmake
Normal file
191
cmake/RippledCore.cmake
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
Exported targets.
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
include(target_protobuf_sources)
|
||||||
|
|
||||||
|
# Protocol buffers cannot participate in a unity build,
|
||||||
|
# because all the generated sources
|
||||||
|
# define a bunch of `static const` variables with the same names,
|
||||||
|
# so we just build them as a separate library.
|
||||||
|
add_library(xrpl.libpb)
|
||||||
|
set_target_properties(xrpl.libpb PROPERTIES UNITY_BUILD OFF)
|
||||||
|
target_protobuf_sources(xrpl.libpb xrpl/proto
|
||||||
|
LANGUAGE cpp
|
||||||
|
IMPORT_DIRS include/xrpl/proto
|
||||||
|
PROTOS include/xrpl/proto/ripple.proto
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE protos "include/xrpl/proto/org/*.proto")
|
||||||
|
target_protobuf_sources(xrpl.libpb xrpl/proto
|
||||||
|
LANGUAGE cpp
|
||||||
|
IMPORT_DIRS include/xrpl/proto
|
||||||
|
PROTOS "${protos}"
|
||||||
|
)
|
||||||
|
target_protobuf_sources(xrpl.libpb xrpl/proto
|
||||||
|
LANGUAGE grpc
|
||||||
|
IMPORT_DIRS include/xrpl/proto
|
||||||
|
PROTOS "${protos}"
|
||||||
|
PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
|
||||||
|
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(xrpl.libpb
|
||||||
|
PUBLIC
|
||||||
|
$<$<BOOL:${MSVC}>:-wd4996>
|
||||||
|
$<$<BOOL:${XCODE}>:
|
||||||
|
--system-header-prefix="google/protobuf"
|
||||||
|
-Wno-deprecated-dynamic-exception-spec
|
||||||
|
>
|
||||||
|
PRIVATE
|
||||||
|
$<$<BOOL:${MSVC}>:-wd4065>
|
||||||
|
$<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(xrpl.libpb
|
||||||
|
PUBLIC
|
||||||
|
protobuf::libprotobuf
|
||||||
|
gRPC::grpc++
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: Clean up the number of library targets later.
|
||||||
|
add_library(xrpl.imports.main INTERFACE)
|
||||||
|
|
||||||
|
target_link_libraries(xrpl.imports.main
|
||||||
|
INTERFACE
|
||||||
|
LibArchive::LibArchive
|
||||||
|
OpenSSL::Crypto
|
||||||
|
Ripple::boost
|
||||||
|
Ripple::opts
|
||||||
|
Ripple::syslibs
|
||||||
|
absl::random_random
|
||||||
|
date::date
|
||||||
|
ed25519::ed25519
|
||||||
|
secp256k1::secp256k1
|
||||||
|
xrpl.libpb
|
||||||
|
xxHash::xxhash
|
||||||
|
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
|
||||||
|
)
|
||||||
|
|
||||||
|
include(add_module)
|
||||||
|
include(target_link_modules)
|
||||||
|
|
||||||
|
# Level 01
|
||||||
|
add_module(xrpl beast)
|
||||||
|
target_link_libraries(xrpl.libxrpl.beast PUBLIC
|
||||||
|
xrpl.imports.main
|
||||||
|
xrpl.libpb
|
||||||
|
)
|
||||||
|
|
||||||
|
# Level 02
|
||||||
|
add_module(xrpl basics)
|
||||||
|
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
|
||||||
|
|
||||||
|
# Level 03
|
||||||
|
add_module(xrpl json)
|
||||||
|
target_link_libraries(xrpl.libxrpl.json PUBLIC xrpl.libxrpl.basics)
|
||||||
|
|
||||||
|
add_module(xrpl crypto)
|
||||||
|
target_link_libraries(xrpl.libxrpl.crypto PUBLIC xrpl.libxrpl.basics)
|
||||||
|
|
||||||
|
# Level 04
|
||||||
|
add_module(xrpl protocol)
|
||||||
|
target_link_libraries(xrpl.libxrpl.protocol PUBLIC
|
||||||
|
xrpl.libxrpl.crypto
|
||||||
|
xrpl.libxrpl.json
|
||||||
|
)
|
||||||
|
|
||||||
|
# Level 05
|
||||||
|
add_module(xrpl resource)
|
||||||
|
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
|
||||||
|
|
||||||
|
add_module(xrpl server)
|
||||||
|
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
|
||||||
|
|
||||||
|
|
||||||
|
add_library(xrpl.libxrpl)
|
||||||
|
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
|
||||||
|
|
||||||
|
add_library(xrpl::libxrpl ALIAS xrpl.libxrpl)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/libxrpl/*.cpp"
|
||||||
|
)
|
||||||
|
target_sources(xrpl.libxrpl PRIVATE ${sources})
|
||||||
|
|
||||||
|
target_link_modules(xrpl PUBLIC
|
||||||
|
basics
|
||||||
|
beast
|
||||||
|
crypto
|
||||||
|
json
|
||||||
|
protocol
|
||||||
|
resource
|
||||||
|
server
|
||||||
|
)
|
||||||
|
|
||||||
|
# All headers in libxrpl are in modules.
|
||||||
|
# Uncomment this stanza if you have not yet moved new headers into a module.
|
||||||
|
# target_include_directories(xrpl.libxrpl
|
||||||
|
# PRIVATE
|
||||||
|
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||||
|
# PUBLIC
|
||||||
|
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
# $<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
|
if(xrpld)
|
||||||
|
add_executable(rippled)
|
||||||
|
if(tests)
|
||||||
|
target_compile_definitions(rippled PUBLIC ENABLE_TESTS)
|
||||||
|
endif()
|
||||||
|
target_include_directories(rippled
|
||||||
|
PRIVATE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp"
|
||||||
|
)
|
||||||
|
target_sources(rippled PRIVATE ${sources})
|
||||||
|
|
||||||
|
if(tests)
|
||||||
|
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp"
|
||||||
|
)
|
||||||
|
target_sources(rippled PRIVATE ${sources})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(rippled
|
||||||
|
Ripple::boost
|
||||||
|
Ripple::opts
|
||||||
|
Ripple::libs
|
||||||
|
xrpl.libxrpl
|
||||||
|
)
|
||||||
|
exclude_if_included(rippled)
|
||||||
|
# define a macro for tests that might need to
|
||||||
|
# be exluded or run differently in CI environment
|
||||||
|
if(is_ci)
|
||||||
|
target_compile_definitions(rippled PRIVATE RIPPLED_RUNNING_IN_CI)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(voidstar)
|
||||||
|
target_compile_options(rippled
|
||||||
|
PRIVATE
|
||||||
|
-fsanitize-coverage=trace-pc-guard
|
||||||
|
)
|
||||||
|
# rippled requires access to antithesis-sdk-cpp implementation file
|
||||||
|
# antithesis_instrumentation.h, which is not exported as INTERFACE
|
||||||
|
target_include_directories(rippled
|
||||||
|
PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/external/antithesis-sdk
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# any files that don't play well with unity should be added here
|
||||||
|
if(tests)
|
||||||
|
set_source_files_properties(
|
||||||
|
# these two seem to produce conflicts in beast teardown template methods
|
||||||
|
src/test/rpc/ValidatorRPC_test.cpp
|
||||||
|
src/test/ledger/Invariants_test.cpp
|
||||||
|
PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
38
cmake/RippledCov.cmake
Normal file
38
cmake/RippledCov.cmake
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
coverage report target
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
if(NOT coverage)
|
||||||
|
message(FATAL_ERROR "Code coverage not enabled! Aborting ...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
|
message(WARNING "Code coverage on Windows is not supported, ignoring 'coverage' flag")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CodeCoverage)
|
||||||
|
|
||||||
|
# The instructions for these commands come from the `CodeCoverage` module,
|
||||||
|
# which was copied from https://github.com/bilke/cmake-modules, commit fb7d2a3,
|
||||||
|
# then locally changed (see CHANGES: section in `CodeCoverage.cmake`)
|
||||||
|
|
||||||
|
set(GCOVR_ADDITIONAL_ARGS ${coverage_extra_args})
|
||||||
|
if(NOT GCOVR_ADDITIONAL_ARGS STREQUAL "")
|
||||||
|
separate_arguments(GCOVR_ADDITIONAL_ARGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND GCOVR_ADDITIONAL_ARGS
|
||||||
|
--exclude-throw-branches
|
||||||
|
--exclude-noncode-lines
|
||||||
|
--exclude-unreachable-branches -s
|
||||||
|
-j ${coverage_test_parallelism})
|
||||||
|
|
||||||
|
setup_target_for_coverage_gcovr(
|
||||||
|
NAME coverage
|
||||||
|
FORMAT ${coverage_format}
|
||||||
|
EXECUTABLE rippled
|
||||||
|
EXECUTABLE_ARGS --unittest$<$<BOOL:${coverage_test}>:=${coverage_test}> --unittest-jobs ${coverage_test_parallelism} --quiet --unittest-log
|
||||||
|
EXCLUDE "src/test" "include/xrpl/beast/test" "include/xrpl/beast/unit_test" "${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
|
||||||
|
DEPENDENCIES rippled
|
||||||
|
)
|
||||||
85
cmake/RippledDocs.cmake
Normal file
85
cmake/RippledDocs.cmake
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
docs target (optional)
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
option(with_docs "Include the docs target?" FALSE)
|
||||||
|
|
||||||
|
if(NOT (with_docs OR only_docs))
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(Doxygen)
|
||||||
|
if(NOT TARGET Doxygen::doxygen)
|
||||||
|
message(STATUS "doxygen executable not found -- skipping docs target")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(doxygen_output_directory "${CMAKE_BINARY_DIR}/docs")
|
||||||
|
set(doxygen_include_path "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
set(doxygen_index_file "${doxygen_output_directory}/html/index.html")
|
||||||
|
set(doxyfile "${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile")
|
||||||
|
|
||||||
|
file(GLOB_RECURSE doxygen_input
|
||||||
|
docs/*.md
|
||||||
|
include/*.h
|
||||||
|
include/*.cpp
|
||||||
|
include/*.md
|
||||||
|
src/*.h
|
||||||
|
src/*.cpp
|
||||||
|
src/*.md
|
||||||
|
Builds/*.md
|
||||||
|
*.md)
|
||||||
|
list(APPEND doxygen_input
|
||||||
|
external/README.md
|
||||||
|
)
|
||||||
|
set(dependencies "${doxygen_input}" "${doxyfile}")
|
||||||
|
|
||||||
|
function(verbose_find_path variable name)
|
||||||
|
# find_path sets a CACHE variable, so don't try using a "local" variable.
|
||||||
|
find_path(${variable} "${name}" ${ARGN})
|
||||||
|
if(NOT ${variable})
|
||||||
|
message(NOTICE "could not find ${name}")
|
||||||
|
else()
|
||||||
|
message(STATUS "found ${name}: ${${variable}}/${name}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
verbose_find_path(doxygen_plantuml_jar_path plantuml.jar PATH_SUFFIXES share/plantuml)
|
||||||
|
verbose_find_path(doxygen_dot_path dot)
|
||||||
|
|
||||||
|
# https://en.cppreference.com/w/Cppreference:Archives
|
||||||
|
# https://stackoverflow.com/questions/60822559/how-to-move-a-file-download-from-configure-step-to-build-step
|
||||||
|
set(download_script "${CMAKE_BINARY_DIR}/docs/download-cppreference.cmake")
|
||||||
|
file(WRITE
|
||||||
|
"${download_script}"
|
||||||
|
"file(DOWNLOAD \
|
||||||
|
http://upload.cppreference.com/mwiki/images/b/b2/html_book_20190607.zip \
|
||||||
|
${CMAKE_BINARY_DIR}/docs/cppreference.zip \
|
||||||
|
EXPECTED_HASH MD5=82b3a612d7d35a83e3cb1195a63689ab \
|
||||||
|
)\n \
|
||||||
|
execute_process( \
|
||||||
|
COMMAND \"${CMAKE_COMMAND}\" -E tar -xf cppreference.zip \
|
||||||
|
)\n"
|
||||||
|
)
|
||||||
|
set(tagfile "${CMAKE_BINARY_DIR}/docs/cppreference-doxygen-web.tag.xml")
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${tagfile}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -P "${download_script}"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/docs"
|
||||||
|
)
|
||||||
|
set(doxygen_tagfiles "${tagfile}=http://en.cppreference.com/w/")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${doxygen_index_file}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E env
|
||||||
|
"DOXYGEN_OUTPUT_DIRECTORY=${doxygen_output_directory}"
|
||||||
|
"DOXYGEN_INCLUDE_PATH=${doxygen_include_path}"
|
||||||
|
"DOXYGEN_TAGFILES=${doxygen_tagfiles}"
|
||||||
|
"DOXYGEN_PLANTUML_JAR_PATH=${doxygen_plantuml_jar_path}"
|
||||||
|
"DOXYGEN_DOT_PATH=${doxygen_dot_path}"
|
||||||
|
"${DOXYGEN_EXECUTABLE}" "${doxyfile}"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
DEPENDS "${dependencies}" "${tagfile}")
|
||||||
|
add_custom_target(docs
|
||||||
|
DEPENDS "${doxygen_index_file}"
|
||||||
|
SOURCES "${dependencies}")
|
||||||
81
cmake/RippledInstall.cmake
Normal file
81
cmake/RippledInstall.cmake
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
install stuff
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
include(create_symbolic_link)
|
||||||
|
|
||||||
|
install (
|
||||||
|
TARGETS
|
||||||
|
common
|
||||||
|
opts
|
||||||
|
ripple_syslibs
|
||||||
|
ripple_boost
|
||||||
|
xrpl.imports.main
|
||||||
|
xrpl.libpb
|
||||||
|
xrpl.libxrpl.basics
|
||||||
|
xrpl.libxrpl.beast
|
||||||
|
xrpl.libxrpl.crypto
|
||||||
|
xrpl.libxrpl.json
|
||||||
|
xrpl.libxrpl.protocol
|
||||||
|
xrpl.libxrpl.resource
|
||||||
|
xrpl.libxrpl.server
|
||||||
|
xrpl.libxrpl
|
||||||
|
antithesis-sdk-cpp
|
||||||
|
EXPORT RippleExports
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
ARCHIVE DESTINATION lib
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
INCLUDES DESTINATION include)
|
||||||
|
|
||||||
|
install(
|
||||||
|
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(CODE "
|
||||||
|
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
|
||||||
|
include(create_symbolic_link)
|
||||||
|
create_symbolic_link(xrpl \
|
||||||
|
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
|
||||||
|
")
|
||||||
|
|
||||||
|
install (EXPORT RippleExports
|
||||||
|
FILE RippleTargets.cmake
|
||||||
|
NAMESPACE Ripple::
|
||||||
|
DESTINATION lib/cmake/ripple)
|
||||||
|
include (CMakePackageConfigHelpers)
|
||||||
|
write_basic_package_version_file (
|
||||||
|
RippleConfigVersion.cmake
|
||||||
|
VERSION ${rippled_version}
|
||||||
|
COMPATIBILITY SameMajorVersion)
|
||||||
|
|
||||||
|
if (is_root_project AND TARGET rippled)
|
||||||
|
install (TARGETS rippled RUNTIME DESTINATION bin)
|
||||||
|
set_target_properties(rippled PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON)
|
||||||
|
# sample configs should not overwrite existing files
|
||||||
|
# install if-not-exists workaround as suggested by
|
||||||
|
# https://cmake.org/Bug/view.php?id=12646
|
||||||
|
install(CODE "
|
||||||
|
macro (copy_if_not_exists SRC DEST NEWNAME)
|
||||||
|
if (NOT EXISTS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\")
|
||||||
|
file (INSTALL FILE_PERMISSIONS OWNER_READ OWNER_WRITE DESTINATION \"\${CMAKE_INSTALL_PREFIX}/\${DEST}\" FILES \"\${SRC}\" RENAME \"\${NEWNAME}\")
|
||||||
|
else ()
|
||||||
|
message (\"-- Skipping : \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\")
|
||||||
|
endif ()
|
||||||
|
endmacro()
|
||||||
|
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/rippled-example.cfg\" etc rippled.cfg)
|
||||||
|
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt)
|
||||||
|
")
|
||||||
|
install(CODE "
|
||||||
|
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
|
||||||
|
include(create_symbolic_link)
|
||||||
|
create_symbolic_link(rippled${suffix} \
|
||||||
|
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
|
||||||
|
")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
install (
|
||||||
|
FILES
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/cmake/RippleConfig.cmake
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/RippleConfigVersion.cmake
|
||||||
|
DESTINATION lib/cmake/ripple)
|
||||||
101
cmake/RippledInterface.cmake
Normal file
101
cmake/RippledInterface.cmake
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
rippled compile options/settings via an interface library
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
add_library (opts INTERFACE)
|
||||||
|
add_library (Ripple::opts ALIAS opts)
|
||||||
|
target_compile_definitions (opts
|
||||||
|
INTERFACE
|
||||||
|
BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS
|
||||||
|
BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
|
||||||
|
BOOST_CONTAINER_FWD_BAD_DEQUE
|
||||||
|
HAS_UNCAUGHT_EXCEPTIONS=1
|
||||||
|
$<$<BOOL:${boost_show_deprecated}>:
|
||||||
|
BOOST_ASIO_NO_DEPRECATED
|
||||||
|
BOOST_FILESYSTEM_NO_DEPRECATED
|
||||||
|
>
|
||||||
|
$<$<NOT:$<BOOL:${boost_show_deprecated}>>:
|
||||||
|
BOOST_COROUTINES_NO_DEPRECATION_WARNING
|
||||||
|
BOOST_BEAST_ALLOW_DEPRECATED
|
||||||
|
BOOST_FILESYSTEM_DEPRECATED
|
||||||
|
>
|
||||||
|
$<$<BOOL:${beast_no_unit_test_inline}>:BEAST_NO_UNIT_TEST_INLINE=1>
|
||||||
|
$<$<BOOL:${beast_disable_autolink}>:BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES=1>
|
||||||
|
$<$<BOOL:${single_io_service_thread}>:RIPPLE_SINGLE_IO_SERVICE_THREAD=1>
|
||||||
|
$<$<BOOL:${voidstar}>:ENABLE_VOIDSTAR>)
|
||||||
|
target_compile_options (opts
|
||||||
|
INTERFACE
|
||||||
|
$<$<AND:$<BOOL:${is_gcc}>,$<COMPILE_LANGUAGE:CXX>>:-Wsuggest-override>
|
||||||
|
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
|
||||||
|
$<$<BOOL:${perf}>:-fno-omit-frame-pointer>
|
||||||
|
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${coverage}>>:-g --coverage -fprofile-abs-path>
|
||||||
|
$<$<AND:$<BOOL:${is_clang}>,$<BOOL:${coverage}>>:-g --coverage>
|
||||||
|
$<$<BOOL:${profile}>:-pg>
|
||||||
|
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>)
|
||||||
|
|
||||||
|
target_link_libraries (opts
|
||||||
|
INTERFACE
|
||||||
|
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${coverage}>>:-g --coverage -fprofile-abs-path>
|
||||||
|
$<$<AND:$<BOOL:${is_clang}>,$<BOOL:${coverage}>>:-g --coverage>
|
||||||
|
$<$<BOOL:${profile}>:-pg>
|
||||||
|
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>)
|
||||||
|
|
||||||
|
if(jemalloc)
|
||||||
|
find_package(jemalloc REQUIRED)
|
||||||
|
target_compile_definitions(opts INTERFACE PROFILE_JEMALLOC)
|
||||||
|
target_link_libraries(opts INTERFACE jemalloc::jemalloc)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (san)
|
||||||
|
target_compile_options (opts
|
||||||
|
INTERFACE
|
||||||
|
# sanitizers recommend minimum of -O1 for reasonable performance
|
||||||
|
$<$<CONFIG:Debug>:-O1>
|
||||||
|
${SAN_FLAG}
|
||||||
|
-fno-omit-frame-pointer)
|
||||||
|
target_compile_definitions (opts
|
||||||
|
INTERFACE
|
||||||
|
$<$<STREQUAL:${san},address>:SANITIZER=ASAN>
|
||||||
|
$<$<STREQUAL:${san},thread>:SANITIZER=TSAN>
|
||||||
|
$<$<STREQUAL:${san},memory>:SANITIZER=MSAN>
|
||||||
|
$<$<STREQUAL:${san},undefined>:SANITIZER=UBSAN>)
|
||||||
|
target_link_libraries (opts INTERFACE ${SAN_FLAG} ${SAN_LIB})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
#[===================================================================[
|
||||||
|
rippled transitive library deps via an interface library
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
add_library (ripple_syslibs INTERFACE)
|
||||||
|
add_library (Ripple::syslibs ALIAS ripple_syslibs)
|
||||||
|
target_link_libraries (ripple_syslibs
|
||||||
|
INTERFACE
|
||||||
|
$<$<BOOL:${MSVC}>:
|
||||||
|
legacy_stdio_definitions.lib
|
||||||
|
Shlwapi
|
||||||
|
kernel32
|
||||||
|
user32
|
||||||
|
gdi32
|
||||||
|
winspool
|
||||||
|
comdlg32
|
||||||
|
advapi32
|
||||||
|
shell32
|
||||||
|
ole32
|
||||||
|
oleaut32
|
||||||
|
uuid
|
||||||
|
odbc32
|
||||||
|
odbccp32
|
||||||
|
crypt32
|
||||||
|
>
|
||||||
|
$<$<NOT:$<BOOL:${MSVC}>>:dl>
|
||||||
|
$<$<NOT:$<OR:$<BOOL:${MSVC}>,$<BOOL:${APPLE}>>>:rt>)
|
||||||
|
|
||||||
|
if (NOT MSVC)
|
||||||
|
set (THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package (Threads)
|
||||||
|
target_link_libraries (ripple_syslibs INTERFACE Threads::Threads)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_library (ripple_libs INTERFACE)
|
||||||
|
add_library (Ripple::libs ALIAS ripple_libs)
|
||||||
|
target_link_libraries (ripple_libs INTERFACE Ripple::syslibs)
|
||||||
80
cmake/RippledSanity.cmake
Normal file
80
cmake/RippledSanity.cmake
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
convenience variables and sanity checks
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
include(ProcessorCount)
|
||||||
|
|
||||||
|
if (NOT ep_procs)
|
||||||
|
ProcessorCount(ep_procs)
|
||||||
|
if (ep_procs GREATER 1)
|
||||||
|
# never use more than half of cores for EP builds
|
||||||
|
math (EXPR ep_procs "${ep_procs} / 2")
|
||||||
|
message (STATUS "Using ${ep_procs} cores for ExternalProject builds.")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
get_property(is_multiconfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
|
||||||
|
set (CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)
|
||||||
|
if (NOT is_multiconfig)
|
||||||
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
|
message (STATUS "Build type not specified - defaulting to Release")
|
||||||
|
set (CMAKE_BUILD_TYPE Release CACHE STRING "build type" FORCE)
|
||||||
|
elseif (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL Release))
|
||||||
|
# for simplicity, these are the only two config types we care about. Limiting
|
||||||
|
# the build types simplifies dealing with external project builds especially
|
||||||
|
message (FATAL_ERROR " *** Only Debug or Release build types are currently supported ***")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
get_directory_property(has_parent PARENT_DIRECTORY)
|
||||||
|
if (has_parent)
|
||||||
|
set (is_root_project OFF)
|
||||||
|
else ()
|
||||||
|
set (is_root_project ON)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES ".*Clang") # both Clang and AppleClang
|
||||||
|
set (is_clang TRUE)
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND
|
||||||
|
CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||||
|
message (FATAL_ERROR "This project requires clang 8 or later")
|
||||||
|
endif ()
|
||||||
|
# TODO min AppleClang version check ?
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
set (is_gcc TRUE)
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||||
|
message (FATAL_ERROR "This project requires GCC 8 or later")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
set (is_linux TRUE)
|
||||||
|
else ()
|
||||||
|
set (is_linux FALSE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("$ENV{CI}" STREQUAL "true" OR "$ENV{CONTINUOUS_INTEGRATION}" STREQUAL "true")
|
||||||
|
set (is_ci TRUE)
|
||||||
|
else ()
|
||||||
|
set (is_ci FALSE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# check for in-source build and fail
|
||||||
|
if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||||
|
message (FATAL_ERROR "Builds (in-source) are not allowed in "
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}. Please remove CMakeCache.txt and the CMakeFiles "
|
||||||
|
"directory from ${CMAKE_CURRENT_SOURCE_DIR} and try building in a separate directory.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (MSVC AND CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
|
||||||
|
message (FATAL_ERROR "Visual Studio 32-bit build is not supported.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
message (FATAL_ERROR "Rippled requires a 64 bit target architecture.\n"
|
||||||
|
"The most likely cause of this warning is trying to build rippled with a 32-bit OS.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (APPLE AND NOT HOMEBREW)
|
||||||
|
find_program (HOMEBREW brew)
|
||||||
|
endif ()
|
||||||
134
cmake/RippledSettings.cmake
Normal file
134
cmake/RippledSettings.cmake
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
declare user options/settings
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
include(ProcessorCount)
|
||||||
|
|
||||||
|
ProcessorCount(PROCESSOR_COUNT)
|
||||||
|
|
||||||
|
option(assert "Enables asserts, even in release builds" OFF)
|
||||||
|
|
||||||
|
option(xrpld "Build xrpld" ON)
|
||||||
|
|
||||||
|
option(tests "Build tests" ON)
|
||||||
|
|
||||||
|
option(unity "Creates a build using UNITY support in cmake. This is the default" ON)
|
||||||
|
if(unity)
|
||||||
|
if(NOT is_ci)
|
||||||
|
set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "")
|
||||||
|
endif()
|
||||||
|
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build")
|
||||||
|
endif()
|
||||||
|
if(is_clang AND is_linux)
|
||||||
|
option(voidstar "Enable Antithesis instrumentation." OFF)
|
||||||
|
endif()
|
||||||
|
if(is_gcc OR is_clang)
|
||||||
|
option(coverage "Generates coverage info." OFF)
|
||||||
|
option(profile "Add profiling flags" OFF)
|
||||||
|
set(coverage_test_parallelism "${PROCESSOR_COUNT}" CACHE STRING
|
||||||
|
"Unit tests parallelism for the purpose of coverage report.")
|
||||||
|
set(coverage_format "html-details" CACHE STRING
|
||||||
|
"Output format of the coverage report.")
|
||||||
|
set(coverage_extra_args "" CACHE STRING
|
||||||
|
"Additional arguments to pass to gcovr.")
|
||||||
|
set(coverage_test "" CACHE STRING
|
||||||
|
"On gcc & clang, the specific unit test(s) to run for coverage. Default is all tests.")
|
||||||
|
if(coverage_test AND NOT coverage)
|
||||||
|
set(coverage ON CACHE BOOL "gcc/clang only" FORCE)
|
||||||
|
endif()
|
||||||
|
option(wextra "compile with extra gcc/clang warnings enabled" ON)
|
||||||
|
else()
|
||||||
|
set(profile OFF CACHE BOOL "gcc/clang only" FORCE)
|
||||||
|
set(coverage OFF CACHE BOOL "gcc/clang only" FORCE)
|
||||||
|
set(wextra OFF CACHE BOOL "gcc/clang only" FORCE)
|
||||||
|
endif()
|
||||||
|
if(is_linux)
|
||||||
|
option(BUILD_SHARED_LIBS "build shared ripple libraries" OFF)
|
||||||
|
option(static "link protobuf, openssl, libc++, and boost statically" ON)
|
||||||
|
option(perf "Enables flags that assist with perf recording" OFF)
|
||||||
|
option(use_gold "enables detection of gold (binutils) linker" ON)
|
||||||
|
option(use_mold "enables detection of mold (binutils) linker" ON)
|
||||||
|
else()
|
||||||
|
# we are not ready to allow shared-libs on windows because it would require
|
||||||
|
# export declarations. On macos it's more feasible, but static openssl
|
||||||
|
# produces odd linker errors, thus we disable shared lib builds for now.
|
||||||
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "build shared ripple libraries - OFF for win/macos" FORCE)
|
||||||
|
set(static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE)
|
||||||
|
set(perf OFF CACHE BOOL "perf flags, linux only" FORCE)
|
||||||
|
set(use_gold OFF CACHE BOOL "gold linker, linux only" FORCE)
|
||||||
|
set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE)
|
||||||
|
endif()
|
||||||
|
if(is_clang)
|
||||||
|
option(use_lld "enables detection of lld linker" ON)
|
||||||
|
else()
|
||||||
|
set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE)
|
||||||
|
endif()
|
||||||
|
option(jemalloc "Enables jemalloc for heap profiling" OFF)
|
||||||
|
option(werr "treat warnings as errors" OFF)
|
||||||
|
option(local_protobuf
|
||||||
|
"Force a local build of protobuf instead of looking for an installed version." OFF)
|
||||||
|
option(local_grpc
|
||||||
|
"Force a local build of gRPC instead of looking for an installed version." OFF)
|
||||||
|
|
||||||
|
# this one is a string and therefore can't be an option
|
||||||
|
set(san "" CACHE STRING "On gcc & clang, add sanitizer instrumentation")
|
||||||
|
set_property(CACHE san PROPERTY STRINGS ";undefined;memory;address;thread")
|
||||||
|
if(san)
|
||||||
|
string(TOLOWER ${san} san)
|
||||||
|
set(SAN_FLAG "-fsanitize=${san}")
|
||||||
|
set(SAN_LIB "")
|
||||||
|
if(is_gcc)
|
||||||
|
if(san STREQUAL "address")
|
||||||
|
set(SAN_LIB "asan")
|
||||||
|
elseif(san STREQUAL "thread")
|
||||||
|
set(SAN_LIB "tsan")
|
||||||
|
elseif(san STREQUAL "memory")
|
||||||
|
set(SAN_LIB "msan")
|
||||||
|
elseif(san STREQUAL "undefined")
|
||||||
|
set(SAN_LIB "ubsan")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set(_saved_CRL ${CMAKE_REQUIRED_LIBRARIES})
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES "${SAN_FLAG};${SAN_LIB}")
|
||||||
|
check_cxx_compiler_flag(${SAN_FLAG} COMPILER_SUPPORTS_SAN)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${_saved_CRL})
|
||||||
|
if(NOT COMPILER_SUPPORTS_SAN)
|
||||||
|
message(FATAL_ERROR "${san} sanitizer does not seem to be supported by your compiler")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set(container_label "" CACHE STRING "tag to use for package building containers")
|
||||||
|
option(packages_only
|
||||||
|
"ONLY generate package building targets. This is special use-case and almost \
|
||||||
|
certainly not what you want. Use with caution as you won't be able to build \
|
||||||
|
any compiled targets locally." OFF)
|
||||||
|
option(have_package_container
|
||||||
|
"Sometimes you already have the tagged container you want to use for package \
|
||||||
|
building and you don't want docker to rebuild it. This flag will detach the \
|
||||||
|
dependency of the package build from the container build. It's an advanced \
|
||||||
|
use case and most likely you should not be touching this flag." OFF)
|
||||||
|
|
||||||
|
# the remaining options are obscure and rarely used
|
||||||
|
option(beast_no_unit_test_inline
|
||||||
|
"Prevents unit test definitions from being inserted into global table"
|
||||||
|
OFF)
|
||||||
|
option(single_io_service_thread
|
||||||
|
"Restricts the number of threads calling io_service::run to one. \
|
||||||
|
This can be useful when debugging."
|
||||||
|
OFF)
|
||||||
|
option(boost_show_deprecated
|
||||||
|
"Allow boost to fail on deprecated usage. Only useful if you're trying\
|
||||||
|
to find deprecated calls."
|
||||||
|
OFF)
|
||||||
|
option(beast_hashers
|
||||||
|
"Use local implementations for sha/ripemd hashes (experimental, not recommended)"
|
||||||
|
OFF)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
option(beast_disable_autolink "Disables autolinking of system libraries on WIN32" OFF)
|
||||||
|
else()
|
||||||
|
set(beast_disable_autolink OFF CACHE BOOL "WIN32 only" FORCE)
|
||||||
|
endif()
|
||||||
|
if(coverage)
|
||||||
|
message(STATUS "coverage build requested - forcing Debug build")
|
||||||
|
set(CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE)
|
||||||
|
endif()
|
||||||
22
cmake/RippledValidatorKeys.cmake
Normal file
22
cmake/RippledValidatorKeys.cmake
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
option (validator_keys "Enables building of validator-keys-tool as a separate target (imported via FetchContent)" OFF)
|
||||||
|
|
||||||
|
if (validator_keys)
|
||||||
|
git_branch (current_branch)
|
||||||
|
# default to tracking VK master branch unless we are on release
|
||||||
|
if (NOT (current_branch STREQUAL "release"))
|
||||||
|
set (current_branch "master")
|
||||||
|
endif ()
|
||||||
|
message (STATUS "tracking ValidatorKeys branch: ${current_branch}")
|
||||||
|
|
||||||
|
FetchContent_Declare (
|
||||||
|
validator_keys_src
|
||||||
|
GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
|
||||||
|
GIT_TAG "${current_branch}"
|
||||||
|
)
|
||||||
|
FetchContent_GetProperties (validator_keys_src)
|
||||||
|
if (NOT validator_keys_src_POPULATED)
|
||||||
|
message (STATUS "Pausing to download ValidatorKeys...")
|
||||||
|
FetchContent_Populate (validator_keys_src)
|
||||||
|
endif ()
|
||||||
|
add_subdirectory (${validator_keys_src_SOURCE_DIR} ${CMAKE_BINARY_DIR}/validator-keys)
|
||||||
|
endif ()
|
||||||
15
cmake/RippledVersion.cmake
Normal file
15
cmake/RippledVersion.cmake
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#[===================================================================[
|
||||||
|
read version from source
|
||||||
|
#]===================================================================]
|
||||||
|
|
||||||
|
file(STRINGS src/libxrpl/protocol/BuildInfo.cpp BUILD_INFO)
|
||||||
|
foreach(line_ ${BUILD_INFO})
|
||||||
|
if(line_ MATCHES "versionString[ ]*=[ ]*\"(.+)\"")
|
||||||
|
set(rippled_version ${CMAKE_MATCH_1})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(rippled_version)
|
||||||
|
message(STATUS "rippled version: ${rippled_version}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "unable to determine rippled version")
|
||||||
|
endif()
|
||||||
37
cmake/add_module.cmake
Normal file
37
cmake/add_module.cmake
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
include(isolate_headers)
|
||||||
|
|
||||||
|
# Create an OBJECT library target named
|
||||||
|
#
|
||||||
|
# ${PROJECT_NAME}.lib${parent}.${name}
|
||||||
|
#
|
||||||
|
# with sources in src/lib${parent}/${name}
|
||||||
|
# and headers in include/${parent}/${name}
|
||||||
|
# that cannot include headers from other directories in include/
|
||||||
|
# unless they come through linked libraries.
|
||||||
|
#
|
||||||
|
# add_module(parent a)
|
||||||
|
# add_module(parent b)
|
||||||
|
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a)
|
||||||
|
function(add_module parent name)
|
||||||
|
set(target ${PROJECT_NAME}.lib${parent}.${name})
|
||||||
|
add_library(${target} OBJECT)
|
||||||
|
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp"
|
||||||
|
)
|
||||||
|
target_sources(${target} PRIVATE ${sources})
|
||||||
|
target_include_directories(${target} PUBLIC
|
||||||
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||||
|
)
|
||||||
|
isolate_headers(
|
||||||
|
${target}
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}"
|
||||||
|
PUBLIC
|
||||||
|
)
|
||||||
|
isolate_headers(
|
||||||
|
${target}
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}"
|
||||||
|
PRIVATE
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
20
cmake/create_symbolic_link.cmake
Normal file
20
cmake/create_symbolic_link.cmake
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# file(CREATE_SYMLINK) only works on Windows with administrator privileges.
|
||||||
|
# https://stackoverflow.com/a/61244115/618906
|
||||||
|
function(create_symbolic_link target link)
|
||||||
|
if(WIN32)
|
||||||
|
if(NOT IS_SYMLINK "${link}")
|
||||||
|
if(NOT IS_ABSOLUTE "${target}")
|
||||||
|
# Relative links work do not work on Windows.
|
||||||
|
set(target "${link}/../${target}")
|
||||||
|
endif()
|
||||||
|
file(TO_NATIVE_PATH "${target}" target)
|
||||||
|
file(TO_NATIVE_PATH "${link}" link)
|
||||||
|
execute_process(COMMAND cmd.exe /c mklink /J "${link}" "${target}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
file(CREATE_LINK "${target}" "${link}" SYMBOLIC)
|
||||||
|
endif()
|
||||||
|
if(NOT IS_SYMLINK "${link}")
|
||||||
|
message(ERROR "failed to create symlink: <${link}>")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
53
cmake/deps/Boost.cmake
Normal file
53
cmake/deps/Boost.cmake
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
find_package(Boost 1.82 REQUIRED
|
||||||
|
COMPONENTS
|
||||||
|
chrono
|
||||||
|
container
|
||||||
|
context
|
||||||
|
coroutine
|
||||||
|
date_time
|
||||||
|
filesystem
|
||||||
|
json
|
||||||
|
program_options
|
||||||
|
regex
|
||||||
|
system
|
||||||
|
thread
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(ripple_boost INTERFACE)
|
||||||
|
add_library(Ripple::boost ALIAS ripple_boost)
|
||||||
|
if(XCODE)
|
||||||
|
target_include_directories(ripple_boost BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
|
||||||
|
target_compile_options(ripple_boost INTERFACE --system-header-prefix="boost/")
|
||||||
|
else()
|
||||||
|
target_include_directories(ripple_boost SYSTEM BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(ripple_boost
|
||||||
|
INTERFACE
|
||||||
|
Boost::boost
|
||||||
|
Boost::chrono
|
||||||
|
Boost::container
|
||||||
|
Boost::coroutine
|
||||||
|
Boost::date_time
|
||||||
|
Boost::filesystem
|
||||||
|
Boost::json
|
||||||
|
Boost::program_options
|
||||||
|
Boost::regex
|
||||||
|
Boost::system
|
||||||
|
Boost::thread)
|
||||||
|
if(Boost_COMPILER)
|
||||||
|
target_link_libraries(ripple_boost INTERFACE Boost::disable_autolinking)
|
||||||
|
endif()
|
||||||
|
if(san AND is_clang)
|
||||||
|
# TODO: gcc does not support -fsanitize-blacklist...can we do something else
|
||||||
|
# for gcc ?
|
||||||
|
if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
|
||||||
|
get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
endif()
|
||||||
|
message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*")
|
||||||
|
target_compile_options(opts
|
||||||
|
INTERFACE
|
||||||
|
# ignore boost headers for sanitizing
|
||||||
|
-fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt)
|
||||||
|
endif()
|
||||||
48
cmake/isolate_headers.cmake
Normal file
48
cmake/isolate_headers.cmake
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
include(create_symbolic_link)
|
||||||
|
|
||||||
|
# Consider include directory B nested under prefix A:
|
||||||
|
#
|
||||||
|
# /path/to/A/then/to/B/...
|
||||||
|
#
|
||||||
|
# Call C the relative path from A to B.
|
||||||
|
# C is what we want to write in `#include` directives:
|
||||||
|
#
|
||||||
|
# #include <then/to/B/...>
|
||||||
|
#
|
||||||
|
# Examples, all from the `jobqueue` module:
|
||||||
|
#
|
||||||
|
# - Library public headers:
|
||||||
|
# B = /include/xrpl/jobqueue
|
||||||
|
# A = /include/
|
||||||
|
# C = xrpl/jobqueue
|
||||||
|
#
|
||||||
|
# - Library private headers:
|
||||||
|
# B = /src/libxrpl/jobqueue
|
||||||
|
# A = /src/
|
||||||
|
# C = libxrpl/jobqueue
|
||||||
|
#
|
||||||
|
# - Test private headers:
|
||||||
|
# B = /tests/jobqueue
|
||||||
|
# A = /
|
||||||
|
# C = tests/jobqueue
|
||||||
|
#
|
||||||
|
# To isolate headers from each other,
|
||||||
|
# we want to create a symlink Y that points to B,
|
||||||
|
# within a subdirectory X of the `CMAKE_BINARY_DIR`,
|
||||||
|
# that has the same relative path C between X and Y,
|
||||||
|
# and then add X as an include directory of the target,
|
||||||
|
# sometimes `PUBLIC` and sometimes `PRIVATE`.
|
||||||
|
# The Cs are all guaranteed to be unique.
|
||||||
|
# We can guarantee a unique X per target by using
|
||||||
|
# `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`.
|
||||||
|
#
|
||||||
|
# isolate_headers(target A B scope)
|
||||||
|
function(isolate_headers target A B scope)
|
||||||
|
file(RELATIVE_PATH C "${A}" "${B}")
|
||||||
|
set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}")
|
||||||
|
set(Y "${X}/${C}")
|
||||||
|
cmake_path(GET Y PARENT_PATH parent)
|
||||||
|
file(MAKE_DIRECTORY "${parent}")
|
||||||
|
create_symbolic_link("${B}" "${Y}")
|
||||||
|
target_include_directories(${target} ${scope} "$<BUILD_INTERFACE:${X}>")
|
||||||
|
endfunction()
|
||||||
24
cmake/target_link_modules.cmake
Normal file
24
cmake/target_link_modules.cmake
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Link a library to its modules (see: `add_module`)
|
||||||
|
# and remove the module sources from the library's sources.
|
||||||
|
#
|
||||||
|
# add_module(parent a)
|
||||||
|
# add_module(parent b)
|
||||||
|
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a)
|
||||||
|
# add_library(project.libparent)
|
||||||
|
# target_link_modules(parent PUBLIC a b)
|
||||||
|
function(target_link_modules parent scope)
|
||||||
|
set(library ${PROJECT_NAME}.lib${parent})
|
||||||
|
foreach(name ${ARGN})
|
||||||
|
set(module ${library}.${name})
|
||||||
|
get_target_property(sources ${library} SOURCES)
|
||||||
|
list(LENGTH sources before)
|
||||||
|
get_target_property(dupes ${module} SOURCES)
|
||||||
|
list(LENGTH dupes expected)
|
||||||
|
list(REMOVE_ITEM sources ${dupes})
|
||||||
|
list(LENGTH sources after)
|
||||||
|
math(EXPR actual "${before} - ${after}")
|
||||||
|
message(STATUS "${module} with ${expected} sources took ${actual} sources from ${library}")
|
||||||
|
set_target_properties(${library} PROPERTIES SOURCES "${sources}")
|
||||||
|
target_link_libraries(${library} ${scope} ${module})
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
62
cmake/target_protobuf_sources.cmake
Normal file
62
cmake/target_protobuf_sources.cmake
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
find_package(Protobuf REQUIRED)
|
||||||
|
|
||||||
|
# .proto files import each other like this:
|
||||||
|
#
|
||||||
|
# import "path/to/file.proto";
|
||||||
|
#
|
||||||
|
# For the protobuf compiler to find these imports,
|
||||||
|
# the parent directory of "path" must be in the import path.
|
||||||
|
#
|
||||||
|
# When generating C++,
|
||||||
|
# it turns into an include statement like this:
|
||||||
|
#
|
||||||
|
# #include "path/to/file.pb.h"
|
||||||
|
#
|
||||||
|
# and the header is generated at a path relative to the output directory
|
||||||
|
# that matches the given .proto path relative to the source directory
|
||||||
|
# minus the first matching prefix on the import path.
|
||||||
|
#
|
||||||
|
# In other words, a file `include/package/path/to/file.proto`
|
||||||
|
# with import path [`include/package`, `include`]
|
||||||
|
# will generate files `output/path/to/file.pb.{h,cc}`
|
||||||
|
# with includes like `#include "path/to/file.pb.h".
|
||||||
|
#
|
||||||
|
# During build, the generated files can find each other if the output
|
||||||
|
# directory is an include directory, but we want to install that directory
|
||||||
|
# under our package's include directory (`include/package`), not as a sibling.
|
||||||
|
# After install, they can find each other if that subdirectory is an include
|
||||||
|
# directory.
|
||||||
|
|
||||||
|
# Add protocol buffer sources to an existing library target.
|
||||||
|
# target:
|
||||||
|
# The name of the library target.
|
||||||
|
# prefix:
|
||||||
|
# The install prefix for headers relative to `CMAKE_INSTALL_INCLUDEDIR`.
|
||||||
|
# This prefix should appear at the start of all your consumer includes.
|
||||||
|
# ARGN:
|
||||||
|
# A list of .proto files.
|
||||||
|
function(target_protobuf_sources target prefix)
|
||||||
|
set(dir "${CMAKE_CURRENT_BINARY_DIR}/pb-${target}")
|
||||||
|
file(MAKE_DIRECTORY "${dir}/${prefix}")
|
||||||
|
|
||||||
|
protobuf_generate(
|
||||||
|
TARGET ${target}
|
||||||
|
PROTOC_OUT_DIR "${dir}/${prefix}"
|
||||||
|
"${ARGN}"
|
||||||
|
)
|
||||||
|
target_include_directories(${target} SYSTEM PUBLIC
|
||||||
|
# Allows #include <package/path/to/file.proto> used by consumer files.
|
||||||
|
$<BUILD_INTERFACE:${dir}>
|
||||||
|
# Allows #include "path/to/file.proto" used by generated files.
|
||||||
|
$<BUILD_INTERFACE:${dir}/${prefix}>
|
||||||
|
# Allows #include <package/path/to/file.proto> used by consumer files.
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
|
# Allows #include "path/to/file.proto" used by generated files.
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${prefix}>
|
||||||
|
)
|
||||||
|
install(
|
||||||
|
DIRECTORY ${dir}/
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
|
FILES_MATCHING PATTERN "*.h"
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
178
conanfile.py
Normal file
178
conanfile.py
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
from conan import ConanFile
|
||||||
|
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Xrpl(ConanFile):
|
||||||
|
name = 'xrpl'
|
||||||
|
|
||||||
|
license = 'ISC'
|
||||||
|
author = 'John Freeman <jfreeman@ripple.com>'
|
||||||
|
url = 'https://github.com/xrplf/rippled'
|
||||||
|
description = 'The XRP Ledger'
|
||||||
|
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||||
|
options = {
|
||||||
|
'assertions': [True, False],
|
||||||
|
'coverage': [True, False],
|
||||||
|
'fPIC': [True, False],
|
||||||
|
'jemalloc': [True, False],
|
||||||
|
'rocksdb': [True, False],
|
||||||
|
'shared': [True, False],
|
||||||
|
'static': [True, False],
|
||||||
|
'tests': [True, False],
|
||||||
|
'unity': [True, False],
|
||||||
|
'xrpld': [True, False],
|
||||||
|
}
|
||||||
|
|
||||||
|
requires = [
|
||||||
|
'date/3.0.3',
|
||||||
|
'grpc/1.50.1',
|
||||||
|
'libarchive/3.7.6',
|
||||||
|
'nudb/2.0.8',
|
||||||
|
'openssl/1.1.1v',
|
||||||
|
'soci/4.0.3',
|
||||||
|
'xxhash/0.8.2',
|
||||||
|
'zlib/1.3.1',
|
||||||
|
]
|
||||||
|
|
||||||
|
tool_requires = [
|
||||||
|
'protobuf/3.21.9',
|
||||||
|
]
|
||||||
|
|
||||||
|
default_options = {
|
||||||
|
'assertions': False,
|
||||||
|
'coverage': False,
|
||||||
|
'fPIC': True,
|
||||||
|
'jemalloc': False,
|
||||||
|
'rocksdb': True,
|
||||||
|
'shared': False,
|
||||||
|
'static': True,
|
||||||
|
'tests': False,
|
||||||
|
'unity': False,
|
||||||
|
'xrpld': False,
|
||||||
|
|
||||||
|
'date/*:header_only': True,
|
||||||
|
'grpc/*:shared': False,
|
||||||
|
'grpc/*:secure': True,
|
||||||
|
'libarchive/*:shared': False,
|
||||||
|
'libarchive/*:with_acl': False,
|
||||||
|
'libarchive/*:with_bzip2': False,
|
||||||
|
'libarchive/*:with_cng': False,
|
||||||
|
'libarchive/*:with_expat': False,
|
||||||
|
'libarchive/*:with_iconv': False,
|
||||||
|
'libarchive/*:with_libxml2': False,
|
||||||
|
'libarchive/*:with_lz4': True,
|
||||||
|
'libarchive/*:with_lzma': False,
|
||||||
|
'libarchive/*:with_lzo': False,
|
||||||
|
'libarchive/*:with_nettle': False,
|
||||||
|
'libarchive/*:with_openssl': False,
|
||||||
|
'libarchive/*:with_pcreposix': False,
|
||||||
|
'libarchive/*:with_xattr': False,
|
||||||
|
'libarchive/*:with_zlib': False,
|
||||||
|
'lz4/*:shared': False,
|
||||||
|
'openssl/*:shared': False,
|
||||||
|
'protobuf/*:shared': False,
|
||||||
|
'protobuf/*:with_zlib': True,
|
||||||
|
'rocksdb/*:enable_sse': False,
|
||||||
|
'rocksdb/*:lite': False,
|
||||||
|
'rocksdb/*:shared': False,
|
||||||
|
'rocksdb/*:use_rtti': True,
|
||||||
|
'rocksdb/*:with_jemalloc': False,
|
||||||
|
'rocksdb/*:with_lz4': True,
|
||||||
|
'rocksdb/*:with_snappy': True,
|
||||||
|
'snappy/*:shared': False,
|
||||||
|
'soci/*:shared': False,
|
||||||
|
'soci/*:with_sqlite3': True,
|
||||||
|
'soci/*:with_boost': True,
|
||||||
|
'xxhash/*:shared': False,
|
||||||
|
}
|
||||||
|
|
||||||
|
def set_version(self):
|
||||||
|
path = f'{self.recipe_folder}/src/libxrpl/protocol/BuildInfo.cpp'
|
||||||
|
regex = r'versionString\s?=\s?\"(.*)\"'
|
||||||
|
with open(path, 'r') as file:
|
||||||
|
matches = (re.search(regex, line) for line in file)
|
||||||
|
match = next(m for m in matches if m)
|
||||||
|
self.version = match.group(1)
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
if self.settings.compiler == 'apple-clang':
|
||||||
|
self.options['boost'].visibility = 'global'
|
||||||
|
|
||||||
|
def requirements(self):
|
||||||
|
self.requires('boost/1.83.0', force=True)
|
||||||
|
self.requires('lz4/1.10.0', force=True)
|
||||||
|
self.requires('protobuf/3.21.9', force=True)
|
||||||
|
self.requires('sqlite3/3.47.0', force=True)
|
||||||
|
if self.options.jemalloc:
|
||||||
|
self.requires('jemalloc/5.3.0')
|
||||||
|
if self.options.rocksdb:
|
||||||
|
self.requires('rocksdb/6.29.5')
|
||||||
|
|
||||||
|
exports_sources = (
|
||||||
|
'CMakeLists.txt',
|
||||||
|
'bin/getRippledInfo',
|
||||||
|
'cfg/*',
|
||||||
|
'cmake/*',
|
||||||
|
'external/*',
|
||||||
|
'include/*',
|
||||||
|
'src/*',
|
||||||
|
)
|
||||||
|
|
||||||
|
def layout(self):
|
||||||
|
cmake_layout(self)
|
||||||
|
# Fix this setting to follow the default introduced in Conan 1.48
|
||||||
|
# to align with our build instructions.
|
||||||
|
self.folders.generators = 'build/generators'
|
||||||
|
|
||||||
|
generators = 'CMakeDeps'
|
||||||
|
def generate(self):
|
||||||
|
tc = CMakeToolchain(self)
|
||||||
|
tc.variables['tests'] = self.options.tests
|
||||||
|
tc.variables['assert'] = self.options.assertions
|
||||||
|
tc.variables['coverage'] = self.options.coverage
|
||||||
|
tc.variables['jemalloc'] = self.options.jemalloc
|
||||||
|
tc.variables['rocksdb'] = self.options.rocksdb
|
||||||
|
tc.variables['BUILD_SHARED_LIBS'] = self.options.shared
|
||||||
|
tc.variables['static'] = self.options.static
|
||||||
|
tc.variables['unity'] = self.options.unity
|
||||||
|
tc.variables['xrpld'] = self.options.xrpld
|
||||||
|
tc.generate()
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.verbose = True
|
||||||
|
cmake.configure()
|
||||||
|
cmake.build()
|
||||||
|
|
||||||
|
def package(self):
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.verbose = True
|
||||||
|
cmake.install()
|
||||||
|
|
||||||
|
def package_info(self):
|
||||||
|
libxrpl = self.cpp_info.components['libxrpl']
|
||||||
|
libxrpl.libs = [
|
||||||
|
'xrpl',
|
||||||
|
'xrpl.libpb',
|
||||||
|
'ed25519',
|
||||||
|
'secp256k1',
|
||||||
|
]
|
||||||
|
# TODO: Fix the protobufs to include each other relative to
|
||||||
|
# `include/`, not `include/ripple/proto/`.
|
||||||
|
libxrpl.includedirs = ['include', 'include/ripple/proto']
|
||||||
|
libxrpl.requires = [
|
||||||
|
'boost::boost',
|
||||||
|
'date::date',
|
||||||
|
'grpc::grpc++',
|
||||||
|
'libarchive::libarchive',
|
||||||
|
'lz4::lz4',
|
||||||
|
'nudb::nudb',
|
||||||
|
'openssl::crypto',
|
||||||
|
'protobuf::libprotobuf',
|
||||||
|
'soci::soci',
|
||||||
|
'sqlite3::sqlite',
|
||||||
|
'xxhash::xxhash',
|
||||||
|
'zlib::zlib',
|
||||||
|
]
|
||||||
|
if self.options.rocksdb:
|
||||||
|
libxrpl.requires.append('rocksdb::librocksdb')
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
VFALCO NOTE - This file appears to be unmaintained.
|
|
||||||
|
|
||||||
Critical protocol changes
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
Mon Apr 8 16:13:12 PDT 2013
|
|
||||||
* The JSON field "inLedger" changing to "ledger_index"
|
|
||||||
|
|
||||||
Previous
|
|
||||||
* The JSON field "metaData" changing to "meta".
|
|
||||||
* RPC ledger will no longer take "ledger", use "ledger_hash" or "ledger_index".
|
|
||||||
* "ledgerClose" events:
|
|
||||||
** "hash" DEPRECATED: use "ledger_hash"
|
|
||||||
** "seqNum" DEPRECATED: use "ledger_index"
|
|
||||||
** "closeTime" DEPRECATED: use "close" or "close_human"
|
|
||||||
* stream "rt_accounts" --> "accounts_proposed"
|
|
||||||
* stream "rt_transactions" --> "transactions_proposed"
|
|
||||||
* subscribe "username" --> "url_username"
|
|
||||||
* subscribe "password" --> "url_password"
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Coding Standards
|
|
||||||
|
|
||||||
Coding standards used here are extreme strict and consistent. The style
|
|
||||||
evolved gradually over the years, incorporating generally acknowledged
|
|
||||||
best-practice C++ advice, experience, and personal preference.
|
|
||||||
|
|
||||||
## Don't Repeat Yourself!
|
|
||||||
|
|
||||||
The [Don't Repeat Yourself][1] principle summarises the essence of what it
|
|
||||||
means to write good code, in all languages, at all levels.
|
|
||||||
|
|
||||||
## Formatting
|
|
||||||
|
|
||||||
The goal of source code formatting should always be to make things as easy to
|
|
||||||
read as possible. White space is used to guide the eye so that details are not
|
|
||||||
overlooked. Blank lines are used to separate code into "paragraphs."
|
|
||||||
|
|
||||||
* No tab characters please.
|
|
||||||
* Tab stops are set to 4 spaces.
|
|
||||||
* Braces are indented in the [Allman style][2].
|
|
||||||
* Always place a space before and after all binary operators,
|
|
||||||
especially assignments (`operator=`).
|
|
||||||
* The `!` operator should always be followed by a space.
|
|
||||||
* The `~` operator should be preceded by a space, but not followed by one.
|
|
||||||
* The `++` and `--` operators should have no spaces between the operator and
|
|
||||||
the operand.
|
|
||||||
* A space never appears before a comma, and always appears after a comma.
|
|
||||||
* Always place a space before an opening parenthesis. One exception is if
|
|
||||||
the parentheses are empty.
|
|
||||||
* Don't put spaces after a parenthesis. A typical member function call might
|
|
||||||
look like this: `foobar (1, 2, 3);`
|
|
||||||
* In general, leave a blank line before an `if` statement.
|
|
||||||
* In general, leave a blank line after a closing brace `}`.
|
|
||||||
* Do not place code or comments on the same line as any opening or
|
|
||||||
closing brace.
|
|
||||||
* Do not write `if` statements all-on-one-line. The exception to this is when
|
|
||||||
you've got a sequence of similar `if` statements, and are aligning them all
|
|
||||||
vertically to highlight their similarities.
|
|
||||||
* In an `if-else` statement, if you surround one half of the statement with
|
|
||||||
braces, you also need to put braces around the other half, to match.
|
|
||||||
* When writing a pointer type, use this spacing: `SomeObject* myObject`.
|
|
||||||
Technically, a more correct spacing would be `SomeObject *myObject`, but
|
|
||||||
it makes more sense for the asterisk to be grouped with the type name,
|
|
||||||
since being a pointer is part of the type, not the variable name. The only
|
|
||||||
time that this can lead to any problems is when you're declaring multiple
|
|
||||||
pointers of the same type in the same statement - which leads on to the next
|
|
||||||
rule:
|
|
||||||
* When declaring multiple pointers, never do so in a single statement, e.g.
|
|
||||||
`SomeObject* p1, *p2;` - instead, always split them out onto separate lines
|
|
||||||
and write the type name again, to make it quite clear what's going on, and
|
|
||||||
avoid the danger of missing out any vital asterisks.
|
|
||||||
* The previous point also applies to references, so always put the `&` next to
|
|
||||||
the type rather than the variable, e.g. `void foo (Thing const& thing)`. And
|
|
||||||
don't put a space on both sides of the `*` or `&` - always put a space after
|
|
||||||
it, but never before it.
|
|
||||||
* The word `const` should be placed to the right of the thing that it modifies,
|
|
||||||
for consistency. For example `int const` refers to an int which is const.
|
|
||||||
`int const*` is a pointer to an int which is const. `int *const` is a const
|
|
||||||
pointer to an int.
|
|
||||||
* Always place a space in between the template angle brackets and the type
|
|
||||||
name. Template code is already hard enough to read!
|
|
||||||
|
|
||||||
## Naming conventions
|
|
||||||
|
|
||||||
* Member variables and method names are written with camel-case, and never
|
|
||||||
begin with a capital letter.
|
|
||||||
* Class names are also written in camel-case, but always begin with a capital
|
|
||||||
letter.
|
|
||||||
* For global variables... well, you shouldn't have any, so it doesn't matter.
|
|
||||||
* Class data members begin with `m_`, static data members begin with `s_`.
|
|
||||||
Global variables begin with `g_`. This is so the scope of the corresponding
|
|
||||||
declaration can be easily determined.
|
|
||||||
* Avoid underscores in your names, especially leading or trailing underscores.
|
|
||||||
In particular, leading underscores should be avoided, as these are often used
|
|
||||||
in standard library code, so to use them in your own code looks quite jarring.
|
|
||||||
* If you really have to write a macro for some reason, then make it all caps,
|
|
||||||
with underscores to separate the words. And obviously make sure that its name
|
|
||||||
is unlikely to clash with symbols used in other libraries or 3rd party code.
|
|
||||||
|
|
||||||
## Types, const-correctness
|
|
||||||
|
|
||||||
* If a method can (and should!) be const, make it const!
|
|
||||||
* If a method definitely doesn't throw an exception (be careful!), mark it as
|
|
||||||
`noexcept`
|
|
||||||
* When returning a temporary object, e.g. a String, the returned object should
|
|
||||||
be non-const, so that if the class has a C++11 move operator, it can be used.
|
|
||||||
* If a local variable can be const, then make it const!
|
|
||||||
* Remember that pointers can be const as well as primitives; For example, if
|
|
||||||
you have a `char*` whose contents are going to be altered, you may still be
|
|
||||||
able to make the pointer itself const, e.g. `char* const foobar = getFoobar();`.
|
|
||||||
* Do not declare all your local variables at the top of a function or method
|
|
||||||
(i.e. in the old-fashioned C-style). Declare them at the last possible moment,
|
|
||||||
and give them as small a scope as possible.
|
|
||||||
* Object parameters should be passed as `const&` wherever possible. Only
|
|
||||||
pass a parameter as a copy-by-value object if you really need to mutate
|
|
||||||
a local copy inside the method, and if making a local copy inside the method
|
|
||||||
would be difficult.
|
|
||||||
* Use portable `for()` loop variable scoping (i.e. do not have multiple for
|
|
||||||
loops in the same scope that each re-declare the same variable name, as
|
|
||||||
this fails on older compilers)
|
|
||||||
* When you're testing a pointer to see if it's null, never write
|
|
||||||
`if (myPointer)`. Always avoid that implicit cast-to-bool by writing it more
|
|
||||||
fully: `if (myPointer != nullptr)`. And likewise, never ever write
|
|
||||||
`if (! myPointer)`, instead always write `if (myPointer == nullptr)`.
|
|
||||||
It is more readable that way.
|
|
||||||
* Avoid C-style casts except when converting between primitive numeric types.
|
|
||||||
Some people would say "avoid C-style casts altogether", but `static_cast` is
|
|
||||||
a bit unreadable when you just want to cast an `int` to a `float`. But
|
|
||||||
whenever a pointer is involved, or a non-primitive object, always use
|
|
||||||
`static_cast`. And when you're reinterpreting data, always use
|
|
||||||
`reinterpret_cast`.
|
|
||||||
* Until C++ gets a universal 64-bit primitive type (part of the C++11
|
|
||||||
standard), it's best to stick to the `int64` and `uint64` typedefs.
|
|
||||||
|
|
||||||
## Object lifetime and ownership
|
|
||||||
|
|
||||||
* Absolutely do NOT use `delete`, `deleteAndZero`, etc. There are very very few
|
|
||||||
situations where you can't use a `ScopedPointer` or some other automatic
|
|
||||||
lifetime management class.
|
|
||||||
* Do not use `new` unless there's no alternative. Whenever you type `new`, always
|
|
||||||
treat it as a failure to find a better solution. If a local variable can be
|
|
||||||
allocated on the stack rather than the heap, then always do so.
|
|
||||||
* Do not ever use `new` or `malloc` to allocate a C++ array. Always use a
|
|
||||||
`HeapBlock` instead.
|
|
||||||
* And just to make it doubly clear: Never use `malloc` or `calloc`.
|
|
||||||
* If a parent object needs to create and own some kind of child object, always
|
|
||||||
use composition as your first choice. If that's not possible (e.g. if the
|
|
||||||
child needs a pointer to the parent for its constructor), then use a
|
|
||||||
`ScopedPointer`.
|
|
||||||
* If possible, pass an object as a reference rather than a pointer. If possible,
|
|
||||||
make it a `const` reference.
|
|
||||||
* Obviously avoid static and global values. Sometimes there's no alternative,
|
|
||||||
but if there is an alternative, then use it, no matter how much effort it
|
|
||||||
involves.
|
|
||||||
* If allocating a local POD structure (e.g. an operating-system structure in
|
|
||||||
native code), and you need to initialise it with zeros, use the `= { 0 };`
|
|
||||||
syntax as your first choice for doing this. If for some reason that's not
|
|
||||||
appropriate, use the `zerostruct()` function, or in case that isn't suitable,
|
|
||||||
use `zeromem()`. Don't use `memset()`.
|
|
||||||
|
|
||||||
## Classes
|
|
||||||
|
|
||||||
* Declare a class's public section first, and put its constructors and
|
|
||||||
destructor first. Any protected items come next, and then private ones.
|
|
||||||
* Use the most restrictive access-specifier possible for each member. Prefer
|
|
||||||
`private` over `protected`, and `protected` over `public`. Don't expose
|
|
||||||
things unnecessarily.
|
|
||||||
* Preferred positioning for any inherited classes is to put them to the right
|
|
||||||
of the class name, vertically aligned, e.g.:
|
|
||||||
class Thing : public Foo,
|
|
||||||
private Bar
|
|
||||||
{
|
|
||||||
}
|
|
||||||
* Put a class's member variables (which should almost always be private, of course),
|
|
||||||
after all the public and protected method declarations.
|
|
||||||
* Any private methods can go towards the end of the class, after the member
|
|
||||||
variables.
|
|
||||||
* If your class does not have copy-by-value semantics, derive the class from
|
|
||||||
`Uncopyable`.
|
|
||||||
* If your class is likely to be leaked, then derive your class from
|
|
||||||
`LeakChecked<>`.
|
|
||||||
* Constructors that take a single parameter should be default be marked
|
|
||||||
`explicit`. Obviously there are cases where you do want implicit conversion,
|
|
||||||
but always think about it carefully before writing a non-explicit constructor.
|
|
||||||
* Do not use `NULL`, `null`, or 0 for a null-pointer. And especially never use
|
|
||||||
'0L', which is particulary burdensome. Use `nullptr` instead - this is the
|
|
||||||
C++2011 standard, so get used to it. There's a fallback definition for `nullptr`
|
|
||||||
in Beast, so it's always possible to use it even if your compiler isn't yet
|
|
||||||
C++2011 compliant.
|
|
||||||
* All the C++ 'guru' books and articles are full of excellent and detailed advice
|
|
||||||
on when it's best to use inheritance vs composition. If you're not already
|
|
||||||
familiar with the received wisdom in these matters, then do some reading!
|
|
||||||
|
|
||||||
## Miscellaneous
|
|
||||||
|
|
||||||
* `goto` statements should not be used at all, even if the alternative is
|
|
||||||
more verbose code. The only exception is when implementing an algorithm in
|
|
||||||
a function as a state machine.
|
|
||||||
* Don't use macros! OK, obviously there are many situations where they're the
|
|
||||||
right tool for the job, but treat them as a last resort. Certainly don't ever
|
|
||||||
use a macro just to hold a constant value or to perform any kind of function
|
|
||||||
that could have been done as a real inline function. And it goes without saying
|
|
||||||
that you should give them names which aren't going to clash with other code.
|
|
||||||
And `#undef` them after you've used them, if possible.
|
|
||||||
* When using the `++` or `--` operators, never use post-increment if
|
|
||||||
pre-increment could be used instead. Although it doesn't matter for
|
|
||||||
primitive types, it's good practice to pre-increment since this can be
|
|
||||||
much more efficient for more complex objects. In particular, if you're
|
|
||||||
writing a for loop, always use pre-increment,
|
|
||||||
e.g. `for (int = 0; i < 10; ++i)`
|
|
||||||
* Never put an "else" statement after a "return"! This is well-explained in the
|
|
||||||
LLVM coding standards...and a couple of other very good pieces of advice from
|
|
||||||
the LLVM standards are in there as well.
|
|
||||||
* When getting a possibly-null pointer and using it only if it's non-null, limit
|
|
||||||
the scope of the pointer as much as possible - e.g. Do NOT do this:
|
|
||||||
|
|
||||||
Foo* f = getFoo ();
|
|
||||||
if (f != nullptr)
|
|
||||||
f->doSomething ();
|
|
||||||
// other code
|
|
||||||
f->doSomething (); // oops! f may be null!
|
|
||||||
|
|
||||||
..instead, prefer to write it like this, which reduces the scope of the
|
|
||||||
pointer, making it impossible to write code that accidentally uses a null
|
|
||||||
pointer:
|
|
||||||
|
|
||||||
if (Foo* f = getFoo ())
|
|
||||||
f->doSomethingElse ();
|
|
||||||
|
|
||||||
// f is out-of-scope here, so impossible to use it if it's null
|
|
||||||
|
|
||||||
(This also results in smaller, cleaner code)
|
|
||||||
|
|
||||||
[1]: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|
|
||||||
[2]: http://en.wikipedia.org/wiki/Indent_style#Allman_style
|
|
||||||
1890
doc/Doxyfile
1890
doc/Doxyfile
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,126 +0,0 @@
|
|||||||
#
|
|
||||||
# Sample ripple.txt
|
|
||||||
#
|
|
||||||
# More information: https://ripple.com/wiki/Ripple.txt
|
|
||||||
#
|
|
||||||
# Publishing this file allows a site to declare in a trustworthy manor ripple
|
|
||||||
# associated information.
|
|
||||||
#
|
|
||||||
# This file is stored on the web server for a domain. This file is searched
|
|
||||||
# for in the following order:
|
|
||||||
# - https://ripple.DOMAIN/ripple.txt
|
|
||||||
# - https://www.DOMAIN/ripple.txt
|
|
||||||
# - https://DOMAIN/ripple.txt
|
|
||||||
#
|
|
||||||
# The server MUST set the following HTTP header when serving this file:
|
|
||||||
# Access-Control-Allow-Origin: *
|
|
||||||
#
|
|
||||||
# This file is UTF-8 with Dos, UNIX, or Mac style end of lines.
|
|
||||||
# Blank lines and lines beginning with '#' are ignored.
|
|
||||||
# Undefined sections are reserved.
|
|
||||||
# No escapes are currently defined.
|
|
||||||
#
|
|
||||||
# IMPORTANT: Please remove these comments before publishing this file. Doing so
|
|
||||||
# makes the file much more readable to humans trying to find info on your site.
|
|
||||||
#
|
|
||||||
# [expires]
|
|
||||||
# Number of days after which this file should be considered expire. Clients
|
|
||||||
# are expected to check this file when they have cause to believe it has
|
|
||||||
# changed or expired. For example, if a client discovers an account declares
|
|
||||||
# that it is associated with the domain, it should check to see if this file
|
|
||||||
# has been updated. If an expiration date is not declared, the default
|
|
||||||
# expiration for this file is 30 days.
|
|
||||||
#
|
|
||||||
# Example: 30
|
|
||||||
#
|
|
||||||
# [accounts]
|
|
||||||
# Only valid in "ripple.txt". A list of accounts that are declared to be
|
|
||||||
# controlled by this domain. A client wishing to indicate that an account is
|
|
||||||
# verified as belonging to a domain will be show the account with a green
|
|
||||||
# background. A client can verify that an account belongs to a domain by
|
|
||||||
# checking if the account's root entry mentions the domain containing this
|
|
||||||
# file and this file found at the domain mentions the account in this
|
|
||||||
# section.
|
|
||||||
#
|
|
||||||
# Example: rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
|
|
||||||
#
|
|
||||||
# [hotwallets]
|
|
||||||
# Only valid in "ripple.txt". A list of accounts that are declared to be
|
|
||||||
# controlled by this domain and used as hotwallets.
|
|
||||||
#
|
|
||||||
# Example: rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
|
|
||||||
#
|
|
||||||
# [validation_public_key]:
|
|
||||||
# Only valid in "ripple.txt". A validation public key that is declared
|
|
||||||
# to be used by this domain for validating ledgers and that it is the
|
|
||||||
# authorized signature for the domain. This does not imply that a node
|
|
||||||
# serving the Ripple protocol is avilable at the web host providing the
|
|
||||||
# file.
|
|
||||||
#
|
|
||||||
# Example: n9MZTnHe5D5Q2cgE8oV2usFwRqhUvEA8MwP5Mu1XVD6TxmssPRev
|
|
||||||
#
|
|
||||||
# [domain]:
|
|
||||||
# Mandatory in "ripple.txt".
|
|
||||||
# Only valid in "ripple.txt".
|
|
||||||
# Must match location of file.
|
|
||||||
#
|
|
||||||
# Example: google.com
|
|
||||||
#
|
|
||||||
# [ips]:
|
|
||||||
# Only valid in "rippled.cfg", "ripple.txt", and the referered [ips_url].
|
|
||||||
# List of ips where the Newcoin protocol is avialable.
|
|
||||||
# One ipv4 or ipv6 address per line.
|
|
||||||
# A port may optionally be specified after adding a space to the address.
|
|
||||||
# By convention, if known, IPs are listed in from most to least trusted.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# 192.168.0.1
|
|
||||||
# 192.168.0.1 3939
|
|
||||||
# 2001:0db8:0100:f101:0210:a4ff:fee3:9566
|
|
||||||
#
|
|
||||||
# [validators]:
|
|
||||||
# Only valid in "rippled.cfg", "ripple.txt", and the referered [validators_url].
|
|
||||||
# List of Ripple validators this node recommends.
|
|
||||||
#
|
|
||||||
# For domains, rippled will probe for https web servers at the specied
|
|
||||||
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
|
|
||||||
#
|
|
||||||
# These are encoded 257-bit secp256k1 public keys.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# redstem.com
|
|
||||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
|
||||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
|
||||||
#
|
|
||||||
# [ips_url]:
|
|
||||||
# Only valid in "ripple.txt".
|
|
||||||
# https URL to a similarily formatted file containing [ips].
|
|
||||||
#
|
|
||||||
# Example: https://google.com/ripple_ips.txt
|
|
||||||
#
|
|
||||||
# [validators_url]:
|
|
||||||
# Only valid in "ripple.txt".
|
|
||||||
# https URL to a similarily formatted file containing [validators].
|
|
||||||
#
|
|
||||||
# Example: https://google.com/ripple_validators.txt
|
|
||||||
#
|
|
||||||
# [currencies]:
|
|
||||||
# This section allows a site to declare currencies it currently issues.
|
|
||||||
#
|
|
||||||
# Examples: (multiple allowed one per line)
|
|
||||||
# USD
|
|
||||||
# BTC
|
|
||||||
# LTC
|
|
||||||
#
|
|
||||||
|
|
||||||
[validation_public_key]
|
|
||||||
n9MZTnHe5D5Q2cgE8oV2usFwRqhUvEA8MwP5Mu1XVD6TxmssPRev
|
|
||||||
|
|
||||||
[domain]
|
|
||||||
loss
|
|
||||||
|
|
||||||
[ips]
|
|
||||||
192.168.0.5
|
|
||||||
|
|
||||||
[validators]
|
|
||||||
redstem.com
|
|
||||||
@@ -1,880 +0,0 @@
|
|||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Rippled Server Instance Configuration Example
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Contents
|
|
||||||
#
|
|
||||||
# 1. Peer Networking
|
|
||||||
#
|
|
||||||
# 2. Websocket Networking
|
|
||||||
#
|
|
||||||
# 3. RPC Networking
|
|
||||||
#
|
|
||||||
# 4. SMS Gateway
|
|
||||||
#
|
|
||||||
# 5. Ripple Protcol
|
|
||||||
#
|
|
||||||
# 6. HTTPS Client
|
|
||||||
#
|
|
||||||
# 7. Database
|
|
||||||
#
|
|
||||||
# 8. Diagnostics
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Purpose
|
|
||||||
#
|
|
||||||
# This file documents and provides examples of all rippled server process
|
|
||||||
# configuration options. When the rippled server instance is launched, it
|
|
||||||
# looks for a file with the following name:
|
|
||||||
#
|
|
||||||
# rippled.cfg
|
|
||||||
#
|
|
||||||
# For more information on where the rippled server instance searches for
|
|
||||||
# the file please visit the Ripple wiki. Specifically, the section explaining
|
|
||||||
# the --conf command line option:
|
|
||||||
#
|
|
||||||
# https://ripple.com/wiki/Rippled#--conf.3Dpath
|
|
||||||
#
|
|
||||||
# This file should be named rippled.cfg. This file is UTF-8 with Dos, UNIX,
|
|
||||||
# or Mac style end of lines. Blank lines and lines beginning with '#' are
|
|
||||||
# ignored. Undefined sections are reserved. No escapes are currently defined.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 1. Peer Networking
|
|
||||||
#
|
|
||||||
#-------------------
|
|
||||||
#
|
|
||||||
# These settings control security and access attributes of the Peer to Peer
|
|
||||||
# server section of the rippled process. Peer Networking implements the
|
|
||||||
# Ripple Payment protocol. It is over peer connections that transactions
|
|
||||||
# and validations are passed from to machine to machine, to make up the
|
|
||||||
# components of closed ledgers.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [ips]
|
|
||||||
#
|
|
||||||
# List of hostnames or ips where the Ripple protocol is served. For a starter
|
|
||||||
# list, you can either copy entries from: https://ripple.com/ripple.txt or if
|
|
||||||
# you prefer you can specify r.ripple.com 51235
|
|
||||||
#
|
|
||||||
# One IPv4 address or domain names per line is allowed. A port may optionally
|
|
||||||
# be specified after adding a space to the address. By convention, if known,
|
|
||||||
# IPs are listed in from most to least trusted.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# 192.168.0.1
|
|
||||||
# 192.168.0.1 3939
|
|
||||||
# r.ripple.com 51235
|
|
||||||
#
|
|
||||||
# This will give you a good, up-to-date list of addresses:
|
|
||||||
#
|
|
||||||
# [ips]
|
|
||||||
# r.ripple.com 51235
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [ips_fixed]
|
|
||||||
#
|
|
||||||
# List of IP addresses or hostnames to which rippled should always attempt to
|
|
||||||
# maintain peer connections with. This is useful for manually forming private
|
|
||||||
# networks, for example to configure a validation server that connects to the
|
|
||||||
# Ripple network through a public-facing server, or for building a set
|
|
||||||
# of cluster peers.
|
|
||||||
#
|
|
||||||
# One IPv4 address or domain names per line is allowed. A port may optionally
|
|
||||||
# be specified after adding a space to the address.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [peer_ip]
|
|
||||||
#
|
|
||||||
# IP address or domain to bind to allow external connections from peers.
|
|
||||||
# Defaults to not binding, which disallows external connections from peers.
|
|
||||||
#
|
|
||||||
# Examples: 0.0.0.0 - Bind on all interfaces.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [peer_port]
|
|
||||||
#
|
|
||||||
# If peer_ip is supplied, corresponding port to bind to for peer connections.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [peer_port_proxy]
|
|
||||||
#
|
|
||||||
# An optional, additional listening port number for peers. Incoming
|
|
||||||
# connections on this port will be required to provide a PROXY Protocol
|
|
||||||
# handshake, described in this document (external link):
|
|
||||||
#
|
|
||||||
# http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
|
|
||||||
#
|
|
||||||
# The PROXY Protocol is a popular method used by elastic load balancing
|
|
||||||
# service providers such as Amazon, to identify the true IP address and
|
|
||||||
# port number of external incoming connections.
|
|
||||||
#
|
|
||||||
# In addition to enabling this setting, it will also be required to
|
|
||||||
# use your provider-specific control panel or administrative web page
|
|
||||||
# to configure your server instance to receive PROXY Protocol handshakes,
|
|
||||||
# and also to restrict access to your instance to the Elastic Load Balancer.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [peer_private]
|
|
||||||
#
|
|
||||||
# 0 or 1.
|
|
||||||
#
|
|
||||||
# 0: Request peers to broadcast your address. Normal outbound peer connections [default]
|
|
||||||
# 1: Request peers not broadcast your address. Only connect to configured peers.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [peers_max]
|
|
||||||
#
|
|
||||||
# The largest number of desired peer connections (incoming or outgoing).
|
|
||||||
# Cluster and fixed peers do not count towards this total. There are
|
|
||||||
# implementation-defined lower limits imposed on this value for security
|
|
||||||
# purposes.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [peer_ssl_cipher_list]
|
|
||||||
#
|
|
||||||
# A colon delimited string with the allowed SSL cipher modes for peer. The
|
|
||||||
# choices for for ciphers are defined by the OpenSSL API function
|
|
||||||
# SSL_CTX_set_cipher_list, documented here (external link):
|
|
||||||
#
|
|
||||||
# http://pic.dhe.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpc2%2Fcpp_ssl_ctx_set_cipher_list.html
|
|
||||||
#
|
|
||||||
# The default setting is "ALL:!LOW:!EXP:!MD5:@STRENGTH", which allows
|
|
||||||
# non-authenticated peer connections (they are, however, secure).
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [node_seed]
|
|
||||||
#
|
|
||||||
# This is used for clustering. To force a particular node seed or key, the
|
|
||||||
# key can be set here. The format is the same as the validation_seed field.
|
|
||||||
# To obtain a validation seed, use the validation_create command.
|
|
||||||
#
|
|
||||||
# Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE
|
|
||||||
# shfArahZT9Q9ckTf3s1psJ7C7qzVN
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [cluster_nodes]
|
|
||||||
#
|
|
||||||
# To extend full trust to other nodes, place their node public keys here.
|
|
||||||
# Generally, you should only do this for nodes under common administration.
|
|
||||||
# Node public keys start with an 'n'. To give a node a name for identification
|
|
||||||
# place a space after the public key and then the name.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [sntp_servers]
|
|
||||||
#
|
|
||||||
# IP address or domain of NTP servers to use for time synchronization.
|
|
||||||
#
|
|
||||||
# These NTP servers are suitable for rippled servers located in the United
|
|
||||||
# States:
|
|
||||||
# time.windows.com
|
|
||||||
# time.apple.com
|
|
||||||
# time.nist.gov
|
|
||||||
# pool.ntp.org
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 2. Websocket Networking
|
|
||||||
#
|
|
||||||
#------------------------
|
|
||||||
#
|
|
||||||
# These settings control security and access attributes of the Websocket
|
|
||||||
# server section of the rippled process, primarily used to service
|
|
||||||
# client requests and backend applications.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_public_ip]
|
|
||||||
#
|
|
||||||
# IP address or domain to bind to allow untrusted connections from clients.
|
|
||||||
# In the future, this option will go away and the peer_ip will accept
|
|
||||||
# websocket client connections.
|
|
||||||
#
|
|
||||||
# Examples: 0.0.0.0 - Bind on all interfaces.
|
|
||||||
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_public_port]
|
|
||||||
#
|
|
||||||
# Port to bind to allow untrusted connections from clients. In the future,
|
|
||||||
# this option will go away and the peer_ip will accept websocket client
|
|
||||||
# connections.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_public_secure]
|
|
||||||
#
|
|
||||||
# 0, 1 or 2.
|
|
||||||
# 0: Provide ws service for websocket_public_ip/websocket_public_port.
|
|
||||||
# 1: Provide both ws and wss service for websocket_public_ip/websocket_public_port. [default]
|
|
||||||
# 2: Provide wss service only for websocket_public_ip/websocket_public_port.
|
|
||||||
#
|
|
||||||
# Browser pages like the Ripple client will not be able to connect to a secure
|
|
||||||
# websocket connection if a self-signed certificate is used. As the Ripple
|
|
||||||
# reference client currently shares secrets with its server, this should be
|
|
||||||
# enabled.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_ping_frequency]
|
|
||||||
#
|
|
||||||
# <number>
|
|
||||||
#
|
|
||||||
# The amount of time to wait in seconds, before sending a websocket 'ping'
|
|
||||||
# message. Ping messages are used to determine if the remote end of the
|
|
||||||
# connection is no longer available.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_ip]
|
|
||||||
#
|
|
||||||
# IP address or domain to bind to allow trusted ADMIN connections from backend
|
|
||||||
# applications.
|
|
||||||
#
|
|
||||||
# Examples: 0.0.0.0 - Bind on all interfaces.
|
|
||||||
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_port]
|
|
||||||
#
|
|
||||||
# Port to bind to allow trusted ADMIN connections from backend applications.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_secure]
|
|
||||||
#
|
|
||||||
# 0, 1, or 2.
|
|
||||||
# 0: Provide ws service only for websocket_ip/websocket_port. [default]
|
|
||||||
# 1: Provide ws and wss service for websocket_ip/websocket_port
|
|
||||||
# 2: Provide wss service for websocket_ip/websocket_port.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_ssl_cert]
|
|
||||||
#
|
|
||||||
# Specify the path to the SSL certificate file in PEM format.
|
|
||||||
# This is not needed if the chain includes it.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_ssl_chain]
|
|
||||||
#
|
|
||||||
# If you need a certificate chain, specify the path to the certificate chain
|
|
||||||
# here. The chain may include the end certificate.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [websocket_ssl_key]
|
|
||||||
#
|
|
||||||
# Specify the filename holding the SSL key in PEM format.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 3. RPC Networking
|
|
||||||
#
|
|
||||||
#------------------
|
|
||||||
#
|
|
||||||
# This group of settings configures security and access attributes of the
|
|
||||||
# RPC server section of the rippled process, used to service both local
|
|
||||||
# and optional remote clients.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_allow_remote]
|
|
||||||
#
|
|
||||||
# 0 or 1.
|
|
||||||
#
|
|
||||||
# 0: Allow RPC connections only from 127.0.0.1. [default]
|
|
||||||
# 1: Allow RPC connections from any IP.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_admin_allow]
|
|
||||||
#
|
|
||||||
# Specify a list of IP addresses allowed to have admin access. One per line.
|
|
||||||
# If you want to test the output of non-admin commands add this section and
|
|
||||||
# just put an ip address not under your control.
|
|
||||||
# Defaults to 127.0.0.1.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_admin_user]
|
|
||||||
#
|
|
||||||
# As a server, require this as the admin user to be specified. Also, require
|
|
||||||
# rpc_admin_user and rpc_admin_password to be checked for RPC admin functions.
|
|
||||||
# The request must specify these as the admin_user and admin_password in the
|
|
||||||
# request object.
|
|
||||||
#
|
|
||||||
# As a client, supply this to the server in the request object.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_admin_password]
|
|
||||||
#
|
|
||||||
# As a server, require this as the admin password to be specified. Also,
|
|
||||||
# require rpc_admin_user and rpc_admin_password to be checked for RPC admin
|
|
||||||
# functions. The request must specify these as the admin_user and
|
|
||||||
# admin_password in the request object.
|
|
||||||
#
|
|
||||||
# As a client, supply this to the server in the request object.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_ip]
|
|
||||||
#
|
|
||||||
# IP address or domain to bind to allow insecure RPC connections.
|
|
||||||
# Defaults to not binding, which disallows RPC connections.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_port]
|
|
||||||
#
|
|
||||||
# If rpc_ip is supplied, corresponding port to bind to for peer connections.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_user]
|
|
||||||
#
|
|
||||||
# As a server, require this user to be specified and require rpc_password to
|
|
||||||
# be checked for RPC access via the rpc_ip and rpc_port. The user and password
|
|
||||||
# must be specified via HTTP's basic authentication method.
|
|
||||||
# As a client, supply this to the server via HTTP's basic authentication
|
|
||||||
# method.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_password]
|
|
||||||
#
|
|
||||||
# As a server, require this password to be specified and require rpc_user to
|
|
||||||
# be checked for RPC access via the rpc_ip and rpc_port. The user and password
|
|
||||||
# must be specified via HTTP's basic authentication method.
|
|
||||||
# As a client, supply this to the server via HTTP's basic authentication
|
|
||||||
# method.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_startup]
|
|
||||||
#
|
|
||||||
# Specify a list of RPC commands to run at startup.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# { "command" : "server_info" }
|
|
||||||
# { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_secure]
|
|
||||||
#
|
|
||||||
# 0 or 1.
|
|
||||||
#
|
|
||||||
# 0: Server certificates are not provided for RPC clients using SSL [default]
|
|
||||||
# 1: Client RPC connections wil be provided with SSL certificates.
|
|
||||||
#
|
|
||||||
# Note that if rpc_secure is enabled, it will also be necessary to configure
|
|
||||||
# the certificate file settings located in rpc_ssl_cert, rpc_ssl_chain, and
|
|
||||||
# rpc_ssl_key
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_ssl_cert]
|
|
||||||
#
|
|
||||||
# <pathname>
|
|
||||||
#
|
|
||||||
# A file system path leading to the SSL certificate file to use for secure
|
|
||||||
# RPC. The file is in PEM format. The file is not needed if the chain
|
|
||||||
# includes it.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_ssl_chain]
|
|
||||||
#
|
|
||||||
# <pathname>
|
|
||||||
#
|
|
||||||
# A file system path leading to the file with the certificate chain.
|
|
||||||
# The chain may include the end certificate.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [rpc_ssl_key]
|
|
||||||
#
|
|
||||||
# <pathname>
|
|
||||||
#
|
|
||||||
# A file system path leading to the file with the SSL key.
|
|
||||||
# The file is in PEM format.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 4. SMS Gateway
|
|
||||||
#
|
|
||||||
#---------------
|
|
||||||
#
|
|
||||||
# If you have a certain SMS messaging provider you can configure these
|
|
||||||
# settings to allow the rippled server instance to send an SMS text to the
|
|
||||||
# configured gateway in response to an admin-level RPC command "sms" with
|
|
||||||
# one parameter, 'text' containing the message to send. This allows backend
|
|
||||||
# applications to use the rippled instance to securely notify administrators
|
|
||||||
# of custom events or information via SMS gateway.
|
|
||||||
#
|
|
||||||
# When the 'sms' RPC command is issued, the configured SMS gateway will be
|
|
||||||
# contacted via HTTPS GET at the URL indicated by sms_url. The URI formed
|
|
||||||
# will be in this format:
|
|
||||||
#
|
|
||||||
# [sms_url]?from=[sms_from]&to=[sms_to]&api_key=[sms_key]&api_secret=[sms_secret]&text=['text']
|
|
||||||
#
|
|
||||||
# Where [...] are the corresponding values from the configuration file, and
|
|
||||||
# ['test'] is the value of the JSON field with name 'text'.
|
|
||||||
#
|
|
||||||
# [sms_url]
|
|
||||||
#
|
|
||||||
# The URL to contact via HTTPS when sending SMS messages
|
|
||||||
#
|
|
||||||
# [sms_from]
|
|
||||||
# [sms_to]
|
|
||||||
# [sms_key]
|
|
||||||
# [sms_secret]
|
|
||||||
#
|
|
||||||
# These are all strings passed directly in the URI as query parameters
|
|
||||||
# to the provider of the SMS gateway.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 5. Ripple Protocol
|
|
||||||
#
|
|
||||||
#------------------
|
|
||||||
#
|
|
||||||
# These settings affect the behavior of the server instance with respect
|
|
||||||
# to Ripple payment protocol level activities such as validating and
|
|
||||||
# closing ledgers, establishing a quorum, or adjusting fees in response
|
|
||||||
# to server overloads.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [node_size]
|
|
||||||
#
|
|
||||||
# Tunes the servers based on the expected load and available memory. Legal
|
|
||||||
# sizes are "tiny", "small", "medium", "large", and "huge". We recommend
|
|
||||||
# you start at the default and raise the setting if you have extra memory.
|
|
||||||
# The default is "tiny".
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [validation_quorum]
|
|
||||||
#
|
|
||||||
# Sets the minimum number of trusted validations a ledger must have before
|
|
||||||
# the server considers it fully validated. Note that if you are validating,
|
|
||||||
# your validation counts.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [ledger_history]
|
|
||||||
#
|
|
||||||
# The number of past ledgers to acquire on server startup and the minimum to
|
|
||||||
# maintain while running.
|
|
||||||
#
|
|
||||||
# To serve clients, servers need historical ledger data. Servers that don't
|
|
||||||
# need to serve clients can set this to "none". Servers that want complete
|
|
||||||
# history can set this to "full".
|
|
||||||
#
|
|
||||||
# The default is: 256
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [fetch_depth]
|
|
||||||
#
|
|
||||||
# The number of past ledgers to serve to other peers that request historical
|
|
||||||
# ledger data (or "full" for no limit).
|
|
||||||
#
|
|
||||||
# Servers that require low latency and high local performance may wish to
|
|
||||||
# restrict the historical ledgers they are willing to serve. Setting this
|
|
||||||
# below 32 can harm network stability as servers require easy access to
|
|
||||||
# recent history to stay in sync. Values below 128 are not recommended.
|
|
||||||
#
|
|
||||||
# The default is: full
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [validation_seed]
|
|
||||||
#
|
|
||||||
# To perform validation, this section should contain either a validation seed
|
|
||||||
# or key. The validation seed is used to generate the validation
|
|
||||||
# public/private key pair. To obtain a validation seed, use the
|
|
||||||
# validation_create command.
|
|
||||||
#
|
|
||||||
# Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE
|
|
||||||
# shfArahZT9Q9ckTf3s1psJ7C7qzVN
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [validators]
|
|
||||||
#
|
|
||||||
# List of nodes to always accept as validators. Nodes are specified by domain
|
|
||||||
# or public key.
|
|
||||||
#
|
|
||||||
# For domains, rippled will probe for https web servers at the specified
|
|
||||||
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
|
|
||||||
#
|
|
||||||
# For public key entries, a comment may optionally be specified after adding
|
|
||||||
# a space to the public key.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# ripple.com
|
|
||||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
|
||||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [validators_file]
|
|
||||||
#
|
|
||||||
# Path to file contain a list of nodes to always accept as validators. Use
|
|
||||||
# this to specify a file other than this file to manage your validators list.
|
|
||||||
#
|
|
||||||
# If this entry is not present or empty and no nodes from previous runs were
|
|
||||||
# found in the database, rippled will look for a validators.txt in the config
|
|
||||||
# directory. If not found there, it will attempt to retrieve the file from
|
|
||||||
# the [validators_site] web site.
|
|
||||||
#
|
|
||||||
# After specifying a different [validators_file] or changing the contents of
|
|
||||||
# the validators file, issue a RPC unl_load command to have rippled load the
|
|
||||||
# file.
|
|
||||||
#
|
|
||||||
# Specify the file by specifying its full path.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# C:/home/johndoe/ripple/validators.txt
|
|
||||||
# /home/johndoe/ripple/validators.txt
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [validators_site]
|
|
||||||
#
|
|
||||||
# Specifies where to find validators.txt for UNL boostrapping and RPC
|
|
||||||
# unl_network command.
|
|
||||||
#
|
|
||||||
# Example: ripple.com
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [path_search]
|
|
||||||
# When searching for paths, the default search aggressiveness. This can take
|
|
||||||
# exponentially more resources as the size is increased.
|
|
||||||
#
|
|
||||||
# The default is: 7
|
|
||||||
#
|
|
||||||
# [path_search_fast]
|
|
||||||
# [path_search_max]
|
|
||||||
# When searching for paths, the minimum and maximum search aggressiveness.
|
|
||||||
#
|
|
||||||
# The default for 'path_search_fast' is 2. The default for 'path_search_max' is 10.
|
|
||||||
#
|
|
||||||
# [path_search_old]
|
|
||||||
#
|
|
||||||
# For clients that use the legacy path finding interfaces, the search
|
|
||||||
# agressivness to use. The default is 7.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 6. HTTPS Client
|
|
||||||
#
|
|
||||||
#----------------
|
|
||||||
#
|
|
||||||
# The rippled server instance uses HTTPS GET requests in a variety of
|
|
||||||
# circumstances, including but not limited to the SMS Messaging Gateway
|
|
||||||
# feature and also for contacting trusted domains to fetch information
|
|
||||||
# such as mapping an email address to a Ripple Payment Network address.
|
|
||||||
#
|
|
||||||
# [ssl_verify]
|
|
||||||
#
|
|
||||||
# 0 or 1.
|
|
||||||
#
|
|
||||||
# 0. HTTPS client connections will not verify certificates.
|
|
||||||
# 1. Certificates will be checked for HTTPS client connections .
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [ssl_verify_file]
|
|
||||||
#
|
|
||||||
# <pathname>
|
|
||||||
#
|
|
||||||
# A file system path leading to the certificate verification file for
|
|
||||||
# HTTPS client requests.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [ssl_verify_dir]
|
|
||||||
#
|
|
||||||
# <pathname>
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# A file system path leading to a file or directory containing the root
|
|
||||||
# certificates that the server will accept for verifying HTTP servers.
|
|
||||||
# Used only for outbound HTTPS client connections.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 7. Database
|
|
||||||
#
|
|
||||||
#------------
|
|
||||||
#
|
|
||||||
# rippled creates 4 SQLite database to hold bookkeeping information
|
|
||||||
# about transactions, local credentials, and various other things.
|
|
||||||
# It also creates the NodeDB, which holds all the objects that
|
|
||||||
# make up the current and historical ledgers. The size of the NodeDB
|
|
||||||
# grows in proportion to the amount of new data and the amount of
|
|
||||||
# historical data (a configurable setting).
|
|
||||||
#
|
|
||||||
# The performance of the underlying storage media where the NodeDB
|
|
||||||
# is placed can affect the performance of the server. Some virtual
|
|
||||||
# hosting providers offer high speed secondary storage, with the
|
|
||||||
# caveat that the data is not persisted across launches. If rippled
|
|
||||||
# runs in such an environment, it can be beneficial to configure the
|
|
||||||
# temp_db setting, which activates a secondary "look-aside" cache
|
|
||||||
# that can speed up the server. Some testing is suggested to determine
|
|
||||||
# if the temp_db setting is an improvement for your environment
|
|
||||||
#
|
|
||||||
# Partial pathnames will be considered relative to the location of
|
|
||||||
# the rippled.cfg file.
|
|
||||||
#
|
|
||||||
# [node_db] Settings for the NodeDB (required)
|
|
||||||
# [temp_db] Settings for the look-aside temporary db (optional)
|
|
||||||
# [import_db] Settings for performing a one-time import (optional)
|
|
||||||
#
|
|
||||||
# Format (without spaces):
|
|
||||||
# One or more lines of key / value pairs:
|
|
||||||
# <key> '=' <value>
|
|
||||||
# ...
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# type=HyperLevelDB
|
|
||||||
# path=db/hyperldb
|
|
||||||
# compression=0
|
|
||||||
#
|
|
||||||
# Choices for 'type' (not case-sensitive)
|
|
||||||
# RocksDB Use Facebook's RocksDB database (preferred)
|
|
||||||
# HyperLevelDB Use an improved version of LevelDB
|
|
||||||
# SQLite Use SQLite
|
|
||||||
# LevelDB Use Google's LevelDB database (deprecated)
|
|
||||||
# none Use no backend
|
|
||||||
#
|
|
||||||
# Required keys:
|
|
||||||
# path Location to store the database (all types)
|
|
||||||
#
|
|
||||||
# Optional keys:
|
|
||||||
# compression 0 for none, 1 for Snappy compression
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# The 'node_db' entry configures the primary, persistent storage.
|
|
||||||
#
|
|
||||||
# The 'temp_db' configures a look-aside cache for high volume storage
|
|
||||||
# which doesn't necessarily persist between server launches. This
|
|
||||||
# is an optional configuration parameter. If it is left out then
|
|
||||||
# no look-aside database is created or used.
|
|
||||||
#
|
|
||||||
# The 'import_db' is used with the '--import' command line option to
|
|
||||||
# migrate the specified database into the current database given
|
|
||||||
# in the [node_db] section.
|
|
||||||
#
|
|
||||||
# [database_path] Path to the book-keeping databases.
|
|
||||||
#
|
|
||||||
# There are 4 book-keeping SQLite database that the server creates and
|
|
||||||
# maintains. If you omit this configuration setting, it will default to
|
|
||||||
# creating a directory called "db" located in the same place as your
|
|
||||||
# rippled.cfg file.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 8. Diagnostics
|
|
||||||
#
|
|
||||||
#---------------
|
|
||||||
#
|
|
||||||
# These settings are designed to help server administrators diagnose
|
|
||||||
# problems, and obtain detailed information about the activities being
|
|
||||||
# performed by the rippled process.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [debug_logfile]
|
|
||||||
#
|
|
||||||
# Specifies were a debug logfile is kept. By default, no debug log is kept.
|
|
||||||
# Unless absolute, the path is relative the directory containing this file.
|
|
||||||
#
|
|
||||||
# Example: debug.log
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# [insight]
|
|
||||||
#
|
|
||||||
# Configuration parameters for the Beast.Insight stats collection module.
|
|
||||||
#
|
|
||||||
# Insight is a module that collects information from the areas of rippled
|
|
||||||
# that have instrumentation. The configuration paramters control where the
|
|
||||||
# collection metrics are sent. The parameters are expressed as key = value
|
|
||||||
# pairs with no white space. The main parameter is the choice of server:
|
|
||||||
#
|
|
||||||
# "server"
|
|
||||||
#
|
|
||||||
# Choice of server to send metrics to. Currently the only choice is
|
|
||||||
# "statsd" which sends UDP packets to a StatsD daemon, which must be
|
|
||||||
# running while rippled is running. More information on StatsD is
|
|
||||||
# available here:
|
|
||||||
# https://github.com/b/statsd_spec
|
|
||||||
#
|
|
||||||
# When server=statsd, these additional keys are used:
|
|
||||||
#
|
|
||||||
# "address" The UDP address and port of the listening StatsD server,
|
|
||||||
# in the format, n.n.n.n:port.
|
|
||||||
#
|
|
||||||
# "prefix" A string prepended to each collected metric. This is used
|
|
||||||
# to distinguish between different running instances of rippled.
|
|
||||||
#
|
|
||||||
# If this section is missing, or the server type is unspecified or unknown,
|
|
||||||
# statistics are not collected or reported.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# [insight]
|
|
||||||
# server=statsd
|
|
||||||
# address=192.168.0.95:4201
|
|
||||||
# prefix=my_validator
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Allow other peers to connect to this server.
|
|
||||||
#
|
|
||||||
[peer_ip]
|
|
||||||
0.0.0.0
|
|
||||||
|
|
||||||
[peer_port]
|
|
||||||
51235
|
|
||||||
|
|
||||||
# Allow untrusted clients to connect to this server.
|
|
||||||
#
|
|
||||||
[websocket_public_ip]
|
|
||||||
0.0.0.0
|
|
||||||
|
|
||||||
[websocket_public_port]
|
|
||||||
5006
|
|
||||||
|
|
||||||
# Provide trusted websocket ADMIN access to the localhost.
|
|
||||||
#
|
|
||||||
[websocket_ip]
|
|
||||||
127.0.0.1
|
|
||||||
|
|
||||||
[websocket_port]
|
|
||||||
6006
|
|
||||||
|
|
||||||
# Provide trusted json-rpc ADMIN access to the localhost.
|
|
||||||
#
|
|
||||||
[rpc_ip]
|
|
||||||
127.0.0.1
|
|
||||||
|
|
||||||
[rpc_port]
|
|
||||||
5005
|
|
||||||
|
|
||||||
[rpc_allow_remote]
|
|
||||||
0
|
|
||||||
|
|
||||||
[node_size]
|
|
||||||
medium
|
|
||||||
|
|
||||||
# This is primary persistent datastore for rippled. This includes transaction
|
|
||||||
# metadata, account states, and ledger headers. Helpful information can be
|
|
||||||
# found here: https://ripple.com/wiki/NodeBackEnd
|
|
||||||
[node_db]
|
|
||||||
type=RocksDB
|
|
||||||
path=/var/lib/rippled/db/rocksdb
|
|
||||||
open_files=2000
|
|
||||||
filter_bits=12
|
|
||||||
cache_mb=256
|
|
||||||
file_size_mb=8
|
|
||||||
file_size_mult=2
|
|
||||||
|
|
||||||
[database_path]
|
|
||||||
/var/lib/rippled/db
|
|
||||||
|
|
||||||
# This needs to be an absolute directory reference, not a relative one.
|
|
||||||
# Modify this value as required.
|
|
||||||
[debug_logfile]
|
|
||||||
/var/log/rippled/debug.log
|
|
||||||
|
|
||||||
[sntp_servers]
|
|
||||||
time.windows.com
|
|
||||||
time.apple.com
|
|
||||||
time.nist.gov
|
|
||||||
pool.ntp.org
|
|
||||||
|
|
||||||
# Where to find some other servers speaking the Ripple protocol.
|
|
||||||
#
|
|
||||||
[ips]
|
|
||||||
r.ripple.com 51235
|
|
||||||
|
|
||||||
# The latest validators can be obtained from
|
|
||||||
# https://ripple.com/ripple.txt
|
|
||||||
#
|
|
||||||
[validators]
|
|
||||||
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
|
|
||||||
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
|
|
||||||
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
|
|
||||||
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
|
|
||||||
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
|
|
||||||
|
|
||||||
# Ditto.
|
|
||||||
[validation_quorum]
|
|
||||||
3
|
|
||||||
|
|
||||||
# Turn down default logging to save disk space in the long run.
|
|
||||||
# Valid values here are trace, debug, info, warning, error, and fatal
|
|
||||||
[rpc_startup]
|
|
||||||
{ "command": "log_level", "severity": "warning" }
|
|
||||||
|
|
||||||
# Configure SSL for WebSockets. Not enabled by default because not everybody
|
|
||||||
# has an SSL cert on their server, but if you uncomment the following lines and
|
|
||||||
# set the path to the SSL certificate and private key the WebSockets protocol
|
|
||||||
# will be protected by SSL/TLS.
|
|
||||||
#[websocket_secure]
|
|
||||||
#1
|
|
||||||
|
|
||||||
#[websocket_ssl_cert]
|
|
||||||
#/etc/ssl/certs/server.crt
|
|
||||||
|
|
||||||
#[websocket_ssl_key]
|
|
||||||
#/etc/ssl/private/server.key
|
|
||||||
|
|
||||||
# Defaults to 0 ("no") so that you can use self-signed SSL certificates for
|
|
||||||
# development, or internally.
|
|
||||||
#[ssl_verify]
|
|
||||||
#0
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Ripple Peer-to-Peer Network Daemon
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=nobody
|
|
||||||
ExecStart=/usr/bin/rippled --conf=/etc/rippled/rippled.cfg
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
114
doc/rippled.init
114
doc/rippled.init
@@ -1,114 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: ripple
|
|
||||||
# Required-Start: $local_fs $remote_fs $network $syslog
|
|
||||||
# Required-Stop: $local_fs $remote_fs $network $syslog
|
|
||||||
# Default-Start: 2 3 4 5
|
|
||||||
# Default-Stop: 0 1 6
|
|
||||||
# Short-Description: starts the ripple network node
|
|
||||||
# Description: starts rippled using start-stop-daemon
|
|
||||||
### END INIT INFO
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
NAME=rippled
|
|
||||||
USER="rippled"
|
|
||||||
GROUP="rippled"
|
|
||||||
PIDFILE=/var/run/$NAME.pid
|
|
||||||
DAEMON=/usr/local/sbin/rippled
|
|
||||||
DAEMON_OPTS="--conf /etc/ripple/rippled.cfg"
|
|
||||||
NET_OPTS="--net $DAEMON_OPTS"
|
|
||||||
LOGDIR="/var/log/rippled"
|
|
||||||
DBDIR="/var/db/rippled/db/hyperldb"
|
|
||||||
|
|
||||||
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
|
|
||||||
|
|
||||||
# I wish it didn't come down to this, but this is the easiest way to ensure
|
|
||||||
# sanity of an install.
|
|
||||||
if [ ! -d $LOGDIR ]; then
|
|
||||||
mkdir -p $LOGDIR
|
|
||||||
chown $USER:$GROUP $LOGDIR
|
|
||||||
fi
|
|
||||||
if [ ! -d $DBDIR ]; then
|
|
||||||
mkdir -p $DBDIR
|
|
||||||
chown -R $USER:$GROUP $DBDIR
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
echo -n "Starting daemon: "$NAME
|
|
||||||
start-stop-daemon --start --quiet --background -m --pidfile $PIDFILE \
|
|
||||||
--exec $DAEMON --chuid $USER --group $GROUP --verbose -- $NET_OPTS
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
stop)
|
|
||||||
echo -n "Stopping daemon: "$NAME
|
|
||||||
$DAEMON $DAEMON_OPTS stop
|
|
||||||
rm -f $PIDFILE
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
restart)
|
|
||||||
echo -n "Restarting daemon: "$NAME
|
|
||||||
$DAEMON $DAEMON_OPTS stop
|
|
||||||
rm -f $PIDFILE
|
|
||||||
start-stop-daemon --start --quiet --background -m --pidfile $PIDFILE \
|
|
||||||
--exec $DAEMON --chuid $USER --group $GROUP -- $NET_OPTS
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
status)
|
|
||||||
echo "Status of $NAME:"
|
|
||||||
echo -n "PID of $NAME: "
|
|
||||||
if [ -f "$PIDFILE" ]; then
|
|
||||||
cat $PIDFILE
|
|
||||||
$DAEMON $DAEMON_OPTS server_info
|
|
||||||
else
|
|
||||||
echo "$NAME not running."
|
|
||||||
fi
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
fetch)
|
|
||||||
echo "$NAME ledger fetching info:"
|
|
||||||
$DAEMON $DAEMON_OPTS fetch_info
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
uptime)
|
|
||||||
echo "$NAME uptime:"
|
|
||||||
$DAEMON $DAEMON_OPTS get_counts
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
startconfig)
|
|
||||||
echo "$NAME is being started with the following command line:"
|
|
||||||
echo "$DAEMON $NET_OPTS"
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
command)
|
|
||||||
# Truncate the script's argument vector by one position to get rid of
|
|
||||||
# this entry.
|
|
||||||
shift
|
|
||||||
|
|
||||||
# Pass the remainder of the argument vector to rippled.
|
|
||||||
$DAEMON $DAEMON_OPTS "$@"
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
test)
|
|
||||||
$DAEMON $DAEMON_OPTS ping
|
|
||||||
echo "."
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 {start|stop|restart|status|fetch|uptime|startconfig|"
|
|
||||||
echo " command|test}"
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#
|
|
||||||
# Default validators.txt
|
|
||||||
#
|
|
||||||
# A list of domains to bootstrap a nodes UNLs or for clients to indirectly
|
|
||||||
# locate IPs to contact the Ripple network.
|
|
||||||
#
|
|
||||||
# This file is UTF-8 with Dos, UNIX, or Mac style end of lines.
|
|
||||||
# Blank lines and lines starting with a '#' are ignored.
|
|
||||||
# All other lines should be hankos or domain names.
|
|
||||||
#
|
|
||||||
# [validators]:
|
|
||||||
# List of nodes to accept as validators specified by public key or domain.
|
|
||||||
#
|
|
||||||
# For domains, rippled will probe for https web servers at the specified
|
|
||||||
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
|
|
||||||
#
|
|
||||||
# Examples: redstem.com
|
|
||||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
|
||||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
|
||||||
#
|
|
||||||
|
|
||||||
[validators]
|
|
||||||
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
|
|
||||||
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
|
|
||||||
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
|
|
||||||
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
|
|
||||||
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
|
|
||||||
3
docs/.gitignore
vendored
Normal file
3
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
html
|
||||||
|
temp
|
||||||
|
out.txt
|
||||||
597
docs/0001-negative-unl/README.md
Normal file
597
docs/0001-negative-unl/README.md
Normal file
@@ -0,0 +1,597 @@
|
|||||||
|
# Negative UNL Engineering Spec
|
||||||
|
|
||||||
|
## The Problem Statement
|
||||||
|
|
||||||
|
The moment-to-moment health of the XRP Ledger network depends on the health and
|
||||||
|
connectivity of a small number of computers (nodes). The most important nodes
|
||||||
|
are validators, specifically ones listed on the unique node list
|
||||||
|
([UNL](#Question-What-are-UNLs)). Ripple publishes a recommended UNL that most
|
||||||
|
network nodes use to determine which peers in the network are trusted. Although
|
||||||
|
most validators use the same list, they are not required to. The XRP Ledger
|
||||||
|
network progresses to the next ledger when enough validators reach agreement
|
||||||
|
(above the minimum quorum of 80%) about what transactions to include in the next
|
||||||
|
ledger.
|
||||||
|
|
||||||
|
As an example, if there are 10 validators on the UNL, at least 8 validators have
|
||||||
|
to agree with the latest ledger for it to become validated. But what if enough
|
||||||
|
of those validators are offline to drop the network below the 80% quorum? The
|
||||||
|
XRP Ledger network favors safety/correctness over advancing the ledger. Which
|
||||||
|
means if enough validators are offline, the network will not be able to validate
|
||||||
|
ledgers.
|
||||||
|
|
||||||
|
Unfortunately validators can go offline at any time for many different reasons.
|
||||||
|
Power outages, network connectivity issues, and hardware failures are just a few
|
||||||
|
scenarios where a validator would appear "offline". Given that most of these
|
||||||
|
events are temporary, it would make sense to temporarily remove that validator
|
||||||
|
from the UNL. But the UNL is updated infrequently and not every node uses the
|
||||||
|
same UNL. So instead of removing the unreliable validator from the Ripple
|
||||||
|
recommended UNL, we can create a second negative UNL which is stored directly on
|
||||||
|
the ledger (so the entire network has the same view). This will help the network
|
||||||
|
see which validators are **currently** unreliable, and adjust their quorum
|
||||||
|
calculation accordingly.
|
||||||
|
|
||||||
|
*Improving the liveness of the network is the main motivation for the negative UNL.*
|
||||||
|
|
||||||
|
### Targeted Faults
|
||||||
|
|
||||||
|
In order to determine which validators are unreliable, we need clearly define
|
||||||
|
what kind of faults to measure and analyze. We want to deal with the faults we
|
||||||
|
frequently observe in the production network. Hence we will only monitor for
|
||||||
|
validators that do not reliably respond to network messages or send out
|
||||||
|
validations disagreeing with the locally generated validations. We will not
|
||||||
|
target other byzantine faults.
|
||||||
|
|
||||||
|
To track whether or not a validator is responding to the network, we could
|
||||||
|
monitor them with a “heartbeat” protocol. Instead of creating a new heartbeat
|
||||||
|
protocol, we can leverage some existing protocol messages to mimic the
|
||||||
|
heartbeat. We picked validation messages because validators should send one and
|
||||||
|
only one validation message per ledger. In addition, we only count the
|
||||||
|
validation messages that agree with the local node's validations.
|
||||||
|
|
||||||
|
With the negative UNL, the network could keep making forward progress safely
|
||||||
|
even if the number of remaining validators gets to 60%. Say we have a network
|
||||||
|
with 10 validators on the UNL and everything is operating correctly. The quorum
|
||||||
|
required for this network would be 8 (80% of 10). When validators fail, the
|
||||||
|
quorum required would be as low as 6 (60% of 10), which is the absolute
|
||||||
|
***minimum quorum***. We need the absolute minimum quorum to be strictly greater
|
||||||
|
than 50% of the original UNL so that there cannot be two partitions of
|
||||||
|
well-behaved nodes headed in different directions. We arbitrarily choose 60% as
|
||||||
|
the minimum quorum to give a margin of safety.
|
||||||
|
|
||||||
|
Consider these events in the absence of negative UNL:
|
||||||
|
1. 1:00pm - validator1 fails, votes vs. quorum: 9 >= 8, we have quorum
|
||||||
|
1. 3:00pm - validator2 fails, votes vs. quorum: 8 >= 8, we have quorum
|
||||||
|
1. 5:00pm - validator3 fails, votes vs. quorum: 7 < 8, we don’t have quorum
|
||||||
|
* **network cannot validate new ledgers with 3 failed validators**
|
||||||
|
|
||||||
|
We're below 80% agreement, so new ledgers cannot be validated. This is how the
|
||||||
|
XRP Ledger operates today, but if the negative UNL was enabled, the events would
|
||||||
|
happen as follows. (Please note that the events below are from a simplified
|
||||||
|
version of our protocol.)
|
||||||
|
|
||||||
|
1. 1:00pm - validator1 fails, votes vs. quorum: 9 >= 8, we have quorum
|
||||||
|
1. 1:40pm - network adds validator1 to negative UNL, quorum changes to ceil(9 * 0.8), or 8
|
||||||
|
1. 3:00pm - validator2 fails, votes vs. quorum: 8 >= 8, we have quorum
|
||||||
|
1. 3:40pm - network adds validator2 to negative UNL, quorum changes to ceil(8 * 0.8), or 7
|
||||||
|
1. 5:00pm - validator3 fails, votes vs. quorum: 7 >= 7, we have quorum
|
||||||
|
1. 5:40pm - network adds validator3 to negative UNL, quorum changes to ceil(7 * 0.8), or 6
|
||||||
|
1. 7:00pm - validator4 fails, votes vs. quorum: 6 >= 6, we have quorum
|
||||||
|
* **network can still validate new ledgers with 4 failed validators**
|
||||||
|
|
||||||
|
## External Interactions
|
||||||
|
|
||||||
|
### Message Format Changes
|
||||||
|
This proposal will:
|
||||||
|
1. add a new pseudo-transaction type
|
||||||
|
1. add the negative UNL to the ledger data structure.
|
||||||
|
|
||||||
|
Any tools or systems that rely on the format of this data will have to be
|
||||||
|
updated.
|
||||||
|
|
||||||
|
### Amendment
|
||||||
|
This feature **will** need an amendment to activate.
|
||||||
|
|
||||||
|
## Design
|
||||||
|
|
||||||
|
This section discusses the following topics about the Negative UNL design:
|
||||||
|
|
||||||
|
* [Negative UNL protocol overview](#Negative-UNL-Protocol-Overview)
|
||||||
|
* [Validator reliability measurement](#Validator-Reliability-Measurement)
|
||||||
|
* [Format Changes](#Format-Changes)
|
||||||
|
* [Negative UNL maintenance](#Negative-UNL-Maintenance)
|
||||||
|
* [Quorum size calculation](#Quorum-Size-Calculation)
|
||||||
|
* [Filter validation messages](#Filter-Validation-Messages)
|
||||||
|
* [High level sequence diagram of code
|
||||||
|
changes](#High-Level-Sequence-Diagram-of-Code-Changes)
|
||||||
|
|
||||||
|
### Negative UNL Protocol Overview
|
||||||
|
|
||||||
|
Every ledger stores a list of zero or more unreliable validators. Updates to the
|
||||||
|
list must be approved by the validators using the consensus mechanism that
|
||||||
|
validators use to agree on the set of transactions. The list is used only when
|
||||||
|
checking if a ledger is fully validated. If a validator V is in the list, nodes
|
||||||
|
with V in their UNL adjust the quorum and V’s validation message is not counted
|
||||||
|
when verifying if a ledger is fully validated. V’s flow of messages and network
|
||||||
|
interactions, however, will remain the same.
|
||||||
|
|
||||||
|
We define the ***effective UNL** = original UNL - negative UNL*, and the
|
||||||
|
***effective quorum*** as the quorum of the *effective UNL*. And we set
|
||||||
|
*effective quorum = Ceiling(80% * effective UNL)*.
|
||||||
|
|
||||||
|
### Validator Reliability Measurement
|
||||||
|
|
||||||
|
A node only measures the reliability of validators on its own UNL, and only
|
||||||
|
proposes based on local observations. There are many metrics that a node can
|
||||||
|
measure about its validators, but we have chosen ledger validation messages.
|
||||||
|
This is because every validator shall send one and only one signed validation
|
||||||
|
message per ledger. This keeps the measurement simple and removes
|
||||||
|
timing/clock-sync issues. A node will measure the percentage of agreeing
|
||||||
|
validation messages (*PAV*) received from each validator on the node's UNL. Note
|
||||||
|
that the node will only count the validation messages that agree with its own
|
||||||
|
validations.
|
||||||
|
|
||||||
|
We define the **PAV** as the **P**ercentage of **A**greed **V**alidation
|
||||||
|
messages received for the last N ledgers, where N = 256 by default.
|
||||||
|
|
||||||
|
When the PAV drops below the ***low-water mark***, the validator is considered
|
||||||
|
unreliable, and is a candidate to be disabled by being added to the negative
|
||||||
|
UNL. A validator must have a PAV higher than the ***high-water mark*** to be
|
||||||
|
re-enabled. The validator is re-enabled by removing it from the negative UNL. In
|
||||||
|
the implementation, we plan to set the low-water mark as 50% and the high-water
|
||||||
|
mark as 80%.
|
||||||
|
|
||||||
|
### Format Changes
|
||||||
|
|
||||||
|
The negative UNL component in a ledger contains three fields.
|
||||||
|
* ***NegativeUNL***: The current negative UNL, a list of unreliable validators.
|
||||||
|
* ***ToDisable***: The validator to be added to the negative UNL on the next
|
||||||
|
flag ledger.
|
||||||
|
* ***ToReEnable***: The validator to be removed from the negative UNL on the
|
||||||
|
next flag ledger.
|
||||||
|
|
||||||
|
All three fields are optional. When the *ToReEnable* field exists, the
|
||||||
|
*NegativeUNL* field cannot be empty.
|
||||||
|
|
||||||
|
A new pseudo-transaction, ***UNLModify***, is added. It has three fields
|
||||||
|
* ***Disabling***: A flag indicating whether the modification is to disable or
|
||||||
|
to re-enable a validator.
|
||||||
|
* ***Seq***: The ledger sequence number.
|
||||||
|
* ***Validator***: The validator to be disabled or re-enabled.
|
||||||
|
|
||||||
|
There would be at most one *disable* `UNLModify` and one *re-enable* `UNLModify`
|
||||||
|
transaction per flag ledger. The full machinery is described further on.
|
||||||
|
|
||||||
|
### Negative UNL Maintenance
|
||||||
|
|
||||||
|
The negative UNL can only be modified on the flag ledgers. If a validator's
|
||||||
|
reliability status changes, it takes two flag ledgers to modify the negative
|
||||||
|
UNL. Let's see an example of the algorithm:
|
||||||
|
|
||||||
|
* Ledger seq = 100: A validator V goes offline.
|
||||||
|
* Ledger seq = 256: This is a flag ledger, and V's reliability measurement *PAV*
|
||||||
|
is lower than the low-water mark. Other validators add `UNLModify`
|
||||||
|
pseudo-transactions `{true, 256, V}` to the transaction set which goes through
|
||||||
|
the consensus. Then the pseudo-transaction is applied to the negative UNL
|
||||||
|
ledger component by setting `ToDisable = V`.
|
||||||
|
* Ledger seq = 257 ~ 511: The negative UNL ledger component is copied from the
|
||||||
|
parent ledger.
|
||||||
|
* Ledger seq=512: This is a flag ledger, and the negative UNL is updated
|
||||||
|
`NegativeUNL = NegativeUNL + ToDisable`.
|
||||||
|
|
||||||
|
The negative UNL may have up to `MaxNegativeListed = floor(original UNL * 25%)`
|
||||||
|
validators. The 25% is because of 75% * 80% = 60%, where 75% = 100% - 25%, 80%
|
||||||
|
is the quorum of the effective UNL, and 60% is the absolute minimum quorum of
|
||||||
|
the original UNL. Adding more than 25% validators to the negative UNL does not
|
||||||
|
improve the liveness of the network, because adding more validators to the
|
||||||
|
negative UNL cannot lower the effective quorum.
|
||||||
|
|
||||||
|
The following is the detailed algorithm:
|
||||||
|
|
||||||
|
* **If** the ledger seq = x is a flag ledger
|
||||||
|
|
||||||
|
1. Compute `NegativeUNL = NegativeUNL + ToDisable - ToReEnable` if they
|
||||||
|
exist in the parent ledger
|
||||||
|
|
||||||
|
1. Try to find a candidate to disable if `sizeof NegativeUNL < MaxNegativeListed`
|
||||||
|
|
||||||
|
1. Find a validator V that has a *PAV* lower than the low-water
|
||||||
|
mark, but is not in `NegativeUNL`.
|
||||||
|
|
||||||
|
1. If two or more are found, their public keys are XORed with the hash
|
||||||
|
of the parent ledger and the one with the lowest XOR result is chosen.
|
||||||
|
|
||||||
|
1. If V is found, create a `UNLModify` pseudo-transaction
|
||||||
|
`TxDisableValidator = {true, x, V}`
|
||||||
|
|
||||||
|
1. Try to find a candidate to re-enable if `sizeof NegativeUNL > 0`:
|
||||||
|
|
||||||
|
1. Find a validator U that is in `NegativeUNL` and has a *PAV* higher
|
||||||
|
than the high-water mark.
|
||||||
|
|
||||||
|
1. If U is not found, try to find one in `NegativeUNL` but not in the
|
||||||
|
local *UNL*.
|
||||||
|
|
||||||
|
1. If two or more are found, their public keys are XORed with the hash
|
||||||
|
of the parent ledger and the one with the lowest XOR result is chosen.
|
||||||
|
|
||||||
|
1. If U is found, create a `UNLModify` pseudo-transaction
|
||||||
|
`TxReEnableValidator = {false, x, U}`
|
||||||
|
|
||||||
|
1. If any `UNLModify` pseudo-transactions are created, add them to the
|
||||||
|
transaction set. The transaction set goes through the consensus algorithm.
|
||||||
|
|
||||||
|
1. If have enough support, the `UNLModify` pseudo-transactions remain in the
|
||||||
|
transaction set agreed by the validators. Then the pseudo-transactions are
|
||||||
|
applied to the ledger:
|
||||||
|
|
||||||
|
1. If have `TxDisableValidator`, set `ToDisable=TxDisableValidator.V`.
|
||||||
|
Else clear `ToDisable`.
|
||||||
|
|
||||||
|
1. If have `TxReEnableValidator`, set
|
||||||
|
`ToReEnable=TxReEnableValidator.U`. Else clear `ToReEnable`.
|
||||||
|
|
||||||
|
* **Else** (not a flag ledger)
|
||||||
|
|
||||||
|
1. Copy the negative UNL ledger component from the parent ledger
|
||||||
|
|
||||||
|
The negative UNL is stored on each ledger because we don't know when a validator
|
||||||
|
may reconnect to the network. If the negative UNL was stored only on every flag
|
||||||
|
ledger, then a new validator would have to wait until it acquires the latest
|
||||||
|
flag ledger to know the negative UNL. So any new ledgers created that are not
|
||||||
|
flag ledgers copy the negative UNL from the parent ledger.
|
||||||
|
|
||||||
|
Note that when we have a validator to disable and a validator to re-enable at
|
||||||
|
the same flag ledger, we create two separate `UNLModify` pseudo-transactions. We
|
||||||
|
want either one or the other or both to make it into the ledger on their own
|
||||||
|
merits.
|
||||||
|
|
||||||
|
Readers may have noticed that we defined several rules of creating the
|
||||||
|
`UNLModify` pseudo-transactions but did not describe how to enforce the rules.
|
||||||
|
The rules are actually enforced by the existing consensus algorithm. Unless
|
||||||
|
enough validators propose the same pseudo-transaction it will not be included in
|
||||||
|
the transaction set of the ledger.
|
||||||
|
|
||||||
|
### Quorum Size Calculation
|
||||||
|
|
||||||
|
The effective quorum is 80% of the effective UNL. Note that because at most 25%
|
||||||
|
of the original UNL can be on the negative UNL, the quorum should not be lower
|
||||||
|
than the absolute minimum quorum (i.e. 60%) of the original UNL. However,
|
||||||
|
considering that different nodes may have different UNLs, to be safe we compute
|
||||||
|
`quorum = Ceiling(max(60% * original UNL, 80% * effective UNL))`.
|
||||||
|
|
||||||
|
### Filter Validation Messages
|
||||||
|
|
||||||
|
If a validator V is in the negative UNL, it still participates in consensus
|
||||||
|
sessions in the same way, i.e. V still follows the protocol and publishes
|
||||||
|
proposal and validation messages. The messages from V are still stored the same
|
||||||
|
way by everyone, used to calculate the new PAV for V, and could be used in
|
||||||
|
future consensus sessions if needed. However V's ledger validation message is
|
||||||
|
not counted when checking if the ledger is fully validated.
|
||||||
|
|
||||||
|
### High Level Sequence Diagram of Code Changes
|
||||||
|
|
||||||
|
The diagram below is the sequence of one round of consensus. Classes and
|
||||||
|
components with non-trivial changes are colored green.
|
||||||
|
|
||||||
|
* The `ValidatorList` class is modified to compute the quorum of the effective
|
||||||
|
UNL.
|
||||||
|
|
||||||
|
* The `Validations` class provides an interface for querying the validation
|
||||||
|
messages from trusted validators.
|
||||||
|
|
||||||
|
* The `ConsensusAdaptor` component:
|
||||||
|
|
||||||
|
* The `RCLConsensus::Adaptor` class is modified for creating `UNLModify`
|
||||||
|
Pseudo-Transactions.
|
||||||
|
|
||||||
|
* The `Change` class is modified for applying `UNLModify`
|
||||||
|
Pseudo-Transactions.
|
||||||
|
|
||||||
|
* The `Ledger` class is modified for creating and adjusting the negative UNL
|
||||||
|
ledger component.
|
||||||
|
|
||||||
|
* The `LedgerMaster` class is modified for filtering out validation messages
|
||||||
|
from negative UNL validators when verifying if a ledger is fully
|
||||||
|
validated.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Roads Not Taken
|
||||||
|
|
||||||
|
### Use a Mechanism Like Fee Voting to Process UNLModify Pseudo-Transactions
|
||||||
|
|
||||||
|
The previous version of the negative UNL specification used the same mechanism
|
||||||
|
as the [fee voting](https://xrpl.org/fee-voting.html#voting-process.) for
|
||||||
|
creating the negative UNL, and used the negative UNL as soon as the ledger was
|
||||||
|
fully validated. However the timing of fully validation can differ among nodes,
|
||||||
|
so different negative UNLs could be used, resulting in different effective UNLs
|
||||||
|
and different quorums for the same ledger. As a result, the network's safety is
|
||||||
|
impacted.
|
||||||
|
|
||||||
|
This updated version does not impact safety though operates a bit more slowly.
|
||||||
|
The negative UNL modifications in the *UNLModify* pseudo-transaction approved by
|
||||||
|
the consensus will take effect at the next flag ledger. The extra time of the
|
||||||
|
256 ledgers should be enough for nodes to be in sync of the negative UNL
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
### Use an Expiration Approach to Re-enable Validators
|
||||||
|
|
||||||
|
After a validator disabled by the negative UNL becomes reliable, other
|
||||||
|
validators explicitly vote for re-enabling it. An alternative approach to
|
||||||
|
re-enable a validator is the expiration approach, which was considered in the
|
||||||
|
previous version of the specification. In the expiration approach, every entry
|
||||||
|
in the negative UNL has a fixed expiration time. One flag ledger interval was
|
||||||
|
chosen as the expiration interval. Once expired, the other validators must
|
||||||
|
continue voting to keep the unreliable validator on the negative UNL. The
|
||||||
|
advantage of this approach is its simplicity. But it has a requirement. The
|
||||||
|
negative UNL protocol must be able to vote multiple unreliable validators to be
|
||||||
|
disabled at the same flag ledger. In this version of the specification, however,
|
||||||
|
only one unreliable validator can be disabled at a flag ledger. So the
|
||||||
|
expiration approach cannot be simply applied.
|
||||||
|
|
||||||
|
### Validator Reliability Measurement and Flag Ledger Frequency
|
||||||
|
|
||||||
|
If the ledger time is about 4.5 seconds and the low-water mark is 50%, then in
|
||||||
|
the worst case, it takes 48 minutes *((0.5 * 256 + 256 + 256) * 4.5 / 60 = 48)*
|
||||||
|
to put an offline validator on the negative UNL. We considered lowering the flag
|
||||||
|
ledger frequency so that the negative UNL can be more responsive. We also
|
||||||
|
considered decoupling the reliability measurement and flag ledger frequency to
|
||||||
|
be more flexible. In practice, however, their benefits are not clear.
|
||||||
|
|
||||||
|
|
||||||
|
## New Attack Vectors
|
||||||
|
|
||||||
|
A group of malicious validators may try to frame a reliable validator and put it
|
||||||
|
on the negative UNL. But they cannot succeed. Because:
|
||||||
|
|
||||||
|
1. A reliable validator sends a signed validation message every ledger. A
|
||||||
|
sufficient peer-to-peer network will propagate the validation messages to other
|
||||||
|
validators. The validators will decide if another validator is reliable or not
|
||||||
|
only by its local observation of the validation messages received. So an honest
|
||||||
|
validator’s vote on another validator’s reliability is accurate.
|
||||||
|
|
||||||
|
1. Given the votes are accurate, and one vote per validator, an honest validator
|
||||||
|
will not create a UNLModify transaction of a reliable validator.
|
||||||
|
|
||||||
|
1. A validator can be added to a negative UNL only through a UNLModify
|
||||||
|
transaction.
|
||||||
|
|
||||||
|
Assuming the group of malicious validators is less than the quorum, they cannot
|
||||||
|
frame a reliable validator.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
The bullet points below briefly summarize the current proposal:
|
||||||
|
|
||||||
|
* The motivation of the negative UNL is to improve the liveness of the network.
|
||||||
|
|
||||||
|
* The targeted faults are the ones frequently observed in the production
|
||||||
|
network.
|
||||||
|
|
||||||
|
* Validators propose negative UNL candidates based on their local measurements.
|
||||||
|
|
||||||
|
* The absolute minimum quorum is 60% of the original UNL.
|
||||||
|
|
||||||
|
* The format of the ledger is changed, and a new *UNLModify* pseudo-transaction
|
||||||
|
is added. Any tools or systems that rely on the format of these data will have
|
||||||
|
to be updated.
|
||||||
|
|
||||||
|
* The negative UNL can only be modified on the flag ledgers.
|
||||||
|
|
||||||
|
* At most one validator can be added to the negative UNL at a flag ledger.
|
||||||
|
|
||||||
|
* At most one validator can be removed from the negative UNL at a flag ledger.
|
||||||
|
|
||||||
|
* If a validator's reliability status changes, it takes two flag ledgers to
|
||||||
|
modify the negative UNL.
|
||||||
|
|
||||||
|
* The quorum is the larger of 80% of the effective UNL and 60% of the original
|
||||||
|
UNL.
|
||||||
|
|
||||||
|
* If a validator is on the negative UNL, its validation messages are ignored
|
||||||
|
when the local node verifies if a ledger is fully validated.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Question: What are UNLs?
|
||||||
|
|
||||||
|
Quote from the [Technical FAQ](https://xrpl.org/technical-faq.html): "They are
|
||||||
|
the lists of transaction validators a given participant believes will not
|
||||||
|
conspire to defraud them."
|
||||||
|
|
||||||
|
### Question: How does the negative UNL proposal affect network liveness?
|
||||||
|
|
||||||
|
The network can make forward progress when more than a quorum of the trusted
|
||||||
|
validators agree with the progress. The lower the quorum size is, the easier for
|
||||||
|
the network to progress. If the quorum is too low, however, the network is not
|
||||||
|
safe because nodes may have different results. So the quorum size used in the
|
||||||
|
consensus protocol is a balance between the safety and the liveness of the
|
||||||
|
network. The negative UNL reduces the size of the effective UNL, resulting in a
|
||||||
|
lower quorum size while keeping the network safe.
|
||||||
|
|
||||||
|
<h3> Question: How does a validator get into the negative UNL? How is a
|
||||||
|
validator removed from the negative UNL? </h3>
|
||||||
|
|
||||||
|
A validator’s reliability is measured by other validators. If a validator
|
||||||
|
becomes unreliable, at a flag ledger, other validators propose *UNLModify*
|
||||||
|
pseudo-transactions which vote the validator to add to the negative UNL during
|
||||||
|
the consensus session. If agreed, the validator is added to the negative UNL at
|
||||||
|
the next flag ledger. The mechanism of removing a validator from the negative
|
||||||
|
UNL is the same.
|
||||||
|
|
||||||
|
### Question: Given a negative UNL, what happens if the UNL changes?
|
||||||
|
|
||||||
|
Answer: Let’s consider the cases:
|
||||||
|
|
||||||
|
1. A validator is added to the UNL, and it is already in the negative UNL. This
|
||||||
|
case could happen when not all the nodes have the same UNL. Note that the
|
||||||
|
negative UNL on the ledger lists unreliable nodes that are not necessarily the
|
||||||
|
validators for everyone.
|
||||||
|
|
||||||
|
In this case, the liveness is affected negatively. Because the minimum
|
||||||
|
quorum could be larger but the usable validators are not increased.
|
||||||
|
|
||||||
|
1. A validator is removed from the UNL, and it is in the negative UNL.
|
||||||
|
|
||||||
|
In this case, the liveness is affected positively. Because the quorum could
|
||||||
|
be smaller but the usable validators are not reduced.
|
||||||
|
|
||||||
|
1. A validator is added to the UNL, and it is not in the negative UNL.
|
||||||
|
1. A validator is removed from the UNL, and it is not in the negative UNL.
|
||||||
|
|
||||||
|
Case 3 and 4 are not affected by the negative UNL protocol.
|
||||||
|
|
||||||
|
### Question: Can we simply lower the quorum to 60% without the negative UNL?
|
||||||
|
|
||||||
|
Answer: No, because the negative UNL approach is safer.
|
||||||
|
|
||||||
|
First let’s compare the two approaches intuitively, (1) the *negative UNL*
|
||||||
|
approach, and (2) *lower quorum*: simply lowering the quorum from 80% to 60%
|
||||||
|
without the negative UNL. The negative UNL approach uses consensus to come up
|
||||||
|
with a list of unreliable validators, which are then removed from the effective
|
||||||
|
UNL temporarily. With this approach, the list of unreliable validators is agreed
|
||||||
|
to by a quorum of validators and will be used by every node in the network to
|
||||||
|
adjust its UNL. The quorum is always 80% of the effective UNL. The lower quorum
|
||||||
|
approach is a tradeoff between safety and liveness and against our principle of
|
||||||
|
preferring safety over liveness. Note that different validators don't have to
|
||||||
|
agree on which validation sources they are ignoring.
|
||||||
|
|
||||||
|
Next we compare the two approaches quantitatively with examples, and apply
|
||||||
|
Theorem 8 of [Analysis of the XRP Ledger Consensus
|
||||||
|
Protocol](https://arxiv.org/abs/1802.07242) paper:
|
||||||
|
|
||||||
|
*XRP LCP guarantees fork safety if **O<sub>i,j</sub> > n<sub>j</sub> / 2 +
|
||||||
|
n<sub>i</sub> − q<sub>i</sub> + t<sub>i,j</sub>** for every pair of nodes
|
||||||
|
P<sub>i</sub>, P<sub>j</sub>,*
|
||||||
|
|
||||||
|
where *O<sub>i,j</sub>* is the overlapping requirement, n<sub>j</sub> and
|
||||||
|
n<sub>i</sub> are UNL sizes, q<sub>i</sub> is the quorum size of P<sub>i</sub>,
|
||||||
|
*t<sub>i,j</sub> = min(t<sub>i</sub>, t<sub>j</sub>, O<sub>i,j</sub>)*, and
|
||||||
|
t<sub>i</sub> and t<sub>j</sub> are the number of faults can be tolerated by
|
||||||
|
P<sub>i</sub> and P<sub>j</sub>.
|
||||||
|
|
||||||
|
We denote *UNL<sub>i</sub>* as *P<sub>i</sub>'s UNL*, and *|UNL<sub>i</sub>|* as
|
||||||
|
the size of *P<sub>i</sub>'s UNL*.
|
||||||
|
|
||||||
|
Assuming *|UNL<sub>i</sub>| = |UNL<sub>j</sub>|*, let's consider the following
|
||||||
|
three cases:
|
||||||
|
|
||||||
|
1. With 80% quorum and 20% faults, *O<sub>i,j</sub> > 100% / 2 + 100% - 80% +
|
||||||
|
20% = 90%*. I.e. fork safety requires > 90% UNL overlaps. This is one of the
|
||||||
|
results in the analysis paper.
|
||||||
|
|
||||||
|
1. If the quorum is 60%, the relationship between the overlapping requirement
|
||||||
|
and the faults that can be tolerated is *O<sub>i,j</sub> > 90% +
|
||||||
|
t<sub>i,j</sub>*. Under the same overlapping condition (i.e. 90%), to guarantee
|
||||||
|
the fork safety, the network cannot tolerate any faults. So under the same
|
||||||
|
overlapping condition, if the quorum is simply lowered, the network can tolerate
|
||||||
|
fewer faults.
|
||||||
|
|
||||||
|
1. With the negative UNL approach, we want to argue that the inequation
|
||||||
|
*O<sub>i,j</sub> > n<sub>j</sub> / 2 + n<sub>i</sub> − q<sub>i</sub> +
|
||||||
|
t<sub>i,j</sub>* is always true to guarantee fork safety, while the negative UNL
|
||||||
|
protocol runs, i.e. the effective quorum is lowered without weakening the
|
||||||
|
network's fault tolerance. To make the discussion easier, we rewrite the
|
||||||
|
inequation as *O<sub>i,j</sub> > n<sub>j</sub> / 2 + (n<sub>i</sub> −
|
||||||
|
q<sub>i</sub>) + min(t<sub>i</sub>, t<sub>j</sub>)*, where O<sub>i,j</sub> is
|
||||||
|
dropped from the definition of t<sub>i,j</sub> because *O<sub>i,j</sub> >
|
||||||
|
min(t<sub>i</sub>, t<sub>j</sub>)* always holds under the parameters we will
|
||||||
|
use. Assuming a validator V is added to the negative UNL, now let's consider the
|
||||||
|
4 cases:
|
||||||
|
|
||||||
|
1. V is not on UNL<sub>i</sub> nor UNL<sub>j</sub>
|
||||||
|
|
||||||
|
The inequation holds because none of the variables change.
|
||||||
|
|
||||||
|
1. V is on UNL<sub>i</sub> but not on UNL<sub>j</sub>
|
||||||
|
|
||||||
|
The value of *(n<sub>i</sub> − q<sub>i</sub>)* is smaller. The value of
|
||||||
|
*min(t<sub>i</sub>, t<sub>j</sub>)* could be smaller too. Other
|
||||||
|
variables do not change. Overall, the left side of the inequation does
|
||||||
|
not change, but the right side is smaller. So the inequation holds.
|
||||||
|
|
||||||
|
1. V is not on UNL<sub>i</sub> but on UNL<sub>j</sub>
|
||||||
|
|
||||||
|
The value of *n<sub>j</sub> / 2* is smaller. The value of
|
||||||
|
*min(t<sub>i</sub>, t<sub>j</sub>)* could be smaller too. Other
|
||||||
|
variables do not change. Overall, the left side of the inequation does
|
||||||
|
not change, but the right side is smaller. So the inequation holds.
|
||||||
|
|
||||||
|
1. V is on both UNL<sub>i</sub> and UNL<sub>j</sub>
|
||||||
|
|
||||||
|
The value of *O<sub>i,j</sub>* is reduced by 1. The values of
|
||||||
|
*n<sub>j</sub> / 2*, *(n<sub>i</sub> − q<sub>i</sub>)*, and
|
||||||
|
*min(t<sub>i</sub>, t<sub>j</sub>)* are reduced by 0.5, 0.2, and 1
|
||||||
|
respectively. The right side is reduced by 1.7. Overall, the left side
|
||||||
|
of the inequation is reduced by 1, and the right side is reduced by 1.7.
|
||||||
|
So the inequation holds.
|
||||||
|
|
||||||
|
The inequation holds for all the cases. So with the negative UNL approach,
|
||||||
|
the network's fork safety is preserved, while the quorum is lowered that
|
||||||
|
increases the network's liveness.
|
||||||
|
|
||||||
|
<h3> Question: We have observed that occasionally a validator wanders off on its
|
||||||
|
own chain. How is this case handled by the negative UNL algorithm? </h3>
|
||||||
|
|
||||||
|
Answer: The case that a validator wanders off on its own chain can be measured
|
||||||
|
with the validations agreement. Because the validations by this validator must
|
||||||
|
be different from other validators' validations of the same sequence numbers.
|
||||||
|
When there are enough disagreed validations, other validators will vote this
|
||||||
|
validator onto the negative UNL.
|
||||||
|
|
||||||
|
In general by measuring the agreement of validations, we also measured the
|
||||||
|
"sanity". If two validators have too many disagreements, one of them could be
|
||||||
|
insane. When enough validators think a validator is insane, that validator is
|
||||||
|
put on the negative UNL.
|
||||||
|
|
||||||
|
<h3> Question: Why would there be at most one disable UNLModify and one
|
||||||
|
re-enable UNLModify transaction per flag ledger? </h3>
|
||||||
|
|
||||||
|
Answer: It is a design choice so that the effective UNL does not change too
|
||||||
|
quickly. A typical targeted scenario is several validators go offline slowly
|
||||||
|
during a long weekend. The current design can handle this kind of cases well
|
||||||
|
without changing the effective UNL too quickly.
|
||||||
|
|
||||||
|
## Appendix
|
||||||
|
|
||||||
|
### Confidence Test
|
||||||
|
|
||||||
|
We will use two test networks, a single machine test network with multiple IP
|
||||||
|
addresses and the QE test network with multiple machines. The single machine
|
||||||
|
network will be used to test all the test cases and to debug. The QE network
|
||||||
|
will be used after that. We want to see the test cases still pass with real
|
||||||
|
network delay. A test case specifies:
|
||||||
|
|
||||||
|
1. a UNL with different number of validators for different test cases,
|
||||||
|
1. a network with zero or more non-validator nodes,
|
||||||
|
1. a sequence of validator reliability change events (by killing/restarting
|
||||||
|
nodes, or by running modified rippled that does not send all validation
|
||||||
|
messages),
|
||||||
|
1. the correct outcomes.
|
||||||
|
|
||||||
|
For all the test cases, the correct outcomes are verified by examining logs. We
|
||||||
|
will grep the log to see if the correct negative UNLs are generated, and whether
|
||||||
|
or not the network is making progress when it should be. The ripdtop tool will
|
||||||
|
be helpful for monitoring validators' states and ledger progress. Some of the
|
||||||
|
timing parameters of rippled will be changed to have faster ledger time. Most if
|
||||||
|
not all test cases do not need client transactions.
|
||||||
|
|
||||||
|
For example, the test cases for the prototype:
|
||||||
|
1. A 10-validator UNL.
|
||||||
|
1. The network does not have other nodes.
|
||||||
|
1. The validators will be started from the genesis. Once they start to produce
|
||||||
|
ledgers, we kill five validators, one every flag ledger interval. Then we
|
||||||
|
will restart them one by one.
|
||||||
|
1. A sequence of events (or the lack of events) such as a killed validator is
|
||||||
|
added to the negative UNL.
|
||||||
|
|
||||||
|
#### Roads Not Taken: Test with Extended CSF
|
||||||
|
|
||||||
|
We considered testing with the current unit test framework, specifically the
|
||||||
|
[Consensus Simulation
|
||||||
|
Framework](https://github.com/ripple/rippled/blob/develop/src/test/csf/README.md)
|
||||||
|
(CSF). However, the CSF currently can only test the generic consensus algorithm
|
||||||
|
as in the paper: [Analysis of the XRP Ledger Consensus
|
||||||
|
Protocol](https://arxiv.org/abs/1802.07242).
|
||||||
79
docs/0001-negative-unl/negativeUNLSqDiagram.puml
Normal file
79
docs/0001-negative-unl/negativeUNLSqDiagram.puml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
@startuml negativeUNL_highLevel_sequence
|
||||||
|
|
||||||
|
skinparam sequenceArrowThickness 2
|
||||||
|
skinparam roundcorner 20
|
||||||
|
skinparam maxmessagesize 160
|
||||||
|
|
||||||
|
actor "Rippled Start" as RS
|
||||||
|
participant "Timer" as T
|
||||||
|
participant "NetworkOPs" as NOP
|
||||||
|
participant "ValidatorList" as VL #lightgreen
|
||||||
|
participant "Consensus" as GC
|
||||||
|
participant "ConsensusAdaptor" as CA #lightgreen
|
||||||
|
participant "Validations" as RM #lightgreen
|
||||||
|
|
||||||
|
RS -> NOP: begin consensus
|
||||||
|
activate NOP
|
||||||
|
NOP -[#green]> VL: <font color=green>update negative UNL
|
||||||
|
hnote over VL#lightgreen: store a copy of\nnegative UNL
|
||||||
|
VL -> NOP
|
||||||
|
NOP -> VL: update trusted validators
|
||||||
|
activate VL
|
||||||
|
VL -> VL: re-calculate quorum
|
||||||
|
hnote over VL#lightgreen: ignore negative listed validators\nwhen calculate quorum
|
||||||
|
VL -> NOP
|
||||||
|
deactivate VL
|
||||||
|
NOP -> GC: start round
|
||||||
|
activate GC
|
||||||
|
GC -> GC: phase = OPEN
|
||||||
|
GC -> NOP
|
||||||
|
deactivate GC
|
||||||
|
deactivate NOP
|
||||||
|
|
||||||
|
loop at regular frequency
|
||||||
|
T -> GC: timerEntry
|
||||||
|
activate GC
|
||||||
|
end
|
||||||
|
|
||||||
|
alt phase == OPEN
|
||||||
|
alt should close ledger
|
||||||
|
GC -> GC: phase = ESTABLISH
|
||||||
|
GC -> CA: onClose
|
||||||
|
activate CA
|
||||||
|
alt sqn%256==0
|
||||||
|
CA -[#green]> RM: <font color=green>getValidations
|
||||||
|
CA -[#green]> CA: <font color=green>create UNLModify Tx
|
||||||
|
hnote over CA#lightgreen: use validatations of the last 256 ledgers\nto figure out UNLModify Tx candidates.\nIf any, create UNLModify Tx, and add to TxSet.
|
||||||
|
end
|
||||||
|
CA -> GC
|
||||||
|
GC -> CA: propose
|
||||||
|
deactivate CA
|
||||||
|
end
|
||||||
|
else phase == ESTABLISH
|
||||||
|
hnote over GC: receive peer postions
|
||||||
|
GC -> GC : update our position
|
||||||
|
GC -> CA : propose \n(if position changed)
|
||||||
|
GC -> GC : check if have consensus
|
||||||
|
alt consensus reached
|
||||||
|
GC -> GC: phase = ACCEPT
|
||||||
|
GC -> CA : onAccept
|
||||||
|
activate CA
|
||||||
|
CA -> CA : build LCL
|
||||||
|
hnote over CA #lightgreen: copy negative UNL from parent ledger
|
||||||
|
alt sqn%256==0
|
||||||
|
CA -[#green]> CA: <font color=green>Adjust negative UNL
|
||||||
|
CA -[#green]> CA: <font color=green>apply UNLModify Tx
|
||||||
|
end
|
||||||
|
CA -> CA : validate and send validation message
|
||||||
|
activate NOP
|
||||||
|
CA -> NOP : end consensus and\n<b>begin next consensus round
|
||||||
|
deactivate NOP
|
||||||
|
deactivate CA
|
||||||
|
hnote over RM: receive validations
|
||||||
|
end
|
||||||
|
else phase == ACCEPTED
|
||||||
|
hnote over GC: timerEntry hash nothing to do at this phase
|
||||||
|
end
|
||||||
|
deactivate GC
|
||||||
|
|
||||||
|
@enduml
|
||||||
BIN
docs/0001-negative-unl/negativeUNL_highLevel_sequence.png
Normal file
BIN
docs/0001-negative-unl/negativeUNL_highLevel_sequence.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 138 KiB |
88
docs/0010-ledger-replay/README.md
Normal file
88
docs/0010-ledger-replay/README.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Ledger Replay
|
||||||
|
|
||||||
|
`LedgerReplayer` is a new `Stoppable` for replaying ledgers.
|
||||||
|
Patterned after two other `Stoppable`s under `JobQueue`---`InboundLedgers`
|
||||||
|
and `InboundTransactions`---it acts like a factory for creating
|
||||||
|
state-machine workers, and a network message demultiplexer for those workers.
|
||||||
|
Think of these workers like asynchronous functions.
|
||||||
|
Like functions, they each take a set of parameters.
|
||||||
|
The `Stoppable` memoizes these functions. It maintains a table for each
|
||||||
|
worker type, mapping sets of arguments to the worker currently working
|
||||||
|
on that argument set.
|
||||||
|
Whenever the `Stoppable` is asked to construct a worker, it first searches its
|
||||||
|
table to see if there is an existing worker with the same or overlapping
|
||||||
|
argument set.
|
||||||
|
If one exists, then it is used. If not, then a new one is created,
|
||||||
|
initialized, and added to the table.
|
||||||
|
|
||||||
|
For `LedgerReplayer`, there are three worker types: `LedgerReplayTask`,
|
||||||
|
`SkipListAcquire`, and `LedgerDeltaAcquire`.
|
||||||
|
Each is derived from `TimeoutCounter` to give it a timeout.
|
||||||
|
For `LedgerReplayTask`, the parameter set
|
||||||
|
is {reason, finish ledger ID, number of ledgers}. For `SkipListAcquire` and
|
||||||
|
`LedgerDeltaAcquire`, there is just one parameter: a ledger ID.
|
||||||
|
|
||||||
|
Each `Stoppable` has an entry point. For `LedgerReplayer`, it is `replay`.
|
||||||
|
`replay` creates two workers: a `LedgerReplayTask` and a `SkipListAcquire`.
|
||||||
|
`LedgerDeltaAcquire`s are created in the callback for when the skip list
|
||||||
|
returns.
|
||||||
|
|
||||||
|
For `SkipListAcquire` and `LedgerDeltaAcquire`, initialization fires off the
|
||||||
|
underlying asynchronous network request and starts the timeout. The argument
|
||||||
|
set identifying the worker is included in the network request, and copied to
|
||||||
|
the network response. `SkipListAcquire` sends a request for a proof path for
|
||||||
|
the skip list of the desired ledger. `LedgerDeltaAcquire` sends a request for
|
||||||
|
the transaction set of the desired ledger.
|
||||||
|
|
||||||
|
`LedgerReplayer` is also a network message demultiplexer.
|
||||||
|
When a response arrives for a request that was sent by a `SkipListAcquire` or
|
||||||
|
`LedgerDeltaAcquire` worker, the `Peer` object knows to send it to the
|
||||||
|
`LedgerReplayer`, which looks up the worker waiting for that response based on
|
||||||
|
the identifying argument set included in the response.
|
||||||
|
|
||||||
|
`LedgerReplayTask` may ask `InboundLedgers` to send requests to acquire
|
||||||
|
the start ledger, but there is no way to attach a callback or be notified when
|
||||||
|
the `InboundLedger` worker completes. All the responses for its messages will
|
||||||
|
be directed to `InboundLedgers`, not `LedgerReplayer`. Instead,
|
||||||
|
`LedgerReplayTask` checks whether the start ledger has arrived every time its
|
||||||
|
timeout expires.
|
||||||
|
|
||||||
|
Like a promise, each worker keeps track of whether it is pending (`!isDone()`)
|
||||||
|
or whether it has resolved successfully (`complete_ == true`) or unsuccessfully
|
||||||
|
(`failed_ == true`). It will never exist in both resolved states at once, nor
|
||||||
|
will it return to a pending state after reaching a resolved state.
|
||||||
|
|
||||||
|
Like promises, some workers can accept continuations to be called when they
|
||||||
|
reach a resolved state, or immediately if they are already resolved.
|
||||||
|
`SkipListAcquire` and `LedgerDeltaAcquire` both accept continuations of a type
|
||||||
|
specific to their payload, both via a method named `addDataCallback()`. Continuations
|
||||||
|
cannot be removed explicitly, but they are held by `std::weak_ptr` so they can
|
||||||
|
be removed implicitly.
|
||||||
|
|
||||||
|
`LedgerReplayTask` is simultaneously:
|
||||||
|
|
||||||
|
1. an asynchronous function,
|
||||||
|
1. a continuation to one `SkipListAcquire` asynchronous function,
|
||||||
|
1. a continuation to zero or more `LedgerDeltaAcquire` asynchronous functions, and
|
||||||
|
1. a continuation to its own timeout.
|
||||||
|
|
||||||
|
Each of these roles corresponds to different entry points:
|
||||||
|
|
||||||
|
1. `init()`
|
||||||
|
1. the callback added to `SkipListAcquire`, which calls `updateSkipList(...)` or `cancel()`
|
||||||
|
1. the callback added to `LedgerDeltaAcquire`, which calls `deltaReady(...)` or `cancel()`
|
||||||
|
1. `onTimer()`
|
||||||
|
|
||||||
|
Each of these entry points does something unique to that entry point. They
|
||||||
|
either (a) transition `LedgerReplayTask` to a terminal failed resolved state
|
||||||
|
(`cancel()` and `onTimer()`) or (b) try to make progress toward the successful
|
||||||
|
resolved state. `init()` and `updateSkipList(...)` call `trigger()` while
|
||||||
|
`deltaReady(...)` calls `tryAdvance()`. There's a similarity between this
|
||||||
|
pattern and the way coroutines are implemented, where every yield saves the spot
|
||||||
|
in the code where it left off and every resume jumps back to that spot.
|
||||||
|
|
||||||
|
### Sequence Diagram
|
||||||
|

|
||||||
|
|
||||||
|
### Class Diagram
|
||||||
|

|
||||||
BIN
docs/0010-ledger-replay/ledger_replay_classes.png
Normal file
BIN
docs/0010-ledger-replay/ledger_replay_classes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
98
docs/0010-ledger-replay/ledger_replay_classes.puml
Normal file
98
docs/0010-ledger-replay/ledger_replay_classes.puml
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
@startuml
|
||||||
|
|
||||||
|
class TimeoutCounter {
|
||||||
|
#app_ : Application&
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeoutCounter o-- "1" Application
|
||||||
|
': app_
|
||||||
|
|
||||||
|
Stoppable <.. Application
|
||||||
|
|
||||||
|
class Application {
|
||||||
|
-m_ledgerReplayer : uptr<LedgerReplayer>
|
||||||
|
-m_inboundLedgers : uptr<InboundLedgers>
|
||||||
|
}
|
||||||
|
|
||||||
|
Application *-- "1" LedgerReplayer
|
||||||
|
': m_ledgerReplayer
|
||||||
|
Application *-- "1" InboundLedgers
|
||||||
|
': m_inboundLedgers
|
||||||
|
|
||||||
|
Stoppable <.. InboundLedgers
|
||||||
|
Application "1" --o InboundLedgers
|
||||||
|
': app_
|
||||||
|
|
||||||
|
class InboundLedgers {
|
||||||
|
-app_ : Application&
|
||||||
|
}
|
||||||
|
|
||||||
|
Stoppable <.. LedgerReplayer
|
||||||
|
InboundLedgers "1" --o LedgerReplayer
|
||||||
|
': inboundLedgers_
|
||||||
|
Application "1" --o LedgerReplayer
|
||||||
|
': app_
|
||||||
|
|
||||||
|
class LedgerReplayer {
|
||||||
|
+createDeltas(LedgerReplayTask)
|
||||||
|
-app_ : Application&
|
||||||
|
-inboundLedgers_ : InboundLedgers&
|
||||||
|
-tasks_ : vector<sptr<LedgerReplayTask>>
|
||||||
|
-deltas_ : hash_map<u256, wptr<LedgerDeltaAcquire>>
|
||||||
|
-skipLists_ : hash_map<u256, wptr<SkipListAcquire>>
|
||||||
|
}
|
||||||
|
|
||||||
|
LedgerReplayer *-- LedgerReplayTask
|
||||||
|
': tasks_
|
||||||
|
LedgerReplayer o-- LedgerDeltaAcquire
|
||||||
|
': deltas_
|
||||||
|
LedgerReplayer o-- SkipListAcquire
|
||||||
|
': skipLists_
|
||||||
|
|
||||||
|
TimeoutCounter <.. LedgerReplayTask
|
||||||
|
InboundLedgers "1" --o LedgerReplayTask
|
||||||
|
': inboundLedgers_
|
||||||
|
LedgerReplayer "1" --o LedgerReplayTask
|
||||||
|
': replayer_
|
||||||
|
|
||||||
|
class LedgerReplayTask {
|
||||||
|
-inboundLedgers_ : InboundLedgers&
|
||||||
|
-replayer_ : LedgerReplayer&
|
||||||
|
-skipListAcquirer_ : sptr<SkipListAcquire>
|
||||||
|
-deltas_ : vector<sptr<LedgerDeltaAcquire>>
|
||||||
|
+addDelta(sptr<LedgerDeltaAcquire>)
|
||||||
|
}
|
||||||
|
|
||||||
|
LedgerReplayTask *-- "1" SkipListAcquire
|
||||||
|
': skipListAcquirer_
|
||||||
|
LedgerReplayTask *-- LedgerDeltaAcquire
|
||||||
|
': deltas_
|
||||||
|
|
||||||
|
TimeoutCounter <.. SkipListAcquire
|
||||||
|
InboundLedgers "1" --o SkipListAcquire
|
||||||
|
': inboundLedgers_
|
||||||
|
LedgerReplayer "1" --o SkipListAcquire
|
||||||
|
': replayer_
|
||||||
|
LedgerReplayTask --o SkipListAcquire : implicit via callback
|
||||||
|
|
||||||
|
class SkipListAcquire {
|
||||||
|
+addDataCallback(callback)
|
||||||
|
-inboundLedgers_ : InboundLedgers&
|
||||||
|
-replayer_ : LedgerReplayer&
|
||||||
|
-dataReadyCallbacks_ : vector<callback>
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeoutCounter <.. LedgerDeltaAcquire
|
||||||
|
InboundLedgers "1" --o LedgerDeltaAcquire
|
||||||
|
': inboundLedgers_
|
||||||
|
LedgerReplayer "1" --o LedgerDeltaAcquire
|
||||||
|
': replayer_
|
||||||
|
LedgerReplayTask --o LedgerDeltaAcquire : implicit via callback
|
||||||
|
|
||||||
|
class LedgerDeltaAcquire {
|
||||||
|
+addDataCallback(callback)
|
||||||
|
-inboundLedgers_ : InboundLedgers&
|
||||||
|
-replayer_ : LedgerReplayer&
|
||||||
|
-dataReadyCallbacks_ : vector<callback>
|
||||||
|
}
|
||||||
|
@enduml
|
||||||
BIN
docs/0010-ledger-replay/ledger_replay_sequence.png
Normal file
BIN
docs/0010-ledger-replay/ledger_replay_sequence.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
85
docs/0010-ledger-replay/ledger_replay_sequence.puml
Normal file
85
docs/0010-ledger-replay/ledger_replay_sequence.puml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
@startuml
|
||||||
|
|
||||||
|
autoactivate on
|
||||||
|
|
||||||
|
' participant app as "Application"
|
||||||
|
participant peer as "Peer"
|
||||||
|
participant lr as "LedgerReplayer"
|
||||||
|
participant lrt as "LedgerReplayTask"
|
||||||
|
participant sla as "SkipListAcquire"
|
||||||
|
participant lda as "LedgerDeltaAcquire"
|
||||||
|
|
||||||
|
[-> lr : replay(finishId, numLedgers)
|
||||||
|
lr -> sla : make_shared(finishHash)
|
||||||
|
return skipList
|
||||||
|
lr -> lrt : make_shared(skipList)
|
||||||
|
return task
|
||||||
|
lr -> sla : init(numPeers=1)
|
||||||
|
sla -> sla : trigger(numPeers=1)
|
||||||
|
sla -> peer : sendRequest(ProofPathRequest)
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
lr -> lrt : init()
|
||||||
|
lrt -> sla : addDataCallback(callback)
|
||||||
|
return
|
||||||
|
return
|
||||||
|
deactivate lr
|
||||||
|
|
||||||
|
[-> peer : onMessage(ProofPathResponse)
|
||||||
|
peer -> lr : gotSkipList(ledgerHeader, item)
|
||||||
|
lr -> sla : processData(ledgerSeq, item)
|
||||||
|
sla -> sla : onSkipListAcquired(skipList, ledgerSeq)
|
||||||
|
sla -> sla : notify()
|
||||||
|
note over sla: call the callbacks added by\naddDataCallback(callback).
|
||||||
|
sla -> lrt : callback(ledgerId)
|
||||||
|
lrt -> lrt : updateSkipList(ledgerId, ledgerSeq, skipList)
|
||||||
|
lrt -> lr : createDeltas(this)
|
||||||
|
loop
|
||||||
|
lr -> lda : make_shared(ledgerId, ledgerSeq)
|
||||||
|
return delta
|
||||||
|
lr -> lrt : addDelta(delta)
|
||||||
|
lrt -> lda : addDataCallback(callback)
|
||||||
|
return
|
||||||
|
return
|
||||||
|
lr -> lda : init(numPeers=1)
|
||||||
|
lda -> lda : trigger(numPeers=1)
|
||||||
|
lda -> peer : sendRequest(ReplayDeltaRequest)
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
deactivate peer
|
||||||
|
|
||||||
|
[-> peer : onMessage(ReplayDeltaResponse)
|
||||||
|
peer -> lr : gotReplayDelta(ledgerHeader)
|
||||||
|
lr -> lda : processData(ledgerHeader, txns)
|
||||||
|
lda -> lda : notify()
|
||||||
|
note over lda: call the callbacks added by\naddDataCallback(callback).
|
||||||
|
lda -> lrt : callback(ledgerId)
|
||||||
|
lrt -> lrt : deltaReady(ledgerId)
|
||||||
|
lrt -> lrt : tryAdvance()
|
||||||
|
loop as long as child can be built
|
||||||
|
lrt -> lda : tryBuild(parent)
|
||||||
|
lda -> lda : onLedgerBuilt()
|
||||||
|
note over lda
|
||||||
|
Schedule a job to store the built ledger.
|
||||||
|
end note
|
||||||
|
return
|
||||||
|
return child
|
||||||
|
end
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
deactivate peer
|
||||||
|
|
||||||
|
|
||||||
|
@enduml
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
# Form
|
# Code Style Cheat Sheet
|
||||||
|
|
||||||
|
## Form
|
||||||
|
|
||||||
- One class per header file.
|
- One class per header file.
|
||||||
- Place each data member on its own line.
|
- Place each data member on its own line.
|
||||||
@@ -11,7 +13,7 @@
|
|||||||
- Order class declarations as types, public, protected, private, then data.
|
- Order class declarations as types, public, protected, private, then data.
|
||||||
- Prefer 'private' over 'protected'
|
- Prefer 'private' over 'protected'
|
||||||
|
|
||||||
# Function
|
## Function
|
||||||
|
|
||||||
- Minimize external dependencies
|
- Minimize external dependencies
|
||||||
* Pass options in the ctor instead of using theConfig
|
* Pass options in the ctor instead of using theConfig
|
||||||
82
docs/CodingStyle.md
Normal file
82
docs/CodingStyle.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# Coding Standards
|
||||||
|
|
||||||
|
Coding standards used here gradually evolve and propagate through
|
||||||
|
code reviews. Some aspects are enforced more strictly than others.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
These rules only apply to our own code. We can't enforce any sort of
|
||||||
|
style on the external repositories and libraries we include. The best
|
||||||
|
guideline is to maintain the standards that are used in those libraries.
|
||||||
|
|
||||||
|
* Tab inserts 4 spaces. No tab characters.
|
||||||
|
* Braces are indented in the [Allman style][1].
|
||||||
|
* Modern C++ principles. No naked ```new``` or ```delete```.
|
||||||
|
* Line lengths limited to 80 characters. Exceptions limited to data and tables.
|
||||||
|
|
||||||
|
## Guidelines
|
||||||
|
|
||||||
|
If you want to do something contrary to these guidelines, understand
|
||||||
|
why you're doing it. Think, use common sense, and consider that this
|
||||||
|
your changes will probably need to be maintained long after you've
|
||||||
|
moved on to other projects.
|
||||||
|
|
||||||
|
* Use white space and blank lines to guide the eye and keep your intent clear.
|
||||||
|
* Put private data members at the top of a class, and the 6 public special
|
||||||
|
members immediately after, in the following order:
|
||||||
|
* Destructor
|
||||||
|
* Default constructor
|
||||||
|
* Copy constructor
|
||||||
|
* Copy assignment
|
||||||
|
* Move constructor
|
||||||
|
* Move assignment
|
||||||
|
* Don't over-inline by defining large functions within the class
|
||||||
|
declaration, not even for template classes.
|
||||||
|
|
||||||
|
## Formatting
|
||||||
|
|
||||||
|
The goal of source code formatting should always be to make things as easy to
|
||||||
|
read as possible. White space is used to guide the eye so that details are not
|
||||||
|
overlooked. Blank lines are used to separate code into "paragraphs."
|
||||||
|
|
||||||
|
* Always place a space before and after all binary operators,
|
||||||
|
especially assignments (`operator=`).
|
||||||
|
* The `!` operator should be preceded by a space, but not followed by one.
|
||||||
|
* The `~` operator should be preceded by a space, but not followed by one.
|
||||||
|
* The `++` and `--` operators should have no spaces between the operator and
|
||||||
|
the operand.
|
||||||
|
* A space never appears before a comma, and always appears after a comma.
|
||||||
|
* Don't put spaces after a parenthesis. A typical member function call might
|
||||||
|
look like this: `foobar (1, 2, 3);`
|
||||||
|
* In general, leave a blank line before an `if` statement.
|
||||||
|
* In general, leave a blank line after a closing brace `}`.
|
||||||
|
* Do not place code on the same line as any opening or
|
||||||
|
closing brace.
|
||||||
|
* Do not write `if` statements all-on-one-line. The exception to this is when
|
||||||
|
you've got a sequence of similar `if` statements, and are aligning them all
|
||||||
|
vertically to highlight their similarities.
|
||||||
|
* In an `if-else` statement, if you surround one half of the statement with
|
||||||
|
braces, you also need to put braces around the other half, to match.
|
||||||
|
* When writing a pointer type, use this spacing: `SomeObject* myObject`.
|
||||||
|
Technically, a more correct spacing would be `SomeObject *myObject`, but
|
||||||
|
it makes more sense for the asterisk to be grouped with the type name,
|
||||||
|
since being a pointer is part of the type, not the variable name. The only
|
||||||
|
time that this can lead to any problems is when you're declaring multiple
|
||||||
|
pointers of the same type in the same statement - which leads on to the next
|
||||||
|
rule:
|
||||||
|
* When declaring multiple pointers, never do so in a single statement, e.g.
|
||||||
|
`SomeObject* p1, *p2;` - instead, always split them out onto separate lines
|
||||||
|
and write the type name again, to make it quite clear what's going on, and
|
||||||
|
avoid the danger of missing out any vital asterisks.
|
||||||
|
* The previous point also applies to references, so always put the `&` next to
|
||||||
|
the type rather than the variable, e.g. `void foo (Thing const& thing)`. And
|
||||||
|
don't put a space on both sides of the `*` or `&` - always put a space after
|
||||||
|
it, but never before it.
|
||||||
|
* The word `const` should be placed to the right of the thing that it modifies,
|
||||||
|
for consistency. For example `int const` refers to an int which is const.
|
||||||
|
`int const*` is a pointer to an int which is const. `int *const` is a const
|
||||||
|
pointer to an int.
|
||||||
|
* Always place a space in between the template angle brackets and the type
|
||||||
|
name. Template code is already hard enough to read!
|
||||||
|
|
||||||
|
[1]: http://en.wikipedia.org/wiki/Indent_style#Allman_style
|
||||||
5
docs/Docker.md
Normal file
5
docs/Docker.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# `rippled` Docker Image
|
||||||
|
|
||||||
|
- Some info relating to Docker containers can be found here: [../Builds/containers](../Builds/containers)
|
||||||
|
- Images for building and testing rippled can be found here: [thejohnfreeman/rippled-docker](https://github.com/thejohnfreeman/rippled-docker/)
|
||||||
|
- These images do not have rippled. They have all the tools necessary to build rippled.
|
||||||
343
docs/Doxyfile
Normal file
343
docs/Doxyfile
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Project related configuration options
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
PROJECT_NAME = "rippled"
|
||||||
|
PROJECT_NUMBER =
|
||||||
|
PROJECT_BRIEF =
|
||||||
|
PROJECT_LOGO =
|
||||||
|
PROJECT_LOGO =
|
||||||
|
OUTPUT_DIRECTORY = $(DOXYGEN_OUTPUT_DIRECTORY)
|
||||||
|
CREATE_SUBDIRS = NO
|
||||||
|
ALLOW_UNICODE_NAMES = NO
|
||||||
|
OUTPUT_LANGUAGE = English
|
||||||
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
REPEAT_BRIEF = YES
|
||||||
|
ABBREVIATE_BRIEF =
|
||||||
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
INLINE_INHERITED_MEMB = YES
|
||||||
|
FULL_PATH_NAMES = NO
|
||||||
|
STRIP_FROM_PATH = src/
|
||||||
|
STRIP_FROM_INC_PATH =
|
||||||
|
SHORT_NAMES = NO
|
||||||
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
INHERIT_DOCS = YES
|
||||||
|
SEPARATE_MEMBER_PAGES = NO
|
||||||
|
TAB_SIZE = 4
|
||||||
|
ALIASES =
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||||
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
EXTENSION_MAPPING =
|
||||||
|
MARKDOWN_SUPPORT = YES
|
||||||
|
AUTOLINK_SUPPORT = YES
|
||||||
|
BUILTIN_STL_SUPPORT = YES
|
||||||
|
CPP_CLI_SUPPORT = NO
|
||||||
|
SIP_SUPPORT = NO
|
||||||
|
IDL_PROPERTY_SUPPORT = YES
|
||||||
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
GROUP_NESTED_COMPOUNDS = NO
|
||||||
|
SUBGROUPING = YES
|
||||||
|
INLINE_GROUPED_CLASSES = NO
|
||||||
|
INLINE_SIMPLE_STRUCTS = NO
|
||||||
|
TYPEDEF_HIDES_STRUCT = NO
|
||||||
|
LOOKUP_CACHE_SIZE = 0
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Build related configuration options
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
EXTRACT_ALL = YES
|
||||||
|
EXTRACT_PRIVATE = YES
|
||||||
|
EXTRACT_PACKAGE = NO
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
EXTRACT_LOCAL_METHODS = YES
|
||||||
|
EXTRACT_ANON_NSPACES = NO
|
||||||
|
HIDE_UNDOC_MEMBERS = NO
|
||||||
|
HIDE_UNDOC_CLASSES = NO
|
||||||
|
HIDE_FRIEND_COMPOUNDS = NO
|
||||||
|
HIDE_IN_BODY_DOCS = NO
|
||||||
|
INTERNAL_DOCS = NO
|
||||||
|
CASE_SENSE_NAMES = YES
|
||||||
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
HIDE_COMPOUND_REFERENCE= NO
|
||||||
|
SHOW_INCLUDE_FILES = NO
|
||||||
|
SHOW_GROUPED_MEMB_INC = NO
|
||||||
|
FORCE_LOCAL_INCLUDES = NO
|
||||||
|
INLINE_INFO = NO
|
||||||
|
SORT_MEMBER_DOCS = NO
|
||||||
|
SORT_BRIEF_DOCS = NO
|
||||||
|
SORT_MEMBERS_CTORS_1ST = YES
|
||||||
|
SORT_GROUP_NAMES = NO
|
||||||
|
SORT_BY_SCOPE_NAME = NO
|
||||||
|
STRICT_PROTO_MATCHING = NO
|
||||||
|
GENERATE_TODOLIST = NO
|
||||||
|
GENERATE_TESTLIST = NO
|
||||||
|
GENERATE_BUGLIST = NO
|
||||||
|
GENERATE_DEPRECATEDLIST= NO
|
||||||
|
ENABLED_SECTIONS =
|
||||||
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
SHOW_USED_FILES = NO
|
||||||
|
SHOW_FILES = NO
|
||||||
|
SHOW_NAMESPACES = YES
|
||||||
|
FILE_VERSION_FILTER =
|
||||||
|
LAYOUT_FILE =
|
||||||
|
CITE_BIB_FILES =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to warning and progress messages
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
QUIET = NO
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
WARN_IF_DOC_ERROR = YES
|
||||||
|
WARN_NO_PARAMDOC = NO
|
||||||
|
WARN_AS_ERROR = NO
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
WARN_LOGFILE =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the input files
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
INPUT = \
|
||||||
|
. \
|
||||||
|
|
||||||
|
|
||||||
|
INPUT_ENCODING = UTF-8
|
||||||
|
FILE_PATTERNS = *.h *.cpp *.md
|
||||||
|
RECURSIVE = YES
|
||||||
|
EXCLUDE = \
|
||||||
|
.github \
|
||||||
|
external/ed25519-donna \
|
||||||
|
external/secp256k1 \
|
||||||
|
|
||||||
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
EXCLUDE_PATTERNS =
|
||||||
|
EXCLUDE_SYMBOLS =
|
||||||
|
EXAMPLE_PATH =
|
||||||
|
EXAMPLE_PATTERNS =
|
||||||
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
IMAGE_PATH = \
|
||||||
|
docs/images/ \
|
||||||
|
docs/images/consensus/ \
|
||||||
|
src/test/csf/ \
|
||||||
|
|
||||||
|
INPUT_FILTER =
|
||||||
|
FILTER_PATTERNS =
|
||||||
|
FILTER_SOURCE_FILES = NO
|
||||||
|
FILTER_SOURCE_PATTERNS =
|
||||||
|
USE_MDFILE_AS_MAINPAGE = ./README.md
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to source browsing
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
SOURCE_BROWSER = YES
|
||||||
|
INLINE_SOURCES = NO
|
||||||
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
REFERENCED_BY_RELATION = NO
|
||||||
|
REFERENCES_RELATION = NO
|
||||||
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
SOURCE_TOOLTIPS = YES
|
||||||
|
USE_HTAGS = NO
|
||||||
|
VERBATIM_HEADERS = YES
|
||||||
|
CLANG_ASSISTED_PARSING = NO
|
||||||
|
CLANG_OPTIONS =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the alphabetical class index
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
ALPHABETICAL_INDEX = YES
|
||||||
|
COLS_IN_ALPHA_INDEX = 5
|
||||||
|
IGNORE_PREFIX =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the HTML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_HTML = YES
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
HTML_HEADER =
|
||||||
|
HTML_FOOTER =
|
||||||
|
HTML_STYLESHEET =
|
||||||
|
HTML_EXTRA_STYLESHEET =
|
||||||
|
HTML_EXTRA_FILES =
|
||||||
|
HTML_COLORSTYLE_HUE = 220
|
||||||
|
HTML_COLORSTYLE_SAT = 100
|
||||||
|
HTML_COLORSTYLE_GAMMA = 80
|
||||||
|
HTML_TIMESTAMP = NO
|
||||||
|
HTML_DYNAMIC_SECTIONS = NO
|
||||||
|
HTML_INDEX_NUM_ENTRIES = 100
|
||||||
|
GENERATE_DOCSET = NO
|
||||||
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||||
|
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||||
|
DOCSET_PUBLISHER_NAME = Publisher
|
||||||
|
GENERATE_HTMLHELP = NO
|
||||||
|
CHM_FILE =
|
||||||
|
HHC_LOCATION =
|
||||||
|
GENERATE_CHI = NO
|
||||||
|
CHM_INDEX_ENCODING =
|
||||||
|
BINARY_TOC = NO
|
||||||
|
TOC_EXPAND = NO
|
||||||
|
GENERATE_QHP = NO
|
||||||
|
QCH_FILE =
|
||||||
|
QHP_NAMESPACE = org.doxygen.Project
|
||||||
|
QHP_VIRTUAL_FOLDER = doc
|
||||||
|
QHP_CUST_FILTER_NAME =
|
||||||
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
QHG_LOCATION =
|
||||||
|
GENERATE_ECLIPSEHELP = NO
|
||||||
|
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
GENERATE_TREEVIEW = NO
|
||||||
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
TREEVIEW_WIDTH = 250
|
||||||
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
FORMULA_FONTSIZE = 10
|
||||||
|
FORMULA_TRANSPARENT = YES
|
||||||
|
USE_MATHJAX = NO
|
||||||
|
MATHJAX_FORMAT = HTML-CSS
|
||||||
|
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||||
|
MATHJAX_EXTENSIONS =
|
||||||
|
MATHJAX_CODEFILE =
|
||||||
|
SEARCHENGINE = YES
|
||||||
|
SERVER_BASED_SEARCH = NO
|
||||||
|
EXTERNAL_SEARCH = NO
|
||||||
|
SEARCHENGINE_URL =
|
||||||
|
SEARCHDATA_FILE = searchdata.xml
|
||||||
|
EXTERNAL_SEARCH_ID =
|
||||||
|
EXTRA_SEARCH_MAPPINGS =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the LaTeX output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_LATEX = NO
|
||||||
|
LATEX_OUTPUT = latex
|
||||||
|
LATEX_CMD_NAME =
|
||||||
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
COMPACT_LATEX = NO
|
||||||
|
PAPER_TYPE = a4
|
||||||
|
EXTRA_PACKAGES =
|
||||||
|
LATEX_HEADER =
|
||||||
|
LATEX_FOOTER =
|
||||||
|
LATEX_EXTRA_STYLESHEET =
|
||||||
|
LATEX_EXTRA_FILES =
|
||||||
|
PDF_HYPERLINKS = YES
|
||||||
|
USE_PDFLATEX = YES
|
||||||
|
LATEX_BATCHMODE = NO
|
||||||
|
LATEX_HIDE_INDICES = NO
|
||||||
|
LATEX_SOURCE_CODE = NO
|
||||||
|
LATEX_BIB_STYLE = plain
|
||||||
|
LATEX_TIMESTAMP = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the RTF output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
RTF_OUTPUT = rtf
|
||||||
|
COMPACT_RTF = NO
|
||||||
|
RTF_HYPERLINKS = NO
|
||||||
|
RTF_STYLESHEET_FILE =
|
||||||
|
RTF_EXTENSIONS_FILE =
|
||||||
|
RTF_SOURCE_CODE = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the man page output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_MAN = NO
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
MAN_SUBDIR =
|
||||||
|
MAN_LINKS = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the XML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_XML = NO
|
||||||
|
XML_OUTPUT = xml
|
||||||
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the DOCBOOK output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_DOCBOOK = NO
|
||||||
|
DOCBOOK_OUTPUT = docbook
|
||||||
|
DOCBOOK_PROGRAMLISTING = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options for the AutoGen Definitions output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
GENERATE_PERLMOD = NO
|
||||||
|
PERLMOD_LATEX = NO
|
||||||
|
PERLMOD_PRETTY = YES
|
||||||
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the preprocessor
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = YES
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH)
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
PREDEFINED = DOXYGEN \
|
||||||
|
GENERATING_DOCS \
|
||||||
|
_MSC_VER \
|
||||||
|
NUDB_POSIX_FILE=1
|
||||||
|
|
||||||
|
EXPAND_AS_DEFINED =
|
||||||
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to external references
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
TAGFILES = $(DOXYGEN_TAGFILES)
|
||||||
|
GENERATE_TAGFILE =
|
||||||
|
ALLEXTERNALS = NO
|
||||||
|
EXTERNAL_GROUPS = YES
|
||||||
|
EXTERNAL_PAGES = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the dot tool
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
CLASS_DIAGRAMS = NO
|
||||||
|
DIA_PATH =
|
||||||
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
HAVE_DOT = YES
|
||||||
|
# DOT_NUM_THREADS = 0 means 1 for every processor.
|
||||||
|
DOT_NUM_THREADS = 0
|
||||||
|
DOT_FONTNAME = Helvetica
|
||||||
|
DOT_FONTSIZE = 10
|
||||||
|
DOT_FONTPATH =
|
||||||
|
CLASS_GRAPH = YES
|
||||||
|
COLLABORATION_GRAPH = YES
|
||||||
|
GROUP_GRAPHS = YES
|
||||||
|
UML_LOOK = NO
|
||||||
|
UML_LIMIT_NUM_FIELDS = 10
|
||||||
|
TEMPLATE_RELATIONS = NO
|
||||||
|
INCLUDE_GRAPH = YES
|
||||||
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
CALL_GRAPH = NO
|
||||||
|
CALLER_GRAPH = NO
|
||||||
|
GRAPHICAL_HIERARCHY = YES
|
||||||
|
DIRECTORY_GRAPH = YES
|
||||||
|
DOT_IMAGE_FORMAT = png
|
||||||
|
INTERACTIVE_SVG = NO
|
||||||
|
DOT_PATH = $(DOXYGEN_DOT_PATH)
|
||||||
|
DOTFILE_DIRS =
|
||||||
|
MSCFILE_DIRS =
|
||||||
|
DIAFILE_DIRS =
|
||||||
|
PLANTUML_JAR_PATH = $(DOXYGEN_PLANTUML_JAR_PATH)
|
||||||
|
PLANTUML_INCLUDE_PATH =
|
||||||
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
DOT_TRANSPARENT = NO
|
||||||
|
DOT_MULTI_TARGETS = NO
|
||||||
|
GENERATE_LEGEND = YES
|
||||||
|
DOT_CLEANUP = YES
|
||||||
63
docs/HeapProfiling.md
Normal file
63
docs/HeapProfiling.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
## Heap profiling of rippled with jemalloc
|
||||||
|
|
||||||
|
The jemalloc library provides a good API for doing heap analysis,
|
||||||
|
including a mechanism to dump a description of the heap from within the
|
||||||
|
running application via a function call. Details on how to perform this
|
||||||
|
activity in general, as well as how to acquire the software, are available on
|
||||||
|
the jemalloc site:
|
||||||
|
[https://github.com/jemalloc/jemalloc/wiki/Use-Case:-Heap-Profiling](https://github.com/jemalloc/jemalloc/wiki/Use-Case:-Heap-Profiling)
|
||||||
|
|
||||||
|
jemalloc is acquired separately from rippled, and is not affiliated
|
||||||
|
with Ripple Labs. If you compile and install jemalloc from the
|
||||||
|
source release with default options, it will install the library and header
|
||||||
|
under `/usr/local/lib` and `/usr/local/include`, respectively. Heap
|
||||||
|
profiling has been tested with rippled on a Linux platform. It should
|
||||||
|
work on platforms on which both rippled and jemalloc are available.
|
||||||
|
|
||||||
|
To link rippled with jemalloc, the argument
|
||||||
|
`profile-jemalloc=<jemalloc_dir>` is provided after the optional target.
|
||||||
|
The `<jemalloc_dir>` argument should be the same as that of the
|
||||||
|
`--prefix` parameter passed to the jemalloc configure script when building.
|
||||||
|
|
||||||
|
## Examples:
|
||||||
|
|
||||||
|
Build rippled with jemalloc library under /usr/local/lib and
|
||||||
|
header under /usr/local/include:
|
||||||
|
|
||||||
|
$ scons profile-jemalloc=/usr/local
|
||||||
|
|
||||||
|
Build rippled using clang with the jemalloc library under /opt/local/lib
|
||||||
|
and header under /opt/local/include:
|
||||||
|
|
||||||
|
$ scons clang profile-jemalloc=/opt/local
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
## Using the jemalloc library from within the code
|
||||||
|
|
||||||
|
The `profile-jemalloc` parameter enables a macro definition called
|
||||||
|
`PROFILE_JEMALLOC`. Include the jemalloc header file as
|
||||||
|
well as the api call(s) that you wish to make within preprocessor
|
||||||
|
conditional groups, such as:
|
||||||
|
|
||||||
|
In global scope:
|
||||||
|
|
||||||
|
#ifdef PROFILE_JEMALLOC
|
||||||
|
#include <jemalloc/jemalloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
And later, within a function scope:
|
||||||
|
|
||||||
|
#ifdef PROFILE_JEMALLOC
|
||||||
|
mallctl("prof.dump", NULL, NULL, NULL, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Fuller descriptions of how to acquire and use jemalloc's api to do memory
|
||||||
|
analysis are available at the [jemalloc
|
||||||
|
site.](http://www.canonware.com/jemalloc/)
|
||||||
|
|
||||||
|
Linking against the jemalloc library will override
|
||||||
|
the system's default `malloc()` and related functions with jemalloc's
|
||||||
|
implementation. This is the case even if the code is not instrumented
|
||||||
|
to use jemalloc's specific API.
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user