Compare commits
1108
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fce453a2d1 | ||
|
|
9d813d8385 | ||
|
|
e4f04f198d | ||
|
|
7401fa234e | ||
|
|
7a009abcdd | ||
|
|
b305244405 | ||
|
|
02a0770436 | ||
|
|
196030bee2 | ||
|
|
d49297f898 | ||
|
|
b5ce847579 | ||
|
|
7dc19bb26e | ||
|
|
82343a06e7 | ||
|
|
5f9753933a | ||
|
|
fcaad20ecc | ||
|
|
f1ddb55252 | ||
|
|
69e8516d1f | ||
|
|
d437f19aae | ||
|
|
977e302e0c | ||
|
|
0bfbcfb5e9 | ||
|
|
7c4d3a457c | ||
|
|
25b2e144b8 | ||
|
|
11db419735 | ||
|
|
4e2d7fe1db | ||
|
|
910d3caacf | ||
|
|
a449937682 | ||
|
|
0b3144f566 | ||
|
|
13701c7ce2 | ||
|
|
3f152ae2bf | ||
|
|
a53dc5a7c7 | ||
|
|
da64f241eb | ||
|
|
caeeb6a7d9 | ||
|
|
694c45cd65 | ||
|
|
dbc6b32a4c | ||
|
|
5ba4a78657 | ||
|
|
1609317ac8 | ||
|
|
3a121f99c7 | ||
|
|
56b97e1386 | ||
|
|
3a62c8b4a2 | ||
|
|
1a0fc75325 | ||
|
|
945b93590d | ||
|
|
701d0a111e | ||
|
|
3c1edca902 | ||
|
|
92e4caa151 | ||
|
|
e767981aaf | ||
|
|
0536eb898d | ||
|
|
433e9c351d | ||
|
|
49a6d7ebcc | ||
|
|
4c25358a08 | ||
|
|
ecd1ab4b42 | ||
|
|
97a73f1c29 | ||
|
|
d118ef9202 | ||
|
|
3cd17f0ee4 | ||
|
|
fc34d9ba1c | ||
|
|
1eb101d70e | ||
|
|
7fea2e4d6c | ||
|
|
cca69a6c16 | ||
|
|
0ed8647b6f | ||
|
|
58843857e5 | ||
|
|
efdcd00da4 | ||
|
|
fee69a889b | ||
|
|
4af8b8ecf3 | ||
|
|
9a31b65cd0 | ||
|
|
5365ccfdb1 | ||
|
|
36f1dd7bb3 | ||
|
|
7b81369c8c | ||
|
|
7a1beacd00 | ||
|
|
32818c528f | ||
|
|
0d6493ec3f | ||
|
|
8715745feb | ||
|
|
aa124cf414 | ||
|
|
a94e47c6be | ||
|
|
6ddbe41376 | ||
|
|
42b2adddee | ||
|
|
18987f92ee | ||
|
|
b26405226e | ||
|
|
e1c7f30e60 | ||
|
|
b366e2c91f | ||
|
|
eb4bda2302 | ||
|
|
d9a1ecd387 | ||
|
|
9debd14b6c | ||
|
|
ff14cd3f9d | ||
|
|
e0481bbeca | ||
|
|
73ab064137 | ||
|
|
2cf0e4cb32 | ||
|
|
7123b29f06 | ||
|
|
037e80c70c | ||
|
|
1c055fe83b | ||
|
|
858538284f | ||
|
|
97c95a4e82 | ||
|
|
a3bdd29615 | ||
|
|
a431fdbdde | ||
|
|
60ba133fc8 | ||
|
|
90d78f924f | ||
|
|
3b2a1ea41d | ||
|
|
2961f3b864 | ||
|
|
3f23cf0c1e | ||
|
|
aac1f5abef | ||
|
|
724d80cf02 | ||
|
|
e7ee5b5932 | ||
|
|
4d4739497d | ||
|
|
4ded059a1c | ||
|
|
799d3ebe5e | ||
|
|
628102ab6c | ||
|
|
f2c0ba1df5 | ||
|
|
79453663b3 | ||
|
|
8600ae2ac4 | ||
|
|
193c84811a | ||
|
|
aef2ec513f | ||
|
|
37539ccb84 | ||
|
|
16128a0212 | ||
|
|
159da73fcd | ||
|
|
9f6f94bd02 | ||
|
|
c4259cb594 | ||
|
|
5ed5744cb6 | ||
|
|
a88edeb79d | ||
|
|
4d65e0101d | ||
|
|
45b07674e5 | ||
|
|
4906962da0 | ||
|
|
3ad1ea386c | ||
|
|
9ea623e125 | ||
|
|
e6117c49ef | ||
|
|
673f558ba5 | ||
|
|
56b80c41b6 | ||
|
|
c98ef0aaf8 | ||
|
|
2170b4deb5 | ||
|
|
913cab2785 | ||
|
|
6c51adc334 | ||
|
|
c6bda0e5d4 | ||
|
|
c3cadcba0e | ||
|
|
9fcafff847 | ||
|
|
53c525f0ed | ||
|
|
8a2a2d065d | ||
|
|
c229842f57 | ||
|
|
9a1a89d98c | ||
|
|
1bf40ad9df | ||
|
|
67889b473c | ||
|
|
05fa9c81de | ||
|
|
6d4fb8866e | ||
|
|
d2054e8653 | ||
|
|
6401363ef1 | ||
|
|
ce99aad438 | ||
|
|
135aef78d7 | ||
|
|
362c73bfbd | ||
|
|
ad66ad4f7d | ||
|
|
9fc6242e5b | ||
|
|
0ac1bbc7ae | ||
|
|
61a1a172fa | ||
|
|
3c96dcaec7 | ||
|
|
98642ec4b5 | ||
|
|
81f0cfdd1e | ||
|
|
b248097b42 | ||
|
|
9ce6a15edc | ||
|
|
55189fbe53 | ||
|
|
0d9e34d651 | ||
|
|
e1ac3f641b | ||
|
|
231893a794 | ||
|
|
65e599fb8e | ||
|
|
4421bf2fa1 | ||
|
|
91ccb7fbda | ||
|
|
9c4f8254ee | ||
|
|
326a9b673e | ||
|
|
b6278d2a6c | ||
|
|
1daaba9224 | ||
|
|
3ecc58d036 | ||
|
|
a715fb3063 | ||
|
|
49742f8fdc | ||
|
|
046a9f8af0 | ||
|
|
ffabb015ef | ||
|
|
84dbb229b6 | ||
|
|
c192637741 | ||
|
|
61f453fcd3 | ||
|
|
7cdf6dc680 | ||
|
|
b9fe61f9da | ||
|
|
4525395cc5 | ||
|
|
9b838f515b | ||
|
|
5b33555fda | ||
|
|
8d737a1428 | ||
|
|
e51b10e6a5 | ||
|
|
93e22da539 | ||
|
|
8ec7da0dee | ||
|
|
5416ce5443 | ||
|
|
4c8015c0a1 | ||
|
|
5734a39e8e | ||
|
|
62e352ef88 | ||
|
|
e1c2cf446e | ||
|
|
c5dc898ed0 | ||
|
|
acbfc879aa | ||
|
|
066d0edf51 | ||
|
|
949ec65118 | ||
|
|
f1f878a000 | ||
|
|
e3edab66e3 | ||
|
|
28d751b2e0 | ||
|
|
7dcfeee0ea | ||
|
|
1bb65189af | ||
|
|
6b06c1b5d3 | ||
|
|
8cf6f24f4d | ||
|
|
b7e1548041 | ||
|
|
2e1bb7e8cc | ||
|
|
1c21690dfe | ||
|
|
7073f31f84 | ||
|
|
5ac1c59527 | ||
|
|
c9799e1369 | ||
|
|
91d773451b | ||
|
|
ebe1ca7c77 | ||
|
|
1bc1cd3366 | ||
|
|
898f523162 | ||
|
|
08bbfed825 | ||
|
|
04f2d3543b | ||
|
|
85886287b4 | ||
|
|
b5912d1543 | ||
|
|
e9e28f75e2 | ||
|
|
b8747e3afc | ||
|
|
bac17061d4 | ||
|
|
99e1b9e2aa | ||
|
|
11fc068cfe | ||
|
|
f9f6f35b93 | ||
|
|
f281027a1c | ||
|
|
e49d499bb5 | ||
|
|
581cb34b11 | ||
|
|
4968babb32 | ||
|
|
ce040b7d33 | ||
|
|
a7e02f7207 | ||
|
|
bf0470ad09 | ||
|
|
7dbf0ced82 | ||
|
|
48e28898a6 | ||
|
|
17ac583508 | ||
|
|
6dc696b745 | ||
|
|
2aab4d4f05 | ||
|
|
94678bacea | ||
|
|
7207740af4 | ||
|
|
5329f18938 | ||
|
|
b81d189ec1 | ||
|
|
a52b4b72e9 | ||
|
|
14b76743c6 | ||
|
|
874124c4e7 | ||
|
|
0a67b6e222 | ||
|
|
6d464c478e | ||
|
|
eb83001bbc | ||
|
|
aacc246ba3 | ||
|
|
444a2bf355 | ||
|
|
b8473aeedd | ||
|
|
91ae72d47a | ||
|
|
74e6260fbd | ||
|
|
a6892f956e | ||
|
|
c018dac13a | ||
|
|
e9a6f5f287 | ||
|
|
a74c466b50 | ||
|
|
97cda51fcf | ||
|
|
963caf2e9d | ||
|
|
769b0f30ef | ||
|
|
e0922a7dd2 | ||
|
|
9c22065459 | ||
|
|
8091e7086e | ||
|
|
00e52296ce | ||
|
|
59ef2fe1b8 | ||
|
|
714ce54135 | ||
|
|
a463c90057 | ||
|
|
f138ae8882 | ||
|
|
bc5be0c30e | ||
|
|
30ae1dd8e8 | ||
|
|
dd91857bf6 | ||
|
|
4a5b0b87ea | ||
|
|
0708268c75 | ||
|
|
77a954c7c3 | ||
|
|
992a01617a | ||
|
|
c9e2c1b1d7 | ||
|
|
686ada0582 | ||
|
|
6291c0c581 | ||
|
|
f9900ba426 | ||
|
|
296ae4305f | ||
|
|
8a9ea66bdf | ||
|
|
92c07f877b | ||
|
|
6d0066eafa | ||
|
|
a49ec594ca | ||
|
|
40ed266617 | ||
|
|
b8eb4ddb0b | ||
|
|
d495c3cc16 | ||
|
|
a92981c967 | ||
|
|
254f821564 | ||
|
|
c6361b391c | ||
|
|
6347daf847 | ||
|
|
f21ddf0c50 | ||
|
|
865c7e587c | ||
|
|
949a046432 | ||
|
|
69470db596 | ||
|
|
52756128da | ||
|
|
433f9f8a13 | ||
|
|
79562a7175 | ||
|
|
dac5518005 | ||
|
|
64b13afee5 | ||
|
|
d054340f13 | ||
|
|
77bf46d018 | ||
|
|
367146f032 | ||
|
|
755ce8cb91 | ||
|
|
b8cd154516 | ||
|
|
d711775cdf | ||
|
|
e0382c546d | ||
|
|
4293023731 | ||
|
|
83bf0c5a11 | ||
|
|
2ba34add2a | ||
|
|
d58babe32c | ||
|
|
b6682f4bbe | ||
|
|
9bb936b75c | ||
|
|
c940727cb4 | ||
|
|
fd8cb44e67 | ||
|
|
7c2f653323 | ||
|
|
420c5fb568 | ||
|
|
aad376296e | ||
|
|
ef68fdb261 | ||
|
|
25912e72a1 | ||
|
|
22760f0922 | ||
|
|
abe04c33c1 | ||
|
|
ba65d1e1e3 | ||
|
|
5ece3d4c10 | ||
|
|
b802ddb848 | ||
|
|
c3b406c5c2 | ||
|
|
e9715cae3b | ||
|
|
5a5d1bf9aa | ||
|
|
23147378a3 | ||
|
|
375d9fdfc9 | ||
|
|
e2cbad6ff4 | ||
|
|
a54d2fd19d | ||
|
|
a575947294 | ||
|
|
79ba74ce71 | ||
|
|
0a03ec569a | ||
|
|
cd64eba76c | ||
|
|
de68f1e5fe | ||
|
|
fce9ff237a | ||
|
|
10c939bc36 | ||
|
|
e753e7a66e | ||
|
|
5d416de32e | ||
|
|
f0f2b3e1f4 | ||
|
|
012cf96d60 | ||
|
|
a0cb6094c6 | ||
|
|
a05a462c8c | ||
|
|
8e62fec1d3 | ||
|
|
6123aa2ed4 | ||
|
|
1234fcfd4f | ||
|
|
04bc4405c7 | ||
|
|
7b203eae1b | ||
|
|
76157c5e03 | ||
|
|
ad4acf3baa | ||
|
|
580fa86ea3 | ||
|
|
675012fe1c | ||
|
|
56926b349a | ||
|
|
87c63e2cb7 | ||
|
|
c8cd8bb591 | ||
|
|
c3817652dc | ||
|
|
3fd83e9345 | ||
|
|
c2522e8ca9 | ||
|
|
1245871004 | ||
|
|
26707a5e03 | ||
|
|
214c32d2ef | ||
|
|
051ff5d205 | ||
|
|
31ad8e647a | ||
|
|
7351939053 | ||
|
|
2d1ebee139 | ||
|
|
9bb9bb5682 | ||
|
|
cdd2d5cc6a | ||
|
|
6ec82b7446 | ||
|
|
e2a93a3feb | ||
|
|
942922960e | ||
|
|
9ba7bcea23 | ||
|
|
d35216434f | ||
|
|
6e1d5c5733 | ||
|
|
562c59b6c1 | ||
|
|
5be125ad1a | ||
|
|
393479ea69 | ||
|
|
623272aa96 | ||
|
|
1c39730531 | ||
|
|
a7b1d86533 | ||
|
|
2795995989 | ||
|
|
cbd23c2b1b | ||
|
|
e3f5b7c59f | ||
|
|
cf7a0415c1 | ||
|
|
bf36363109 | ||
|
|
3399f72113 | ||
|
|
8c0b4a5132 | ||
|
|
f6e545bce5 | ||
|
|
c6c5cdd1dc | ||
|
|
ae7e5f4b2c | ||
|
|
81d2fd615d | ||
|
|
899a65ae87 | ||
|
|
6ce9321094 | ||
|
|
a20c6cb04b | ||
|
|
ddd369e731 | ||
|
|
78817bd001 | ||
|
|
6d32a2f299 | ||
|
|
72021b3221 | ||
|
|
5e4e7c6d34 | ||
|
|
c974872494 | ||
|
|
7823363bba | ||
|
|
6feae1993d | ||
|
|
93bc3af7c6 | ||
|
|
74556edcff | ||
|
|
36224838dd | ||
|
|
bc88a02fe2 | ||
|
|
ba72eff3e6 | ||
|
|
d835cade15 | ||
|
|
355b73843c | ||
|
|
4767f3d87e | ||
|
|
36aa243c56 | ||
|
|
9df5ce1fb7 | ||
|
|
71f0f4c335 | ||
|
|
f17bbc9eac | ||
|
|
ca9bcc90a5 | ||
|
|
384999556c | ||
|
|
afc29ed445 | ||
|
|
a09f386537 | ||
|
|
2ebc111b70 | ||
|
|
e961766e4b | ||
|
|
681b90768a | ||
|
|
cdca1a46b1 | ||
|
|
f677995603 | ||
|
|
e1a36058b4 | ||
|
|
439b424261 | ||
|
|
6f21a10a56 | ||
|
|
fd66c0dcf6 | ||
|
|
9c00af1b86 | ||
|
|
a3e785cb4a | ||
|
|
6926d63655 | ||
|
|
48dea93c7e | ||
|
|
0b7addc031 | ||
|
|
031bfaf120 | ||
|
|
f15a1edbf2 | ||
|
|
75b8e4c981 | ||
|
|
bcaeb83fef | ||
|
|
60b9acc09d | ||
|
|
deb9882520 | ||
|
|
da5ae1efe1 | ||
|
|
eebe784191 | ||
|
|
f9485eb9c2 | ||
|
|
36a1934845 | ||
|
|
df5bd147fa | ||
|
|
977351f419 | ||
|
|
f61eb23f8f | ||
|
|
10af768c60 | ||
|
|
7efed6617c | ||
|
|
a9ec408844 | ||
|
|
b260c849f7 | ||
|
|
2c06eb76d6 | ||
|
|
6bcade5e6d | ||
|
|
4524fbe936 | ||
|
|
6c7ababd3f | ||
|
|
a428f44793 | ||
|
|
b576785aac | ||
|
|
3b5b55de19 | ||
|
|
ee6989970f | ||
|
|
bac708fa34 | ||
|
|
93d9bfb682 | ||
|
|
e6c8c9a6ab | ||
|
|
34387326d1 | ||
|
|
aca2a0fd1b | ||
|
|
0e8a709f92 | ||
|
|
d50a26f4ae | ||
|
|
baee4a1576 | ||
|
|
1bf7e6a408 | ||
|
|
59351c8cb8 | ||
|
|
230b8554f6 | ||
|
|
b47cde70fa | ||
|
|
e89f7d9023 | ||
|
|
94374aa93d | ||
|
|
05c8635749 | ||
|
|
0f79a0024c | ||
|
|
7fc2f9dc29 | ||
|
|
ec0607900d | ||
|
|
8a2d27309d | ||
|
|
d77e59309d | ||
|
|
2a1f18b6ab | ||
|
|
34bfd13548 | ||
|
|
7e7844f169 | ||
|
|
2e22781f8f | ||
|
|
99d5ad097c | ||
|
|
1b2bbd3888 | ||
|
|
095d5d2e31 | ||
|
|
1916561e60 | ||
|
|
ae66f57fa0 | ||
|
|
107eb76b20 | ||
|
|
296eab3045 | ||
|
|
e5ac8662c8 | ||
|
|
c1b2080f4e | ||
|
|
eedcf910eb | ||
|
|
b72cd90c19 | ||
|
|
c0f89e5b2d | ||
|
|
1e37185d74 | ||
|
|
3f3d61b043 | ||
|
|
7ef1513f9b | ||
|
|
b536dfa552 | ||
|
|
f0accce286 | ||
|
|
6bc2ee2735 | ||
|
|
3c82ee49c0 | ||
|
|
e435b42426 | ||
|
|
9481fa0a4b | ||
|
|
1d67b7ffb6 | ||
|
|
de1f4792cd | ||
|
|
681ce94a34 | ||
|
|
cd3772bf4f | ||
|
|
b3f7db7a15 | ||
|
|
4e37131602 | ||
|
|
0d6eb7fefc | ||
|
|
7b7733077a | ||
|
|
ae49729afb | ||
|
|
3ff209d95d | ||
|
|
7d2810abbc | ||
|
|
8b68d37e84 | ||
|
|
a62e027002 | ||
|
|
e7038d286d | ||
|
|
44fd0e3349 | ||
|
|
84d70caa87 | ||
|
|
e129ae3706 | ||
|
|
e797ec138d | ||
|
|
a923d7c884 | ||
|
|
cce77196cd | ||
|
|
c0f47e5eed | ||
|
|
1cd590ace9 | ||
|
|
f33cf74d0f | ||
|
|
6cb411e5bb | ||
|
|
b1a74d71f1 | ||
|
|
026c51033c | ||
|
|
eff73c9728 | ||
|
|
947000c94f | ||
|
|
67e3f182f5 | ||
|
|
6ed97f0d04 | ||
|
|
743862857e | ||
|
|
e8bdf8171b | ||
|
|
7319420c8f | ||
|
|
e8d771fcac | ||
|
|
32b3618c74 | ||
|
|
22e72e19b3 | ||
|
|
485568d460 | ||
|
|
e32704e7f6 | ||
|
|
03bc45a26a | ||
|
|
1e524b7210 | ||
|
|
5a09b6496d | ||
|
|
2aa5911fb9 | ||
|
|
a19c0a8255 | ||
|
|
4d8b912acc | ||
|
|
1af8987c79 | ||
|
|
78649d45b9 | ||
|
|
899ae8aa8e | ||
|
|
b6c141c059 | ||
|
|
316836f43b | ||
|
|
6123339baf | ||
|
|
35918cbd7e | ||
|
|
c8e0341248 | ||
|
|
4ad97f6a36 | ||
|
|
09cfad9d71 | ||
|
|
7fa84518c8 | ||
|
|
6675aec686 | ||
|
|
e271bae5ec | ||
|
|
142ba6660a | ||
|
|
b27196b770 | ||
|
|
811bc62d65 | ||
|
|
f476aa937e | ||
|
|
932110fb93 | ||
|
|
1865e8f088 | ||
|
|
fdae1face5 | ||
|
|
ad39d8707d | ||
|
|
cc61650f86 | ||
|
|
b2805823ce | ||
|
|
1dc6a2fea6 | ||
|
|
b38adaa736 | ||
|
|
80e9f76261 | ||
|
|
399a1afd94 | ||
|
|
8ddf4766ea | ||
|
|
966071d437 | ||
|
|
279cdd0760 | ||
|
|
1ab2744c84 | ||
|
|
47ffceef0d | ||
|
|
0ad1f0e233 | ||
|
|
1221c0ba3f | ||
|
|
d45e2074a6 | ||
|
|
03352ea863 | ||
|
|
713edd565c | ||
|
|
a32b7a32f3 | ||
|
|
04092f3e6b | ||
|
|
fc74a6c8ca | ||
|
|
2a669b95fb | ||
|
|
9d92b6eb92 | ||
|
|
73c741f20c | ||
|
|
929a05e898 | ||
|
|
268366e446 | ||
|
|
4cddfd1074 | ||
|
|
eb8296120b | ||
|
|
daac7f2988 | ||
|
|
ca46a79144 | ||
|
|
e155eb9fa3 | ||
|
|
4691b2b809 | ||
|
|
3ecf478ff0 | ||
|
|
c084130d3e | ||
|
|
f4af6b670c | ||
|
|
d9c763437e | ||
|
|
e78c4ab9b3 | ||
|
|
7247f8e41f | ||
|
|
b6b5046cce | ||
|
|
dde2ab59ae | ||
|
|
bb6235733d | ||
|
|
595ad44ee7 | ||
|
|
20fc5ffa38 | ||
|
|
6ef0c382c3 | ||
|
|
575e6add43 | ||
|
|
235377585d | ||
|
|
b74e085272 | ||
|
|
008fbbd652 | ||
|
|
c3d41d4e17 | ||
|
|
faa3a79a5f | ||
|
|
03dd33dbbe | ||
|
|
049b48928f | ||
|
|
75ad0c3c2d | ||
|
|
79403f169e | ||
|
|
2790cf35af | ||
|
|
f9b63c5f8c | ||
|
|
db5e4da268 | ||
|
|
c1d8368fdc | ||
|
|
4b4104e400 | ||
|
|
ad348c8e2f | ||
|
|
b13aa8f172 | ||
|
|
9c92d77b64 | ||
|
|
cd95892bf0 | ||
|
|
7b4ab2077b | ||
|
|
578b5691bc | ||
|
|
6353fa72d8 | ||
|
|
fd07ca87ce | ||
|
|
11ae85645b | ||
|
|
3aabb0314a | ||
|
|
13ccb8cbfe | ||
|
|
efdb854a7c | ||
|
|
98f4d37f1a | ||
|
|
37673c6de6 | ||
|
|
7896af731f | ||
|
|
877dfbe992 | ||
|
|
5b9ea1b4e0 | ||
|
|
710fda49f0 | ||
|
|
2b14bda6b8 | ||
|
|
1abfc5b1cf | ||
|
|
c9bd5ec452 | ||
|
|
51643caf60 | ||
|
|
ee63be26a1 | ||
|
|
1900c907fd | ||
|
|
a9d4495d83 | ||
|
|
7b8447a95a | ||
|
|
7931f1f8f9 | ||
|
|
20b75022aa | ||
|
|
dbc8903bac | ||
|
|
a4f720d866 | ||
|
|
4b8369c071 | ||
|
|
72333147d3 | ||
|
|
64cda4aeda | ||
|
|
6ede77b254 | ||
|
|
c94eee5fc3 | ||
|
|
322b85898f | ||
|
|
cf09dd044a | ||
|
|
a4c1a34163 | ||
|
|
d140909562 | ||
|
|
f9fd47e7d0 | ||
|
|
67fbf9eb00 | ||
|
|
730aceac6d | ||
|
|
1bf396f9af | ||
|
|
45c2f34295 | ||
|
|
ff10e0eaf1 | ||
|
|
6b8f526df3 | ||
|
|
e51ce5c508 | ||
|
|
8c41e17c93 | ||
|
|
5d72ebe0cc | ||
|
|
f07ce297f6 | ||
|
|
a87239e802 | ||
|
|
3e6c482229 | ||
|
|
176ecd4c3b | ||
|
|
211ad166af | ||
|
|
fe47d6a1a4 | ||
|
|
4dd93e5bbb | ||
|
|
10f2445a99 | ||
|
|
f1b24598f5 | ||
|
|
2d0929e305 | ||
|
|
8e01e73de4 | ||
|
|
7c8edf5632 | ||
|
|
25284b5325 | ||
|
|
06d2ac65b5 | ||
|
|
e3888b38bb | ||
|
|
5da2995bcd | ||
|
|
92e6f29cc8 | ||
|
|
a2468656e4 | ||
|
|
0358ad83cb | ||
|
|
3aab77af8d | ||
|
|
85447abe7f | ||
|
|
71c6d05902 | ||
|
|
8d062bc880 | ||
|
|
9e2d46b33f | ||
|
|
6080431383 | ||
|
|
5cafdc2f29 | ||
|
|
ff845aa793 | ||
|
|
55c9271695 | ||
|
|
f148397e1b | ||
|
|
82c9e72aab | ||
|
|
cdeac2bca0 | ||
|
|
4682e72cf4 | ||
|
|
1e5e69ec9d | ||
|
|
6e5f521463 | ||
|
|
abdad1f6d3 | ||
|
|
752f4a3d67 | ||
|
|
550e2743d7 | ||
|
|
8f9e730ad6 | ||
|
|
4235a97cf4 | ||
|
|
8b19b84140 | ||
|
|
5b585c0285 | ||
|
|
b0e7bc15c2 | ||
|
|
533349cc0d | ||
|
|
eab8fecd26 | ||
|
|
1f2621b574 | ||
|
|
ff8b95df93 | ||
|
|
8f6f21c94c | ||
|
|
7a938b2dea | ||
|
|
2e76375e8a | ||
|
|
9715113898 | ||
|
|
8e46b9ea5d | ||
|
|
33dfcf2663 | ||
|
|
7508d96327 | ||
|
|
b8bf2af3e3 | ||
|
|
9ee940098d | ||
|
|
e476cf7968 | ||
|
|
c315111bc7 | ||
|
|
8a47a71772 | ||
|
|
b115e2879a | ||
|
|
73ec10a49e | ||
|
|
325a4c0e5b | ||
|
|
b360c9403f | ||
|
|
ca4ee1e8cf | ||
|
|
2e5474e864 | ||
|
|
19c8ea3288 | ||
|
|
6260271b78 | ||
|
|
83427c478f | ||
|
|
0870f48b5c | ||
|
|
c3fb68545a | ||
|
|
aa599bfaf9 | ||
|
|
62c0f35b5a | ||
|
|
0de1566eaf | ||
|
|
39bf59d372 | ||
|
|
554848fe6b | ||
|
|
d05d5bcb70 | ||
|
|
8d3f98fe38 | ||
|
|
826cdb2186 | ||
|
|
c394fbdfc3 | ||
|
|
2fb5837a55 | ||
|
|
8cbf1a3e1b | ||
|
|
04ce49130a | ||
|
|
3ff23ecbfa | ||
|
|
ab8bf393c2 | ||
|
|
d0390181ec | ||
|
|
2f5c036faa | ||
|
|
c41ccb6c37 | ||
|
|
9e40e246ec | ||
|
|
afac38e492 | ||
|
|
1cd93e63fd | ||
|
|
a3458213f4 | ||
|
|
c0f29ea9c6 | ||
|
|
fa09b9afb1 | ||
|
|
7dba12fc81 | ||
|
|
95442094df | ||
|
|
1ce1dbbc50 | ||
|
|
8ac20305df | ||
|
|
98fed009d7 | ||
|
|
c79f2b9d38 | ||
|
|
b38141601c | ||
|
|
03fa955e9e | ||
|
|
f41dd4feb6 | ||
|
|
f2496d87c9 | ||
|
|
0c062f9c08 | ||
|
|
d677826312 | ||
|
|
9ec1abf880 | ||
|
|
92d56d82f4 | ||
|
|
f628e121df | ||
|
|
2b29ceab83 | ||
|
|
4a874eff70 | ||
|
|
e3c250f240 | ||
|
|
899db1f7c3 | ||
|
|
d9562e2aee | ||
|
|
d568d6fabc | ||
|
|
da6752eccb | ||
|
|
9a5b13b7c8 | ||
|
|
8459d75597 | ||
|
|
b780a64ed9 | ||
|
|
60fae3a59d | ||
|
|
c1d04a9d13 | ||
|
|
424c27bada | ||
|
|
3c57b980e5 | ||
|
|
52411b12e3 | ||
|
|
6f8d00310b | ||
|
|
f955084572 | ||
|
|
d923620d5a | ||
|
|
2a862d497f | ||
|
|
bda4e5be95 | ||
|
|
ae12c70afe | ||
|
|
efe9ec4906 | ||
|
|
b161f56bd2 | ||
|
|
3464dc2fdf | ||
|
|
893998cb70 | ||
|
|
083c5b003c | ||
|
|
8c8652e7bb | ||
|
|
051d993d62 | ||
|
|
07c842d6e0 | ||
|
|
b9d3585f4c | ||
|
|
05afaf6094 | ||
|
|
3a52f05692 | ||
|
|
64bf3fccd2 | ||
|
|
dec79c70a1 | ||
|
|
21a8f71859 | ||
|
|
edfc2c215c | ||
|
|
16d491a134 | ||
|
|
7559e4311e | ||
|
|
a41b4acec3 | ||
|
|
fd50cd128a | ||
|
|
e99b98873c | ||
|
|
6b953a03d0 | ||
|
|
37a3e610b7 | ||
|
|
f87d8d0b7f | ||
|
|
5ff6148444 | ||
|
|
0130b28879 | ||
|
|
4cdd830003 | ||
|
|
f1425dcb26 | ||
|
|
cd8d3a0c88 | ||
|
|
8729ee4fa2 | ||
|
|
544cfa63ab | ||
|
|
0b9a2cc11c | ||
|
|
25768a291e | ||
|
|
19bd9cf945 | ||
|
|
8aabe1b488 | ||
|
|
3a0f80da74 | ||
|
|
5911780735 | ||
|
|
1e24ef4d0d | ||
|
|
207d33eaba | ||
|
|
d645c5fbab | ||
|
|
960759d22b | ||
|
|
5b7da270c9 | ||
|
|
58edb1b15d | ||
|
|
655051ef98 | ||
|
|
93653d9a58 | ||
|
|
492fb9d054 | ||
|
|
4e16d600b0 | ||
|
|
fa8372a83b | ||
|
|
9614f6db8d | ||
|
|
e216aefd23 | ||
|
|
cf7dd36829 | ||
|
|
3fb71cdfea | ||
|
|
a01f5d4495 | ||
|
|
d16c5d0e93 | ||
|
|
825e2c9527 | ||
|
|
c309686679 | ||
|
|
3dc3f55ecb | ||
|
|
f59bfd65da | ||
|
|
33f2d24f54 | ||
|
|
03a4316dcd | ||
|
|
4cb5622d18 | ||
|
|
4abcdd80bf | ||
|
|
4963fe7809 | ||
|
|
a64cf77e84 | ||
|
|
57fa377730 | ||
|
|
d4f46122f7 | ||
|
|
bf23e59900 | ||
|
|
c578efaabd | ||
|
|
a98ca86a45 | ||
|
|
b26d952d09 | ||
|
|
736fb5c5b0 | ||
|
|
a777cf7166 | ||
|
|
6ff889c8d6 | ||
|
|
5ec5ebac31 | ||
|
|
793b5c7cc3 | ||
|
|
237d0bb1b0 | ||
|
|
61e173215b | ||
|
|
6f316cddbb | ||
|
|
75d8c52004 | ||
|
|
6867f017ec | ||
|
|
3fd55fa56b | ||
|
|
572114b8ba | ||
|
|
1215f26a84 | ||
|
|
d4fa5a0f1d | ||
|
|
2c3d0d826d | ||
|
|
100e198eb3 | ||
|
|
63d7ca328f | ||
|
|
b72b12a960 | ||
|
|
0523c946f9 | ||
|
|
4172a3c8b7 | ||
|
|
9b11c4b319 | ||
|
|
135186e33d | ||
|
|
f82a262ffe | ||
|
|
4b685c5e26 | ||
|
|
921fda94c7 | ||
|
|
1078dff3a9 | ||
|
|
8a923fb420 | ||
|
|
ced22687eb | ||
|
|
177282d9f9 | ||
|
|
cddf63efe9 | ||
|
|
1bc987772c | ||
|
|
c755ceeffa | ||
|
|
6db8a862bb | ||
|
|
6311e53a76 | ||
|
|
ef65ddf351 | ||
|
|
a54ac2ef79 | ||
|
|
86cf17c1f4 | ||
|
|
daa2d89ef5 | ||
|
|
0e53275d40 | ||
|
|
dda1a42a2a | ||
|
|
a259c7bd75 | ||
|
|
d10d0a20b1 | ||
|
|
70b8557b63 | ||
|
|
0e7e252951 | ||
|
|
d53a9e877a | ||
|
|
a03e9e34ab | ||
|
|
d874c633d7 | ||
|
|
dedf46ed1f | ||
|
|
d42f7e4a1c | ||
|
|
dd20829dbe | ||
|
|
670bd993f3 | ||
|
|
6f6f5d79fb | ||
|
|
3f4eaa99d5 | ||
|
|
94e1a833d6 | ||
|
|
27e48d73dd | ||
|
|
aa1b770974 | ||
|
|
bb56e97177 | ||
|
|
0f22d51309 | ||
|
|
b1734f84b3 | ||
|
|
839fc8df7d | ||
|
|
a4728d3c72 | ||
|
|
6806bff57b | ||
|
|
66f8f8aff2 | ||
|
|
bc384c01e3 | ||
|
|
976a3a5e7b | ||
|
|
122b319520 | ||
|
|
29d5976c01 | ||
|
|
cd266a05d2 | ||
|
|
6ba2533e2b | ||
|
|
dd327f0b22 | ||
|
|
927448601c | ||
|
|
1f04cc1f23 | ||
|
|
ec6580d840 | ||
|
|
9e7d9affbe | ||
|
|
52fbee6749 | ||
|
|
0f0a70e251 | ||
|
|
fac769ff17 | ||
|
|
690be5bf7f | ||
|
|
1d8de2791a | ||
|
|
3e32aa896c | ||
|
|
65ecca2904 | ||
|
|
62de84d5b6 | ||
|
|
2f30322a4e | ||
|
|
145c862ee0 | ||
|
|
bd1bec5c93 | ||
|
|
2f1f35cc71 | ||
|
|
be1123b5df | ||
|
|
5ccb4586b5 | ||
|
|
d8d708704d | ||
|
|
063eefe896 | ||
|
|
65819140dd | ||
|
|
0e2278cc76 | ||
|
|
bdd56d2516 | ||
|
|
7fb590208c | ||
|
|
02b00c025a | ||
|
|
8935c4386c | ||
|
|
bcd2c71031 | ||
|
|
69495f5b59 | ||
|
|
3f703ff8a4 | ||
|
|
46d8ae47dc | ||
|
|
5bc4ee257f | ||
|
|
aac6d88f72 | ||
|
|
f00698aafd | ||
|
|
e1634128c1 | ||
|
|
a3ea3ad911 | ||
|
|
0eec00055f | ||
|
|
e8df325796 | ||
|
|
ec8baf23d8 | ||
|
|
63487e1d69 | ||
|
|
a0353c8627 | ||
|
|
6ecbcebd44 | ||
|
|
0f83a0a634 | ||
|
|
e6a8c278f5 | ||
|
|
780dfa0c7c | ||
|
|
5e692f9071 | ||
|
|
40c61a310f | ||
|
|
22ce395130 | ||
|
|
716b4a3b09 | ||
|
|
eb48dc9b68 | ||
|
|
fc7d4a13b0 | ||
|
|
73ca65a6ff | ||
|
|
f157ac9b68 | ||
|
|
773f896bcd | ||
|
|
0001a6bad0 | ||
|
|
a64f2421d2 | ||
|
|
8a42462271 | ||
|
|
b08bf32040 | ||
|
|
a45803d8a0 | ||
|
|
ec00e73c9d | ||
|
|
dd20cb7301 | ||
|
|
ac3cdf75fa | ||
|
|
3e288f1066 | ||
|
|
80d5e52923 | ||
|
|
a51b08e386 | ||
|
|
6b7b9793ab | ||
|
|
e4233e45be | ||
|
|
47bac4a0c9 | ||
|
|
b31480232b | ||
|
|
73c7e9edf1 | ||
|
|
5eb5fcd0f4 | ||
|
|
fbcb05388e | ||
|
|
0addca1070 | ||
|
|
a8fcaeb141 | ||
|
|
2e057b8f52 | ||
|
|
84710cf27e | ||
|
|
7ed40c1ec7 | ||
|
|
97a91f23f1 | ||
|
|
5065626984 | ||
|
|
15263bc0d7 | ||
|
|
8c4c2eeffc | ||
|
|
d7528557df | ||
|
|
dc26f3bd74 | ||
|
|
8652f80ab3 | ||
|
|
e5895af4a2 | ||
|
|
dfb65ed89f | ||
|
|
6c31cecc7d | ||
|
|
095361bead | ||
|
|
9108828aeb | ||
|
|
8e376c84cf | ||
|
|
0169d0dafd | ||
|
|
a0d76bda99 | ||
|
|
36f1a8f3ca | ||
|
|
f04bae3f0b | ||
|
|
95f86f9de0 | ||
|
|
e8ef39e734 | ||
|
|
702a7815b9 | ||
|
|
276eabd4e5 | ||
|
|
509aea5d04 | ||
|
|
f7a49e7be7 | ||
|
|
21e6c963ab | ||
|
|
74d3ba6b5e | ||
|
|
43cde484f4 | ||
|
|
c31f4de7d5 | ||
|
|
6fd1609410 | ||
|
|
9c75a3aaa8 | ||
|
|
a3d8494a04 | ||
|
|
a9e22df765 | ||
|
|
b9b4a2659d | ||
|
|
072297e661 | ||
|
|
13b260e7f7 | ||
|
|
ac31651a42 | ||
|
|
49c619d65d | ||
|
|
b0a9a27288 | ||
|
|
c9a557e0d9 | ||
|
|
fcb7cd0eb0 | ||
|
|
9ccd4ee240 | ||
|
|
84c48de5d9 | ||
|
|
9f6265e0b4 | ||
|
|
a5be80828a | ||
|
|
3969d6b767 | ||
|
|
dad9190142 | ||
|
|
9d143426ee | ||
|
|
727765b248 | ||
|
|
780c40329e | ||
|
|
489782e21b | ||
|
|
5d6398f20e | ||
|
|
6ce5879071 | ||
|
|
05c1325885 | ||
|
|
9331714089 | ||
|
|
d5e1cc095c | ||
|
|
c2437b7bf2 | ||
|
|
bfd1099ef3 | ||
|
|
f3b691d618 | ||
|
|
66c8c66f40 | ||
|
|
0cfc344f82 | ||
|
|
c3ecf8355d | ||
|
|
a09aa0aa72 | ||
|
|
91f6d4b013 | ||
|
|
40d16a8f88 | ||
|
|
f88fcdbcfc | ||
|
|
e16e9ad343 | ||
|
|
7d2b3f05db | ||
|
|
9d4489360b | ||
|
|
5f1783c9a5 | ||
|
|
7655e660f3 | ||
|
|
a5847fd06f | ||
|
|
91fb111462 | ||
|
|
8665e32221 | ||
|
|
07f1be0ff6 | ||
|
|
1449644c34 | ||
|
|
5454aebf13 | ||
|
|
a4fd3de0b0 | ||
|
|
599a6bfb24 | ||
|
|
60fe55cdc0 | ||
|
|
501308239f | ||
|
|
21e27b8034 | ||
|
|
8d3017febb | ||
|
|
d196c236b8 | ||
|
|
f8c675bc5e | ||
|
|
caf3cfa7d8 | ||
|
|
bfee6699d2 | ||
|
|
627d4fbf74 | ||
|
|
a633f93707 | ||
|
|
588d6ec828 | ||
|
|
025d8ebc59 | ||
|
|
189f5f8aae | ||
|
|
3c37078a85 | ||
|
|
e309293a47 | ||
|
|
4d87f16e95 | ||
|
|
053317e334 | ||
|
|
662c51605f | ||
|
|
f01015bac5 | ||
|
|
ad16bafa66 | ||
|
|
b45924a234 | ||
|
|
fb911a4542 | ||
|
|
9297e1b90d | ||
|
|
4eaf89666f |
+84
-1
@@ -390,7 +390,7 @@ jobs:
|
|||||||
|
|
||||||
build-appimage:
|
build-appimage:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2004:202104-01
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
@@ -398,6 +398,16 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: install appimage-builder
|
name: install appimage-builder
|
||||||
command: |
|
command: |
|
||||||
|
# appimage-builder requires /dev/snd to exist. It creates containers during the testing phase
|
||||||
|
# that pass sound devices from the host to the testing container. (hard coded!)
|
||||||
|
# https://github.com/AppImageCrafters/appimage-builder/blob/master/appimagebuilder/modules/test/execution_test.py#L54
|
||||||
|
# Circleci doesn't provide a working sound device; this is enough to fake it.
|
||||||
|
if [ ! -e /dev/snd ]
|
||||||
|
then
|
||||||
|
sudo mkdir /dev/snd
|
||||||
|
sudo mknod /dev/snd/ControlC0 c 1 2
|
||||||
|
fi
|
||||||
|
|
||||||
# docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html
|
# docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace
|
sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace
|
||||||
@@ -618,6 +628,11 @@ jobs:
|
|||||||
default: "latest"
|
default: "latest"
|
||||||
description: A comma-separated string containing docker image tags to build and push (default = latest)
|
description: A comma-separated string containing docker image tags to build and push (default = latest)
|
||||||
|
|
||||||
|
target:
|
||||||
|
type: string
|
||||||
|
default: "lotus-all-in-one"
|
||||||
|
description: Docker target to build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- run:
|
- run:
|
||||||
name: Confirm that environment variables are set
|
name: Confirm that environment variables are set
|
||||||
@@ -657,6 +672,7 @@ jobs:
|
|||||||
|
|
||||||
docker build \
|
docker build \
|
||||||
<<#parameters.extra-build-args>><<parameters.extra-build-args>><</parameters.extra-build-args>> \
|
<<#parameters.extra-build-args>><<parameters.extra-build-args>><</parameters.extra-build-args>> \
|
||||||
|
--target <<parameters.target>> \
|
||||||
-f <<parameters.path>>/<<parameters.dockerfile>> \
|
-f <<parameters.path>>/<<parameters.dockerfile>> \
|
||||||
$docker_tag_args \
|
$docker_tag_args \
|
||||||
<<parameters.path>>
|
<<parameters.path>>
|
||||||
@@ -705,6 +721,17 @@ jobs:
|
|||||||
- packer/build:
|
- packer/build:
|
||||||
template: tools/packer/lotus.pkr.hcl
|
template: tools/packer/lotus.pkr.hcl
|
||||||
args: "-var ci_workspace_bins=./linux-butterflynet -var lotus_network=butterflynet -var git_tag=$CIRCLE_TAG"
|
args: "-var ci_workspace_bins=./linux-butterflynet -var lotus_network=butterflynet -var git_tag=$CIRCLE_TAG"
|
||||||
|
publish-packer-snap:
|
||||||
|
description: build packer image with snap. mainnet only.
|
||||||
|
executor:
|
||||||
|
name: packer/default
|
||||||
|
packer-version: 1.6.6
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: "."
|
||||||
|
- packer/build:
|
||||||
|
template: tools/packer/lotus-snap.pkr.hcl
|
||||||
publish-dockerhub:
|
publish-dockerhub:
|
||||||
description: publish to dockerhub
|
description: publish to dockerhub
|
||||||
machine:
|
machine:
|
||||||
@@ -785,6 +812,11 @@ workflows:
|
|||||||
suite: itest-deals_512mb
|
suite: itest-deals_512mb
|
||||||
target: "./itests/deals_512mb_test.go"
|
target: "./itests/deals_512mb_test.go"
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: test-itest-deals_anycid
|
||||||
|
suite: itest-deals_anycid
|
||||||
|
target: "./itests/deals_anycid_test.go"
|
||||||
|
|
||||||
- test:
|
- test:
|
||||||
name: test-itest-deals_concurrent
|
name: test-itest-deals_concurrent
|
||||||
suite: itest-deals_concurrent
|
suite: itest-deals_concurrent
|
||||||
@@ -850,6 +882,11 @@ workflows:
|
|||||||
suite: itest-get_messages_in_ts
|
suite: itest-get_messages_in_ts
|
||||||
target: "./itests/get_messages_in_ts_test.go"
|
target: "./itests/get_messages_in_ts_test.go"
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: test-itest-mempool
|
||||||
|
suite: itest-mempool
|
||||||
|
target: "./itests/mempool_test.go"
|
||||||
|
|
||||||
- test:
|
- test:
|
||||||
name: test-itest-multisig
|
name: test-itest-multisig
|
||||||
suite: itest-multisig
|
suite: itest-multisig
|
||||||
@@ -880,6 +917,11 @@ workflows:
|
|||||||
suite: itest-sector_finalize_early
|
suite: itest-sector_finalize_early
|
||||||
target: "./itests/sector_finalize_early_test.go"
|
target: "./itests/sector_finalize_early_test.go"
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: test-itest-sector_make_cc_avail
|
||||||
|
suite: itest-sector_make_cc_avail
|
||||||
|
target: "./itests/sector_make_cc_avail_test.go"
|
||||||
|
|
||||||
- test:
|
- test:
|
||||||
name: test-itest-sector_miner_collateral
|
name: test-itest-sector_miner_collateral
|
||||||
suite: itest-sector_miner_collateral
|
suite: itest-sector_miner_collateral
|
||||||
@@ -890,6 +932,16 @@ workflows:
|
|||||||
suite: itest-sector_pledge
|
suite: itest-sector_pledge
|
||||||
target: "./itests/sector_pledge_test.go"
|
target: "./itests/sector_pledge_test.go"
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: test-itest-sector_prefer_no_upgrade
|
||||||
|
suite: itest-sector_prefer_no_upgrade
|
||||||
|
target: "./itests/sector_prefer_no_upgrade_test.go"
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: test-itest-sector_revert_available
|
||||||
|
suite: itest-sector_revert_available
|
||||||
|
target: "./itests/sector_revert_available_test.go"
|
||||||
|
|
||||||
- test:
|
- test:
|
||||||
name: test-itest-sector_terminate
|
name: test-itest-sector_terminate
|
||||||
suite: itest-sector_terminate
|
suite: itest-sector_terminate
|
||||||
@@ -920,6 +972,11 @@ workflows:
|
|||||||
suite: itest-wdpost
|
suite: itest-wdpost
|
||||||
target: "./itests/wdpost_test.go"
|
target: "./itests/wdpost_test.go"
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: test-itest-worker
|
||||||
|
suite: itest-worker
|
||||||
|
target: "./itests/worker_test.go"
|
||||||
|
|
||||||
- test:
|
- test:
|
||||||
name: test-unit-cli
|
name: test-unit-cli
|
||||||
suite: utest-unit-cli
|
suite: utest-unit-cli
|
||||||
@@ -981,10 +1038,19 @@ workflows:
|
|||||||
tags:
|
tags:
|
||||||
only:
|
only:
|
||||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||||
|
- build-appimage:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore:
|
||||||
|
- /.*/
|
||||||
|
tags:
|
||||||
|
only:
|
||||||
|
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||||
- publish:
|
- publish:
|
||||||
requires:
|
requires:
|
||||||
- build-all
|
- build-all
|
||||||
- build-macos
|
- build-macos
|
||||||
|
- build-appimage
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore:
|
ignore:
|
||||||
@@ -997,6 +1063,13 @@ workflows:
|
|||||||
path: .
|
path: .
|
||||||
repo: lotus-dev
|
repo: lotus-dev
|
||||||
tag: '${CIRCLE_SHA1:0:8}'
|
tag: '${CIRCLE_SHA1:0:8}'
|
||||||
|
target: lotus-all-in-one
|
||||||
|
- build-and-push-image:
|
||||||
|
dockerfile: Dockerfile.lotus
|
||||||
|
path: .
|
||||||
|
repo: lotus-test
|
||||||
|
tag: '${CIRCLE_SHA1:0:8}'
|
||||||
|
target: lotus-test
|
||||||
- publish-packer-mainnet:
|
- publish-packer-mainnet:
|
||||||
requires:
|
requires:
|
||||||
- build-all
|
- build-all
|
||||||
@@ -1063,3 +1136,13 @@ workflows:
|
|||||||
- publish-dockerhub:
|
- publish-dockerhub:
|
||||||
name: publish-dockerhub-nightly
|
name: publish-dockerhub-nightly
|
||||||
tag: nightly
|
tag: nightly
|
||||||
|
monthly:
|
||||||
|
triggers:
|
||||||
|
- schedule:
|
||||||
|
cron: "0 0 1 * *"
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
- publish-packer-snap
|
||||||
|
|||||||
+54
-1
@@ -390,7 +390,7 @@ jobs:
|
|||||||
|
|
||||||
build-appimage:
|
build-appimage:
|
||||||
machine:
|
machine:
|
||||||
image: ubuntu-2004:202104-01
|
image: ubuntu-2004:202111-02
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
@@ -398,6 +398,16 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: install appimage-builder
|
name: install appimage-builder
|
||||||
command: |
|
command: |
|
||||||
|
# appimage-builder requires /dev/snd to exist. It creates containers during the testing phase
|
||||||
|
# that pass sound devices from the host to the testing container. (hard coded!)
|
||||||
|
# https://github.com/AppImageCrafters/appimage-builder/blob/master/appimagebuilder/modules/test/execution_test.py#L54
|
||||||
|
# Circleci doesn't provide a working sound device; this is enough to fake it.
|
||||||
|
if [ ! -e /dev/snd ]
|
||||||
|
then
|
||||||
|
sudo mkdir /dev/snd
|
||||||
|
sudo mknod /dev/snd/ControlC0 c 1 2
|
||||||
|
fi
|
||||||
|
|
||||||
# docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html
|
# docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace
|
sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace
|
||||||
@@ -618,6 +628,11 @@ jobs:
|
|||||||
default: "latest"
|
default: "latest"
|
||||||
description: A comma-separated string containing docker image tags to build and push (default = latest)
|
description: A comma-separated string containing docker image tags to build and push (default = latest)
|
||||||
|
|
||||||
|
target:
|
||||||
|
type: string
|
||||||
|
default: "lotus-all-in-one"
|
||||||
|
description: Docker target to build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- run:
|
- run:
|
||||||
name: Confirm that environment variables are set
|
name: Confirm that environment variables are set
|
||||||
@@ -657,6 +672,7 @@ jobs:
|
|||||||
|
|
||||||
docker build \
|
docker build \
|
||||||
<<#parameters.extra-build-args>><<parameters.extra-build-args>><</parameters.extra-build-args>> \
|
<<#parameters.extra-build-args>><<parameters.extra-build-args>><</parameters.extra-build-args>> \
|
||||||
|
--target <<parameters.target>> \
|
||||||
-f <<parameters.path>>/<<parameters.dockerfile>> \
|
-f <<parameters.path>>/<<parameters.dockerfile>> \
|
||||||
$docker_tag_args \
|
$docker_tag_args \
|
||||||
<<parameters.path>>
|
<<parameters.path>>
|
||||||
@@ -705,6 +721,17 @@ jobs:
|
|||||||
- packer/build:
|
- packer/build:
|
||||||
template: tools/packer/lotus.pkr.hcl
|
template: tools/packer/lotus.pkr.hcl
|
||||||
args: "-var ci_workspace_bins=./linux-butterflynet -var lotus_network=butterflynet -var git_tag=$CIRCLE_TAG"
|
args: "-var ci_workspace_bins=./linux-butterflynet -var lotus_network=butterflynet -var git_tag=$CIRCLE_TAG"
|
||||||
|
publish-packer-snap:
|
||||||
|
description: build packer image with snap. mainnet only.
|
||||||
|
executor:
|
||||||
|
name: packer/default
|
||||||
|
packer-version: 1.6.6
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: "."
|
||||||
|
- packer/build:
|
||||||
|
template: tools/packer/lotus-snap.pkr.hcl
|
||||||
publish-dockerhub:
|
publish-dockerhub:
|
||||||
description: publish to dockerhub
|
description: publish to dockerhub
|
||||||
machine:
|
machine:
|
||||||
@@ -816,10 +843,19 @@ workflows:
|
|||||||
tags:
|
tags:
|
||||||
only:
|
only:
|
||||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||||
|
- build-appimage:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
ignore:
|
||||||
|
- /.*/
|
||||||
|
tags:
|
||||||
|
only:
|
||||||
|
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||||
- publish:
|
- publish:
|
||||||
requires:
|
requires:
|
||||||
- build-all
|
- build-all
|
||||||
- build-macos
|
- build-macos
|
||||||
|
- build-appimage
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore:
|
ignore:
|
||||||
@@ -832,6 +868,13 @@ workflows:
|
|||||||
path: .
|
path: .
|
||||||
repo: lotus-dev
|
repo: lotus-dev
|
||||||
tag: '${CIRCLE_SHA1:0:8}'
|
tag: '${CIRCLE_SHA1:0:8}'
|
||||||
|
target: lotus-all-in-one
|
||||||
|
- build-and-push-image:
|
||||||
|
dockerfile: Dockerfile.lotus
|
||||||
|
path: .
|
||||||
|
repo: lotus-test
|
||||||
|
tag: '${CIRCLE_SHA1:0:8}'
|
||||||
|
target: lotus-test
|
||||||
- publish-packer-mainnet:
|
- publish-packer-mainnet:
|
||||||
requires:
|
requires:
|
||||||
- build-all
|
- build-all
|
||||||
@@ -898,3 +941,13 @@ workflows:
|
|||||||
- publish-dockerhub:
|
- publish-dockerhub:
|
||||||
name: publish-dockerhub-nightly
|
name: publish-dockerhub-nightly
|
||||||
tag: nightly
|
tag: nightly
|
||||||
|
monthly:
|
||||||
|
triggers:
|
||||||
|
- schedule:
|
||||||
|
cron: "0 0 1 * *"
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
- publish-packer-snap
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
Before you mark the PR ready for review, please make sure that:
|
Before you mark the PR ready for review, please make sure that:
|
||||||
- [ ] All commits have a clear commit message.
|
- [ ] All commits have a clear commit message.
|
||||||
- [ ] The PR title is in the form of `<PR type>: <area>: <change being made>`
|
- [ ] The PR title is in the form of of `<PR type>: <area>: <change being made>`
|
||||||
- example: ` fix: mempool: Introduce a cache for valid signatures`
|
- example: ` fix: mempool: Introduce a cache for valid signatures`
|
||||||
- `PR type`: _fix_, _feat_, _INTERFACE BREAKING CHANGE_, _CONSENSUS BREAKING_, _build_, _chore_, _ci_, _docs_, _misc_,_perf_, _refactor_, _revert_, _style_, _test_
|
- `PR type`: _fix_, _feat_, _INTERFACE BREAKING CHANGE_, _CONSENSUS BREAKING_, _build_, _chore_, _ci_, _docs_,_perf_, _refactor_, _revert_, _style_, _test_
|
||||||
- `area`: _api_, _chain_, _state_, _vm_, _data transfer_, _market_, _mempool_, _message_, _block production_, _multisig_, _networking_, _paychan_, _proving_, _sealing_, _wallet_
|
- `area`: _api_, _chain_, _state_, _vm_, _data transfer_, _market_, _mempool_, _message_, _block production_, _multisig_, _networking_, _paychan_, _proving_, _sealing_, _wallet_, _deps_
|
||||||
- [ ] This PR has tests for new functionality or change in behaviour
|
- [ ] This PR has tests for new functionality or change in behaviour
|
||||||
- [ ] If new user-facing features are introduced, clear usage guidelines and / or documentation updates should be included in https://lotus.filecoin.io or [Discussion Tutorials.](https://github.com/filecoin-project/lotus/discussions/categories/tutorials)
|
- [ ] If new user-facing features are introduced, clear usage guidelines and / or documentation updates should be included in https://lotus.filecoin.io or [Discussion Tutorials.](https://github.com/filecoin-project/lotus/discussions/categories/tutorials)
|
||||||
- [ ] CI is green
|
- [ ] CI is green
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ build/paramfetch.sh
|
|||||||
/bundle
|
/bundle
|
||||||
/darwin
|
/darwin
|
||||||
/linux
|
/linux
|
||||||
|
*.snap
|
||||||
|
|
||||||
*-fuzz.zip
|
*-fuzz.zip
|
||||||
/chain/types/work_msg/
|
/chain/types/work_msg/
|
||||||
|
|||||||
+5
-5
@@ -49,23 +49,23 @@ AppDir:
|
|||||||
fedora:
|
fedora:
|
||||||
image: appimagecrafters/tests-env:fedora-30
|
image: appimagecrafters/tests-env:fedora-30
|
||||||
command: ./AppRun
|
command: ./AppRun
|
||||||
use_host_x: true
|
use_host_x: false
|
||||||
debian:
|
debian:
|
||||||
image: appimagecrafters/tests-env:debian-stable
|
image: appimagecrafters/tests-env:debian-stable
|
||||||
command: ./AppRun
|
command: ./AppRun
|
||||||
use_host_x: true
|
use_host_x: false
|
||||||
arch:
|
arch:
|
||||||
image: appimagecrafters/tests-env:archlinux-latest
|
image: appimagecrafters/tests-env:archlinux-latest
|
||||||
command: ./AppRun
|
command: ./AppRun
|
||||||
use_host_x: true
|
use_host_x: false
|
||||||
centos:
|
centos:
|
||||||
image: appimagecrafters/tests-env:centos-7
|
image: appimagecrafters/tests-env:centos-7
|
||||||
command: ./AppRun
|
command: ./AppRun
|
||||||
use_host_x: true
|
use_host_x: false
|
||||||
ubuntu:
|
ubuntu:
|
||||||
image: appimagecrafters/tests-env:ubuntu-xenial
|
image: appimagecrafters/tests-env:ubuntu-xenial
|
||||||
command: ./AppRun
|
command: ./AppRun
|
||||||
use_host_x: true
|
use_host_x: false
|
||||||
AppImage:
|
AppImage:
|
||||||
arch: x86_64
|
arch: x86_64
|
||||||
update-information: guess
|
update-information: guess
|
||||||
|
|||||||
+328
-200
@@ -1,12 +1,141 @@
|
|||||||
# Lotus changelog
|
# Lotus changelog
|
||||||
|
|
||||||
|
# 1.15.0 / 2022-03-09
|
||||||
|
|
||||||
|
This is an optional release with retrieval improvements(client side), SP ux with unsealing, snap deals and regular deal making and many other new features, improvements and bug fixes.
|
||||||
|
|
||||||
|
## Highlights
|
||||||
|
- feat:sealing: StartEpochSealingBuffer triggers packing on time([filecoin-project/lotus#7905](https://github.com/filecoin-project/lotus/pull/7905))
|
||||||
|
- use the `StartEpochSealingBuffer` configuration variable as a way to enforce that sectors are packed for sealing / updating no matter how many deals they have if the nearest deal start date is close enough to the present.
|
||||||
|
- feat: #6017 market: retrieval ask CLI command ([filecoin-project/lotus#7814](https://github.com/filecoin-project/lotus/pull/7814))
|
||||||
|
- feat(graphsync): allow setting of per-peer incoming requests for miners ([filecoin-project/lotus#7578](https://github.com/filecoin-project/lotus/pull/7578))
|
||||||
|
- by setting `SimultaneousTransfersForStoragePerClient` in deal making configuration.
|
||||||
|
- Make retrieval even faster ([filecoin-project/lotus#7746](https://github.com/filecoin-project/lotus/pull/7746))
|
||||||
|
- feat: #7747 sealing: Adding conf variable for capping number of concurrent unsealing jobs (#7884) ([filecoin-project/lotus#7884](https://github.com/filecoin-project/lotus/pull/7884))
|
||||||
|
- by setting `MaxConcurrentUnseals` in `DAGStoreConfig`
|
||||||
|
|
||||||
|
## New Features
|
||||||
|
- feat: mpool: Cache state nonces ([filecoin-project/lotus#8005](https://github.com/filecoin-project/lotus/pull/8005))
|
||||||
|
- chore: build: make the OhSnap epoch configurable by an envvar for devnets ([filecoin-project/lotus#7995](https://github.com/filecoin-project/lotus/pull/7995))
|
||||||
|
- Shed: Add a util to send a batch of messages ([filecoin-project/lotus#7667](https://github.com/filecoin-project/lotus/pull/7667))
|
||||||
|
- Add api for transfer diagnostics ([filecoin-project/lotus#7759](https://github.com/filecoin-project/lotus/pull/7759))
|
||||||
|
- Shed: Add a util to list terminated deals ([filecoin-project/lotus#7774](https://github.com/filecoin-project/lotus/pull/7774))
|
||||||
|
- Expose EnableGasTracing as an env_var ([filecoin-project/lotus#7750](https://github.com/filecoin-project/lotus/pull/7750))
|
||||||
|
- Command to list active sector locks ([filecoin-project/lotus#7735](https://github.com/filecoin-project/lotus/pull/7735))
|
||||||
|
- Initial switch to OpenTelemetry ([filecoin-project/lotus#7725](https://github.com/filecoin-project/lotus/pull/7725))
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
- splitstore sortless compaction ([filecoin-project/lotus#8008](https://github.com/filecoin-project/lotus/pull/8008))
|
||||||
|
- perf: chain: Make drand logs in daemon less noisy (#7955) ([filecoin-project/lotus#7955](https://github.com/filecoin-project/lotus/pull/7955))
|
||||||
|
- chore: shed: storage stats 2.0 ([filecoin-project/lotus#7941](https://github.com/filecoin-project/lotus/pull/7941))
|
||||||
|
- misc: api: Annotate lotus tests according to listed behaviors ([filecoin-project/lotus#7835](https://github.com/filecoin-project/lotus/pull/7835))
|
||||||
|
- some basic splitstore refactors ([filecoin-project/lotus#7999](https://github.com/filecoin-project/lotus/pull/7999))
|
||||||
|
- chore: sealer: quieten a log ([filecoin-project/lotus#7998](https://github.com/filecoin-project/lotus/pull/7998))
|
||||||
|
- tvx: supply network version when extracting messages. ([filecoin-project/lotus#7996](https://github.com/filecoin-project/lotus/pull/7996))
|
||||||
|
- chore: remove inaccurate comment in sealtasks ([filecoin-project/lotus#7977](https://github.com/filecoin-project/lotus/pull/7977))
|
||||||
|
- Refactor: VM: Remove the NetworkVersionGetter ([filecoin-project/lotus#7818](https://github.com/filecoin-project/lotus/pull/7818))
|
||||||
|
- refactor: state: Move randomness versioning out of the VM ([filecoin-project/lotus#7816](https://github.com/filecoin-project/lotus/pull/7816))
|
||||||
|
- updating to new datastore/blockstore code with contexts ([filecoin-project/lotus#7646](https://github.com/filecoin-project/lotus/pull/7646))
|
||||||
|
- Mempool msg selection should respect block message limits ([filecoin-project/lotus#7321](https://github.com/filecoin-project/lotus/pull/7321))
|
||||||
|
- Minor improvement for OpenTelemetry ([filecoin-project/lotus#7760](https://github.com/filecoin-project/lotus/pull/7760))
|
||||||
|
- Sort lotus-miner retrieval-deals by dealId ([filecoin-project/lotus#7749](https://github.com/filecoin-project/lotus/pull/7749))
|
||||||
|
- dagstore pieceReader: Always read full in ReadAt ([filecoin-project/lotus#7737](https://github.com/filecoin-project/lotus/pull/7737))
|
||||||
|
|
||||||
|
## Bug Fixes
|
||||||
|
- fix: sealing: Stop recovery attempts after fault ([filecoin-project/lotus#8014](https://github.com/filecoin-project/lotus/pull/8014))
|
||||||
|
- fix:snap: pay for the collateral difference needed if the miner available balance is insufficient ([filecoin-project/lotus#8234](https://github.com/filecoin-project/lotus/pull/8234))
|
||||||
|
- sealer: fix error message ([filecoin-project/lotus#8136](https://github.com/filecoin-project/lotus/pull/8136))
|
||||||
|
- typo in variable name ([filecoin-project/lotus#8134](https://github.com/filecoin-project/lotus/pull/8134))
|
||||||
|
- fix: sealer: allow enable/disabling ReplicaUpdate tasks ([filecoin-project/lotus#8093](https://github.com/filecoin-project/lotus/pull/8093))
|
||||||
|
- chore: chain: fix log ([filecoin-project/lotus#7993](https://github.com/filecoin-project/lotus/pull/7993))
|
||||||
|
- Fix: chain: create a new VM for each epoch ([filecoin-project/lotus#7966](https://github.com/filecoin-project/lotus/pull/7966))
|
||||||
|
- fix: doc generation struct slice example value ([filecoin-project/lotus#7851](https://github.com/filecoin-project/lotus/pull/7851))
|
||||||
|
- fix: returned error not be accept correctly ([filecoin-project/lotus#7852](https://github.com/filecoin-project/lotus/pull/7852))
|
||||||
|
- fix: #7577 markets: When retrying Add Piece, first seek to start of reader ([filecoin-project/lotus#7812](https://github.com/filecoin-project/lotus/pull/7812))
|
||||||
|
- misc: n/a sealing: Fix grammatical error in a log warning message ([filecoin-project/lotus#7831](https://github.com/filecoin-project/lotus/pull/7831))
|
||||||
|
- sectors update-state checks if sector exists before changing its state ([filecoin-project/lotus#7762](https://github.com/filecoin-project/lotus/pull/7762))
|
||||||
|
- SplitStore: supress compaction near upgrades ([filecoin-project/lotus#7734](https://github.com/filecoin-project/lotus/pull/7734))
|
||||||
|
|
||||||
|
## Dependency Updates
|
||||||
|
- github.com/filecoin-project/go-commp-utils (v0.1.2 -> v0.1.3):
|
||||||
|
- github.com/filecoin-project/dagstore (v0.4.3 -> v0.4.4):
|
||||||
|
- github.com/filecoin-project/go-fil-markets (v1.13.4 -> v1.19.2):
|
||||||
|
- github.com/filecoin-project/go-statestore (v0.1.1 -> v0.2.0):
|
||||||
|
- github.com/filecoin-project/go-storedcounter (v0.0.0-20200421200003-1c99c62e8a5b -> v0.1.0):
|
||||||
|
- github.com/filecoin-project/specs-actors/v2 (v2.3.5 -> v2.3.6):
|
||||||
|
- feat(deps): update markets stack ([filecoin-project/lotus#7959](https://github.com/filecoin-project/lotus/pull/7959))
|
||||||
|
- Use go-libp2p-connmgr v0.3.1 ([filecoin-project/lotus#7957](https://github.com/filecoin-project/lotus/pull/7957))
|
||||||
|
- dep/fix 7701 Dependency: update to ipld-legacy to v0.1.1 ([filecoin-project/lotus#7751](https://github.com/filecoin-project/lotus/pull/7751))
|
||||||
|
|
||||||
|
## Others
|
||||||
|
- chore: backport: release ([filecoin-project/lotus#8245](https://github.com/filecoin-project/lotus/pull/8245))
|
||||||
|
- Lotus release v1.15.0-rc3 ([filecoin-project/lotus#8236](https://github.com/filecoin-project/lotus/pull/8236))
|
||||||
|
- Lotus release v1.15.0-rc2 ([filecoin-project/lotus#8211](https://github.com/filecoin-project/lotus/pull/8211))
|
||||||
|
- Merge branch 'releases' into release/v1.15.0
|
||||||
|
- chore: build: backport releases ([filecoin-project/lotus#8193](https://github.com/filecoin-project/lotus/pull/8193))
|
||||||
|
- Merge branch 'releases' into release/v1.15.0
|
||||||
|
- bump the version to v1.15.0-rc1
|
||||||
|
- chore: build: v1.14.0 -> master ([filecoin-project/lotus#8053](https://github.com/filecoin-project/lotus/pull/8053))
|
||||||
|
- chore: merge release/v1.14.0 PRs into master ([filecoin-project/lotus#7979](https://github.com/filecoin-project/lotus/pull/7979))
|
||||||
|
- chore: update PR template ([filecoin-project/lotus#7918](https://github.com/filecoin-project/lotus/pull/7918))
|
||||||
|
- build: release: bump master version to v1.15.0-dev ([filecoin-project/lotus#7922](https://github.com/filecoin-project/lotus/pull/7922))
|
||||||
|
- misc: docs: remove issue number from the pr title ([filecoin-project/lotus#7902](https://github.com/filecoin-project/lotus/pull/7902))
|
||||||
|
- Snapcraft grade no develgrade ([filecoin-project/lotus#7802](https://github.com/filecoin-project/lotus/pull/7802))
|
||||||
|
- chore: create pull_request_template.md ([filecoin-project/lotus#7726](https://github.com/filecoin-project/lotus/pull/7726))
|
||||||
|
- Disable appimage ([filecoin-project/lotus#7707](https://github.com/filecoin-project/lotus/pull/7707))
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
| Contributor | Commits | Lines ± | Files Changed |
|
||||||
|
|-------------|---------|---------|---------------|
|
||||||
|
| @arajasek | 73 | +7232/-2778 | 386 |
|
||||||
|
| @zenground0 | 27 | +5604/-1049 | 219 |
|
||||||
|
| @vyzo | 118 | +4356/-1470 | 253 |
|
||||||
|
| @zl | 1 | +3725/-309 | 8 |
|
||||||
|
| @dirkmc | 7 | +1392/-1110 | 61 |
|
||||||
|
| arajasek | 37 | +221/-1329 | 90 |
|
||||||
|
| @magik6k | 33 | +1138/-336 | 101 |
|
||||||
|
| @whyrusleeping | 2 | +483/-585 | 28 |
|
||||||
|
| Darko Brdareski | 14 | +725/-276 | 154 |
|
||||||
|
| @rvagg | 2 | +43/-947 | 10 |
|
||||||
|
| @hannahhoward | 5 | +436/-335 | 31 |
|
||||||
|
| @hannahhoward | 12 | +507/-133 | 37 |
|
||||||
|
| @jennijuju | 27 | +333/-178 | 54 |
|
||||||
|
| @TheMenko | 8 | +237/-179 | 17 |
|
||||||
|
| c r | 2 | +227/-45 | 12 |
|
||||||
|
| @dirkmck | 12 | +188/-40 | 27 |
|
||||||
|
| @ribasushi | 3 | +128/-62 | 3 |
|
||||||
|
| @raulk | 6 | +128/-49 | 9 |
|
||||||
|
| @Whyrusleeping | 1 | +76/-70 | 8 |
|
||||||
|
| @Stebalien | 1 | +55/-37 | 1 |
|
||||||
|
| @jennijuju | 11 | +29/-16 | 11 |
|
||||||
|
| @aarshkshah1992 | 1 | +23/-19 | 5 |
|
||||||
|
| @travisperson | 1 | +0/-18 | 2 |
|
||||||
|
| @gstuart | 3 | +12/-1 | 3 |
|
||||||
|
| @coryschwartz | 4 | +5/-6 | 4 |
|
||||||
|
| @pefish | 1 | +4/-3 | 1 |
|
||||||
|
| @Kubuxu | 1 | +5/-2 | 2 |
|
||||||
|
| Colin Kennedy | 1 | +4/-2 | 1 |
|
||||||
|
| Rob Quist | 1 | +2/-2 | 1 |
|
||||||
|
| @shotcollin | 1 | +1/-1 | 1 |
|
||||||
|
|
||||||
|
|
||||||
|
# 1.14.4 / 2022-03-03
|
||||||
|
|
||||||
|
This is a *highly recommended* optional release for storage providers that are doing snap deals. This fix the bug
|
||||||
|
that causes some snap deal sectors are stuck in `FinalizeReplicaUpdate`. In addition, SPs should be able to force
|
||||||
|
update sectors status without getting blocked by `normal shutdown of state machine`.
|
||||||
|
|
||||||
|
# v1.14.3 / 2022-02-28
|
||||||
|
|
||||||
|
This is an **optional** release, that includes a fix to properly register the `--really-do-it` flag for abort-upgrade.
|
||||||
|
|
||||||
# 1.14.2 / 2022-02-24
|
# 1.14.2 / 2022-02-24
|
||||||
|
|
||||||
This is an **optional** release of lotus, that's had a couple more improvements w.r.t Snap experience for storage providers in preparation of the[upcoming OhSnap upgrade](https://github.com/filecoin-project/community/discussions/74?sort=new#discussioncomment-1922550).
|
This is an **optional** release of lotus, that's had a couple more improvements w.r.t Snap experience for storage providers in preparation of the[upcoming OhSnap upgrade](https://github.com/filecoin-project/community/discussions/74?sort=new#discussioncomment-1922550).
|
||||||
|
|
||||||
Note that the network is STILL scheduled to upgrade to v15 on March 1st at 2022-03-01T15:00:00Z. All node operators, including storage providers, must upgrade to at least Lotus v1.14.0 before that time. Storage providers must update their daemons, miners, and worker(s).
|
Note that the network is STILL scheduled to upgrade to v15 on March 1st at 2022-03-01T15:00:00Z. All node operators, including storage providers, must upgrade to at least Lotus v1.14.0 before that time. Storage providers must update their daemons, miners, and worker(s).
|
||||||
|
|
||||||
Wanna know how to Snap your deal? Check [this](https://github.com/filecoin-project/lotus/discussions/8141) out!
|
Wanna know how to Snap your deal? Check [this](https://github.com/filecoin-project/lotus/discussions/8141) out!
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- fix lotus-bench for sealing jobs (#8173)
|
- fix lotus-bench for sealing jobs (#8173)
|
||||||
@@ -15,8 +144,8 @@ Wanna know how to Snap your deal? Check [this](https://github.com/filecoin-proje
|
|||||||
- fix: sealing: missing file type (#8180)
|
- fix: sealing: missing file type (#8180)
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
- Retract force-pushed v1.14.0 to work around stale gomod caches (#8159): We originally tagged v1.14.0 off the wrong
|
- Retract force-pushed v1.14.0 to work around stale gomod caches (#8159): We originally tagged v1.14.0 off the wrong
|
||||||
commit and fixed that by a force push, in which is a really bad practise since it messes up the go mod. Therefore,
|
commit and fixed that by a force push, in which is a really bad practise since it messes up the go mod. Therefore,
|
||||||
we want to retract it and users may use v1.14.1&^.
|
we want to retract it and users may use v1.14.1&^.
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
@@ -35,7 +164,7 @@ This is an **optional** release of lotus, that fixes the incorrect *comment* of
|
|||||||
|
|
||||||
# 1.14.0 / 2022-02-17
|
# 1.14.0 / 2022-02-17
|
||||||
|
|
||||||
This is a MANDATORY release of Lotus that introduces [Filecoin network v15,
|
This is a MANDATORY release of Lotus that introduces [Filecoin network v15,
|
||||||
codenamed the OhSnap upgrade](https://github.com/filecoin-project/community/discussions/74?sort=new#discussioncomment-1922550).
|
codenamed the OhSnap upgrade](https://github.com/filecoin-project/community/discussions/74?sort=new#discussioncomment-1922550).
|
||||||
|
|
||||||
The network is scheduled to upgrade to v15 on March 1st at 2022-03-01T15:00:00Z. All node operators, including storage providers, must upgrade to this release (or a later release) before that time. Storage providers must update their daemons, miners, and worker(s).
|
The network is scheduled to upgrade to v15 on March 1st at 2022-03-01T15:00:00Z. All node operators, including storage providers, must upgrade to this release (or a later release) before that time. Storage providers must update their daemons, miners, and worker(s).
|
||||||
@@ -52,7 +181,7 @@ It is recommended that storage providers download the new params before updating
|
|||||||
- Upgrade the Lotus daemon and miner **when the previous step is complete**
|
- Upgrade the Lotus daemon and miner **when the previous step is complete**
|
||||||
|
|
||||||
All node operators, including storage providers, should be aware that a pre-migration will begin at 2022-03-01T13:30:00Z (90 minutes before the real upgrade). The pre-migration will take between 20 and 50 minutes, depending on hardware specs. During this time, expect slower block validation times, increased CPU and memory usage, and longer delays for API queries.
|
All node operators, including storage providers, should be aware that a pre-migration will begin at 2022-03-01T13:30:00Z (90 minutes before the real upgrade). The pre-migration will take between 20 and 50 minutes, depending on hardware specs. During this time, expect slower block validation times, increased CPU and memory usage, and longer delays for API queries.
|
||||||
|
|
||||||
## New Features and Changes
|
## New Features and Changes
|
||||||
- Integrate actor v7-rc1:
|
- Integrate actor v7-rc1:
|
||||||
- Integrate v7 actors ([#7617](https://github.com/filecoin-project/lotus/pull/7617))
|
- Integrate v7 actors ([#7617](https://github.com/filecoin-project/lotus/pull/7617))
|
||||||
@@ -78,7 +207,7 @@ All node operators, including storage providers, should be aware that a pre-migr
|
|||||||
- Fix: state: circsuypply calc around null blocks ([#7890](https://github.com/filecoin-project/lotus/pull/7890))
|
- Fix: state: circsuypply calc around null blocks ([#7890](https://github.com/filecoin-project/lotus/pull/7890))
|
||||||
- Mempool msg selection should respect block message limits ([#7321](https://github.com/filecoin-project/lotus/pull/7321))
|
- Mempool msg selection should respect block message limits ([#7321](https://github.com/filecoin-project/lotus/pull/7321))
|
||||||
SplitStore: supress compaction near upgrades ([#7734](https://github.com/filecoin-project/lotus/pull/7734))
|
SplitStore: supress compaction near upgrades ([#7734](https://github.com/filecoin-project/lotus/pull/7734))
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
- chore: create pull_request_template.md ([#7726](https://github.com/filecoin-project/lotus/pull/7726))
|
- chore: create pull_request_template.md ([#7726](https://github.com/filecoin-project/lotus/pull/7726))
|
||||||
|
|
||||||
@@ -101,17 +230,15 @@ All node operators, including storage providers, should be aware that a pre-migr
|
|||||||
| Travis Person | 1 | +2/-2 | 2 |
|
| Travis Person | 1 | +2/-2 | 2 |
|
||||||
| Rod Vagg | 1 | +2/-2 | 2 |
|
| Rod Vagg | 1 | +2/-2 | 2 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# v1.13.2 / 2022-01-09
|
# v1.13.2 / 2022-01-09
|
||||||
|
|
||||||
Lotus v1.13.2 is a *highly recommended* feature release with remarkable retrieval improvements, new features like
|
Lotus v1.13.2 is a *highly recommended* feature release with remarkable retrieval improvements, new features like
|
||||||
worker management, schedule enhancements and so on.
|
worker management, schedule enhancements and so on.
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
- 🚀🚀🚀Improve retrieval deal experience
|
- 🚀🚀🚀Improve retrieval deal experience
|
||||||
- Testing result with MinerX.3 shows the retrieval deal success rate has increased dramatically with faster transfer
|
- Testing result with MinerX.3 shows the retrieval deal success rate has increased dramatically with faster transfer
|
||||||
speed, you can join or follow along furthur performance testings [here](https://github.com/filecoin-project/lotus/discussions/7874). We recommend application developers to integrate with the new
|
speed, you can join or follow along furthur performance testings [here](https://github.com/filecoin-project/lotus/discussions/7874). We recommend application developers to integrate with the new
|
||||||
retrieval APIs to provide a better client experience.
|
retrieval APIs to provide a better client experience.
|
||||||
- 🌟🌟🌟 Reduce retrieval Time-To-First-Byte over 100x ([#7693](https://github.com/filecoin-project/lotus/pull/7693))
|
- 🌟🌟🌟 Reduce retrieval Time-To-First-Byte over 100x ([#7693](https://github.com/filecoin-project/lotus/pull/7693))
|
||||||
- This change makes most free, small retrievals sub-second
|
- This change makes most free, small retrievals sub-second
|
||||||
@@ -203,7 +330,7 @@ worker management, schedule enhancements and so on.
|
|||||||
| @jennijuju | 1 | +1/-1 | 1 |
|
| @jennijuju | 1 | +1/-1 | 1 |
|
||||||
| @hunjixin | 1 | +1/-0 | 1 |
|
| @hunjixin | 1 | +1/-0 | 1 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# v1.13.1 / 2021-11-26
|
# v1.13.1 / 2021-11-26
|
||||||
|
|
||||||
@@ -286,32 +413,32 @@ Contributors
|
|||||||
| @hannahhoward | 1 | +3/-2 | 2 |
|
| @hannahhoward | 1 | +3/-2 | 2 |
|
||||||
| Marten Seemann | 1 | +3/-0 | 1 |
|
| Marten Seemann | 1 | +3/-0 | 1 |
|
||||||
| @ZenGround0 | 1 | +1/-1 | 1 |
|
| @ZenGround0 | 1 | +1/-1 | 1 |
|
||||||
|
|
||||||
|
|
||||||
# v1.13.0 / 2021-10-18
|
# v1.13.0 / 2021-10-18
|
||||||
|
|
||||||
Lotus v1.13.0 is a *highly recommended* feature release for all lotus users(i.e: storage providers, data brokers, application developers and so on) that supports the upcoming
|
Lotus v1.13.0 is a *highly recommended* feature release for all lotus users(i.e: storage providers, data brokers, application developers and so on) that supports the upcoming
|
||||||
[Network v14 Chocolate upgrade](https://github.com/filecoin-project/lotus/discussions/7431).
|
[Network v14 Chocolate upgrade](https://github.com/filecoin-project/lotus/discussions/7431).
|
||||||
This feature release includes the latest functionalities and improvements, like data transfer rate-limiting for both storage and retrieval deals, proof v10 with CUDA support, etc. You can find more details in the Changelog below.
|
This feature release includes the latest functionalities and improvements, like data transfer rate-limiting for both storage and retrieval deals, proof v10 with CUDA support, etc. You can find more details in the Changelog below.
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
- Enable separate storage and retrieval transfer limits ([filecoin-project/lotus#7405](https://github.com/filecoin-project/lotus/pull/7405))
|
- Enable separate storage and retrieval transfer limits ([filecoin-project/lotus#7405](https://github.com/filecoin-project/lotus/pull/7405))
|
||||||
- `SimultaneousTransfer` is now replaced by `SimultaneousTransfersForStorage` and `SimultaneousTransfersForRetrieval`, where users may set the amount of ongoing data transfer for storage and retrieval deals in parallel separately. The default value for both is set to 20.
|
- `SimultaneousTransfer` is now replaced by `SimultaneousTransfersForStorage` and `SimultaneousTransfersForRetrieval`, where users may set the amount of ongoing data transfer for storage and retrieval deals in parallel separately. The default value for both is set to 20.
|
||||||
- If you are using the lotus client, these two configuration variables are under the `Client` section in `./lotus/config.toml`.
|
- If you are using the lotus client, these two configuration variables are under the `Client` section in `./lotus/config.toml`.
|
||||||
- If you are a service provider, these two configuration variables should be set under the `Dealmaking` section in `/.lotusminer/config.toml`.
|
- If you are a service provider, these two configuration variables should be set under the `Dealmaking` section in `/.lotusminer/config.toml`.
|
||||||
- Update proofs to v10.0.0 ([filecoin-project/lotus#7420](https://github.com/filecoin-project/lotus/pull/7420))
|
- Update proofs to v10.0.0 ([filecoin-project/lotus#7420](https://github.com/filecoin-project/lotus/pull/7420))
|
||||||
- This version supports CUDA. To enable CUDA instead of openCL, build lotus with `FFI_USE_CUDA=1 FFI_BUILD_FROM_SOURCE=1 ...`.
|
- This version supports CUDA. To enable CUDA instead of openCL, build lotus with `FFI_USE_CUDA=1 FFI_BUILD_FROM_SOURCE=1 ...`.
|
||||||
- You can find additional Nvidia driver installation instructions written by MinerX fellows [here](https://github.com/filecoin-project/lotus/discussions/7443#discussioncomment-1425274) and perf improvements result on PC2/C2/WindowPoSt computation on different profiles [here](https://github.com/filecoin-project/lotus/discussions/7443), most people observe a 30-50% decrease in computation time.
|
- You can find additional Nvidia driver installation instructions written by MinerX fellows [here](https://github.com/filecoin-project/lotus/discussions/7443#discussioncomment-1425274) and perf improvements result on PC2/C2/WindowPoSt computation on different profiles [here](https://github.com/filecoin-project/lotus/discussions/7443), most people observe a 30-50% decrease in computation time.
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
- Feat/datamodel selector retrieval ([filecoin-project/lotus#6393](https://github.com/filecoin-project/lotus/pull/66393393))
|
- Feat/datamodel selector retrieval ([filecoin-project/lotus#6393](https://github.com/filecoin-project/lotus/pull/66393393))
|
||||||
- This introduces a new RetrievalOrder-struct field and a CLI option that takes a string representation as understood by [https://pkg.go.dev/github.com/ipld/go-ipld-selector-text-lite#SelectorSpecFromPath](https://pkg.go.dev/github.com/ipld/go-ipld-selector-text-lite#SelectorSpecFromPath). This allows for partial retrieval of any sub-DAG of a deal provided the user knows the exact low-level shape of the deal contents.
|
- This introduces a new RetrievalOrder-struct field and a CLI option that takes a string representation as understood by [https://pkg.go.dev/github.com/ipld/go-ipld-selector-text-lite#SelectorSpecFromPath](https://pkg.go.dev/github.com/ipld/go-ipld-selector-text-lite#SelectorSpecFromPath). This allows for partial retrieval of any sub-DAG of a deal provided the user knows the exact low-level shape of the deal contents.
|
||||||
- For example, to retrieve the first entry of a UnixFS directory by executing, run `lotus client retrieve --miner f0XXXXX --datamodel-path-selector 'Links/0/Hash' bafyROOTCID ~/output`
|
- For example, to retrieve the first entry of a UnixFS directory by executing, run `lotus client retrieve --miner f0XXXXX --datamodel-path-selector 'Links/0/Hash' bafyROOTCID ~/output`
|
||||||
- Expose storage stats on the metrics endpoint ([filecoin-project/lotus#7418](https://github.com/filecoin-project/lotus/pull/7418))
|
- Expose storage stats on the metrics endpoint ([filecoin-project/lotus#7418](https://github.com/filecoin-project/lotus/pull/7418))
|
||||||
- feat: Catch panic to generate report and reraise ([filecoin-project/lotus#7341](https://github.com/filecoin-project/lotus/pull/7341))
|
- feat: Catch panic to generate report and reraise ([filecoin-project/lotus#7341](https://github.com/filecoin-project/lotus/pull/7341))
|
||||||
- Set `LOTUS_PANIC_REPORT_PATH` and `LOTUS_PANIC_JOURNAL_LOOKBACK` to get reports generated when a panic occurs on your daemon miner or workers.
|
- Set `LOTUS_PANIC_REPORT_PATH` and `LOTUS_PANIC_JOURNAL_LOOKBACK` to get reports generated when a panic occurs on your daemon miner or workers.
|
||||||
- Add envconfig docs to the config ([filecoin-project/lotus#7412](https://github.com/filecoin-project/lotus/pull/7412))
|
- Add envconfig docs to the config ([filecoin-project/lotus#7412](https://github.com/filecoin-project/lotus/pull/7412))
|
||||||
- You can now find supported env vars in [default-lotus-miner-config.toml](https://github.com/filecoin-project/lotus/blob/master/documentation/en/default-lotus-miner-config.toml).
|
- You can now find supported env vars in [default-lotus-miner-config.toml](https://github.com/filecoin-project/lotus/blob/master/documentation/en/default-lotus-miner-config.toml).
|
||||||
- lotus shed: fr32 utils ([filecoin-project/lotus#7355](https://github.com/filecoin-project/lotus/pull/7355))
|
- lotus shed: fr32 utils ([filecoin-project/lotus#7355](https://github.com/filecoin-project/lotus/pull/7355))
|
||||||
- Miner CLI: Allow trying to change owners of any miner actor ([filecoin-project/lotus#7328](https://github.com/filecoin-project/lotus/pull/7328))
|
- Miner CLI: Allow trying to change owners of any miner actor ([filecoin-project/lotus#7328](https://github.com/filecoin-project/lotus/pull/7328))
|
||||||
- Add --unproven flag to the sectors list command ([filecoin-project/lotus#7308](https://github.com/filecoin-project/lotus/pull/7308))
|
- Add --unproven flag to the sectors list command ([filecoin-project/lotus#7308](https://github.com/filecoin-project/lotus/pull/7308))
|
||||||
@@ -328,7 +455,7 @@ This feature release includes the latest functionalities and improvements, like
|
|||||||
- Prep retrieval for selectors: no functional changes ([filecoin-project/lotus#7306](https://github.com/filecoin-project/lotus/pull/7306))
|
- Prep retrieval for selectors: no functional changes ([filecoin-project/lotus#7306](https://github.com/filecoin-project/lotus/pull/7306))
|
||||||
- Seed: improve helptext ([filecoin-project/lotus#7304](https://github.com/filecoin-project/lotus/pull/7304))
|
- Seed: improve helptext ([filecoin-project/lotus#7304](https://github.com/filecoin-project/lotus/pull/7304))
|
||||||
- Mempool: reduce size of sigValCache ([filecoin-project/lotus#7305](https://github.com/filecoin-project/lotus/pull/7305))
|
- Mempool: reduce size of sigValCache ([filecoin-project/lotus#7305](https://github.com/filecoin-project/lotus/pull/7305))
|
||||||
- Stop indirectly depending on deprecated github.com/prometheus/common ([filecoin-project/lotus#7474](https://github.com/filecoin-project/lotus/pull/7474))
|
- Stop indirectly depending on deprecated github.com/prometheus/common ([filecoin-project/lotus#7474](https://github.com/filecoin-project/lotus/pull/7474))
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- StateSearchMsg: Correct usage of the allowReplaced flag ([filecoin-project/lotus#7450](https://github.com/filecoin-project/lotus/pull/7450))
|
- StateSearchMsg: Correct usage of the allowReplaced flag ([filecoin-project/lotus#7450](https://github.com/filecoin-project/lotus/pull/7450))
|
||||||
@@ -383,7 +510,7 @@ This feature release includes the latest functionalities and improvements, like
|
|||||||
|
|
||||||
# v1.12.0 / 2021-10-12
|
# v1.12.0 / 2021-10-12
|
||||||
|
|
||||||
This is a mandatory release of Lotus that introduces [Filecoin Network v14](https://github.com/filecoin-project/community/discussions/74#discussioncomment-1398542), codenamed the Chocolate upgrade. The Filecoin mainnet will upgrade at epoch 1231620, on 2021-10-26T13:30:00Z.
|
This is a mandatory release of Lotus that introduces [Filecoin Network v14](https://github.com/filecoin-project/community/discussions/74#discussioncomment-1398542), codenamed the Chocolate upgrade. The Filecoin mainnet will upgrade at epoch 1231620, on 2021-10-26T13:30:00Z.
|
||||||
|
|
||||||
The Chocolate upgrade introduces the following FIPs, delivered in [v6 actors](https://github.com/filecoin-project/specs-actors/releases/tag/v6.0.0)
|
The Chocolate upgrade introduces the following FIPs, delivered in [v6 actors](https://github.com/filecoin-project/specs-actors/releases/tag/v6.0.0)
|
||||||
|
|
||||||
@@ -397,7 +524,7 @@ The Chocolate upgrade introduces the following FIPs, delivered in [v6 actors](ht
|
|||||||
Note that this release is built on top of lotus v1.11.3. Enterprising users like storage providers, data brokers and others are recommended to use lotus v1.13.0 for latest new features, improvements and bug fixes.
|
Note that this release is built on top of lotus v1.11.3. Enterprising users like storage providers, data brokers and others are recommended to use lotus v1.13.0 for latest new features, improvements and bug fixes.
|
||||||
|
|
||||||
## New Features and Changes
|
## New Features and Changes
|
||||||
- Implement and support [FIP-0024](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0024.md) BatchBalancer & BatchDiscount Post-HyperDrive Adjustment:
|
- Implement and support [FIP-0024](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0024.md) BatchBalancer & BatchDiscount Post-HyperDrive Adjustment:
|
||||||
- Precommit batch balancer support/config ([filecoin-project/lotus#7410](https://github.com/filecoin-project/lotus/pull/7410))
|
- Precommit batch balancer support/config ([filecoin-project/lotus#7410](https://github.com/filecoin-project/lotus/pull/7410))
|
||||||
- Set `BatchPreCommitAboveBaseFee` to decide whether sending out a PreCommits in individual messages or in a batch.
|
- Set `BatchPreCommitAboveBaseFee` to decide whether sending out a PreCommits in individual messages or in a batch.
|
||||||
- The default value of `BatchPreCommitAboveBaseFee` and `AggregateAboveBaseFee` are now updated to 0.32nanoFIL.
|
- The default value of `BatchPreCommitAboveBaseFee` and `AggregateAboveBaseFee` are now updated to 0.32nanoFIL.
|
||||||
@@ -414,17 +541,17 @@ Note that this release is built on top of lotus v1.11.3. Enterprising users like
|
|||||||
## Dependency Updates
|
## Dependency Updates
|
||||||
- Add [v6 actors](https://github.com/filecoin-project/specs-actors/releases/tag/v6.0.0)
|
- Add [v6 actors](https://github.com/filecoin-project/specs-actors/releases/tag/v6.0.0)
|
||||||
- **Protocol changes**
|
- **Protocol changes**
|
||||||
- Multisig Approve only hashes when hash in params
|
- Multisig Approve only hashes when hash in params
|
||||||
- FIP 0020 WithdrawBalance methods return withdrawn value
|
- FIP 0020 WithdrawBalance methods return withdrawn value
|
||||||
- FIP 0021 Fix bug in power calculation when extending verified deals sectors
|
- FIP 0021 Fix bug in power calculation when extending verified deals sectors
|
||||||
- FIP 0022 PublishStorageDeals drops errors in batch
|
- FIP 0022 PublishStorageDeals drops errors in batch
|
||||||
- FIP 0024 BatchBalancer update and burn added to PreCommitBatch
|
- FIP 0024 BatchBalancer update and burn added to PreCommitBatch
|
||||||
- FIP 0026 Add FaultMaxAge extension
|
- FIP 0026 Add FaultMaxAge extension
|
||||||
- Reduce calls to power and reward actors by passing values from power cron
|
- Reduce calls to power and reward actors by passing values from power cron
|
||||||
- Defensive programming hardening power cron against programmer error
|
- Defensive programming hardening power cron against programmer error
|
||||||
- **Implementation changes**
|
- **Implementation changes**
|
||||||
- Move to xerrors
|
- Move to xerrors
|
||||||
- Improved logging: burn events are not logged with reasons and burned value.
|
- Improved logging: burn events are not logged with reasons and burned value.
|
||||||
- github.com/filecoin-project/go-state-types (v0.1.1-0.20210810190654-139e0e79e69e -> v0.1.1-0.20210915140513-d354ccf10379):
|
- github.com/filecoin-project/go-state-types (v0.1.1-0.20210810190654-139e0e79e69e -> v0.1.1-0.20210915140513-d354ccf10379):
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
@@ -449,20 +576,20 @@ Note that this release is built on top of lotus v1.11.3. Enterprising users like
|
|||||||
|
|
||||||
# v1.11.3 / 2021-09-29
|
# v1.11.3 / 2021-09-29
|
||||||
|
|
||||||
lotus v1.11.3 is a feature release that's **highly recommended to ALL lotus users to upgrade**, including node
|
lotus v1.11.3 is a feature release that's **highly recommended to ALL lotus users to upgrade**, including node
|
||||||
operators, storage providers and clients. It includes many improvements and bug fixes that result in perf
|
operators, storage providers and clients. It includes many improvements and bug fixes that result in perf
|
||||||
improvements in different area, like deal making, sealing and so on.
|
improvements in different area, like deal making, sealing and so on.
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
|
|
||||||
- 🌟🌟Introduce `MaxStagingDealsBytes - reject new deals if our staging deals area is full ([filecoin-project/lotus#7276](https://github.com/filecoin-project/lotus/pull/7276))
|
- 🌟🌟Introduce `MaxStagingDealsBytes - reject new deals if our staging deals area is full ([filecoin-project/lotus#7276](https://github.com/filecoin-project/lotus/pull/7276))
|
||||||
- Set `MaxStagingDealsBytes` under the [Dealmaking] section of the markets' subsystem's `config.toml` to reject new incoming deals when the `deal-staging` directory of market subsystem's repo gets too large.
|
- Set `MaxStagingDealsBytes` under the [Dealmaking] section of the markets' subsystem's `config.toml` to reject new incoming deals when the `deal-staging` directory of market subsystem's repo gets too large.
|
||||||
- 🌟🌟miner: Command to list/remove expired sectors locally ([filecoin-project/lotus#7140](https://github.com/filecoin-project/lotus/pull/7140))
|
- 🌟🌟miner: Command to list/remove expired sectors locally ([filecoin-project/lotus#7140](https://github.com/filecoin-project/lotus/pull/7140))
|
||||||
- run `./lotus-miner sectors expired -h` for more details.
|
- run `./lotus-miner sectors expired -h` for more details.
|
||||||
- 🚀update to ffi to update-bellperson-proofs-v9-0-2 ([filecoin-project/lotus#7369](https://github.com/filecoin-project/lotus/pull/7369))
|
- 🚀update to ffi to update-bellperson-proofs-v9-0-2 ([filecoin-project/lotus#7369](https://github.com/filecoin-project/lotus/pull/7369))
|
||||||
- MinerX fellows(early testers of lotus releases) have reported faster WindowPoSt computation!
|
- MinerX fellows(early testers of lotus releases) have reported faster WindowPoSt computation!
|
||||||
- 🌟dealpublisher: Fully validate deals before publishing ([filecoin-project/lotus#7234](https://github.com/filecoin-project/lotus/pull/7234))
|
- 🌟dealpublisher: Fully validate deals before publishing ([filecoin-project/lotus#7234](https://github.com/filecoin-project/lotus/pull/7234))
|
||||||
- This excludes the expired deals before sending out a PSD message which reduces the chances of PSD message failure due to invalid deals.
|
- This excludes the expired deals before sending out a PSD message which reduces the chances of PSD message failure due to invalid deals.
|
||||||
- 🌟Simple alert system; FD limit alerts ([filecoin-project/lotus#7108](https://github.com/filecoin-project/lotus/pull/7108))
|
- 🌟Simple alert system; FD limit alerts ([filecoin-project/lotus#7108](https://github.com/filecoin-project/lotus/pull/7108))
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
@@ -533,7 +660,7 @@ improvements in different area, like deal making, sealing and so on.
|
|||||||
- Turn off patch ([filecoin-project/lotus#7172](https://github.com/filecoin-project/lotus/pull/7172))
|
- Turn off patch ([filecoin-project/lotus#7172](https://github.com/filecoin-project/lotus/pull/7172))
|
||||||
- test: disable flaky TestSimultaneousTransferLimit ([filecoin-project/lotus#7153](https://github.com/filecoin-project/lotus/pull/7153))
|
- test: disable flaky TestSimultaneousTransferLimit ([filecoin-project/lotus#7153](https://github.com/filecoin-project/lotus/pull/7153))
|
||||||
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
| Contributor | Commits | Lines ± | Files Changed |
|
| Contributor | Commits | Lines ± | Files Changed |
|
||||||
@@ -565,46 +692,46 @@ improvements in different area, like deal making, sealing and so on.
|
|||||||
|
|
||||||
# v1.11.2 / 2021-09-06
|
# v1.11.2 / 2021-09-06
|
||||||
|
|
||||||
lotus v1.11.2 is a feature release that's **highly recommended ALL lotus users to upgrade**, including node operators,
|
lotus v1.11.2 is a feature release that's **highly recommended ALL lotus users to upgrade**, including node operators,
|
||||||
storage providers and clients.
|
storage providers and clients.
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
- 🌟🌟🌟 Introduce Dagstore and CARv2 for deal-making (#6671) ([filecoin-project/lotus#6671](https://github.com/filecoin-project/lotus/pull/6671))
|
- 🌟🌟🌟 Introduce Dagstore and CARv2 for deal-making (#6671) ([filecoin-project/lotus#6671](https://github.com/filecoin-project/lotus/pull/6671))
|
||||||
- **[lotus miner markets' Dagstore](https://docs.filecoin.io/mine/lotus/dagstore/#conceptual-overview)** is a
|
- **[lotus miner markets' Dagstore](https://docs.filecoin.io/mine/lotus/dagstore/#conceptual-overview)** is a
|
||||||
component of the `markets` subsystem in lotus-miner. It is a sharded store to hold large IPLD graphs efficiently,
|
component of the `markets` subsystem in lotus-miner. It is a sharded store to hold large IPLD graphs efficiently,
|
||||||
packaged as location-transparent attachable CAR files and it replaces the former Badger staging blockstore. It
|
packaged as location-transparent attachable CAR files and it replaces the former Badger staging blockstore. It
|
||||||
is designed to provide high efficiency and throughput, and minimize resource utilization during deal-making operations.
|
is designed to provide high efficiency and throughput, and minimize resource utilization during deal-making operations.
|
||||||
The dagstore also leverages the indexing features of [CARv2](https://github.com/ipld/ipld/blob/master/specs/transport/car/carv2/index.md) to enable plan CAR files to act as read and write
|
The dagstore also leverages the indexing features of [CARv2](https://github.com/ipld/ipld/blob/master/specs/transport/car/carv2/index.md) to enable plan CAR files to act as read and write
|
||||||
blockstores, which are served as the direct medium for data exchanges in markets for both storage and retrieval
|
blockstores, which are served as the direct medium for data exchanges in markets for both storage and retrieval
|
||||||
deal making without requiring intermediate buffers.
|
deal making without requiring intermediate buffers.
|
||||||
- In the future, lotus will leverage and interact with Dagstore a lot for new features and improvements for deal
|
- In the future, lotus will leverage and interact with Dagstore a lot for new features and improvements for deal
|
||||||
making, therefore, it's highly recommended to lotus users to go through [Lotus Miner: About the markets dagstore](https://docs.filecoin.io/mine/lotus/dagstore/#conceptual-overview) thoroughly to learn more about Dagstore's
|
making, therefore, it's highly recommended to lotus users to go through [Lotus Miner: About the markets dagstore](https://docs.filecoin.io/mine/lotus/dagstore/#conceptual-overview) thoroughly to learn more about Dagstore's
|
||||||
conceptual overview, terminology, directory structure, configuration and so on.
|
conceptual overview, terminology, directory structure, configuration and so on.
|
||||||
- **Note**:
|
- **Note**:
|
||||||
- When you first start your lotus-miner or market subsystem with this release, a one-time/first-time **dagstore migration** will be triggered which replaces the former Badger staging blockstore with dagstore. We highly
|
- When you first start your lotus-miner or market subsystem with this release, a one-time/first-time **dagstore migration** will be triggered which replaces the former Badger staging blockstore with dagstore. We highly
|
||||||
recommend storage providers to read this [section](https://docs.filecoin.io/mine/lotus/dagstore/#first-time-migration) to learn more about
|
recommend storage providers to read this [section](https://docs.filecoin.io/mine/lotus/dagstore/#first-time-migration) to learn more about
|
||||||
what the process does, what to expect and how monitor it.
|
what the process does, what to expect and how monitor it.
|
||||||
- It is highly recommended to **wait all ongoing data transfer to finish or cancel inbound storage deals that
|
- It is highly recommended to **wait all ongoing data transfer to finish or cancel inbound storage deals that
|
||||||
are still transferring**, using the `lotus-miner data-transfers cancel` command before upgrade your market nodes. Reason being that the new dagstore changes attributes in the internal deal state objects, and the paths to the staging CARs where the deal data was being placed will be lost.
|
are still transferring**, using the `lotus-miner data-transfers cancel` command before upgrade your market nodes. Reason being that the new dagstore changes attributes in the internal deal state objects, and the paths to the staging CARs where the deal data was being placed will be lost.
|
||||||
- ‼️Having your dags initialized will become important in the near feature for you to provide a better storage
|
- ‼️Having your dags initialized will become important in the near feature for you to provide a better storage
|
||||||
and retrieval service. We'd suggest you to start [forced bulk initialization] soon if possible as this process
|
and retrieval service. We'd suggest you to start [forced bulk initialization] soon if possible as this process
|
||||||
places relatively high IP workload on your storage system and is better to be carried out gradually and over a
|
places relatively high IP workload on your storage system and is better to be carried out gradually and over a
|
||||||
longer timeframe. Read how to do properly perform a force bulk initialization [here](https://docs.filecoin.io/mine/lotus/dagstore/#forcing-bulk-initialization).
|
longer timeframe. Read how to do properly perform a force bulk initialization [here](https://docs.filecoin.io/mine/lotus/dagstore/#forcing-bulk-initialization).
|
||||||
- ⏮ Rollback Alert(from v1.11.2-rcX to any version lower): If a storages deal is initiated with M1/v1.11.2(-rcX)
|
- ⏮ Rollback Alert(from v1.11.2-rcX to any version lower): If a storages deal is initiated with M1/v1.11.2(-rcX)
|
||||||
release, it needs to get to the `StorageDealAwaitingPrecommit` state before you can do a version rollback or the markets process may panic.
|
release, it needs to get to the `StorageDealAwaitingPrecommit` state before you can do a version rollback or the markets process may panic.
|
||||||
- 💙 **Special thanks to [MinerX fellows for testing and providing valuable feedbacks](https://github.com/filecoin-project/lotus/discussions/6852) for Dagstore in the past month!**
|
- 💙 **Special thanks to [MinerX fellows for testing and providing valuable feedbacks](https://github.com/filecoin-project/lotus/discussions/6852) for Dagstore in the past month!**
|
||||||
- 🌟🌟 rpcenc: Support reader redirect ([filecoin-project/lotus#6952](https://github.com/filecoin-project/lotus/pull/6952))
|
- 🌟🌟 rpcenc: Support reader redirect ([filecoin-project/lotus#6952](https://github.com/filecoin-project/lotus/pull/6952))
|
||||||
- This allows market processes to send piece bytes directly to workers involved on `AddPiece`.
|
- This allows market processes to send piece bytes directly to workers involved on `AddPiece`.
|
||||||
- Extending sectors: more practical and flexible tools ([filecoin-project/lotus#6097](https://github.com/filecoin-project/lotus/pull/6097))
|
- Extending sectors: more practical and flexible tools ([filecoin-project/lotus#6097](https://github.com/filecoin-project/lotus/pull/6097))
|
||||||
- `lotus-miner sectors check-expire` to inspect expiring sectors.
|
- `lotus-miner sectors check-expire` to inspect expiring sectors.
|
||||||
- `lotus-miner sectors renew` for renewing expiring sectors, see the command help menu for customizable option
|
- `lotus-miner sectors renew` for renewing expiring sectors, see the command help menu for customizable option
|
||||||
like `extension`, `new-expiration` and so on.
|
like `extension`, `new-expiration` and so on.
|
||||||
- ‼️ MpoolReplaceCmd ( lotus mpool replace`) now takes FIL for fee-limit ([filecoin-project/lotus#6927](https://github.com/filecoin-project/lotus/pull/6927))
|
- ‼️ MpoolReplaceCmd ( lotus mpool replace`) now takes FIL for fee-limit ([filecoin-project/lotus#6927](https://github.com/filecoin-project/lotus/pull/6927))
|
||||||
- Drop townhall/chainwatch ([filecoin-project/lotus#6912](https://github.com/filecoin-project/lotus/pull/6912))
|
- Drop townhall/chainwatch ([filecoin-project/lotus#6912](https://github.com/filecoin-project/lotus/pull/6912))
|
||||||
- ChainWatch is no longer supported by lotus.
|
- ChainWatch is no longer supported by lotus.
|
||||||
- Configurable CC Sector Expiration ([filecoin-project/lotus#6803](https://github.com/filecoin-project/lotus/pull/6803))
|
- Configurable CC Sector Expiration ([filecoin-project/lotus#6803](https://github.com/filecoin-project/lotus/pull/6803))
|
||||||
- Set `CommittedCapacitySectorLifetime` in lotus-miner/config.toml to specify the default expiration for a new CC
|
- Set `CommittedCapacitySectorLifetime` in lotus-miner/config.toml to specify the default expiration for a new CC
|
||||||
sector, value must be between 180-540 days inclusive.
|
sector, value must be between 180-540 days inclusive.
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
- api/command for encoding actor params ([filecoin-project/lotus#7150](https://github.com/filecoin-project/lotus/pull/7150))
|
- api/command for encoding actor params ([filecoin-project/lotus#7150](https://github.com/filecoin-project/lotus/pull/7150))
|
||||||
@@ -671,10 +798,10 @@ storage providers and clients.
|
|||||||
- remove m1 templates and make area selection multi-optionable ([filecoin-project/lotus#7121](https://github.com/filecoin-project/lotus/pull/7121))
|
- remove m1 templates and make area selection multi-optionable ([filecoin-project/lotus#7121](https://github.com/filecoin-project/lotus/pull/7121))
|
||||||
- release -> master ([filecoin-project/lotus#7105](https://github.com/filecoin-project/lotus/pull/7105))
|
- release -> master ([filecoin-project/lotus#7105](https://github.com/filecoin-project/lotus/pull/7105))
|
||||||
- Lotus release process - how we make releases ([filecoin-project/lotus#6944](https://github.com/filecoin-project/lotus/pull/6944))
|
- Lotus release process - how we make releases ([filecoin-project/lotus#6944](https://github.com/filecoin-project/lotus/pull/6944))
|
||||||
- codecov: fix mock name ([filecoin-project/lotus#7039](https://github.com/filecoin-project/lotus/pull/7039))
|
- codecov: fix mock name ([filecoin-project/lotus#7039](https://github.com/filecoin-project/lotus/pull/7039))
|
||||||
- codecov: fix regexes ([filecoin-project/lotus#7037](https://github.com/filecoin-project/lotus/pull/7037))
|
- codecov: fix regexes ([filecoin-project/lotus#7037](https://github.com/filecoin-project/lotus/pull/7037))
|
||||||
- chore: disable flaky test ([filecoin-project/lotus#6957](https://github.com/filecoin-project/lotus/pull/6957))
|
- chore: disable flaky test ([filecoin-project/lotus#6957](https://github.com/filecoin-project/lotus/pull/6957))
|
||||||
- set buildtype in nerpa and butterfly ([filecoin-project/lotus#6085](https://github.com/filecoin-project/lotus/pull/6085))
|
- set buildtype in nerpa and butterfly ([filecoin-project/lotus#6085](https://github.com/filecoin-project/lotus/pull/6085))
|
||||||
- release v1.11.1 backport -> master ([filecoin-project/lotus#6929](https://github.com/filecoin-project/lotus/pull/6929))
|
- release v1.11.1 backport -> master ([filecoin-project/lotus#6929](https://github.com/filecoin-project/lotus/pull/6929))
|
||||||
- chore: fixup issue templates ([filecoin-project/lotus#6899](https://github.com/filecoin-project/lotus/pull/6899))
|
- chore: fixup issue templates ([filecoin-project/lotus#6899](https://github.com/filecoin-project/lotus/pull/6899))
|
||||||
- bump master version to v1.11.2-dev ([filecoin-project/lotus#6903](https://github.com/filecoin-project/lotus/pull/6903))
|
- bump master version to v1.11.2-dev ([filecoin-project/lotus#6903](https://github.com/filecoin-project/lotus/pull/6903))
|
||||||
@@ -716,15 +843,15 @@ Contributors
|
|||||||
|
|
||||||
> Note: for discussion about this release, please comment [here](https://github.com/filecoin-project/lotus/discussions/6904)
|
> Note: for discussion about this release, please comment [here](https://github.com/filecoin-project/lotus/discussions/6904)
|
||||||
|
|
||||||
This is a **highly recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes.
|
This is a **highly recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes.
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
- ⭐️⭐️⭐️[**lotus-miner market subsystem**](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) is introduced in this release! It is **highly recommended** for storage providers to run markets processes on a separate machine! Doing so, only this machine needs to exposes public ports for deal making. This also means that the other miner operations can now be completely isolated by from the deal making processes and storage providers can stop and restarts the markets process without affecting an ongoing Winning/Window PoSt!
|
- ⭐️⭐️⭐️[**lotus-miner market subsystem**](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) is introduced in this release! It is **highly recommended** for storage providers to run markets processes on a separate machine! Doing so, only this machine needs to exposes public ports for deal making. This also means that the other miner operations can now be completely isolated by from the deal making processes and storage providers can stop and restarts the markets process without affecting an ongoing Winning/Window PoSt!
|
||||||
- More details on the concepts, architecture and how to split the market process can be found [here](https://docs.filecoin.io/mine/lotus/split-markets-miners/#concepts).
|
- More details on the concepts, architecture and how to split the market process can be found [here](https://docs.filecoin.io/mine/lotus/split-markets-miners/#concepts).
|
||||||
- Base on your system setup(running on separate machines, same machine and so on), please see the suggested practice by community members [here](https://github.com/filecoin-project/lotus/discussions/7047#discussion-3515335).
|
- Base on your system setup(running on separate machines, same machine and so on), please see the suggested practice by community members [here](https://github.com/filecoin-project/lotus/discussions/7047#discussion-3515335).
|
||||||
- Note: if you are running lotus-worker on a different machine, you will need to set `MARKETS_API_INFO` for certain CLI to work properly. This will be improved by #7072.
|
- Note: if you are running lotus-worker on a different machine, you will need to set `MARKETS_API_INFO` for certain CLI to work properly. This will be improved by #7072.
|
||||||
- Huge thanks to MinerX fellows for [helping testing the implementation, reporting the issues so they were fixed by now and providing feedbacks](https://github.com/filecoin-project/lotus/discussions/6861) to user docs in the past three weeks!
|
- Huge thanks to MinerX fellows for [helping testing the implementation, reporting the issues so they were fixed by now and providing feedbacks](https://github.com/filecoin-project/lotus/discussions/6861) to user docs in the past three weeks!
|
||||||
- Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629))
|
- Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629))
|
||||||
- Better control your sector collateral payment by setting `CollateralFromMinerBalance`, `AvailableBalanceBuffer` and `DisableCollateralFallback`.
|
- Better control your sector collateral payment by setting `CollateralFromMinerBalance`, `AvailableBalanceBuffer` and `DisableCollateralFallback`.
|
||||||
- `CollateralFromMinerBalance`: whether to use available miner balance for sector collateral instead of sending it with each message, default is `false`.
|
- `CollateralFromMinerBalance`: whether to use available miner balance for sector collateral instead of sending it with each message, default is `false`.
|
||||||
- `AvailableBalanceBuffer`: minimum available balance to keep in the miner actor before sending it with messages, default is 0FIL.
|
- `AvailableBalanceBuffer`: minimum available balance to keep in the miner actor before sending it with messages, default is 0FIL.
|
||||||
@@ -732,114 +859,114 @@ This is a **highly recommended** but optional Lotus v1.11.1 release that introd
|
|||||||
- Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697))
|
- Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697))
|
||||||
- Set `DealPublishControl` to set the wallet used for sending `PublishStorageDeals` messages, instructions [here](https://docs.filecoin.io/mine/lotus/miner-addresses/#control-addresses).
|
- Set `DealPublishControl` to set the wallet used for sending `PublishStorageDeals` messages, instructions [here](https://docs.filecoin.io/mine/lotus/miner-addresses/#control-addresses).
|
||||||
- Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848))
|
- Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848))
|
||||||
- You can now preview the the default and updated node config by running `lotus/lotus-miner config default/updated`
|
- You can now preview the the default and updated node config by running `lotus/lotus-miner config default/updated`
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
- ⭐️⭐️⭐️ Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356))
|
- ⭐️⭐️⭐️ Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356))
|
||||||
- **⭐️⭐️ Experimental** [Splitstore]((https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md)) (more details coming in v1.11.2! Stay tuned! Join the discussion [here](https://github.com/filecoin-project/lotus/discussions/5788) if you have questions!) :
|
- **⭐️⭐️ Experimental** [Splitstore]((https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md)) (more details coming in v1.11.2! Stay tuned! Join the discussion [here](https://github.com/filecoin-project/lotus/discussions/5788) if you have questions!) :
|
||||||
- Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867))
|
- Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867))
|
||||||
- Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854))
|
- Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854))
|
||||||
- splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811))
|
- splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811))
|
||||||
- fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841))
|
- fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841))
|
||||||
- Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833))
|
- Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833))
|
||||||
- cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760))
|
- cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760))
|
||||||
- Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775))
|
- Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775))
|
||||||
- Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817))
|
- Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817))
|
||||||
- Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777))
|
- Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777))
|
||||||
- Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762))
|
- Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762))
|
||||||
- Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756))
|
- Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756))
|
||||||
- Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754))
|
- Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754))
|
||||||
- Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474))
|
- Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474))
|
||||||
- lotus-shed: initial export cmd for markets related metadata ([filecoin-project/lotus#6840](https://github.com/filecoin-project/lotus/pull/6840))
|
- lotus-shed: initial export cmd for markets related metadata ([filecoin-project/lotus#6840](https://github.com/filecoin-project/lotus/pull/6840))
|
||||||
- add a very verbose -vv flag to lotus and lotus-miner. ([filecoin-project/lotus#6888](https://github.com/filecoin-project/lotus/pull/6888))
|
- add a very verbose -vv flag to lotus and lotus-miner. ([filecoin-project/lotus#6888](https://github.com/filecoin-project/lotus/pull/6888))
|
||||||
- Add allocated sectorid vis ([filecoin-project/lotus#4638](https://github.com/filecoin-project/lotus/pull/4638))
|
- Add allocated sectorid vis ([filecoin-project/lotus#4638](https://github.com/filecoin-project/lotus/pull/4638))
|
||||||
- add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640))
|
- add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640))
|
||||||
- Run `lotus-miner actor compact-allocated` to compact sector number allocations to reduce the size of the allocated sector number bitfield.
|
- Run `lotus-miner actor compact-allocated` to compact sector number allocations to reduce the size of the allocated sector number bitfield.
|
||||||
- Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642))
|
- Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642))
|
||||||
- Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743))
|
- Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743))
|
||||||
- Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696))
|
- Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696))
|
||||||
- Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694))
|
- Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694))
|
||||||
- Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620))
|
- Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620))
|
||||||
- commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650))
|
- commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650))
|
||||||
- shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631))
|
- shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631))
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683))
|
- Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683))
|
||||||
- fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724))
|
- fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724))
|
||||||
- fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802))
|
- fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802))
|
||||||
- test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804))
|
- test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804))
|
||||||
- wrap close(wait) with sync.Once to avoid panic ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800))
|
- wrap close(wait) with sync.Once to avoid panic ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800))
|
||||||
- fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787))
|
- fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787))
|
||||||
- ClientRetrieve stops on cancel([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739))
|
- ClientRetrieve stops on cancel([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739))
|
||||||
- Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066))
|
- Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066))
|
||||||
- fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688))
|
- fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688))
|
||||||
- Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679))
|
- Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679))
|
||||||
- Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680))
|
- Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680))
|
||||||
- storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653))
|
- storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653))
|
||||||
- Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664))
|
- Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664))
|
||||||
- Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658))
|
- Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658))
|
||||||
- fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635))
|
- fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635))
|
||||||
- remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634))
|
- remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634))
|
||||||
- fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625))
|
- fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625))
|
||||||
|
|
||||||
## Improvements
|
## Improvements
|
||||||
- Eliminate inefficiency in markets logging ([filecoin-project/lotus#6895](https://github.com/filecoin-project/lotus/pull/6895))
|
- Eliminate inefficiency in markets logging ([filecoin-project/lotus#6895](https://github.com/filecoin-project/lotus/pull/6895))
|
||||||
- rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886))
|
- rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886))
|
||||||
- fix racy TestSimultanenousTransferLimit. ([filecoin-project/lotus#6862](https://github.com/filecoin-project/lotus/pull/6862))
|
- fix racy TestSimultanenousTransferLimit. ([filecoin-project/lotus#6862](https://github.com/filecoin-project/lotus/pull/6862))
|
||||||
- ValidateBlock: Assert that block header height's are greater than parents ([filecoin-project/lotus#6872](https://github.com/filecoin-project/lotus/pull/6872))
|
- ValidateBlock: Assert that block header height's are greater than parents ([filecoin-project/lotus#6872](https://github.com/filecoin-project/lotus/pull/6872))
|
||||||
- feat: Don't panic when api impl is nil ([filecoin-project/lotus#6857](https://github.com/filecoin-project/lotus/pull/6857))
|
- feat: Don't panic when api impl is nil ([filecoin-project/lotus#6857](https://github.com/filecoin-project/lotus/pull/6857))
|
||||||
- add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544))
|
- add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544))
|
||||||
- easy way to make install app ([filecoin-project/lotus#5183](https://github.com/filecoin-project/lotus/pull/5183))
|
- easy way to make install app ([filecoin-project/lotus#5183](https://github.com/filecoin-project/lotus/pull/5183))
|
||||||
- api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818))
|
- api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818))
|
||||||
- add SealProof in SectorBuilder ([filecoin-project/lotus#6815](https://github.com/filecoin-project/lotus/pull/6815))
|
- add SealProof in SectorBuilder ([filecoin-project/lotus#6815](https://github.com/filecoin-project/lotus/pull/6815))
|
||||||
- sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763))
|
- sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763))
|
||||||
- ClientFindData: always fetch peer id from chain ([filecoin-project/lotus#6807](https://github.com/filecoin-project/lotus/pull/6807))
|
- ClientFindData: always fetch peer id from chain ([filecoin-project/lotus#6807](https://github.com/filecoin-project/lotus/pull/6807))
|
||||||
- test: handle null blocks in TestForkRefuseCall ([filecoin-project/lotus#6758](https://github.com/filecoin-project/lotus/pull/6758))
|
- test: handle null blocks in TestForkRefuseCall ([filecoin-project/lotus#6758](https://github.com/filecoin-project/lotus/pull/6758))
|
||||||
- Add more deal details to lotus-miner info ([filecoin-project/lotus#6708](https://github.com/filecoin-project/lotus/pull/6708))
|
- Add more deal details to lotus-miner info ([filecoin-project/lotus#6708](https://github.com/filecoin-project/lotus/pull/6708))
|
||||||
- add election backtest ([filecoin-project/lotus#5950](https://github.com/filecoin-project/lotus/pull/5950))
|
- add election backtest ([filecoin-project/lotus#5950](https://github.com/filecoin-project/lotus/pull/5950))
|
||||||
- add dollar sign ([filecoin-project/lotus#6690](https://github.com/filecoin-project/lotus/pull/6690))
|
- add dollar sign ([filecoin-project/lotus#6690](https://github.com/filecoin-project/lotus/pull/6690))
|
||||||
- get-actor cli spelling fix ([filecoin-project/lotus#6681](https://github.com/filecoin-project/lotus/pull/6681))
|
- get-actor cli spelling fix ([filecoin-project/lotus#6681](https://github.com/filecoin-project/lotus/pull/6681))
|
||||||
- polish(statetree): accept a context in statetree diff for timeouts ([filecoin-project/lotus#6639](https://github.com/filecoin-project/lotus/pull/6639))
|
- polish(statetree): accept a context in statetree diff for timeouts ([filecoin-project/lotus#6639](https://github.com/filecoin-project/lotus/pull/6639))
|
||||||
- Add helptext to lotus chain export ([filecoin-project/lotus#6672](https://github.com/filecoin-project/lotus/pull/6672))
|
- Add helptext to lotus chain export ([filecoin-project/lotus#6672](https://github.com/filecoin-project/lotus/pull/6672))
|
||||||
- add an incremental nonce itest. ([filecoin-project/lotus#6663](https://github.com/filecoin-project/lotus/pull/6663))
|
- add an incremental nonce itest. ([filecoin-project/lotus#6663](https://github.com/filecoin-project/lotus/pull/6663))
|
||||||
- commit batch: Initialize the FailedSectors map ([filecoin-project/lotus#6647](https://github.com/filecoin-project/lotus/pull/6647))
|
- commit batch: Initialize the FailedSectors map ([filecoin-project/lotus#6647](https://github.com/filecoin-project/lotus/pull/6647))
|
||||||
- Fast-path retry submitting commit aggregate if commit is still valid ([filecoin-project/lotus#6638](https://github.com/filecoin-project/lotus/pull/6638))
|
- Fast-path retry submitting commit aggregate if commit is still valid ([filecoin-project/lotus#6638](https://github.com/filecoin-project/lotus/pull/6638))
|
||||||
- Reuse timers in sealing batch logic ([filecoin-project/lotus#6636](https://github.com/filecoin-project/lotus/pull/6636))
|
- Reuse timers in sealing batch logic ([filecoin-project/lotus#6636](https://github.com/filecoin-project/lotus/pull/6636))
|
||||||
|
|
||||||
## Dependency Updates
|
## Dependency Updates
|
||||||
- Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890))
|
- Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890))
|
||||||
- update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885))
|
- update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885))
|
||||||
- Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674))
|
- Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674))
|
||||||
- github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.2):
|
- github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.2):
|
||||||
- github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.2):
|
- github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.2):
|
||||||
- github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1)
|
- github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1)
|
||||||
- github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210810190654-139e0e79e69e)
|
- github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210810190654-139e0e79e69e)
|
||||||
- github.com/filecoin-project/go-statemachine (v0.0.0-20200925024713-05bd7c71fbfe -> v1.0.1)
|
- github.com/filecoin-project/go-statemachine (v0.0.0-20200925024713-05bd7c71fbfe -> v1.0.1)
|
||||||
- update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764))
|
- update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764))
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
- Master->v1.11.1 ([filecoin-project/lotus#7051](https://github.com/filecoin-project/lotus/pull/7051))
|
- Master->v1.11.1 ([filecoin-project/lotus#7051](https://github.com/filecoin-project/lotus/pull/7051))
|
||||||
- v1.11.1-rc2 ([filecoin-project/lotus#6966](https://github.com/filecoin-project/lotus/pull/6966))
|
- v1.11.1-rc2 ([filecoin-project/lotus#6966](https://github.com/filecoin-project/lotus/pull/6966))
|
||||||
- Backport master -> v1.11.1 ([filecoin-project/lotus#6965](https://github.com/filecoin-project/lotus/pull/6965))
|
- Backport master -> v1.11.1 ([filecoin-project/lotus#6965](https://github.com/filecoin-project/lotus/pull/6965))
|
||||||
- Fixes in master -> release ([filecoin-project/lotus#6933](https://github.com/filecoin-project/lotus/pull/6933))
|
- Fixes in master -> release ([filecoin-project/lotus#6933](https://github.com/filecoin-project/lotus/pull/6933))
|
||||||
- Add changelog for v1.11.1-rc1 and bump the version ([filecoin-project/lotus#6900](https://github.com/filecoin-project/lotus/pull/6900))
|
- Add changelog for v1.11.1-rc1 and bump the version ([filecoin-project/lotus#6900](https://github.com/filecoin-project/lotus/pull/6900))
|
||||||
- Fix merge release -> v1.11.1 ([filecoin-project/lotus#6897](https://github.com/filecoin-project/lotus/pull/6897))
|
- Fix merge release -> v1.11.1 ([filecoin-project/lotus#6897](https://github.com/filecoin-project/lotus/pull/6897))
|
||||||
- Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880))
|
- Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880))
|
||||||
- Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879))
|
- Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879))
|
||||||
- Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856))
|
- Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856))
|
||||||
- Fix links in issue templates
|
- Fix links in issue templates
|
||||||
- Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798)
|
- Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798)
|
||||||
- Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837))
|
- Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837))
|
||||||
- add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544))
|
- add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544))
|
||||||
- release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828))
|
- release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828))
|
||||||
- Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773))
|
- Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773))
|
||||||
- Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757))
|
- Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757))
|
||||||
- Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747))
|
- Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747))
|
||||||
- Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710))
|
- Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710))
|
||||||
- Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709))
|
- Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709))
|
||||||
- Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689))
|
- Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689))
|
||||||
- Update version.go to 1.11.1 ([filecoin-project/lotus#6621](https://github.com/filecoin-project/lotus/pull/6621))
|
- Update version.go to 1.11.1 ([filecoin-project/lotus#6621](https://github.com/filecoin-project/lotus/pull/6621))
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
| Contributor | Commits | Lines ± | Files Changed |
|
| Contributor | Commits | Lines ± | Files Changed |
|
||||||
@@ -880,7 +1007,7 @@ This is a **highly recommended** but optional Lotus v1.11.1 release that introd
|
|||||||
| dependabot[bot] | 1 | +3/-3 | 1 |
|
| dependabot[bot] | 1 | +3/-3 | 1 |
|
||||||
| zhoutian527 | 1 | +2/-2 | 1 |
|
| zhoutian527 | 1 | +2/-2 | 1 |
|
||||||
| xloem | 1 | +4/-0 | 1 |
|
| xloem | 1 | +4/-0 | 1 |
|
||||||
| @travisperson| 2 | +2/-2 | 3 |
|
| | 2 | +2/-2 | 3 |
|
||||||
| Liviu Damian | 2 | +2/-2 | 2 |
|
| Liviu Damian | 2 | +2/-2 | 2 |
|
||||||
| @jimpick | 2 | +2/-2 | 2 |
|
| @jimpick | 2 | +2/-2 | 2 |
|
||||||
| Frank | 1 | +3/-0 | 1 |
|
| Frank | 1 | +3/-0 | 1 |
|
||||||
@@ -889,9 +1016,10 @@ This is a **highly recommended** but optional Lotus v1.11.1 release that introd
|
|||||||
|
|
||||||
# 1.11.0 / 2021-07-22
|
# 1.11.0 / 2021-07-22
|
||||||
|
|
||||||
This is a **highly recommended** release of Lotus that have many bug fixes, improvements and new features.
|
This is a **highly recommended** release of Lotus that have many bug fixes, improvements and new features.
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
|
- Miner SimultaneousTransfers config ([filecoin-project/lotus#6612](https://github.com/filecoin-project/lotus/pull/6612))
|
||||||
- Miner SimultaneousTransfers config ([filecoin-project/lotus#6612](https://github.com/filecoin-project/lotus/pull/6612))
|
- Miner SimultaneousTransfers config ([filecoin-project/lotus#6612](https://github.com/filecoin-project/lotus/pull/6612))
|
||||||
- Set `SimultaneousTransfers` in lotus miner config to configure the maximum number of parallel online data transfers, including both storage and retrieval deals.
|
- Set `SimultaneousTransfers` in lotus miner config to configure the maximum number of parallel online data transfers, including both storage and retrieval deals.
|
||||||
- Dynamic Retrieval pricing ([filecoin-project/lotus#6175](https://github.com/filecoin-project/lotus/pull/6175))
|
- Dynamic Retrieval pricing ([filecoin-project/lotus#6175](https://github.com/filecoin-project/lotus/pull/6175))
|
||||||
@@ -900,7 +1028,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- run `lotus mpool manage and follow the instructions!
|
- run `lotus mpool manage and follow the instructions!
|
||||||
- Demo available at https://www.youtube.com/watch?v=QDocpLQjZgQ.
|
- Demo available at https://www.youtube.com/watch?v=QDocpLQjZgQ.
|
||||||
- Add utils to use multisigs as miner owners ([filecoin-project/lotus#6490](https://github.com/filecoin-project/lotus/pull/6490))
|
- Add utils to use multisigs as miner owners ([filecoin-project/lotus#6490](https://github.com/filecoin-project/lotus/pull/6490))
|
||||||
|
|
||||||
## More New Features
|
## More New Features
|
||||||
- feat: implement lotus-sim ([filecoin-project/lotus#6406](https://github.com/filecoin-project/lotus/pull/6406))
|
- feat: implement lotus-sim ([filecoin-project/lotus#6406](https://github.com/filecoin-project/lotus/pull/6406))
|
||||||
- implement a command to export a car ([filecoin-project/lotus#6405](https://github.com/filecoin-project/lotus/pull/6405))
|
- implement a command to export a car ([filecoin-project/lotus#6405](https://github.com/filecoin-project/lotus/pull/6405))
|
||||||
@@ -917,11 +1045,11 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Transplant some useful commands to lotus-shed actor ([filecoin-project/lotus#5913](https://github.com/filecoin-project/lotus/pull/5913))
|
- Transplant some useful commands to lotus-shed actor ([filecoin-project/lotus#5913](https://github.com/filecoin-project/lotus/pull/5913))
|
||||||
- run `lotus-shed actor`
|
- run `lotus-shed actor`
|
||||||
- actor wrapper codegen ([filecoin-project/lotus#6108](https://github.com/filecoin-project/lotus/pull/6108))
|
- actor wrapper codegen ([filecoin-project/lotus#6108](https://github.com/filecoin-project/lotus/pull/6108))
|
||||||
- Add a shed util to count miners by post type ([filecoin-project/lotus#6169](https://github.com/filecoin-project/lotus/pull/6169))
|
- Add a shed util to count miners by post type ([filecoin-project/lotus#6169](https://github.com/filecoin-project/lotus/pull/6169))
|
||||||
- shed: command to list duplicate messages in tipsets (steb) ([filecoin-project/lotus#5847](https://github.com/filecoin-project/lotus/pull/5847))
|
- shed: command to list duplicate messages in tipsets (steb) ([filecoin-project/lotus#5847](https://github.com/filecoin-project/lotus/pull/5847))
|
||||||
- feat: allow checkpointing to forks ([filecoin-project/lotus#6107](https://github.com/filecoin-project/lotus/pull/6107))
|
- feat: allow checkpointing to forks ([filecoin-project/lotus#6107](https://github.com/filecoin-project/lotus/pull/6107))
|
||||||
- Add a CLI tool for miner proving deadline ([filecoin-project/lotus#6132](https://github.com/filecoin-project/lotus/pull/6132))
|
- Add a CLI tool for miner proving deadline ([filecoin-project/lotus#6132](https://github.com/filecoin-project/lotus/pull/6132))
|
||||||
- run `lotus state miner-proving-deadline`
|
- run `lotus state miner-proving-deadline`
|
||||||
|
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
@@ -930,7 +1058,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Make query-ask CLI more graceful ([filecoin-project/lotus#6590](https://github.com/filecoin-project/lotus/pull/6590))
|
- Make query-ask CLI more graceful ([filecoin-project/lotus#6590](https://github.com/filecoin-project/lotus/pull/6590))
|
||||||
- scale up sector expiration to avoid sector expire in batch-pre-commit waitting ([filecoin-project/lotus#6566](https://github.com/filecoin-project/lotus/pull/6566))
|
- scale up sector expiration to avoid sector expire in batch-pre-commit waitting ([filecoin-project/lotus#6566](https://github.com/filecoin-project/lotus/pull/6566))
|
||||||
- Fix an error in msigLockCancel ([filecoin-project/lotus#6582](https://github.com/filecoin-project/lotus/pull/6582)
|
- Fix an error in msigLockCancel ([filecoin-project/lotus#6582](https://github.com/filecoin-project/lotus/pull/6582)
|
||||||
- fix circleci being out of sync. ([filecoin-project/lotus#6573](https://github.com/filecoin-project/lotus/pull/6573))
|
- fix circleci being out of sync. ([filecoin-project/lotus#6573](https://github.com/filecoin-project/lotus/pull/6573))
|
||||||
- Fix helptext for ask price([filecoin-project/lotus#6560](https://github.com/filecoin-project/lotus/pull/6560))
|
- Fix helptext for ask price([filecoin-project/lotus#6560](https://github.com/filecoin-project/lotus/pull/6560))
|
||||||
- fix commit finalize failed ([filecoin-project/lotus#6521](https://github.com/filecoin-project/lotus/pull/6521))
|
- fix commit finalize failed ([filecoin-project/lotus#6521](https://github.com/filecoin-project/lotus/pull/6521))
|
||||||
- Fix soup ([filecoin-project/lotus#6501](https://github.com/filecoin-project/lotus/pull/6501))
|
- Fix soup ([filecoin-project/lotus#6501](https://github.com/filecoin-project/lotus/pull/6501))
|
||||||
@@ -955,7 +1083,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Speed up StateListMessages in some cases ([filecoin-project/lotus#6007](https://github.com/filecoin-project/lotus/pull/6007))
|
- Speed up StateListMessages in some cases ([filecoin-project/lotus#6007](https://github.com/filecoin-project/lotus/pull/6007))
|
||||||
- fix(splitstore): fix a panic on revert-only head changes ([filecoin-project/lotus#6133](https://github.com/filecoin-project/lotus/pull/6133))
|
- fix(splitstore): fix a panic on revert-only head changes ([filecoin-project/lotus#6133](https://github.com/filecoin-project/lotus/pull/6133))
|
||||||
- drand: fix beacon cache ([filecoin-project/lotus#6164](https://github.com/filecoin-project/lotus/pull/6164))
|
- drand: fix beacon cache ([filecoin-project/lotus#6164](https://github.com/filecoin-project/lotus/pull/6164))
|
||||||
|
|
||||||
## Improvements
|
## Improvements
|
||||||
- gateway: Add support for Version method ([filecoin-project/lotus#6618](https://github.com/filecoin-project/lotus/pull/6618))
|
- gateway: Add support for Version method ([filecoin-project/lotus#6618](https://github.com/filecoin-project/lotus/pull/6618))
|
||||||
- revamped integration test kit (aka. Operation Sparks Joy) ([filecoin-project/lotus#6329](https://github.com/filecoin-project/lotus/pull/6329))
|
- revamped integration test kit (aka. Operation Sparks Joy) ([filecoin-project/lotus#6329](https://github.com/filecoin-project/lotus/pull/6329))
|
||||||
@@ -990,7 +1118,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Remove log line when tracing is not configured ([filecoin-project/lotus#6334](https://github.com/filecoin-project/lotus/pull/6334))
|
- Remove log line when tracing is not configured ([filecoin-project/lotus#6334](https://github.com/filecoin-project/lotus/pull/6334))
|
||||||
- separate tracing environment variables ([filecoin-project/lotus#6323](https://github.com/filecoin-project/lotus/pull/6323))
|
- separate tracing environment variables ([filecoin-project/lotus#6323](https://github.com/filecoin-project/lotus/pull/6323))
|
||||||
- feat: log dispute rate ([filecoin-project/lotus#6322](https://github.com/filecoin-project/lotus/pull/6322))
|
- feat: log dispute rate ([filecoin-project/lotus#6322](https://github.com/filecoin-project/lotus/pull/6322))
|
||||||
- Move verifreg shed utils to CLI ([filecoin-project/lotus#6135](https://github.com/filecoin-project/lotus/pull/6135))
|
- Move verifreg shed utils to CLI ([filecoin-project/lotus#6135](https://github.com/filecoin-project/lotus/pull/6135))
|
||||||
- consider storiface.PathStorage when calculating storage requirements ([filecoin-project/lotus#6233](https://github.com/filecoin-project/lotus/pull/6233))
|
- consider storiface.PathStorage when calculating storage requirements ([filecoin-project/lotus#6233](https://github.com/filecoin-project/lotus/pull/6233))
|
||||||
- `storage` module: add go docs and minor code quality refactors ([filecoin-project/lotus#6259](https://github.com/filecoin-project/lotus/pull/6259))
|
- `storage` module: add go docs and minor code quality refactors ([filecoin-project/lotus#6259](https://github.com/filecoin-project/lotus/pull/6259))
|
||||||
- Increase data transfer timeouts ([filecoin-project/lotus#6300](https://github.com/filecoin-project/lotus/pull/6300))
|
- Increase data transfer timeouts ([filecoin-project/lotus#6300](https://github.com/filecoin-project/lotus/pull/6300))
|
||||||
@@ -1007,7 +1135,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Testground checks on push ([filecoin-project/lotus#5887](https://github.com/filecoin-project/lotus/pull/5887))
|
- Testground checks on push ([filecoin-project/lotus#5887](https://github.com/filecoin-project/lotus/pull/5887))
|
||||||
- Use EmptyTSK where appropriate ([filecoin-project/lotus#6134](https://github.com/filecoin-project/lotus/pull/6134))
|
- Use EmptyTSK where appropriate ([filecoin-project/lotus#6134](https://github.com/filecoin-project/lotus/pull/6134))
|
||||||
- upgrade `lotus-soup` testplans and reduce deals concurrency to a single miner ([filecoin-project/lotus#6122](https://github.com/filecoin-project/lotus/pull/6122)
|
- upgrade `lotus-soup` testplans and reduce deals concurrency to a single miner ([filecoin-project/lotus#6122](https://github.com/filecoin-project/lotus/pull/6122)
|
||||||
|
|
||||||
## Dependency Updates
|
## Dependency Updates
|
||||||
- downgrade libp2p/go-libp2p-yamux to v0.5.1. ([filecoin-project/lotus#6605](https://github.com/filecoin-project/lotus/pull/6605))
|
- downgrade libp2p/go-libp2p-yamux to v0.5.1. ([filecoin-project/lotus#6605](https://github.com/filecoin-project/lotus/pull/6605))
|
||||||
- Update libp2p to 0.14.2 ([filecoin-project/lotus#6404](https://github.com/filecoin-project/lotus/pull/6404))
|
- Update libp2p to 0.14.2 ([filecoin-project/lotus#6404](https://github.com/filecoin-project/lotus/pull/6404))
|
||||||
@@ -1015,7 +1143,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Use new actor tags ([filecoin-project/lotus#6291](https://github.com/filecoin-project/lotus/pull/6291))
|
- Use new actor tags ([filecoin-project/lotus#6291](https://github.com/filecoin-project/lotus/pull/6291))
|
||||||
- chore: update go-libp2p ([filecoin-project/lotus#6231](https://github.com/filecoin-project/lotus/pull/6231))
|
- chore: update go-libp2p ([filecoin-project/lotus#6231](https://github.com/filecoin-project/lotus/pull/6231))
|
||||||
- Update ffi to proofs v7 ([filecoin-project/lotus#6150](https://github.com/filecoin-project/lotus/pull/6150))
|
- Update ffi to proofs v7 ([filecoin-project/lotus#6150](https://github.com/filecoin-project/lotus/pull/6150))
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
- Initial draft: basic build instructions on Readme ([filecoin-project/lotus#6498](https://github.com/filecoin-project/lotus/pull/6498))
|
- Initial draft: basic build instructions on Readme ([filecoin-project/lotus#6498](https://github.com/filecoin-project/lotus/pull/6498))
|
||||||
- Remove rc changelog, compile the new changelog for final release only ([filecoin-project/lotus#6444](https://github.com/filecoin-project/lotus/pull/6444))
|
- Remove rc changelog, compile the new changelog for final release only ([filecoin-project/lotus#6444](https://github.com/filecoin-project/lotus/pull/6444))
|
||||||
@@ -1033,8 +1161,8 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
- Introduce a release issue template ([filecoin-project/lotus#5826](https://github.com/filecoin-project/lotus/pull/5826))
|
- Introduce a release issue template ([filecoin-project/lotus#5826](https://github.com/filecoin-project/lotus/pull/5826))
|
||||||
- This is a 1:1 forward-port of PR#6183 from 1.9.x to master ([filecoin-project/lotus#6196](https://github.com/filecoin-project/lotus/pull/6196))
|
- This is a 1:1 forward-port of PR#6183 from 1.9.x to master ([filecoin-project/lotus#6196](https://github.com/filecoin-project/lotus/pull/6196))
|
||||||
- Update cli gen ([filecoin-project/lotus#6155](https://github.com/filecoin-project/lotus/pull/6155))
|
- Update cli gen ([filecoin-project/lotus#6155](https://github.com/filecoin-project/lotus/pull/6155))
|
||||||
- Generate CLI docs ([filecoin-project/lotus#6145](https://github.com/filecoin-project/lotus/pull/6145))
|
- Generate CLI docs ([filecoin-project/lotus#6145](https://github.com/filecoin-project/lotus/pull/6145))
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
| Contributor | Commits | Lines ± | Files Changed |
|
| Contributor | Commits | Lines ± | Files Changed |
|
||||||
@@ -1046,7 +1174,7 @@ This is a **highly recommended** release of Lotus that have many bug fixes, impr
|
|||||||
| @Stebalien | 106 | +7653/-2718 | 273 |
|
| @Stebalien | 106 | +7653/-2718 | 273 |
|
||||||
| dirkmc | 11 | +2580/-1371 | 77 |
|
| dirkmc | 11 | +2580/-1371 | 77 |
|
||||||
| @dirkmc | 39 | +1865/-1194 | 79 |
|
| @dirkmc | 39 | +1865/-1194 | 79 |
|
||||||
| @Kubuxu | 19 | +1973/-485 | 81 |
|
| | 19 | +1973/-485 | 81 |
|
||||||
| @vyzo | 4 | +1748/-330 | 50 |
|
| @vyzo | 4 | +1748/-330 | 50 |
|
||||||
| @aarshkshah1992 | 5 | +1462/-213 | 27 |
|
| @aarshkshah1992 | 5 | +1462/-213 | 27 |
|
||||||
| @coryschwartz | 35 | +568/-206 | 59 |
|
| @coryschwartz | 35 | +568/-206 | 59 |
|
||||||
@@ -1083,10 +1211,10 @@ This is an optional but **highly recommended** release of Lotus for lotus miners
|
|||||||
## New Features
|
## New Features
|
||||||
- commit batch: AggregateAboveBaseFee config #6650
|
- commit batch: AggregateAboveBaseFee config #6650
|
||||||
- `AggregateAboveBaseFee` is added to miner sealing configuration for setting the network base fee to start aggregating proofs. When the network base fee is lower than this value, the prove commits will be submitted individually via `ProveCommitSector`. According to the [Batch Incentive Alignment](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md#batch-incentive-alignment) introduced in FIP-0013, we recommend miners to set this value to 0.15 nanoFIL(which is the default value) to avoid unexpected aggregation fee in burn and enjoy the most benefits of aggregation!
|
- `AggregateAboveBaseFee` is added to miner sealing configuration for setting the network base fee to start aggregating proofs. When the network base fee is lower than this value, the prove commits will be submitted individually via `ProveCommitSector`. According to the [Batch Incentive Alignment](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md#batch-incentive-alignment) introduced in FIP-0013, we recommend miners to set this value to 0.15 nanoFIL(which is the default value) to avoid unexpected aggregation fee in burn and enjoy the most benefits of aggregation!
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- storage: Fix FinalizeSector with sectors in storage paths #6652
|
- storage: Fix FinalizeSector with sectors in storage paths #6652
|
||||||
- Fix tiny error in check-client-datacap #6664
|
- Fix tiny error in check-client-datacap #6664
|
||||||
- Fix: precommit_batch method used the wrong cfg.PreCommitBatchWait #6658
|
- Fix: precommit_batch method used the wrong cfg.PreCommitBatchWait #6658
|
||||||
- to optimize the batchwait #6636
|
- to optimize the batchwait #6636
|
||||||
- fix getTicket: sector precommitted but expired case #6635
|
- fix getTicket: sector precommitted but expired case #6635
|
||||||
@@ -1115,10 +1243,10 @@ This is an optional but **highly recommended** release of Lotus for lotus miners
|
|||||||
## New Features
|
## New Features
|
||||||
- commit batch: AggregateAboveBaseFee config #6650
|
- commit batch: AggregateAboveBaseFee config #6650
|
||||||
- `AggregateAboveBaseFee` is added to miner sealing configuration for setting the network base fee to start aggregating proofs. When the network base fee is lower than this value, the prove commits will be submitted individually via `ProveCommitSector`. According to the [Batch Incentive Alignment](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md#batch-incentive-alignment) introduced in FIP-0013, we recommend miners to set this value to 0.15 nanoFIL(which is the default value) to avoid unexpected aggregation fee in burn and enjoy the most benefits of aggregation!
|
- `AggregateAboveBaseFee` is added to miner sealing configuration for setting the network base fee to start aggregating proofs. When the network base fee is lower than this value, the prove commits will be submitted individually via `ProveCommitSector`. According to the [Batch Incentive Alignment](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md#batch-incentive-alignment) introduced in FIP-0013, we recommend miners to set this value to 0.15 nanoFIL(which is the default value) to avoid unexpected aggregation fee in burn and enjoy the most benefits of aggregation!
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- storage: Fix FinalizeSector with sectors in storage paths #6652
|
- storage: Fix FinalizeSector with sectors in storage paths #6652
|
||||||
- Fix tiny error in check-client-datacap #6664
|
- Fix tiny error in check-client-datacap #6664
|
||||||
- Fix: precommit_batch method used the wrong cfg.PreCommitBatchWait #6658
|
- Fix: precommit_batch method used the wrong cfg.PreCommitBatchWait #6658
|
||||||
- to optimize the batchwait #6636
|
- to optimize the batchwait #6636
|
||||||
- fix getTicket: sector precommitted but expired case #6635
|
- fix getTicket: sector precommitted but expired case #6635
|
||||||
@@ -1161,10 +1289,10 @@ FIPs [0008](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0008.m
|
|||||||
**Check out the documentation [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#precommitsectorsbatch) for details on the new Lotus miner sealing config options, [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#fees-section) for fee config options, and explanations of the new features.**
|
**Check out the documentation [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#precommitsectorsbatch) for details on the new Lotus miner sealing config options, [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#fees-section) for fee config options, and explanations of the new features.**
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
- We recommend to keep `PreCommitSectorsBatch` as 1.
|
- We recommend to keep `PreCommitSectorsBatch` as 1.
|
||||||
- We recommend miners to set `PreCommitBatchWait` lower than 30 hours.
|
- We recommend miners to set `PreCommitBatchWait` lower than 30 hours.
|
||||||
- We recommend miners to set a longer `CommitBatchSlack` and `PreCommitBatchSlack` to prevent message failures
|
- We recommend miners to set a longer `CommitBatchSlack` and `PreCommitBatchSlack` to prevent message failures
|
||||||
due to expirations.
|
due to expirations.
|
||||||
|
|
||||||
### Projected state tree growth
|
### Projected state tree growth
|
||||||
|
|
||||||
@@ -1175,9 +1303,9 @@ Given these assumptions:
|
|||||||
- We'd expect a network storage growth rate of around 530PiB per day. 😳 🎉 🥳 😅
|
- We'd expect a network storage growth rate of around 530PiB per day. 😳 🎉 🥳 😅
|
||||||
- We'd expect network bandwidth dedicated to `SubmitWindowedPoSt` to grow by about 0.02% per day.
|
- We'd expect network bandwidth dedicated to `SubmitWindowedPoSt` to grow by about 0.02% per day.
|
||||||
- We'd expect the [state-tree](https://spec.filecoin.io/#section-systems.filecoin_vm.state_tree) (and therefore [snapshot](https://docs.filecoin.io/get-started/lotus/chain/#lightweight-snapshot)) size to grow by 1.16GiB per day.
|
- We'd expect the [state-tree](https://spec.filecoin.io/#section-systems.filecoin_vm.state_tree) (and therefore [snapshot](https://docs.filecoin.io/get-started/lotus/chain/#lightweight-snapshot)) size to grow by 1.16GiB per day.
|
||||||
- Nearly all of the state-tree growth is expected to come from new sector metadata.
|
- Nearly all of the state-tree growth is expected to come from new sector metadata.
|
||||||
- We'd expect the daily lotus datastore growth rate to increase by about 10-15% (from current ~21GiB/day).
|
- We'd expect the daily lotus datastore growth rate to increase by about 10-15% (from current ~21GiB/day).
|
||||||
- Most "growth" of the lotus datastore is due to "churn", historical data that's no longer referenced by the latest state-tree.
|
- Most "growth" of the lotus datastore is due to "churn", historical data that's no longer referenced by the latest state-tree.
|
||||||
|
|
||||||
### Future improvements
|
### Future improvements
|
||||||
|
|
||||||
@@ -2866,4 +2994,4 @@ We are grateful for every contribution!
|
|||||||
|
|
||||||
We are very excited to release **lotus** 0.1.0. This is our testnet release. To install lotus and join the testnet, please visit [lotu.sh](lotu.sh). Please file bug reports as [issues](https://github.com/filecoin-project/lotus/issues).
|
We are very excited to release **lotus** 0.1.0. This is our testnet release. To install lotus and join the testnet, please visit [lotu.sh](lotu.sh). Please file bug reports as [issues](https://github.com/filecoin-project/lotus/issues).
|
||||||
|
|
||||||
A huge thank you to all contributors for this testnet release!
|
A huge thank you to all contributors for this testnet release!
|
||||||
+48
-2
@@ -28,6 +28,14 @@ WORKDIR /opt/filecoin
|
|||||||
RUN make clean deps
|
RUN make clean deps
|
||||||
|
|
||||||
|
|
||||||
|
FROM builder-local AS builder-test
|
||||||
|
MAINTAINER Lotus Development Team
|
||||||
|
|
||||||
|
WORKDIR /opt/filecoin
|
||||||
|
|
||||||
|
RUN make debug
|
||||||
|
|
||||||
|
|
||||||
FROM builder-local AS builder
|
FROM builder-local AS builder
|
||||||
MAINTAINER Lotus Development Team
|
MAINTAINER Lotus Development Team
|
||||||
|
|
||||||
@@ -53,8 +61,9 @@ COPY --from=builder /usr/lib/x86_64-linux-gnu/libnuma.so.1 /lib/
|
|||||||
COPY --from=builder /usr/lib/x86_64-linux-gnu/libhwloc.so.5 /lib/
|
COPY --from=builder /usr/lib/x86_64-linux-gnu/libhwloc.so.5 /lib/
|
||||||
COPY --from=builder /usr/lib/x86_64-linux-gnu/libOpenCL.so.1 /lib/
|
COPY --from=builder /usr/lib/x86_64-linux-gnu/libOpenCL.so.1 /lib/
|
||||||
|
|
||||||
RUN useradd -r -u 532 -U fc
|
RUN useradd -r -u 532 -U fc \
|
||||||
|
&& mkdir -p /etc/OpenCL/vendors \
|
||||||
|
&& echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd
|
||||||
|
|
||||||
###
|
###
|
||||||
FROM base AS lotus
|
FROM base AS lotus
|
||||||
@@ -197,6 +206,43 @@ RUN chown fc: /var/lib/lotus-worker
|
|||||||
RUN chown fc: /var/lib/lotus-wallet
|
RUN chown fc: /var/lib/lotus-wallet
|
||||||
|
|
||||||
|
|
||||||
|
VOLUME /var/tmp/filecoin-proof-parameters
|
||||||
|
VOLUME /var/lib/lotus
|
||||||
|
VOLUME /var/lib/lotus-miner
|
||||||
|
VOLUME /var/lib/lotus-worker
|
||||||
|
VOLUME /var/lib/lotus-wallet
|
||||||
|
|
||||||
|
EXPOSE 1234
|
||||||
|
EXPOSE 2345
|
||||||
|
EXPOSE 3456
|
||||||
|
EXPOSE 1777
|
||||||
|
|
||||||
|
###
|
||||||
|
from base as lotus-test
|
||||||
|
|
||||||
|
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
|
||||||
|
ENV LOTUS_MINER_PATH /var/lib/lotus-miner
|
||||||
|
ENV LOTUS_PATH /var/lib/lotus
|
||||||
|
ENV LOTUS_WORKER_PATH /var/lib/lotus-worker
|
||||||
|
ENV WALLET_PATH /var/lib/lotus-wallet
|
||||||
|
|
||||||
|
COPY --from=builder-test /opt/filecoin/lotus /usr/local/bin/
|
||||||
|
COPY --from=builder-test /opt/filecoin/lotus-miner /usr/local/bin/
|
||||||
|
COPY --from=builder-test /opt/filecoin/lotus-worker /usr/local/bin/
|
||||||
|
COPY --from=builder-test /opt/filecoin/lotus-seed /usr/local/bin/
|
||||||
|
|
||||||
|
RUN mkdir /var/tmp/filecoin-proof-parameters
|
||||||
|
RUN mkdir /var/lib/lotus
|
||||||
|
RUN mkdir /var/lib/lotus-miner
|
||||||
|
RUN mkdir /var/lib/lotus-worker
|
||||||
|
RUN mkdir /var/lib/lotus-wallet
|
||||||
|
RUN chown fc: /var/tmp/filecoin-proof-parameters
|
||||||
|
RUN chown fc: /var/lib/lotus
|
||||||
|
RUN chown fc: /var/lib/lotus-miner
|
||||||
|
RUN chown fc: /var/lib/lotus-worker
|
||||||
|
RUN chown fc: /var/lib/lotus-wallet
|
||||||
|
|
||||||
|
|
||||||
VOLUME /var/tmp/filecoin-proof-parameters
|
VOLUME /var/tmp/filecoin-proof-parameters
|
||||||
VOLUME /var/lib/lotus
|
VOLUME /var/lib/lotus
|
||||||
VOLUME /var/lib/lotus-miner
|
VOLUME /var/lib/lotus-miner
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ BINS+=lotus-miner
|
|||||||
|
|
||||||
lotus-worker: $(BUILD_DEPS)
|
lotus-worker: $(BUILD_DEPS)
|
||||||
rm -f lotus-worker
|
rm -f lotus-worker
|
||||||
$(GOCC) build $(GOFLAGS) -o lotus-worker ./cmd/lotus-seal-worker
|
$(GOCC) build $(GOFLAGS) -o lotus-worker ./cmd/lotus-worker
|
||||||
.PHONY: lotus-worker
|
.PHONY: lotus-worker
|
||||||
BINS+=lotus-worker
|
BINS+=lotus-worker
|
||||||
|
|
||||||
@@ -345,6 +345,8 @@ gen: actors-gen type-gen method-gen cfgdoc-gen docsgen api-gen circleci
|
|||||||
@echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO MAKE docsgen-cli"
|
@echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO MAKE docsgen-cli"
|
||||||
.PHONY: gen
|
.PHONY: gen
|
||||||
|
|
||||||
|
jen: gen
|
||||||
|
|
||||||
snap: lotus lotus-miner lotus-worker
|
snap: lotus lotus-miner lotus-worker
|
||||||
snapcraft
|
snapcraft
|
||||||
# snapcraft upload ./lotus_*.snap
|
# snapcraft upload ./lotus_*.snap
|
||||||
@@ -360,4 +362,4 @@ print-%:
|
|||||||
@echo $*=$($*)
|
@echo $*=$($*)
|
||||||
|
|
||||||
circleci:
|
circleci:
|
||||||
go generate -x ./.circleci
|
go generate -x ./.circleci
|
||||||
|
|||||||
+25
-3
@@ -689,7 +689,17 @@ type FullNode interface {
|
|||||||
// MethodGroup: Paych
|
// MethodGroup: Paych
|
||||||
// The Paych methods are for interacting with and managing payment channels
|
// The Paych methods are for interacting with and managing payment channels
|
||||||
|
|
||||||
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error) //perm:sign
|
// PaychGet gets or creates a payment channel between address pair
|
||||||
|
// The specified amount will be reserved for use. If there aren't enough non-reserved funds
|
||||||
|
// available, funds will be added through an on-chain message.
|
||||||
|
// - When opts.OffChain is true, this call will not cause any messages to be sent to the chain (no automatic
|
||||||
|
// channel creation/funds adding). If the operation can't be performed without sending a message an error will be
|
||||||
|
// returned. Note that even when this option is specified, this call can be blocked by previous operations on the
|
||||||
|
// channel waiting for on-chain operations.
|
||||||
|
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt, opts PaychGetOpts) (*ChannelInfo, error) //perm:sign
|
||||||
|
// PaychFund gets or creates a payment channel between address pair.
|
||||||
|
// The specified amount will be added to the channel through on-chain send for future use
|
||||||
|
PaychFund(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error) //perm:sign
|
||||||
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign
|
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error) //perm:sign
|
||||||
PaychAvailableFunds(ctx context.Context, ch address.Address) (*ChannelAvailableFunds, error) //perm:sign
|
PaychAvailableFunds(ctx context.Context, ch address.Address) (*ChannelAvailableFunds, error) //perm:sign
|
||||||
PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*ChannelAvailableFunds, error) //perm:sign
|
PaychAvailableFundsByFromTo(ctx context.Context, from, to address.Address) (*ChannelAvailableFunds, error) //perm:sign
|
||||||
@@ -828,6 +838,10 @@ const (
|
|||||||
PCHOutbound
|
PCHOutbound
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PaychGetOpts struct {
|
||||||
|
OffChain bool
|
||||||
|
}
|
||||||
|
|
||||||
type PaychStatus struct {
|
type PaychStatus struct {
|
||||||
ControlAddr address.Address
|
ControlAddr address.Address
|
||||||
Direction PCHDir
|
Direction PCHDir
|
||||||
@@ -845,16 +859,23 @@ type ChannelAvailableFunds struct {
|
|||||||
From address.Address
|
From address.Address
|
||||||
// To is the to address of the channel
|
// To is the to address of the channel
|
||||||
To address.Address
|
To address.Address
|
||||||
// ConfirmedAmt is the amount of funds that have been confirmed on-chain
|
|
||||||
// for the channel
|
// ConfirmedAmt is the total amount of funds that have been confirmed on-chain for the channel
|
||||||
ConfirmedAmt types.BigInt
|
ConfirmedAmt types.BigInt
|
||||||
// PendingAmt is the amount of funds that are pending confirmation on-chain
|
// PendingAmt is the amount of funds that are pending confirmation on-chain
|
||||||
PendingAmt types.BigInt
|
PendingAmt types.BigInt
|
||||||
|
|
||||||
|
// NonReservedAmt is part of ConfirmedAmt that is available for use (e.g. when the payment channel was pre-funded)
|
||||||
|
NonReservedAmt types.BigInt
|
||||||
|
// PendingAvailableAmt is the amount of funds that are pending confirmation on-chain that will become available once confirmed
|
||||||
|
PendingAvailableAmt types.BigInt
|
||||||
|
|
||||||
// PendingWaitSentinel can be used with PaychGetWaitReady to wait for
|
// PendingWaitSentinel can be used with PaychGetWaitReady to wait for
|
||||||
// confirmation of pending funds
|
// confirmation of pending funds
|
||||||
PendingWaitSentinel *cid.Cid
|
PendingWaitSentinel *cid.Cid
|
||||||
// QueuedAmt is the amount that is queued up behind a pending request
|
// QueuedAmt is the amount that is queued up behind a pending request
|
||||||
QueuedAmt types.BigInt
|
QueuedAmt types.BigInt
|
||||||
|
|
||||||
// VoucherRedeemedAmt is the amount that is redeemed by vouchers on-chain
|
// VoucherRedeemedAmt is the amount that is redeemed by vouchers on-chain
|
||||||
// and in the local datastore
|
// and in the local datastore
|
||||||
VoucherReedeemedAmt types.BigInt
|
VoucherReedeemedAmt types.BigInt
|
||||||
@@ -900,6 +921,7 @@ type QueryOffer struct {
|
|||||||
Size uint64
|
Size uint64
|
||||||
MinPrice types.BigInt
|
MinPrice types.BigInt
|
||||||
UnsealPrice types.BigInt
|
UnsealPrice types.BigInt
|
||||||
|
PricePerByte abi.TokenAmount
|
||||||
PaymentInterval uint64
|
PaymentInterval uint64
|
||||||
PaymentIntervalIncrease uint64
|
PaymentIntervalIncrease uint64
|
||||||
Miner address.Address
|
Miner address.Address
|
||||||
|
|||||||
+2
-1
@@ -45,8 +45,9 @@ type Gateway interface {
|
|||||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||||
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
|
||||||
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*MsigTransaction, error)
|
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*MsigTransaction, error)
|
||||||
|
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||||
|
MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MsigVesting, error)
|
||||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||||
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
|
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
|
||||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||||
"github.com/libp2p/go-libp2p-core/network"
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
@@ -25,6 +26,7 @@ type Net interface {
|
|||||||
|
|
||||||
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) //perm:read
|
NetConnectedness(context.Context, peer.ID) (network.Connectedness, error) //perm:read
|
||||||
NetPeers(context.Context) ([]peer.AddrInfo, error) //perm:read
|
NetPeers(context.Context) ([]peer.AddrInfo, error) //perm:read
|
||||||
|
NetPing(context.Context, peer.ID) (time.Duration, error) //perm:read
|
||||||
NetConnect(context.Context, peer.AddrInfo) error //perm:write
|
NetConnect(context.Context, peer.AddrInfo) error //perm:write
|
||||||
NetAddrsListen(context.Context) (peer.AddrInfo, error) //perm:read
|
NetAddrsListen(context.Context) (peer.AddrInfo, error) //perm:read
|
||||||
NetDisconnect(context.Context, peer.ID) error //perm:write
|
NetDisconnect(context.Context, peer.ID) error //perm:write
|
||||||
@@ -51,6 +53,15 @@ type Net interface {
|
|||||||
NetBlockRemove(ctx context.Context, acl NetBlockList) error //perm:admin
|
NetBlockRemove(ctx context.Context, acl NetBlockList) error //perm:admin
|
||||||
NetBlockList(ctx context.Context) (NetBlockList, error) //perm:read
|
NetBlockList(ctx context.Context) (NetBlockList, error) //perm:read
|
||||||
|
|
||||||
|
NetProtectAdd(ctx context.Context, acl []peer.ID) error //perm:admin
|
||||||
|
NetProtectRemove(ctx context.Context, acl []peer.ID) error //perm:admin
|
||||||
|
NetProtectList(ctx context.Context) ([]peer.ID, error) //perm:read
|
||||||
|
|
||||||
|
// ResourceManager API
|
||||||
|
NetStat(ctx context.Context, scope string) (NetStat, error) //perm:read
|
||||||
|
NetLimit(ctx context.Context, scope string) (NetLimit, error) //perm:read
|
||||||
|
NetSetLimit(ctx context.Context, scope string, limit NetLimit) error //perm:admin
|
||||||
|
|
||||||
// ID returns peerID of libp2p node backing this API
|
// ID returns peerID of libp2p node backing this API
|
||||||
ID(context.Context) (peer.ID, error) //perm:read
|
ID(context.Context) (peer.ID, error) //perm:read
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-32
@@ -24,7 +24,6 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||||
)
|
)
|
||||||
@@ -92,7 +91,8 @@ type StorageMiner interface {
|
|||||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error //perm:admin
|
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error //perm:admin
|
||||||
// SectorRemove removes the sector from storage. It doesn't terminate it on-chain, which can
|
// SectorRemove removes the sector from storage. It doesn't terminate it on-chain, which can
|
||||||
// be done with SectorTerminate. Removing and not terminating live sectors will cause additional penalties.
|
// be done with SectorTerminate. Removing and not terminating live sectors will cause additional penalties.
|
||||||
SectorRemove(context.Context, abi.SectorNumber) error //perm:admin
|
SectorRemove(context.Context, abi.SectorNumber) error //perm:admin
|
||||||
|
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber, snap bool) error //perm:admin
|
||||||
// SectorTerminate terminates the sector on-chain (adding it to a termination batch first), then
|
// SectorTerminate terminates the sector on-chain (adding it to a termination batch first), then
|
||||||
// automatically removes it from storage
|
// automatically removes it from storage
|
||||||
SectorTerminate(context.Context, abi.SectorNumber) error //perm:admin
|
SectorTerminate(context.Context, abi.SectorNumber) error //perm:admin
|
||||||
@@ -100,8 +100,7 @@ type StorageMiner interface {
|
|||||||
// Returns null if message wasn't sent
|
// Returns null if message wasn't sent
|
||||||
SectorTerminateFlush(ctx context.Context) (*cid.Cid, error) //perm:admin
|
SectorTerminateFlush(ctx context.Context) (*cid.Cid, error) //perm:admin
|
||||||
// SectorTerminatePending returns a list of pending sector terminations to be sent in the next batch message
|
// SectorTerminatePending returns a list of pending sector terminations to be sent in the next batch message
|
||||||
SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
|
SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
|
||||||
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber, snap bool) error //perm:admin
|
|
||||||
// SectorPreCommitFlush immediately sends a PreCommit message with sectors batched for PreCommit.
|
// SectorPreCommitFlush immediately sends a PreCommit message with sectors batched for PreCommit.
|
||||||
// Returns null if message wasn't sent
|
// Returns null if message wasn't sent
|
||||||
SectorPreCommitFlush(ctx context.Context) ([]sealiface.PreCommitBatchRes, error) //perm:admin
|
SectorPreCommitFlush(ctx context.Context) ([]sealiface.PreCommitBatchRes, error) //perm:admin
|
||||||
@@ -143,20 +142,21 @@ type StorageMiner interface {
|
|||||||
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) //perm:admin
|
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) //perm:admin
|
||||||
SealingAbort(ctx context.Context, call storiface.CallID) error //perm:admin
|
SealingAbort(ctx context.Context, call storiface.CallID) error //perm:admin
|
||||||
|
|
||||||
//stores.SectorIndex
|
// SectorIndex
|
||||||
StorageAttach(context.Context, stores.StorageInfo, fsutil.FsStat) error //perm:admin
|
StorageAttach(context.Context, storiface.StorageInfo, fsutil.FsStat) error //perm:admin
|
||||||
StorageInfo(context.Context, stores.ID) (stores.StorageInfo, error) //perm:admin
|
StorageInfo(context.Context, storiface.ID) (storiface.StorageInfo, error) //perm:admin
|
||||||
StorageReportHealth(context.Context, stores.ID, stores.HealthReport) error //perm:admin
|
StorageReportHealth(context.Context, storiface.ID, storiface.HealthReport) error //perm:admin
|
||||||
StorageDeclareSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error //perm:admin
|
StorageDeclareSector(ctx context.Context, storageID storiface.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error //perm:admin
|
||||||
StorageDropSector(ctx context.Context, storageID stores.ID, s abi.SectorID, ft storiface.SectorFileType) error //perm:admin
|
StorageDropSector(ctx context.Context, storageID storiface.ID, s abi.SectorID, ft storiface.SectorFileType) error //perm:admin
|
||||||
StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) //perm:admin
|
StorageFindSector(ctx context.Context, sector abi.SectorID, ft storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]storiface.SectorStorageInfo, error) //perm:admin
|
||||||
StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]stores.StorageInfo, error) //perm:admin
|
StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]storiface.StorageInfo, error) //perm:admin
|
||||||
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error //perm:admin
|
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error //perm:admin
|
||||||
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) //perm:admin
|
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) //perm:admin
|
||||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) //perm:admin
|
StorageList(ctx context.Context) (map[storiface.ID][]storiface.Decl, error) //perm:admin
|
||||||
|
StorageGetLocks(ctx context.Context) (storiface.SectorLocks, error) //perm:admin
|
||||||
|
|
||||||
StorageLocal(ctx context.Context) (map[stores.ID]string, error) //perm:admin
|
StorageLocal(ctx context.Context) (map[storiface.ID]string, error) //perm:admin
|
||||||
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) //perm:admin
|
StorageStat(ctx context.Context, id storiface.ID) (fsutil.FsStat, error) //perm:admin
|
||||||
|
|
||||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error //perm:write
|
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error //perm:write
|
||||||
MarketListDeals(ctx context.Context) ([]MarketDeal, error) //perm:read
|
MarketListDeals(ctx context.Context) ([]MarketDeal, error) //perm:read
|
||||||
@@ -169,6 +169,8 @@ type StorageMiner interface {
|
|||||||
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error) //perm:read
|
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error) //perm:read
|
||||||
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error) //perm:write
|
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error) //perm:write
|
||||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error) //perm:write
|
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error) //perm:write
|
||||||
|
// MarketDataTransferDiagnostics generates debugging information about current data transfers over graphsync
|
||||||
|
MarketDataTransferDiagnostics(ctx context.Context, p peer.ID) (*TransferDiagnostics, error) //perm:write
|
||||||
// MarketRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
// MarketRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
||||||
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
|
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
|
||||||
// MarketCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
// MarketCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
||||||
@@ -219,6 +221,16 @@ type StorageMiner interface {
|
|||||||
// DagstoreGC runs garbage collection on the DAG store.
|
// DagstoreGC runs garbage collection on the DAG store.
|
||||||
DagstoreGC(ctx context.Context) ([]DagstoreShardResult, error) //perm:admin
|
DagstoreGC(ctx context.Context) ([]DagstoreShardResult, error) //perm:admin
|
||||||
|
|
||||||
|
// IndexerAnnounceDeal informs indexer nodes that a new deal was received,
|
||||||
|
// so they can download its index
|
||||||
|
IndexerAnnounceDeal(ctx context.Context, proposalCid cid.Cid) error //perm:admin
|
||||||
|
|
||||||
|
// IndexerAnnounceAllDeals informs the indexer nodes aboutall active deals.
|
||||||
|
IndexerAnnounceAllDeals(ctx context.Context) error //perm:admin
|
||||||
|
|
||||||
|
// DagstoreLookupPieces returns information about shards that contain the given CID.
|
||||||
|
DagstoreLookupPieces(ctx context.Context, cid cid.Cid) ([]DagstoreShardInfo, error) //perm:admin
|
||||||
|
|
||||||
// RuntimeSubsystems returns the subsystems that are enabled
|
// RuntimeSubsystems returns the subsystems that are enabled
|
||||||
// in this instance.
|
// in this instance.
|
||||||
RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read
|
RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read
|
||||||
@@ -253,13 +265,12 @@ type StorageMiner interface {
|
|||||||
// the path specified when calling CreateBackup is within the base path
|
// the path specified when calling CreateBackup is within the base path
|
||||||
CreateBackup(ctx context.Context, fpath string) error //perm:admin
|
CreateBackup(ctx context.Context, fpath string) error //perm:admin
|
||||||
|
|
||||||
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, update []bool, expensive bool) (map[abi.SectorNumber]string, error) //perm:admin
|
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) //perm:admin
|
||||||
|
|
||||||
ComputeProof(ctx context.Context, ssi []builtin.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtin.PoStProof, error) //perm:read
|
ComputeProof(ctx context.Context, ssi []builtin.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtin.PoStProof, error) //perm:read
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ storiface.WorkerReturn = *new(StorageMiner)
|
var _ storiface.WorkerReturn = *new(StorageMiner)
|
||||||
var _ stores.SectorIndex = *new(StorageMiner)
|
|
||||||
|
|
||||||
type SealRes struct {
|
type SealRes struct {
|
||||||
Err string
|
Err string
|
||||||
@@ -283,19 +294,20 @@ type SectorPiece struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorInfo struct {
|
type SectorInfo struct {
|
||||||
SectorID abi.SectorNumber
|
SectorID abi.SectorNumber
|
||||||
State SectorState
|
State SectorState
|
||||||
CommD *cid.Cid
|
CommD *cid.Cid
|
||||||
CommR *cid.Cid
|
CommR *cid.Cid
|
||||||
Proof []byte
|
Proof []byte
|
||||||
Deals []abi.DealID
|
Deals []abi.DealID
|
||||||
Pieces []SectorPiece
|
Pieces []SectorPiece
|
||||||
Ticket SealTicket
|
Ticket SealTicket
|
||||||
Seed SealSeed
|
Seed SealSeed
|
||||||
PreCommitMsg *cid.Cid
|
PreCommitMsg *cid.Cid
|
||||||
CommitMsg *cid.Cid
|
CommitMsg *cid.Cid
|
||||||
Retries uint64
|
Retries uint64
|
||||||
ToUpgrade bool
|
ToUpgrade bool
|
||||||
|
ReplicaUpdateMessage *cid.Cid
|
||||||
|
|
||||||
LastErr string
|
LastErr string
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -26,6 +27,7 @@ func goCmd() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDoesntDependOnFFI(t *testing.T) {
|
func TestDoesntDependOnFFI(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_FFI_DEPENDENCE_001
|
||||||
deps, err := exec.Command(goCmd(), "list", "-deps", "github.com/filecoin-project/lotus/api").Output()
|
deps, err := exec.Command(goCmd(), "list", "-deps", "github.com/filecoin-project/lotus/api").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -38,6 +40,7 @@ func TestDoesntDependOnFFI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDoesntDependOnBuild(t *testing.T) {
|
func TestDoesntDependOnBuild(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_FFI_DEPENDENCE_002
|
||||||
deps, err := exec.Command(goCmd(), "list", "-deps", "github.com/filecoin-project/lotus/api").Output()
|
deps, err := exec.Command(goCmd(), "list", "-deps", "github.com/filecoin-project/lotus/api").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -50,6 +53,7 @@ func TestDoesntDependOnBuild(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReturnTypes(t *testing.T) {
|
func TestReturnTypes(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_001
|
||||||
errType := reflect.TypeOf(new(error)).Elem()
|
errType := reflect.TypeOf(new(error)).Elem()
|
||||||
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
||||||
jmarsh := reflect.TypeOf(new(json.Marshaler)).Elem()
|
jmarsh := reflect.TypeOf(new(json.Marshaler)).Elem()
|
||||||
@@ -115,6 +119,7 @@ func TestReturnTypes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPermTags(t *testing.T) {
|
func TestPermTags(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_PERM_TAGS_001
|
||||||
_ = PermissionedFullAPI(&FullNodeStruct{})
|
_ = PermissionedFullAPI(&FullNodeStruct{})
|
||||||
_ = PermissionedStorMinerAPI(&StorageMinerStruct{})
|
_ = PermissionedStorMinerAPI(&StorageMinerStruct{})
|
||||||
_ = PermissionedWorkerAPI(&WorkerStruct{})
|
_ = PermissionedWorkerAPI(&WorkerStruct{})
|
||||||
|
|||||||
+6
-2
@@ -7,8 +7,9 @@ import (
|
|||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/v5/actors/runtime/proof"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
)
|
)
|
||||||
@@ -29,7 +30,7 @@ type Worker interface {
|
|||||||
|
|
||||||
// TaskType -> Weight
|
// TaskType -> Weight
|
||||||
TaskTypes(context.Context) (map[sealtasks.TaskType]struct{}, error) //perm:admin
|
TaskTypes(context.Context) (map[sealtasks.TaskType]struct{}, error) //perm:admin
|
||||||
Paths(context.Context) ([]stores.StoragePath, error) //perm:admin
|
Paths(context.Context) ([]storiface.StoragePath, error) //perm:admin
|
||||||
Info(context.Context) (storiface.WorkerInfo, error) //perm:admin
|
Info(context.Context) (storiface.WorkerInfo, error) //perm:admin
|
||||||
|
|
||||||
// storiface.WorkerCalls
|
// storiface.WorkerCalls
|
||||||
@@ -49,6 +50,9 @@ type Worker interface {
|
|||||||
UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin
|
UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin
|
||||||
Fetch(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) //perm:admin
|
Fetch(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) //perm:admin
|
||||||
|
|
||||||
|
GenerateWinningPoSt(ctx context.Context, ppt abi.RegisteredPoStProof, mid abi.ActorID, sectors []storiface.PostSectorChallenge, randomness abi.PoStRandomness) ([]proof.PoStProof, error) //perm:admin
|
||||||
|
GenerateWindowPoSt(ctx context.Context, ppt abi.RegisteredPoStProof, mid abi.ActorID, sectors []storiface.PostSectorChallenge, partitionIdx int, randomness abi.PoStRandomness) (storiface.WindowPoStResult, error) //perm:admin
|
||||||
|
|
||||||
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
||||||
TaskEnable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
TaskEnable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
||||||
|
|
||||||
|
|||||||
+43
-5
@@ -1,6 +1,7 @@
|
|||||||
package docgen
|
package docgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/ipfs/go-graphsync"
|
||||||
"github.com/libp2p/go-libp2p-core/metrics"
|
"github.com/libp2p/go-libp2p-core/metrics"
|
||||||
"github.com/libp2p/go-libp2p-core/network"
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
@@ -38,7 +40,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
@@ -120,6 +121,7 @@ func init() {
|
|||||||
addExample(api.FullAPIVersion1)
|
addExample(api.FullAPIVersion1)
|
||||||
addExample(api.PCHInbound)
|
addExample(api.PCHInbound)
|
||||||
addExample(time.Minute)
|
addExample(time.Minute)
|
||||||
|
addExample(graphsync.NewRequestID())
|
||||||
addExample(datatransfer.TransferID(3))
|
addExample(datatransfer.TransferID(3))
|
||||||
addExample(datatransfer.Ongoing)
|
addExample(datatransfer.Ongoing)
|
||||||
addExample(storeIDExample)
|
addExample(storeIDExample)
|
||||||
@@ -196,10 +198,10 @@ func init() {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
addExample(api.SectorState(sealing.Proving))
|
addExample(api.SectorState(sealing.Proving))
|
||||||
addExample(stores.ID("76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8"))
|
addExample(storiface.ID("76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8"))
|
||||||
addExample(storiface.FTUnsealed)
|
addExample(storiface.FTUnsealed)
|
||||||
addExample(storiface.PathSealing)
|
addExample(storiface.PathSealing)
|
||||||
addExample(map[stores.ID][]stores.Decl{
|
addExample(map[storiface.ID][]storiface.Decl{
|
||||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": {
|
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": {
|
||||||
{
|
{
|
||||||
SectorID: abi.SectorID{Miner: 1000, Number: 100},
|
SectorID: abi.SectorID{Miner: 1000, Number: 100},
|
||||||
@@ -207,7 +209,7 @@ func init() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
addExample(map[stores.ID]string{
|
addExample(map[storiface.ID]string{
|
||||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": "/data/path",
|
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": "/data/path",
|
||||||
})
|
})
|
||||||
addExample(map[uuid.UUID][]storiface.WorkerJob{
|
addExample(map[uuid.UUID][]storiface.WorkerJob{
|
||||||
@@ -250,10 +252,18 @@ func init() {
|
|||||||
addExample(map[abi.SectorNumber]string{
|
addExample(map[abi.SectorNumber]string{
|
||||||
123: "can't acquire read lock",
|
123: "can't acquire read lock",
|
||||||
})
|
})
|
||||||
|
addExample(json.RawMessage(`"json raw message"`))
|
||||||
addExample(map[api.SectorState]int{
|
addExample(map[api.SectorState]int{
|
||||||
api.SectorState(sealing.Proving): 120,
|
api.SectorState(sealing.Proving): 120,
|
||||||
})
|
})
|
||||||
addExample([]abi.SectorNumber{123, 124})
|
addExample([]abi.SectorNumber{123, 124})
|
||||||
|
addExample([]storiface.SectorLock{
|
||||||
|
{
|
||||||
|
Sector: abi.SectorID{Number: 123, Miner: 1000},
|
||||||
|
Write: [storiface.FileTypes]uint{0, 0, 1},
|
||||||
|
Read: [storiface.FileTypes]uint{2, 3, 0},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// worker specific
|
// worker specific
|
||||||
addExample(storiface.AcquireMove)
|
addExample(storiface.AcquireMove)
|
||||||
@@ -289,6 +299,34 @@ func init() {
|
|||||||
Error: "<error>",
|
Error: "<error>",
|
||||||
})
|
})
|
||||||
addExample(storiface.ResourceTable)
|
addExample(storiface.ResourceTable)
|
||||||
|
addExample(network.ScopeStat{
|
||||||
|
Memory: 123,
|
||||||
|
NumStreamsInbound: 1,
|
||||||
|
NumStreamsOutbound: 2,
|
||||||
|
NumConnsInbound: 3,
|
||||||
|
NumConnsOutbound: 4,
|
||||||
|
NumFD: 5,
|
||||||
|
})
|
||||||
|
addExample(map[string]network.ScopeStat{
|
||||||
|
"abc": {
|
||||||
|
Memory: 123,
|
||||||
|
NumStreamsInbound: 1,
|
||||||
|
NumStreamsOutbound: 2,
|
||||||
|
NumConnsInbound: 3,
|
||||||
|
NumConnsOutbound: 4,
|
||||||
|
NumFD: 5,
|
||||||
|
}})
|
||||||
|
addExample(api.NetLimit{
|
||||||
|
Memory: 123,
|
||||||
|
StreamsInbound: 1,
|
||||||
|
StreamsOutbound: 2,
|
||||||
|
Streams: 3,
|
||||||
|
ConnsInbound: 3,
|
||||||
|
ConnsOutbound: 4,
|
||||||
|
Conns: 4,
|
||||||
|
FD: 5,
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
|
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
|
||||||
@@ -339,7 +377,7 @@ func ExampleValue(method string, t, parent reflect.Type) interface{} {
|
|||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
out := reflect.New(t).Elem()
|
out := reflect.New(t).Elem()
|
||||||
reflect.Append(out, reflect.ValueOf(ExampleValue(method, t.Elem(), t)))
|
out = reflect.Append(out, reflect.ValueOf(ExampleValue(method, t.Elem(), t)))
|
||||||
return out.Interface()
|
return out.Interface()
|
||||||
case reflect.Chan:
|
case reflect.Chan:
|
||||||
return ExampleValue(method, t.Elem(), nil)
|
return ExampleValue(method, t.Elem(), nil)
|
||||||
|
|||||||
+123
-5
@@ -8,6 +8,7 @@ import (
|
|||||||
context "context"
|
context "context"
|
||||||
json "encoding/json"
|
json "encoding/json"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
time "time"
|
||||||
|
|
||||||
address "github.com/filecoin-project/go-address"
|
address "github.com/filecoin-project/go-address"
|
||||||
bitfield "github.com/filecoin-project/go-bitfield"
|
bitfield "github.com/filecoin-project/go-bitfield"
|
||||||
@@ -1811,6 +1812,21 @@ func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetLimit mocks base method.
|
||||||
|
func (m *MockFullNode) NetLimit(arg0 context.Context, arg1 string) (api.NetLimit, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetLimit", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(api.NetLimit)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetLimit indicates an expected call of NetLimit.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetLimit(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetLimit", reflect.TypeOf((*MockFullNode)(nil).NetLimit), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// NetPeerInfo mocks base method.
|
// NetPeerInfo mocks base method.
|
||||||
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
|
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@@ -1841,6 +1857,64 @@ func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call {
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetPing mocks base method.
|
||||||
|
func (m *MockFullNode) NetPing(arg0 context.Context, arg1 peer.ID) (time.Duration, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetPing", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(time.Duration)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetPing indicates an expected call of NetPing.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetPing(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPing", reflect.TypeOf((*MockFullNode)(nil).NetPing), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectAdd mocks base method.
|
||||||
|
func (m *MockFullNode) NetProtectAdd(arg0 context.Context, arg1 []peer.ID) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetProtectAdd", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectAdd indicates an expected call of NetProtectAdd.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetProtectAdd(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectAdd", reflect.TypeOf((*MockFullNode)(nil).NetProtectAdd), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectList mocks base method.
|
||||||
|
func (m *MockFullNode) NetProtectList(arg0 context.Context) ([]peer.ID, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetProtectList", arg0)
|
||||||
|
ret0, _ := ret[0].([]peer.ID)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectList indicates an expected call of NetProtectList.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetProtectList(arg0 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectList", reflect.TypeOf((*MockFullNode)(nil).NetProtectList), arg0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectRemove mocks base method.
|
||||||
|
func (m *MockFullNode) NetProtectRemove(arg0 context.Context, arg1 []peer.ID) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetProtectRemove", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectRemove indicates an expected call of NetProtectRemove.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetProtectRemove(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectRemove", reflect.TypeOf((*MockFullNode)(nil).NetProtectRemove), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// NetPubsubScores mocks base method.
|
// NetPubsubScores mocks base method.
|
||||||
func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) {
|
func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@@ -1856,6 +1930,35 @@ func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Ca
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetSetLimit mocks base method.
|
||||||
|
func (m *MockFullNode) NetSetLimit(arg0 context.Context, arg1 string, arg2 api.NetLimit) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetSetLimit", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetSetLimit indicates an expected call of NetSetLimit.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetSetLimit(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetSetLimit", reflect.TypeOf((*MockFullNode)(nil).NetSetLimit), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetStat mocks base method.
|
||||||
|
func (m *MockFullNode) NetStat(arg0 context.Context, arg1 string) (api.NetStat, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetStat", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(api.NetStat)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetStat indicates an expected call of NetStat.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetStat(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetStat", reflect.TypeOf((*MockFullNode)(nil).NetStat), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// NodeStatus mocks base method.
|
// NodeStatus mocks base method.
|
||||||
func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) {
|
func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@@ -1931,19 +2034,34 @@ func (mr *MockFullNodeMockRecorder) PaychCollect(arg0, arg1 interface{}) *gomock
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychCollect", reflect.TypeOf((*MockFullNode)(nil).PaychCollect), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychCollect", reflect.TypeOf((*MockFullNode)(nil).PaychCollect), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaychGet mocks base method.
|
// PaychFund mocks base method.
|
||||||
func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (*api.ChannelInfo, error) {
|
func (m *MockFullNode) PaychFund(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int) (*api.ChannelInfo, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "PaychGet", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "PaychFund", arg0, arg1, arg2, arg3)
|
||||||
|
ret0, _ := ret[0].(*api.ChannelInfo)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// PaychFund indicates an expected call of PaychFund.
|
||||||
|
func (mr *MockFullNodeMockRecorder) PaychFund(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychFund", reflect.TypeOf((*MockFullNode)(nil).PaychFund), arg0, arg1, arg2, arg3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PaychGet mocks base method.
|
||||||
|
func (m *MockFullNode) PaychGet(arg0 context.Context, arg1, arg2 address.Address, arg3 big.Int, arg4 api.PaychGetOpts) (*api.ChannelInfo, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "PaychGet", arg0, arg1, arg2, arg3, arg4)
|
||||||
ret0, _ := ret[0].(*api.ChannelInfo)
|
ret0, _ := ret[0].(*api.ChannelInfo)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaychGet indicates an expected call of PaychGet.
|
// PaychGet indicates an expected call of PaychGet.
|
||||||
func (mr *MockFullNodeMockRecorder) PaychGet(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
|
func (mr *MockFullNodeMockRecorder) PaychGet(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGet", reflect.TypeOf((*MockFullNode)(nil).PaychGet), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PaychGet", reflect.TypeOf((*MockFullNode)(nil).PaychGet), arg0, arg1, arg2, arg3, arg4)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaychGetWaitReady mocks base method.
|
// PaychGetWaitReady mocks base method.
|
||||||
|
|||||||
+262
-54
@@ -25,12 +25,12 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||||
"github.com/filecoin-project/lotus/journal/alerting"
|
"github.com/filecoin-project/lotus/journal/alerting"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/node/repo/imports"
|
"github.com/filecoin-project/lotus/node/repo/imports"
|
||||||
|
"github.com/filecoin-project/specs-actors/v5/actors/runtime/proof"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@@ -306,7 +306,9 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"`
|
PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||||
|
|
||||||
PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) `perm:"sign"`
|
PaychFund func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) `perm:"sign"`
|
||||||
|
|
||||||
|
PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 PaychGetOpts) (*ChannelInfo, error) `perm:"sign"`
|
||||||
|
|
||||||
PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"`
|
PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"`
|
||||||
|
|
||||||
@@ -516,6 +518,8 @@ type GatewayStruct struct {
|
|||||||
|
|
||||||
MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) ``
|
MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) ``
|
||||||
|
|
||||||
|
MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) ``
|
||||||
|
|
||||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||||
|
|
||||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) ``
|
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) ``
|
||||||
@@ -587,11 +591,25 @@ type NetStruct struct {
|
|||||||
|
|
||||||
NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"`
|
NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"`
|
||||||
|
|
||||||
|
NetLimit func(p0 context.Context, p1 string) (NetLimit, error) `perm:"read"`
|
||||||
|
|
||||||
NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"`
|
NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"`
|
||||||
|
|
||||||
NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"`
|
NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"`
|
||||||
|
|
||||||
|
NetPing func(p0 context.Context, p1 peer.ID) (time.Duration, error) `perm:"read"`
|
||||||
|
|
||||||
|
NetProtectAdd func(p0 context.Context, p1 []peer.ID) error `perm:"admin"`
|
||||||
|
|
||||||
|
NetProtectList func(p0 context.Context) ([]peer.ID, error) `perm:"read"`
|
||||||
|
|
||||||
|
NetProtectRemove func(p0 context.Context, p1 []peer.ID) error `perm:"admin"`
|
||||||
|
|
||||||
NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"`
|
NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"`
|
||||||
|
|
||||||
|
NetSetLimit func(p0 context.Context, p1 string, p2 NetLimit) error `perm:"admin"`
|
||||||
|
|
||||||
|
NetStat func(p0 context.Context, p1 string) (NetStat, error) `perm:"read"`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +637,7 @@ type StorageMinerStruct struct {
|
|||||||
|
|
||||||
ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"`
|
ActorSectorSize func(p0 context.Context, p1 address.Address) (abi.SectorSize, error) `perm:"read"`
|
||||||
|
|
||||||
CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 []bool, p4 bool) (map[abi.SectorNumber]string, error) `perm:"admin"`
|
CheckProvable func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) `perm:"admin"`
|
||||||
|
|
||||||
ComputeProof func(p0 context.Context, p1 []builtin.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtin.PoStProof, error) `perm:"read"`
|
ComputeProof func(p0 context.Context, p1 []builtin.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtin.PoStProof, error) `perm:"read"`
|
||||||
|
|
||||||
@@ -633,6 +651,8 @@ type StorageMinerStruct struct {
|
|||||||
|
|
||||||
DagstoreListShards func(p0 context.Context) ([]DagstoreShardInfo, error) `perm:"read"`
|
DagstoreListShards func(p0 context.Context) ([]DagstoreShardInfo, error) `perm:"read"`
|
||||||
|
|
||||||
|
DagstoreLookupPieces func(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) `perm:"admin"`
|
||||||
|
|
||||||
DagstoreRecoverShard func(p0 context.Context, p1 string) error `perm:"write"`
|
DagstoreRecoverShard func(p0 context.Context, p1 string) error `perm:"write"`
|
||||||
|
|
||||||
DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"`
|
DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"`
|
||||||
@@ -667,8 +687,14 @@ type StorageMinerStruct struct {
|
|||||||
|
|
||||||
DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"`
|
DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"`
|
||||||
|
|
||||||
|
IndexerAnnounceAllDeals func(p0 context.Context) error `perm:"admin"`
|
||||||
|
|
||||||
|
IndexerAnnounceDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||||
|
|
||||||
MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||||
|
|
||||||
|
MarketDataTransferDiagnostics func(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) `perm:"write"`
|
||||||
|
|
||||||
MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"`
|
MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"`
|
||||||
|
|
||||||
MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
||||||
@@ -799,27 +825,29 @@ type StorageMinerStruct struct {
|
|||||||
|
|
||||||
StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"`
|
StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||||
|
|
||||||
StorageAttach func(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"`
|
StorageAttach func(p0 context.Context, p1 storiface.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"`
|
||||||
|
|
||||||
StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
|
StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageDeclareSector func(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"`
|
StorageDeclareSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"`
|
||||||
|
|
||||||
StorageDropSector func(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error `perm:"admin"`
|
StorageDropSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error `perm:"admin"`
|
||||||
|
|
||||||
StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
|
StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]storiface.SectorStorageInfo, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageInfo func(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) `perm:"admin"`
|
StorageGetLocks func(p0 context.Context) (storiface.SectorLocks, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageList func(p0 context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
|
StorageInfo func(p0 context.Context, p1 storiface.ID) (storiface.StorageInfo, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageLocal func(p0 context.Context) (map[stores.ID]string, error) `perm:"admin"`
|
StorageList func(p0 context.Context) (map[storiface.ID][]storiface.Decl, error) `perm:"admin"`
|
||||||
|
|
||||||
|
StorageLocal func(p0 context.Context) (map[storiface.ID]string, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error `perm:"admin"`
|
StorageLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error `perm:"admin"`
|
||||||
|
|
||||||
StorageReportHealth func(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error `perm:"admin"`
|
StorageReportHealth func(p0 context.Context, p1 storiface.ID, p2 storiface.HealthReport) error `perm:"admin"`
|
||||||
|
|
||||||
StorageStat func(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) `perm:"admin"`
|
StorageStat func(p0 context.Context, p1 storiface.ID) (fsutil.FsStat, error) `perm:"admin"`
|
||||||
|
|
||||||
StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"`
|
StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"`
|
||||||
|
|
||||||
@@ -872,11 +900,15 @@ type WorkerStruct struct {
|
|||||||
|
|
||||||
GenerateSectorKeyFromData func(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid) (storiface.CallID, error) `perm:"admin"`
|
GenerateSectorKeyFromData func(p0 context.Context, p1 storage.SectorRef, p2 cid.Cid) (storiface.CallID, error) `perm:"admin"`
|
||||||
|
|
||||||
|
GenerateWindowPoSt func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 int, p5 abi.PoStRandomness) (storiface.WindowPoStResult, error) `perm:"admin"`
|
||||||
|
|
||||||
|
GenerateWinningPoSt func(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 abi.PoStRandomness) ([]proof.PoStProof, error) `perm:"admin"`
|
||||||
|
|
||||||
Info func(p0 context.Context) (storiface.WorkerInfo, error) `perm:"admin"`
|
Info func(p0 context.Context) (storiface.WorkerInfo, error) `perm:"admin"`
|
||||||
|
|
||||||
MoveStorage func(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"`
|
MoveStorage func(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"`
|
||||||
|
|
||||||
Paths func(p0 context.Context) ([]stores.StoragePath, error) `perm:"admin"`
|
Paths func(p0 context.Context) ([]storiface.StoragePath, error) `perm:"admin"`
|
||||||
|
|
||||||
ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"`
|
ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"`
|
||||||
|
|
||||||
@@ -2175,14 +2207,25 @@ func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid
|
|||||||
return *new(cid.Cid), ErrNotSupported
|
return *new(cid.Cid), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) {
|
func (s *FullNodeStruct) PaychFund(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) {
|
||||||
|
if s.Internal.PaychFund == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.PaychFund(p0, p1, p2, p3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStub) PaychFund(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 PaychGetOpts) (*ChannelInfo, error) {
|
||||||
if s.Internal.PaychGet == nil {
|
if s.Internal.PaychGet == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.PaychGet(p0, p1, p2, p3)
|
return s.Internal.PaychGet(p0, p1, p2, p3, p4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) {
|
func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 PaychGetOpts) (*ChannelInfo, error) {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3275,6 +3318,17 @@ func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 t
|
|||||||
return *new(types.BigInt), ErrNotSupported
|
return *new(types.BigInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) {
|
||||||
|
if s.Internal.MsigGetVestingSchedule == nil {
|
||||||
|
return *new(MsigVesting), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.MsigGetVestingSchedule(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) {
|
||||||
|
return *new(MsigVesting), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) {
|
func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) {
|
||||||
if s.Internal.StateAccountKey == nil {
|
if s.Internal.StateAccountKey == nil {
|
||||||
return *new(address.Address), ErrNotSupported
|
return *new(address.Address), ErrNotSupported
|
||||||
@@ -3627,6 +3681,17 @@ func (s *NetStub) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, er
|
|||||||
return *new(peer.AddrInfo), ErrNotSupported
|
return *new(peer.AddrInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetLimit(p0 context.Context, p1 string) (NetLimit, error) {
|
||||||
|
if s.Internal.NetLimit == nil {
|
||||||
|
return *new(NetLimit), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetLimit(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetLimit(p0 context.Context, p1 string) (NetLimit, error) {
|
||||||
|
return *new(NetLimit), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *NetStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) {
|
func (s *NetStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) {
|
||||||
if s.Internal.NetPeerInfo == nil {
|
if s.Internal.NetPeerInfo == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
@@ -3649,6 +3714,50 @@ func (s *NetStub) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) {
|
|||||||
return *new([]peer.AddrInfo), ErrNotSupported
|
return *new([]peer.AddrInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetPing(p0 context.Context, p1 peer.ID) (time.Duration, error) {
|
||||||
|
if s.Internal.NetPing == nil {
|
||||||
|
return *new(time.Duration), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetPing(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetPing(p0 context.Context, p1 peer.ID) (time.Duration, error) {
|
||||||
|
return *new(time.Duration), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetProtectAdd(p0 context.Context, p1 []peer.ID) error {
|
||||||
|
if s.Internal.NetProtectAdd == nil {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetProtectAdd(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetProtectAdd(p0 context.Context, p1 []peer.ID) error {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetProtectList(p0 context.Context) ([]peer.ID, error) {
|
||||||
|
if s.Internal.NetProtectList == nil {
|
||||||
|
return *new([]peer.ID), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetProtectList(p0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetProtectList(p0 context.Context) ([]peer.ID, error) {
|
||||||
|
return *new([]peer.ID), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetProtectRemove(p0 context.Context, p1 []peer.ID) error {
|
||||||
|
if s.Internal.NetProtectRemove == nil {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetProtectRemove(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetProtectRemove(p0 context.Context, p1 []peer.ID) error {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *NetStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) {
|
func (s *NetStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) {
|
||||||
if s.Internal.NetPubsubScores == nil {
|
if s.Internal.NetPubsubScores == nil {
|
||||||
return *new([]PubsubScore), ErrNotSupported
|
return *new([]PubsubScore), ErrNotSupported
|
||||||
@@ -3660,6 +3769,28 @@ func (s *NetStub) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) {
|
|||||||
return *new([]PubsubScore), ErrNotSupported
|
return *new([]PubsubScore), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetSetLimit(p0 context.Context, p1 string, p2 NetLimit) error {
|
||||||
|
if s.Internal.NetSetLimit == nil {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetSetLimit(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetSetLimit(p0 context.Context, p1 string, p2 NetLimit) error {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStruct) NetStat(p0 context.Context, p1 string) (NetStat, error) {
|
||||||
|
if s.Internal.NetStat == nil {
|
||||||
|
return *new(NetStat), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.NetStat(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *NetStub) NetStat(p0 context.Context, p1 string) (NetStat, error) {
|
||||||
|
return *new(NetStat), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error {
|
func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error {
|
||||||
if s.Internal.Sign == nil {
|
if s.Internal.Sign == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
@@ -3704,14 +3835,14 @@ func (s *StorageMinerStub) ActorSectorSize(p0 context.Context, p1 address.Addres
|
|||||||
return *new(abi.SectorSize), ErrNotSupported
|
return *new(abi.SectorSize), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 []bool, p4 bool) (map[abi.SectorNumber]string, error) {
|
func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) {
|
||||||
if s.Internal.CheckProvable == nil {
|
if s.Internal.CheckProvable == nil {
|
||||||
return *new(map[abi.SectorNumber]string), ErrNotSupported
|
return *new(map[abi.SectorNumber]string), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.CheckProvable(p0, p1, p2, p3, p4)
|
return s.Internal.CheckProvable(p0, p1, p2, p3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 []bool, p4 bool) (map[abi.SectorNumber]string, error) {
|
func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) {
|
||||||
return *new(map[abi.SectorNumber]string), ErrNotSupported
|
return *new(map[abi.SectorNumber]string), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3781,6 +3912,17 @@ func (s *StorageMinerStub) DagstoreListShards(p0 context.Context) ([]DagstoreSha
|
|||||||
return *new([]DagstoreShardInfo), ErrNotSupported
|
return *new([]DagstoreShardInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStruct) DagstoreLookupPieces(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) {
|
||||||
|
if s.Internal.DagstoreLookupPieces == nil {
|
||||||
|
return *new([]DagstoreShardInfo), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.DagstoreLookupPieces(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStub) DagstoreLookupPieces(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) {
|
||||||
|
return *new([]DagstoreShardInfo), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) DagstoreRecoverShard(p0 context.Context, p1 string) error {
|
func (s *StorageMinerStruct) DagstoreRecoverShard(p0 context.Context, p1 string) error {
|
||||||
if s.Internal.DagstoreRecoverShard == nil {
|
if s.Internal.DagstoreRecoverShard == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
@@ -3968,6 +4110,28 @@ func (s *StorageMinerStub) DealsSetPieceCidBlocklist(p0 context.Context, p1 []ci
|
|||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStruct) IndexerAnnounceAllDeals(p0 context.Context) error {
|
||||||
|
if s.Internal.IndexerAnnounceAllDeals == nil {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.IndexerAnnounceAllDeals(p0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStub) IndexerAnnounceAllDeals(p0 context.Context) error {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStruct) IndexerAnnounceDeal(p0 context.Context, p1 cid.Cid) error {
|
||||||
|
if s.Internal.IndexerAnnounceDeal == nil {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.IndexerAnnounceDeal(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStub) IndexerAnnounceDeal(p0 context.Context, p1 cid.Cid) error {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error {
|
func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error {
|
||||||
if s.Internal.MarketCancelDataTransfer == nil {
|
if s.Internal.MarketCancelDataTransfer == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
@@ -3979,6 +4143,17 @@ func (s *StorageMinerStub) MarketCancelDataTransfer(p0 context.Context, p1 datat
|
|||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStruct) MarketDataTransferDiagnostics(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) {
|
||||||
|
if s.Internal.MarketDataTransferDiagnostics == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.MarketDataTransferDiagnostics(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStub) MarketDataTransferDiagnostics(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) {
|
func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) {
|
||||||
if s.Internal.MarketDataTransferUpdates == nil {
|
if s.Internal.MarketDataTransferUpdates == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
@@ -4694,92 +4869,103 @@ func (s *StorageMinerStub) StorageAddLocal(p0 context.Context, p1 string) error
|
|||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error {
|
func (s *StorageMinerStruct) StorageAttach(p0 context.Context, p1 storiface.StorageInfo, p2 fsutil.FsStat) error {
|
||||||
if s.Internal.StorageAttach == nil {
|
if s.Internal.StorageAttach == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageAttach(p0, p1, p2)
|
return s.Internal.StorageAttach(p0, p1, p2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error {
|
func (s *StorageMinerStub) StorageAttach(p0 context.Context, p1 storiface.StorageInfo, p2 fsutil.FsStat) error {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) {
|
func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) {
|
||||||
if s.Internal.StorageBestAlloc == nil {
|
if s.Internal.StorageBestAlloc == nil {
|
||||||
return *new([]stores.StorageInfo), ErrNotSupported
|
return *new([]storiface.StorageInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageBestAlloc(p0, p1, p2, p3)
|
return s.Internal.StorageBestAlloc(p0, p1, p2, p3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) {
|
func (s *StorageMinerStub) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) {
|
||||||
return *new([]stores.StorageInfo), ErrNotSupported
|
return *new([]storiface.StorageInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error {
|
func (s *StorageMinerStruct) StorageDeclareSector(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error {
|
||||||
if s.Internal.StorageDeclareSector == nil {
|
if s.Internal.StorageDeclareSector == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageDeclareSector(p0, p1, p2, p3, p4)
|
return s.Internal.StorageDeclareSector(p0, p1, p2, p3, p4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error {
|
func (s *StorageMinerStub) StorageDeclareSector(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error {
|
func (s *StorageMinerStruct) StorageDropSector(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error {
|
||||||
if s.Internal.StorageDropSector == nil {
|
if s.Internal.StorageDropSector == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageDropSector(p0, p1, p2, p3)
|
return s.Internal.StorageDropSector(p0, p1, p2, p3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error {
|
func (s *StorageMinerStub) StorageDropSector(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) {
|
func (s *StorageMinerStruct) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]storiface.SectorStorageInfo, error) {
|
||||||
if s.Internal.StorageFindSector == nil {
|
if s.Internal.StorageFindSector == nil {
|
||||||
return *new([]stores.SectorStorageInfo), ErrNotSupported
|
return *new([]storiface.SectorStorageInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageFindSector(p0, p1, p2, p3, p4)
|
return s.Internal.StorageFindSector(p0, p1, p2, p3, p4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) {
|
func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]storiface.SectorStorageInfo, error) {
|
||||||
return *new([]stores.SectorStorageInfo), ErrNotSupported
|
return *new([]storiface.SectorStorageInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) {
|
func (s *StorageMinerStruct) StorageGetLocks(p0 context.Context) (storiface.SectorLocks, error) {
|
||||||
|
if s.Internal.StorageGetLocks == nil {
|
||||||
|
return *new(storiface.SectorLocks), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StorageGetLocks(p0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStub) StorageGetLocks(p0 context.Context) (storiface.SectorLocks, error) {
|
||||||
|
return *new(storiface.SectorLocks), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 storiface.ID) (storiface.StorageInfo, error) {
|
||||||
if s.Internal.StorageInfo == nil {
|
if s.Internal.StorageInfo == nil {
|
||||||
return *new(stores.StorageInfo), ErrNotSupported
|
return *new(storiface.StorageInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageInfo(p0, p1)
|
return s.Internal.StorageInfo(p0, p1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) {
|
func (s *StorageMinerStub) StorageInfo(p0 context.Context, p1 storiface.ID) (storiface.StorageInfo, error) {
|
||||||
return *new(stores.StorageInfo), ErrNotSupported
|
return *new(storiface.StorageInfo), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) {
|
func (s *StorageMinerStruct) StorageList(p0 context.Context) (map[storiface.ID][]storiface.Decl, error) {
|
||||||
if s.Internal.StorageList == nil {
|
if s.Internal.StorageList == nil {
|
||||||
return *new(map[stores.ID][]stores.Decl), ErrNotSupported
|
return *new(map[storiface.ID][]storiface.Decl), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageList(p0)
|
return s.Internal.StorageList(p0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) {
|
func (s *StorageMinerStub) StorageList(p0 context.Context) (map[storiface.ID][]storiface.Decl, error) {
|
||||||
return *new(map[stores.ID][]stores.Decl), ErrNotSupported
|
return *new(map[storiface.ID][]storiface.Decl), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageLocal(p0 context.Context) (map[stores.ID]string, error) {
|
func (s *StorageMinerStruct) StorageLocal(p0 context.Context) (map[storiface.ID]string, error) {
|
||||||
if s.Internal.StorageLocal == nil {
|
if s.Internal.StorageLocal == nil {
|
||||||
return *new(map[stores.ID]string), ErrNotSupported
|
return *new(map[storiface.ID]string), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageLocal(p0)
|
return s.Internal.StorageLocal(p0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageLocal(p0 context.Context) (map[stores.ID]string, error) {
|
func (s *StorageMinerStub) StorageLocal(p0 context.Context) (map[storiface.ID]string, error) {
|
||||||
return *new(map[stores.ID]string), ErrNotSupported
|
return *new(map[storiface.ID]string), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error {
|
func (s *StorageMinerStruct) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error {
|
||||||
@@ -4793,25 +4979,25 @@ func (s *StorageMinerStub) StorageLock(p0 context.Context, p1 abi.SectorID, p2 s
|
|||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error {
|
func (s *StorageMinerStruct) StorageReportHealth(p0 context.Context, p1 storiface.ID, p2 storiface.HealthReport) error {
|
||||||
if s.Internal.StorageReportHealth == nil {
|
if s.Internal.StorageReportHealth == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageReportHealth(p0, p1, p2)
|
return s.Internal.StorageReportHealth(p0, p1, p2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error {
|
func (s *StorageMinerStub) StorageReportHealth(p0 context.Context, p1 storiface.ID, p2 storiface.HealthReport) error {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) {
|
func (s *StorageMinerStruct) StorageStat(p0 context.Context, p1 storiface.ID) (fsutil.FsStat, error) {
|
||||||
if s.Internal.StorageStat == nil {
|
if s.Internal.StorageStat == nil {
|
||||||
return *new(fsutil.FsStat), ErrNotSupported
|
return *new(fsutil.FsStat), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.StorageStat(p0, p1)
|
return s.Internal.StorageStat(p0, p1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStub) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) {
|
func (s *StorageMinerStub) StorageStat(p0 context.Context, p1 storiface.ID) (fsutil.FsStat, error) {
|
||||||
return *new(fsutil.FsStat), ErrNotSupported
|
return *new(fsutil.FsStat), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5002,6 +5188,28 @@ func (s *WorkerStub) GenerateSectorKeyFromData(p0 context.Context, p1 storage.Se
|
|||||||
return *new(storiface.CallID), ErrNotSupported
|
return *new(storiface.CallID), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *WorkerStruct) GenerateWindowPoSt(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 int, p5 abi.PoStRandomness) (storiface.WindowPoStResult, error) {
|
||||||
|
if s.Internal.GenerateWindowPoSt == nil {
|
||||||
|
return *new(storiface.WindowPoStResult), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.GenerateWindowPoSt(p0, p1, p2, p3, p4, p5)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WorkerStub) GenerateWindowPoSt(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 int, p5 abi.PoStRandomness) (storiface.WindowPoStResult, error) {
|
||||||
|
return *new(storiface.WindowPoStResult), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WorkerStruct) GenerateWinningPoSt(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 abi.PoStRandomness) ([]proof.PoStProof, error) {
|
||||||
|
if s.Internal.GenerateWinningPoSt == nil {
|
||||||
|
return *new([]proof.PoStProof), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.GenerateWinningPoSt(p0, p1, p2, p3, p4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WorkerStub) GenerateWinningPoSt(p0 context.Context, p1 abi.RegisteredPoStProof, p2 abi.ActorID, p3 []storiface.PostSectorChallenge, p4 abi.PoStRandomness) ([]proof.PoStProof, error) {
|
||||||
|
return *new([]proof.PoStProof), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *WorkerStruct) Info(p0 context.Context) (storiface.WorkerInfo, error) {
|
func (s *WorkerStruct) Info(p0 context.Context) (storiface.WorkerInfo, error) {
|
||||||
if s.Internal.Info == nil {
|
if s.Internal.Info == nil {
|
||||||
return *new(storiface.WorkerInfo), ErrNotSupported
|
return *new(storiface.WorkerInfo), ErrNotSupported
|
||||||
@@ -5024,15 +5232,15 @@ func (s *WorkerStub) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 st
|
|||||||
return *new(storiface.CallID), ErrNotSupported
|
return *new(storiface.CallID), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WorkerStruct) Paths(p0 context.Context) ([]stores.StoragePath, error) {
|
func (s *WorkerStruct) Paths(p0 context.Context) ([]storiface.StoragePath, error) {
|
||||||
if s.Internal.Paths == nil {
|
if s.Internal.Paths == nil {
|
||||||
return *new([]stores.StoragePath), ErrNotSupported
|
return *new([]storiface.StoragePath), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.Paths(p0)
|
return s.Internal.Paths(p0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WorkerStub) Paths(p0 context.Context) ([]stores.StoragePath, error) {
|
func (s *WorkerStub) Paths(p0 context.Context) ([]storiface.StoragePath, error) {
|
||||||
return *new([]stores.StoragePath), ErrNotSupported
|
return *new([]storiface.StoragePath), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WorkerStruct) ProcessSession(p0 context.Context) (uuid.UUID, error) {
|
func (s *WorkerStruct) ProcessSession(p0 context.Context) (uuid.UUID, error) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -29,6 +30,7 @@ type StrC struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetInternalStructs(t *testing.T) {
|
func TestGetInternalStructs(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_API_STRUCTS_001
|
||||||
var proxy StrA
|
var proxy StrA
|
||||||
|
|
||||||
sts := GetInternalStructs(&proxy)
|
sts := GetInternalStructs(&proxy)
|
||||||
@@ -44,6 +46,7 @@ func TestGetInternalStructs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNestedInternalStructs(t *testing.T) {
|
func TestNestedInternalStructs(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_API_STRUCTS_001
|
||||||
var proxy StrC
|
var proxy StrC
|
||||||
|
|
||||||
// check that only the top-level internal struct gets picked up
|
// check that only the top-level internal struct gets picked up
|
||||||
|
|||||||
@@ -5,11 +5,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
|
|
||||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/ipfs/go-graphsync"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||||
@@ -53,6 +56,30 @@ type MessageSendSpec struct {
|
|||||||
MaxFee abi.TokenAmount
|
MaxFee abi.TokenAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GraphSyncDataTransfer provides diagnostics on a data transfer happening over graphsync
|
||||||
|
type GraphSyncDataTransfer struct {
|
||||||
|
// GraphSync request id for this transfer
|
||||||
|
RequestID *graphsync.RequestID
|
||||||
|
// Graphsync state for this transfer
|
||||||
|
RequestState string
|
||||||
|
// If a channel ID is present, indicates whether this is the current graphsync request for this channel
|
||||||
|
// (could have changed in a restart)
|
||||||
|
IsCurrentChannelRequest bool
|
||||||
|
// Data transfer channel ID for this transfer
|
||||||
|
ChannelID *datatransfer.ChannelID
|
||||||
|
// Data transfer state for this transfer
|
||||||
|
ChannelState *DataTransferChannel
|
||||||
|
// Diagnostic information about this request -- and unexpected inconsistencies in
|
||||||
|
// request state
|
||||||
|
Diagnostics []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// TransferDiagnostics give current information about transfers going over graphsync that may be helpful for debugging
|
||||||
|
type TransferDiagnostics struct {
|
||||||
|
ReceivingTransfers []*GraphSyncDataTransfer
|
||||||
|
SendingTransfers []*GraphSyncDataTransfer
|
||||||
|
}
|
||||||
|
|
||||||
type DataTransferChannel struct {
|
type DataTransferChannel struct {
|
||||||
TransferID datatransfer.TransferID
|
TransferID datatransfer.TransferID
|
||||||
Status datatransfer.Status
|
Status datatransfer.Status
|
||||||
@@ -98,6 +125,28 @@ func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelSta
|
|||||||
return channel
|
return channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NetStat struct {
|
||||||
|
System *network.ScopeStat `json:",omitempty"`
|
||||||
|
Transient *network.ScopeStat `json:",omitempty"`
|
||||||
|
Services map[string]network.ScopeStat `json:",omitempty"`
|
||||||
|
Protocols map[string]network.ScopeStat `json:",omitempty"`
|
||||||
|
Peers map[string]network.ScopeStat `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetLimit struct {
|
||||||
|
Dynamic bool `json:",omitempty"`
|
||||||
|
// set if Dynamic is false
|
||||||
|
Memory int64 `json:",omitempty"`
|
||||||
|
// set if Dynamic is true
|
||||||
|
MemoryFraction float64 `json:",omitempty"`
|
||||||
|
MinMemory int64 `json:",omitempty"`
|
||||||
|
MaxMemory int64 `json:",omitempty"`
|
||||||
|
|
||||||
|
Streams, StreamsInbound, StreamsOutbound int
|
||||||
|
Conns, ConnsInbound, ConnsOutbound int
|
||||||
|
FD int
|
||||||
|
}
|
||||||
|
|
||||||
type NetBlockList struct {
|
type NetBlockList struct {
|
||||||
Peers []peer.ID
|
Peers []peer.ID
|
||||||
IPAddrs []string
|
IPAddrs []string
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package v0mocks
|
|||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
time "time"
|
||||||
|
|
||||||
address "github.com/filecoin-project/go-address"
|
address "github.com/filecoin-project/go-address"
|
||||||
bitfield "github.com/filecoin-project/go-bitfield"
|
bitfield "github.com/filecoin-project/go-bitfield"
|
||||||
@@ -1724,6 +1725,21 @@ func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetLimit mocks base method.
|
||||||
|
func (m *MockFullNode) NetLimit(arg0 context.Context, arg1 string) (api.NetLimit, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetLimit", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(api.NetLimit)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetLimit indicates an expected call of NetLimit.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetLimit(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetLimit", reflect.TypeOf((*MockFullNode)(nil).NetLimit), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// NetPeerInfo mocks base method.
|
// NetPeerInfo mocks base method.
|
||||||
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
|
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@@ -1754,6 +1770,64 @@ func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call {
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetPing mocks base method.
|
||||||
|
func (m *MockFullNode) NetPing(arg0 context.Context, arg1 peer.ID) (time.Duration, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetPing", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(time.Duration)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetPing indicates an expected call of NetPing.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetPing(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPing", reflect.TypeOf((*MockFullNode)(nil).NetPing), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectAdd mocks base method.
|
||||||
|
func (m *MockFullNode) NetProtectAdd(arg0 context.Context, arg1 []peer.ID) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetProtectAdd", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectAdd indicates an expected call of NetProtectAdd.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetProtectAdd(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectAdd", reflect.TypeOf((*MockFullNode)(nil).NetProtectAdd), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectList mocks base method.
|
||||||
|
func (m *MockFullNode) NetProtectList(arg0 context.Context) ([]peer.ID, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetProtectList", arg0)
|
||||||
|
ret0, _ := ret[0].([]peer.ID)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectList indicates an expected call of NetProtectList.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetProtectList(arg0 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectList", reflect.TypeOf((*MockFullNode)(nil).NetProtectList), arg0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectRemove mocks base method.
|
||||||
|
func (m *MockFullNode) NetProtectRemove(arg0 context.Context, arg1 []peer.ID) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetProtectRemove", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetProtectRemove indicates an expected call of NetProtectRemove.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetProtectRemove(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectRemove", reflect.TypeOf((*MockFullNode)(nil).NetProtectRemove), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// NetPubsubScores mocks base method.
|
// NetPubsubScores mocks base method.
|
||||||
func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) {
|
func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@@ -1769,6 +1843,35 @@ func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Ca
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetSetLimit mocks base method.
|
||||||
|
func (m *MockFullNode) NetSetLimit(arg0 context.Context, arg1 string, arg2 api.NetLimit) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetSetLimit", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetSetLimit indicates an expected call of NetSetLimit.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetSetLimit(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetSetLimit", reflect.TypeOf((*MockFullNode)(nil).NetSetLimit), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetStat mocks base method.
|
||||||
|
func (m *MockFullNode) NetStat(arg0 context.Context, arg1 string) (api.NetStat, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NetStat", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(api.NetStat)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetStat indicates an expected call of NetStat.
|
||||||
|
func (mr *MockFullNodeMockRecorder) NetStat(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetStat", reflect.TypeOf((*MockFullNode)(nil).NetStat), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// PaychAllocateLane mocks base method.
|
// PaychAllocateLane mocks base method.
|
||||||
func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) {
|
func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
|||||||
@@ -337,4 +337,8 @@ func (w *WrapperV1Full) clientRetrieve(ctx context.Context, order RetrievalOrder
|
|||||||
finish(w.ClientExport(ctx, eref, *ref))
|
finish(w.ClientExport(ctx, eref, *ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WrapperV1Full) PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) {
|
||||||
|
return w.FullNode.PaychFund(ctx, from, to, amt)
|
||||||
|
}
|
||||||
|
|
||||||
var _ FullNode = &WrapperV1Full{}
|
var _ FullNode = &WrapperV1Full{}
|
||||||
|
|||||||
+2
-2
@@ -57,8 +57,8 @@ var (
|
|||||||
FullAPIVersion0 = newVer(1, 5, 0)
|
FullAPIVersion0 = newVer(1, 5, 0)
|
||||||
FullAPIVersion1 = newVer(2, 2, 0)
|
FullAPIVersion1 = newVer(2, 2, 0)
|
||||||
|
|
||||||
MinerAPIVersion0 = newVer(1, 4, 0)
|
MinerAPIVersion0 = newVer(1, 5, 0)
|
||||||
WorkerAPIVersion0 = newVer(1, 5, 0)
|
WorkerAPIVersion0 = newVer(1, 6, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:varcheck,deadcode
|
//nolint:varcheck,deadcode
|
||||||
|
|||||||
+9
-9
@@ -25,35 +25,35 @@ func NewAPIBlockstore(cio ChainIO) Blockstore {
|
|||||||
return Adapt(bs) // return an adapted blockstore.
|
return Adapt(bs) // return an adapted blockstore.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiBlockstore) DeleteBlock(cid.Cid) error {
|
func (a *apiBlockstore) DeleteBlock(context.Context, cid.Cid) error {
|
||||||
return xerrors.New("not supported")
|
return xerrors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiBlockstore) Has(c cid.Cid) (bool, error) {
|
func (a *apiBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
|
||||||
return a.api.ChainHasObj(context.TODO(), c)
|
return a.api.ChainHasObj(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiBlockstore) Get(c cid.Cid) (blocks.Block, error) {
|
func (a *apiBlockstore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
|
||||||
bb, err := a.api.ChainReadObj(context.TODO(), c)
|
bb, err := a.api.ChainReadObj(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return blocks.NewBlockWithCid(bb, c)
|
return blocks.NewBlockWithCid(bb, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiBlockstore) GetSize(c cid.Cid) (int, error) {
|
func (a *apiBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
|
||||||
bb, err := a.api.ChainReadObj(context.TODO(), c)
|
bb, err := a.api.ChainReadObj(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return len(bb), nil
|
return len(bb), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiBlockstore) Put(blocks.Block) error {
|
func (a *apiBlockstore) Put(context.Context, blocks.Block) error {
|
||||||
return xerrors.New("not supported")
|
return xerrors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiBlockstore) PutMany([]blocks.Block) error {
|
func (a *apiBlockstore) PutMany(context.Context, []blocks.Block) error {
|
||||||
return xerrors.New("not supported")
|
return xerrors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-21
@@ -64,7 +64,7 @@ func NewAutobatch(ctx context.Context, backingBs Blockstore, bufferCapacity int)
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) Put(blk block.Block) error {
|
func (bs *AutobatchBlockstore) Put(ctx context.Context, blk block.Block) error {
|
||||||
bs.stateLock.Lock()
|
bs.stateLock.Lock()
|
||||||
defer bs.stateLock.Unlock()
|
defer bs.stateLock.Unlock()
|
||||||
|
|
||||||
@@ -94,19 +94,19 @@ func (bs *AutobatchBlockstore) flushWorker(ctx context.Context) {
|
|||||||
case <-bs.flushCh:
|
case <-bs.flushCh:
|
||||||
// TODO: check if we _should_ actually flush. We could get a spurious wakeup
|
// TODO: check if we _should_ actually flush. We could get a spurious wakeup
|
||||||
// here.
|
// here.
|
||||||
putErr := bs.doFlush(false)
|
putErr := bs.doFlush(ctx, false)
|
||||||
for putErr != nil {
|
for putErr != nil {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-time.After(bs.flushRetryDelay):
|
case <-time.After(bs.flushRetryDelay):
|
||||||
autolog.Errorf("FLUSH ERRORED: %w, retrying after %v", putErr, bs.flushRetryDelay)
|
autolog.Errorf("FLUSH ERRORED: %w, retrying after %v", putErr, bs.flushRetryDelay)
|
||||||
putErr = bs.doFlush(true)
|
putErr = bs.doFlush(ctx, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
// Do one last flush.
|
// Do one last flush.
|
||||||
_ = bs.doFlush(false)
|
_ = bs.doFlush(ctx, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,13 +114,13 @@ func (bs *AutobatchBlockstore) flushWorker(ctx context.Context) {
|
|||||||
|
|
||||||
// caller must NOT hold stateLock
|
// caller must NOT hold stateLock
|
||||||
// set retryOnly to true to only retry a failed flush and not flush anything new.
|
// set retryOnly to true to only retry a failed flush and not flush anything new.
|
||||||
func (bs *AutobatchBlockstore) doFlush(retryOnly bool) error {
|
func (bs *AutobatchBlockstore) doFlush(ctx context.Context, retryOnly bool) error {
|
||||||
bs.doFlushLock.Lock()
|
bs.doFlushLock.Lock()
|
||||||
defer bs.doFlushLock.Unlock()
|
defer bs.doFlushLock.Unlock()
|
||||||
|
|
||||||
// If we failed to flush last time, try flushing again.
|
// If we failed to flush last time, try flushing again.
|
||||||
if bs.flushErr != nil {
|
if bs.flushErr != nil {
|
||||||
bs.flushErr = bs.backingBs.PutMany(bs.flushingBatch.blockList)
|
bs.flushErr = bs.backingBs.PutMany(ctx, bs.flushingBatch.blockList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we failed, or we're _only_ retrying, bail.
|
// If we failed, or we're _only_ retrying, bail.
|
||||||
@@ -137,7 +137,7 @@ func (bs *AutobatchBlockstore) doFlush(retryOnly bool) error {
|
|||||||
bs.stateLock.Unlock()
|
bs.stateLock.Unlock()
|
||||||
|
|
||||||
// And try to flush it.
|
// And try to flush it.
|
||||||
bs.flushErr = bs.backingBs.PutMany(bs.flushingBatch.blockList)
|
bs.flushErr = bs.backingBs.PutMany(ctx, bs.flushingBatch.blockList)
|
||||||
|
|
||||||
// If we succeeded, reset the batch. Otherwise, we'll try again next time.
|
// If we succeeded, reset the batch. Otherwise, we'll try again next time.
|
||||||
if bs.flushErr == nil {
|
if bs.flushErr == nil {
|
||||||
@@ -151,7 +151,7 @@ func (bs *AutobatchBlockstore) doFlush(retryOnly bool) error {
|
|||||||
|
|
||||||
// caller must NOT hold stateLock
|
// caller must NOT hold stateLock
|
||||||
func (bs *AutobatchBlockstore) Flush(ctx context.Context) error {
|
func (bs *AutobatchBlockstore) Flush(ctx context.Context) error {
|
||||||
return bs.doFlush(false)
|
return bs.doFlush(ctx, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) Shutdown(ctx context.Context) error {
|
func (bs *AutobatchBlockstore) Shutdown(ctx context.Context) error {
|
||||||
@@ -169,9 +169,9 @@ func (bs *AutobatchBlockstore) Shutdown(ctx context.Context) error {
|
|||||||
return bs.flushErr
|
return bs.flushErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) Get(c cid.Cid) (block.Block, error) {
|
func (bs *AutobatchBlockstore) Get(ctx context.Context, c cid.Cid) (block.Block, error) {
|
||||||
// may seem backward to check the backingBs first, but that is the likeliest case
|
// may seem backward to check the backingBs first, but that is the likeliest case
|
||||||
blk, err := bs.backingBs.Get(c)
|
blk, err := bs.backingBs.Get(ctx, c)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return blk, nil
|
return blk, nil
|
||||||
}
|
}
|
||||||
@@ -192,10 +192,10 @@ func (bs *AutobatchBlockstore) Get(c cid.Cid) (block.Block, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs.Get(c)
|
return bs.Get(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) DeleteBlock(cid.Cid) error {
|
func (bs *AutobatchBlockstore) DeleteBlock(context.Context, cid.Cid) error {
|
||||||
// if we wanted to support this, we would have to:
|
// if we wanted to support this, we would have to:
|
||||||
// - flush
|
// - flush
|
||||||
// - delete from the backingBs (if present)
|
// - delete from the backingBs (if present)
|
||||||
@@ -204,13 +204,13 @@ func (bs *AutobatchBlockstore) DeleteBlock(cid.Cid) error {
|
|||||||
return xerrors.New("deletion is unsupported")
|
return xerrors.New("deletion is unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) DeleteMany(cids []cid.Cid) error {
|
func (bs *AutobatchBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
|
||||||
// see note in DeleteBlock()
|
// see note in DeleteBlock()
|
||||||
return xerrors.New("deletion is unsupported")
|
return xerrors.New("deletion is unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) Has(c cid.Cid) (bool, error) {
|
func (bs *AutobatchBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
|
||||||
_, err := bs.Get(c)
|
_, err := bs.Get(ctx, c)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
@@ -221,8 +221,8 @@ func (bs *AutobatchBlockstore) Has(c cid.Cid) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) GetSize(c cid.Cid) (int, error) {
|
func (bs *AutobatchBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
|
||||||
blk, err := bs.Get(c)
|
blk, err := bs.Get(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -230,9 +230,9 @@ func (bs *AutobatchBlockstore) GetSize(c cid.Cid) (int, error) {
|
|||||||
return len(blk.RawData()), nil
|
return len(blk.RawData()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) PutMany(blks []block.Block) error {
|
func (bs *AutobatchBlockstore) PutMany(ctx context.Context, blks []block.Block) error {
|
||||||
for _, blk := range blks {
|
for _, blk := range blks {
|
||||||
if err := bs.Put(blk); err != nil {
|
if err := bs.Put(ctx, blk); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,8 +252,8 @@ func (bs *AutobatchBlockstore) HashOnRead(enabled bool) {
|
|||||||
bs.backingBs.HashOnRead(enabled)
|
bs.backingBs.HashOnRead(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *AutobatchBlockstore) View(cid cid.Cid, callback func([]byte) error) error {
|
func (bs *AutobatchBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) error {
|
||||||
blk, err := bs.Get(cid)
|
blk, err := bs.Get(ctx, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ func TestAutobatchBlockstore(t *testing.T) {
|
|||||||
|
|
||||||
ab := NewAutobatch(ctx, NewMemory(), len(b0.RawData())+len(b1.RawData())-1)
|
ab := NewAutobatch(ctx, NewMemory(), len(b0.RawData())+len(b1.RawData())-1)
|
||||||
|
|
||||||
require.NoError(t, ab.Put(b0))
|
require.NoError(t, ab.Put(ctx, b0))
|
||||||
require.NoError(t, ab.Put(b1))
|
require.NoError(t, ab.Put(ctx, b1))
|
||||||
require.NoError(t, ab.Put(b2))
|
require.NoError(t, ab.Put(ctx, b2))
|
||||||
|
|
||||||
v0, err := ab.Get(b0.Cid())
|
v0, err := ab.Get(ctx, b0.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b0.RawData(), v0.RawData())
|
require.Equal(t, b0.RawData(), v0.RawData())
|
||||||
|
|
||||||
v1, err := ab.Get(b1.Cid())
|
v1, err := ab.Get(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b1.RawData(), v1.RawData())
|
require.Equal(t, b1.RawData(), v1.RawData())
|
||||||
|
|
||||||
v2, err := ab.Get(b2.Cid())
|
v2, err := ab.Get(ctx, b2.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b2.RawData(), v2.RawData())
|
require.Equal(t, b2.RawData(), v2.RawData())
|
||||||
|
|
||||||
|
|||||||
@@ -525,7 +525,7 @@ func (b *Blockstore) Size() (int64, error) {
|
|||||||
|
|
||||||
// View implements blockstore.Viewer, which leverages zero-copy read-only
|
// View implements blockstore.Viewer, which leverages zero-copy read-only
|
||||||
// access to values.
|
// access to values.
|
||||||
func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error {
|
func (b *Blockstore) View(ctx context.Context, cid cid.Cid, fn func([]byte) error) error {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -552,7 +552,7 @@ func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Has implements Blockstore.Has.
|
// Has implements Blockstore.Has.
|
||||||
func (b *Blockstore) Has(cid cid.Cid) (bool, error) {
|
func (b *Blockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -582,7 +582,7 @@ func (b *Blockstore) Has(cid cid.Cid) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get implements Blockstore.Get.
|
// Get implements Blockstore.Get.
|
||||||
func (b *Blockstore) Get(cid cid.Cid) (blocks.Block, error) {
|
func (b *Blockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
|
||||||
if !cid.Defined() {
|
if !cid.Defined() {
|
||||||
return nil, blockstore.ErrNotFound
|
return nil, blockstore.ErrNotFound
|
||||||
}
|
}
|
||||||
@@ -619,7 +619,7 @@ func (b *Blockstore) Get(cid cid.Cid) (blocks.Block, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSize implements Blockstore.GetSize.
|
// GetSize implements Blockstore.GetSize.
|
||||||
func (b *Blockstore) GetSize(cid cid.Cid) (int, error) {
|
func (b *Blockstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -652,7 +652,7 @@ func (b *Blockstore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put implements Blockstore.Put.
|
// Put implements Blockstore.Put.
|
||||||
func (b *Blockstore) Put(block blocks.Block) error {
|
func (b *Blockstore) Put(ctx context.Context, block blocks.Block) error {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -691,7 +691,7 @@ func (b *Blockstore) Put(block blocks.Block) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PutMany implements Blockstore.PutMany.
|
// PutMany implements Blockstore.PutMany.
|
||||||
func (b *Blockstore) PutMany(blocks []blocks.Block) error {
|
func (b *Blockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -755,7 +755,7 @@ func (b *Blockstore) PutMany(blocks []blocks.Block) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBlock implements Blockstore.DeleteBlock.
|
// DeleteBlock implements Blockstore.DeleteBlock.
|
||||||
func (b *Blockstore) DeleteBlock(cid cid.Cid) error {
|
func (b *Blockstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -774,7 +774,7 @@ func (b *Blockstore) DeleteBlock(cid cid.Cid) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Blockstore) DeleteMany(cids []cid.Cid) error {
|
func (b *Blockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
|
||||||
if err := b.access(); err != nil {
|
if err := b.access(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
//stm: #unit
|
||||||
package badgerbs
|
package badgerbs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -19,6 +20,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBadgerBlockstore(t *testing.T) {
|
func TestBadgerBlockstore(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
(&Suite{
|
(&Suite{
|
||||||
NewBlockstore: newBlockstore(DefaultOptions),
|
NewBlockstore: newBlockstore(DefaultOptions),
|
||||||
OpenBlockstore: openBlockstore(DefaultOptions),
|
OpenBlockstore: openBlockstore(DefaultOptions),
|
||||||
@@ -37,6 +40,8 @@ func TestBadgerBlockstore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStorageKey(t *testing.T) {
|
func TestStorageKey(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_STORAGE_KEY_001
|
||||||
bs, _ := newBlockstore(DefaultOptions)(t)
|
bs, _ := newBlockstore(DefaultOptions)(t)
|
||||||
bbs := bs.(*Blockstore)
|
bbs := bs.(*Blockstore)
|
||||||
defer bbs.Close() //nolint:errcheck
|
defer bbs.Close() //nolint:errcheck
|
||||||
@@ -72,20 +77,13 @@ func newBlockstore(optsSupplier func(path string) Options) func(tb testing.TB) (
|
|||||||
return func(tb testing.TB) (bs blockstore.BasicBlockstore, path string) {
|
return func(tb testing.TB) (bs blockstore.BasicBlockstore, path string) {
|
||||||
tb.Helper()
|
tb.Helper()
|
||||||
|
|
||||||
path, err := ioutil.TempDir("", "")
|
path = tb.TempDir()
|
||||||
if err != nil {
|
|
||||||
tb.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := Open(optsSupplier(path))
|
db, err := Open(optsSupplier(path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tb.Fatal(err)
|
tb.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tb.Cleanup(func() {
|
|
||||||
_ = os.RemoveAll(path)
|
|
||||||
})
|
|
||||||
|
|
||||||
return db, path
|
return db, path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,17 +96,11 @@ func openBlockstore(optsSupplier func(path string) Options) func(tb testing.TB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testMove(t *testing.T, optsF func(string) Options) {
|
func testMove(t *testing.T, optsF func(string) Options) {
|
||||||
basePath, err := ioutil.TempDir("", "")
|
ctx := context.Background()
|
||||||
if err != nil {
|
basePath := t.TempDir()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dbPath := filepath.Join(basePath, "db")
|
dbPath := filepath.Join(basePath, "db")
|
||||||
|
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.RemoveAll(basePath)
|
|
||||||
})
|
|
||||||
|
|
||||||
db, err := Open(optsF(dbPath))
|
db, err := Open(optsF(dbPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -122,7 +114,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
// add some blocks
|
// add some blocks
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
blk := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
|
blk := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
|
||||||
err := db.Put(blk)
|
err := db.Put(ctx, blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -132,7 +124,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
// delete some of them
|
// delete some of them
|
||||||
for i := 5; i < 10; i++ {
|
for i := 5; i < 10; i++ {
|
||||||
c := have[i].Cid()
|
c := have[i].Cid()
|
||||||
err := db.DeleteBlock(c)
|
err := db.DeleteBlock(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -145,7 +137,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
for i := 10; i < 1000; i++ {
|
for i := 10; i < 1000; i++ {
|
||||||
blk := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
|
blk := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
|
||||||
err := db.Put(blk)
|
err := db.Put(ctx, blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -165,7 +157,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
// now check that we have all the blocks in have and none in the deleted lists
|
// now check that we have all the blocks in have and none in the deleted lists
|
||||||
checkBlocks := func() {
|
checkBlocks := func() {
|
||||||
for _, blk := range have {
|
for _, blk := range have {
|
||||||
has, err := db.Has(blk.Cid())
|
has, err := db.Has(ctx, blk.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -174,7 +166,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
t.Fatal("missing block")
|
t.Fatal("missing block")
|
||||||
}
|
}
|
||||||
|
|
||||||
blk2, err := db.Get(blk.Cid())
|
blk2, err := db.Get(ctx, blk.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -185,7 +177,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range deleted {
|
for _, c := range deleted {
|
||||||
has, err := db.Has(c)
|
has, err := db.Has(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -263,10 +255,16 @@ func testMove(t *testing.T, optsF func(string) Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMoveNoPrefix(t *testing.T) {
|
func TestMoveNoPrefix(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_DELETE_001, @SPLITSTORE_BADGER_COLLECT_GARBAGE_001
|
||||||
testMove(t, DefaultOptions)
|
testMove(t, DefaultOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMoveWithPrefix(t *testing.T) {
|
func TestMoveWithPrefix(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_DELETE_001, @SPLITSTORE_BADGER_COLLECT_GARBAGE_001
|
||||||
testMove(t, func(path string) Options {
|
testMove(t, func(path string) Options {
|
||||||
opts := DefaultOptions(path)
|
opts := DefaultOptions(path)
|
||||||
opts.Prefix = "/prefixed/"
|
opts.Prefix = "/prefixed/"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package badgerbs
|
package badgerbs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -44,28 +45,38 @@ func (s *Suite) RunTests(t *testing.T, prefix string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestGetWhenKeyNotPresent(t *testing.T) {
|
func (s *Suite) TestGetWhenKeyNotPresent(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
}
|
}
|
||||||
|
|
||||||
c := cid.NewCidV0(u.Hash([]byte("stuff")))
|
c := cid.NewCidV0(u.Hash([]byte("stuff")))
|
||||||
bl, err := bs.Get(c)
|
bl, err := bs.Get(ctx, c)
|
||||||
require.Nil(t, bl)
|
require.Nil(t, bl)
|
||||||
require.Equal(t, blockstore.ErrNotFound, err)
|
require.Equal(t, blockstore.ErrNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestGetWhenKeyIsNil(t *testing.T) {
|
func (s *Suite) TestGetWhenKeyIsNil(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := bs.Get(cid.Undef)
|
_, err := bs.Get(ctx, cid.Undef)
|
||||||
require.Equal(t, blockstore.ErrNotFound, err)
|
require.Equal(t, blockstore.ErrNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestPutThenGetBlock(t *testing.T) {
|
func (s *Suite) TestPutThenGetBlock(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -73,15 +84,18 @@ func (s *Suite) TestPutThenGetBlock(t *testing.T) {
|
|||||||
|
|
||||||
orig := blocks.NewBlock([]byte("some data"))
|
orig := blocks.NewBlock([]byte("some data"))
|
||||||
|
|
||||||
err := bs.Put(orig)
|
err := bs.Put(ctx, orig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fetched, err := bs.Get(orig.Cid())
|
fetched, err := bs.Get(ctx, orig.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, orig.RawData(), fetched.RawData())
|
require.Equal(t, orig.RawData(), fetched.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestHas(t *testing.T) {
|
func (s *Suite) TestHas(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_HAS_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -89,19 +103,23 @@ func (s *Suite) TestHas(t *testing.T) {
|
|||||||
|
|
||||||
orig := blocks.NewBlock([]byte("some data"))
|
orig := blocks.NewBlock([]byte("some data"))
|
||||||
|
|
||||||
err := bs.Put(orig)
|
err := bs.Put(ctx, orig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ok, err := bs.Has(orig.Cid())
|
ok, err := bs.Has(ctx, orig.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
|
|
||||||
ok, err = bs.Has(blocks.NewBlock([]byte("another thing")).Cid())
|
ok, err = bs.Has(ctx, blocks.NewBlock([]byte("another thing")).Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, ok)
|
require.False(t, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestCidv0v1(t *testing.T) {
|
func (s *Suite) TestCidv0v1(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -109,15 +127,20 @@ func (s *Suite) TestCidv0v1(t *testing.T) {
|
|||||||
|
|
||||||
orig := blocks.NewBlock([]byte("some data"))
|
orig := blocks.NewBlock([]byte("some data"))
|
||||||
|
|
||||||
err := bs.Put(orig)
|
err := bs.Put(ctx, orig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fetched, err := bs.Get(cid.NewCidV1(cid.DagProtobuf, orig.Cid().Hash()))
|
fetched, err := bs.Get(ctx, cid.NewCidV1(cid.DagProtobuf, orig.Cid().Hash()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, orig.RawData(), fetched.RawData())
|
require.Equal(t, orig.RawData(), fetched.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestPutThenGetSizeBlock(t *testing.T) {
|
func (s *Suite) TestPutThenGetSizeBlock(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_SIZE_001
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -127,26 +150,28 @@ func (s *Suite) TestPutThenGetSizeBlock(t *testing.T) {
|
|||||||
missingBlock := blocks.NewBlock([]byte("missingBlock"))
|
missingBlock := blocks.NewBlock([]byte("missingBlock"))
|
||||||
emptyBlock := blocks.NewBlock([]byte{})
|
emptyBlock := blocks.NewBlock([]byte{})
|
||||||
|
|
||||||
err := bs.Put(block)
|
err := bs.Put(ctx, block)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
blockSize, err := bs.GetSize(block.Cid())
|
blockSize, err := bs.GetSize(ctx, block.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, block.RawData(), blockSize)
|
require.Len(t, block.RawData(), blockSize)
|
||||||
|
|
||||||
err = bs.Put(emptyBlock)
|
err = bs.Put(ctx, emptyBlock)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
emptySize, err := bs.GetSize(emptyBlock.Cid())
|
emptySize, err := bs.GetSize(ctx, emptyBlock.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Zero(t, emptySize)
|
require.Zero(t, emptySize)
|
||||||
|
|
||||||
missingSize, err := bs.GetSize(missingBlock.Cid())
|
missingSize, err := bs.GetSize(ctx, missingBlock.Cid())
|
||||||
require.Equal(t, blockstore.ErrNotFound, err)
|
require.Equal(t, blockstore.ErrNotFound, err)
|
||||||
require.Equal(t, -1, missingSize)
|
require.Equal(t, -1, missingSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestAllKeysSimple(t *testing.T) {
|
func (s *Suite) TestAllKeysSimple(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -163,6 +188,9 @@ func (s *Suite) TestAllKeysSimple(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestAllKeysRespectsContext(t *testing.T) {
|
func (s *Suite) TestAllKeysRespectsContext(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_ALL_KEYS_CHAN_001
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -193,6 +221,7 @@ func (s *Suite) TestAllKeysRespectsContext(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestDoubleClose(t *testing.T) {
|
func (s *Suite) TestDoubleClose(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
c, ok := bs.(io.Closer)
|
c, ok := bs.(io.Closer)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -203,6 +232,10 @@ func (s *Suite) TestDoubleClose(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestReopenPutGet(t *testing.T) {
|
func (s *Suite) TestReopenPutGet(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, path := s.NewBlockstore(t)
|
bs, path := s.NewBlockstore(t)
|
||||||
c, ok := bs.(io.Closer)
|
c, ok := bs.(io.Closer)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -210,7 +243,7 @@ func (s *Suite) TestReopenPutGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
orig := blocks.NewBlock([]byte("some data"))
|
orig := blocks.NewBlock([]byte("some data"))
|
||||||
err := bs.Put(orig)
|
err := bs.Put(ctx, orig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = c.Close()
|
err = c.Close()
|
||||||
@@ -219,7 +252,7 @@ func (s *Suite) TestReopenPutGet(t *testing.T) {
|
|||||||
bs, err = s.OpenBlockstore(t, path)
|
bs, err = s.OpenBlockstore(t, path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fetched, err := bs.Get(orig.Cid())
|
fetched, err := bs.Get(ctx, orig.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, orig.RawData(), fetched.RawData())
|
require.Equal(t, orig.RawData(), fetched.RawData())
|
||||||
|
|
||||||
@@ -228,6 +261,11 @@ func (s *Suite) TestReopenPutGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestPutMany(t *testing.T) {
|
func (s *Suite) TestPutMany(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_OPEN_001, @SPLITSTORE_BADGER_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_HAS_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_GET_001, @SPLITSTORE_BADGER_PUT_MANY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_ALL_KEYS_CHAN_001
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -238,15 +276,15 @@ func (s *Suite) TestPutMany(t *testing.T) {
|
|||||||
blocks.NewBlock([]byte("foo2")),
|
blocks.NewBlock([]byte("foo2")),
|
||||||
blocks.NewBlock([]byte("foo3")),
|
blocks.NewBlock([]byte("foo3")),
|
||||||
}
|
}
|
||||||
err := bs.PutMany(blks)
|
err := bs.PutMany(ctx, blks)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, blk := range blks {
|
for _, blk := range blks {
|
||||||
fetched, err := bs.Get(blk.Cid())
|
fetched, err := bs.Get(ctx, blk.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, blk.RawData(), fetched.RawData())
|
require.Equal(t, blk.RawData(), fetched.RawData())
|
||||||
|
|
||||||
ok, err := bs.Has(blk.Cid())
|
ok, err := bs.Has(ctx, blk.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
}
|
}
|
||||||
@@ -259,6 +297,12 @@ func (s *Suite) TestPutMany(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Suite) TestDelete(t *testing.T) {
|
func (s *Suite) TestDelete(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_001, @SPLITSTORE_BADGER_POOLED_STORAGE_KEY_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_DELETE_001, @SPLITSTORE_BADGER_POOLED_STORAGE_HAS_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_ALL_KEYS_CHAN_001, @SPLITSTORE_BADGER_HAS_001
|
||||||
|
//stm: @SPLITSTORE_BADGER_PUT_MANY_001
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
bs, _ := s.NewBlockstore(t)
|
bs, _ := s.NewBlockstore(t)
|
||||||
if c, ok := bs.(io.Closer); ok {
|
if c, ok := bs.(io.Closer); ok {
|
||||||
defer func() { require.NoError(t, c.Close()) }()
|
defer func() { require.NoError(t, c.Close()) }()
|
||||||
@@ -269,10 +313,10 @@ func (s *Suite) TestDelete(t *testing.T) {
|
|||||||
blocks.NewBlock([]byte("foo2")),
|
blocks.NewBlock([]byte("foo2")),
|
||||||
blocks.NewBlock([]byte("foo3")),
|
blocks.NewBlock([]byte("foo3")),
|
||||||
}
|
}
|
||||||
err := bs.PutMany(blks)
|
err := bs.PutMany(ctx, blks)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = bs.DeleteBlock(blks[1].Cid())
|
err = bs.DeleteBlock(ctx, blks[1].Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ch, err := bs.AllKeysChan(context.Background())
|
ch, err := bs.AllKeysChan(context.Background())
|
||||||
@@ -285,17 +329,17 @@ func (s *Suite) TestDelete(t *testing.T) {
|
|||||||
cid.NewCidV1(cid.Raw, blks[2].Cid().Hash()),
|
cid.NewCidV1(cid.Raw, blks[2].Cid().Hash()),
|
||||||
})
|
})
|
||||||
|
|
||||||
has, err := bs.Has(blks[1].Cid())
|
has, err := bs.Has(ctx, blks[1].Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, has)
|
require.False(t, has)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func insertBlocks(t *testing.T, bs blockstore.BasicBlockstore, count int) []cid.Cid {
|
func insertBlocks(t *testing.T, bs blockstore.BasicBlockstore, count int) []cid.Cid {
|
||||||
|
ctx := context.Background()
|
||||||
keys := make([]cid.Cid, count)
|
keys := make([]cid.Cid, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
block := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
|
block := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
|
||||||
err := bs.Put(block)
|
err := bs.Put(ctx, block)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// NewBlock assigns a CIDv0; we convert it to CIDv1 because that's what
|
// NewBlock assigns a CIDv0; we convert it to CIDv1 because that's what
|
||||||
// the store returns.
|
// the store returns.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package blockstore
|
package blockstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
ds "github.com/ipfs/go-datastore"
|
ds "github.com/ipfs/go-datastore"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
@@ -27,7 +29,7 @@ type BasicBlockstore = blockstore.Blockstore
|
|||||||
type Viewer = blockstore.Viewer
|
type Viewer = blockstore.Viewer
|
||||||
|
|
||||||
type BatchDeleter interface {
|
type BatchDeleter interface {
|
||||||
DeleteMany(cids []cid.Cid) error
|
DeleteMany(ctx context.Context, cids []cid.Cid) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockstoreIterator is a trait for efficient iteration
|
// BlockstoreIterator is a trait for efficient iteration
|
||||||
@@ -93,17 +95,17 @@ type adaptedBlockstore struct {
|
|||||||
|
|
||||||
var _ Blockstore = (*adaptedBlockstore)(nil)
|
var _ Blockstore = (*adaptedBlockstore)(nil)
|
||||||
|
|
||||||
func (a *adaptedBlockstore) View(cid cid.Cid, callback func([]byte) error) error {
|
func (a *adaptedBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) error {
|
||||||
blk, err := a.Get(cid)
|
blk, err := a.Get(ctx, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return callback(blk.RawData())
|
return callback(blk.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *adaptedBlockstore) DeleteMany(cids []cid.Cid) error {
|
func (a *adaptedBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
|
||||||
for _, cid := range cids {
|
for _, cid := range cids {
|
||||||
err := a.DeleteBlock(cid)
|
err := a.DeleteBlock(ctx, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-23
@@ -88,34 +88,34 @@ func (bs *BufferedBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid,
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) DeleteBlock(c cid.Cid) error {
|
func (bs *BufferedBlockstore) DeleteBlock(ctx context.Context, c cid.Cid) error {
|
||||||
if err := bs.read.DeleteBlock(c); err != nil {
|
if err := bs.read.DeleteBlock(ctx, c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs.write.DeleteBlock(c)
|
return bs.write.DeleteBlock(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) DeleteMany(cids []cid.Cid) error {
|
func (bs *BufferedBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
|
||||||
if err := bs.read.DeleteMany(cids); err != nil {
|
if err := bs.read.DeleteMany(ctx, cids); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs.write.DeleteMany(cids)
|
return bs.write.DeleteMany(ctx, cids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) View(c cid.Cid, callback func([]byte) error) error {
|
func (bs *BufferedBlockstore) View(ctx context.Context, c cid.Cid, callback func([]byte) error) error {
|
||||||
// both stores are viewable.
|
// both stores are viewable.
|
||||||
if err := bs.write.View(c, callback); err == ErrNotFound {
|
if err := bs.write.View(ctx, c, callback); err == ErrNotFound {
|
||||||
// not found in write blockstore; fall through.
|
// not found in write blockstore; fall through.
|
||||||
} else {
|
} else {
|
||||||
return err // propagate errors, or nil, i.e. found.
|
return err // propagate errors, or nil, i.e. found.
|
||||||
}
|
}
|
||||||
return bs.read.View(c, callback)
|
return bs.read.View(ctx, c, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) Get(c cid.Cid) (block.Block, error) {
|
func (bs *BufferedBlockstore) Get(ctx context.Context, c cid.Cid) (block.Block, error) {
|
||||||
if out, err := bs.write.Get(c); err != nil {
|
if out, err := bs.write.Get(ctx, c); err != nil {
|
||||||
if err != ErrNotFound {
|
if err != ErrNotFound {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -123,20 +123,20 @@ func (bs *BufferedBlockstore) Get(c cid.Cid) (block.Block, error) {
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs.read.Get(c)
|
return bs.read.Get(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) GetSize(c cid.Cid) (int, error) {
|
func (bs *BufferedBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
|
||||||
s, err := bs.read.GetSize(c)
|
s, err := bs.read.GetSize(ctx, c)
|
||||||
if err == ErrNotFound || s == 0 {
|
if err == ErrNotFound || s == 0 {
|
||||||
return bs.write.GetSize(c)
|
return bs.write.GetSize(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) Put(blk block.Block) error {
|
func (bs *BufferedBlockstore) Put(ctx context.Context, blk block.Block) error {
|
||||||
has, err := bs.read.Has(blk.Cid()) // TODO: consider dropping this check
|
has, err := bs.read.Has(ctx, blk.Cid()) // TODO: consider dropping this check
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -145,11 +145,11 @@ func (bs *BufferedBlockstore) Put(blk block.Block) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs.write.Put(blk)
|
return bs.write.Put(ctx, blk)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) Has(c cid.Cid) (bool, error) {
|
func (bs *BufferedBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
|
||||||
has, err := bs.write.Has(c)
|
has, err := bs.write.Has(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ func (bs *BufferedBlockstore) Has(c cid.Cid) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return bs.read.Has(c)
|
return bs.read.Has(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) HashOnRead(hor bool) {
|
func (bs *BufferedBlockstore) HashOnRead(hor bool) {
|
||||||
@@ -165,8 +165,8 @@ func (bs *BufferedBlockstore) HashOnRead(hor bool) {
|
|||||||
bs.write.HashOnRead(hor)
|
bs.write.HashOnRead(hor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) PutMany(blks []block.Block) error {
|
func (bs *BufferedBlockstore) PutMany(ctx context.Context, blks []block.Block) error {
|
||||||
return bs.write.PutMany(blks)
|
return bs.write.PutMany(ctx, blks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BufferedBlockstore) Read() Blockstore {
|
func (bs *BufferedBlockstore) Read() Blockstore {
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package blockstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type hotViewKey struct{}
|
||||||
|
|
||||||
|
var hotView = hotViewKey{}
|
||||||
|
|
||||||
|
// WithHotView constructs a new context with an option that provides a hint to the blockstore
|
||||||
|
// (e.g. the splitstore) that the object (and its ipld references) should be kept hot.
|
||||||
|
func WithHotView(ctx context.Context) context.Context {
|
||||||
|
return context.WithValue(ctx, hotView, struct{}{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsHotView returns true if the hot view option is set in the context
|
||||||
|
func IsHotView(ctx context.Context) bool {
|
||||||
|
v := ctx.Value(hotView)
|
||||||
|
return v != nil
|
||||||
|
}
|
||||||
+12
-12
@@ -18,39 +18,39 @@ func NewDiscardStore(bs Blockstore) Blockstore {
|
|||||||
return &discardstore{bs: bs}
|
return &discardstore{bs: bs}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) Has(cid cid.Cid) (bool, error) {
|
func (b *discardstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
|
||||||
return b.bs.Has(cid)
|
return b.bs.Has(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) HashOnRead(hor bool) {
|
func (b *discardstore) HashOnRead(hor bool) {
|
||||||
b.bs.HashOnRead(hor)
|
b.bs.HashOnRead(hor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) Get(cid cid.Cid) (blocks.Block, error) {
|
func (b *discardstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
|
||||||
return b.bs.Get(cid)
|
return b.bs.Get(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) GetSize(cid cid.Cid) (int, error) {
|
func (b *discardstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
|
||||||
return b.bs.GetSize(cid)
|
return b.bs.GetSize(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) View(cid cid.Cid, f func([]byte) error) error {
|
func (b *discardstore) View(ctx context.Context, cid cid.Cid, f func([]byte) error) error {
|
||||||
return b.bs.View(cid, f)
|
return b.bs.View(ctx, cid, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) Put(blk blocks.Block) error {
|
func (b *discardstore) Put(ctx context.Context, blk blocks.Block) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) PutMany(blks []blocks.Block) error {
|
func (b *discardstore) PutMany(ctx context.Context, blks []blocks.Block) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) DeleteBlock(cid cid.Cid) error {
|
func (b *discardstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *discardstore) DeleteMany(cids []cid.Cid) error {
|
func (b *discardstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,14 +71,14 @@ func (fbs *FallbackStore) getFallback(c cid.Cid) (blocks.Block, error) {
|
|||||||
// chain bitswap puts blocks in temp blockstore which is cleaned up
|
// chain bitswap puts blocks in temp blockstore which is cleaned up
|
||||||
// every few min (to drop any messages we fetched but don't want)
|
// every few min (to drop any messages we fetched but don't want)
|
||||||
// in this case we want to keep this block around
|
// in this case we want to keep this block around
|
||||||
if err := fbs.Put(b); err != nil {
|
if err := fbs.Put(ctx, b); err != nil {
|
||||||
return nil, xerrors.Errorf("persisting fallback-fetched block: %w", err)
|
return nil, xerrors.Errorf("persisting fallback-fetched block: %w", err)
|
||||||
}
|
}
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fbs *FallbackStore) Get(c cid.Cid) (blocks.Block, error) {
|
func (fbs *FallbackStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
|
||||||
b, err := fbs.Blockstore.Get(c)
|
b, err := fbs.Blockstore.Get(ctx, c)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
return b, nil
|
return b, nil
|
||||||
@@ -89,8 +89,8 @@ func (fbs *FallbackStore) Get(c cid.Cid) (blocks.Block, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fbs *FallbackStore) GetSize(c cid.Cid) (int, error) {
|
func (fbs *FallbackStore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
|
||||||
sz, err := fbs.Blockstore.GetSize(c)
|
sz, err := fbs.Blockstore.GetSize(ctx, c)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
return sz, nil
|
return sz, nil
|
||||||
|
|||||||
+16
-16
@@ -38,7 +38,7 @@ func decodeCid(cid cid.Cid) (inline bool, data []byte, err error) {
|
|||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) Has(cid cid.Cid) (bool, error) {
|
func (b *idstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
|
||||||
inline, _, err := decodeCid(cid)
|
inline, _, err := decodeCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, xerrors.Errorf("error decoding Cid: %w", err)
|
return false, xerrors.Errorf("error decoding Cid: %w", err)
|
||||||
@@ -48,10 +48,10 @@ func (b *idstore) Has(cid cid.Cid) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.bs.Has(cid)
|
return b.bs.Has(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) Get(cid cid.Cid) (blocks.Block, error) {
|
func (b *idstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
|
||||||
inline, data, err := decodeCid(cid)
|
inline, data, err := decodeCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("error decoding Cid: %w", err)
|
return nil, xerrors.Errorf("error decoding Cid: %w", err)
|
||||||
@@ -61,10 +61,10 @@ func (b *idstore) Get(cid cid.Cid) (blocks.Block, error) {
|
|||||||
return blocks.NewBlockWithCid(data, cid)
|
return blocks.NewBlockWithCid(data, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.bs.Get(cid)
|
return b.bs.Get(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) GetSize(cid cid.Cid) (int, error) {
|
func (b *idstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
|
||||||
inline, data, err := decodeCid(cid)
|
inline, data, err := decodeCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, xerrors.Errorf("error decoding Cid: %w", err)
|
return 0, xerrors.Errorf("error decoding Cid: %w", err)
|
||||||
@@ -74,10 +74,10 @@ func (b *idstore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
return len(data), err
|
return len(data), err
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.bs.GetSize(cid)
|
return b.bs.GetSize(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) View(cid cid.Cid, cb func([]byte) error) error {
|
func (b *idstore) View(ctx context.Context, cid cid.Cid, cb func([]byte) error) error {
|
||||||
inline, data, err := decodeCid(cid)
|
inline, data, err := decodeCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error decoding Cid: %w", err)
|
return xerrors.Errorf("error decoding Cid: %w", err)
|
||||||
@@ -87,10 +87,10 @@ func (b *idstore) View(cid cid.Cid, cb func([]byte) error) error {
|
|||||||
return cb(data)
|
return cb(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.bs.View(cid, cb)
|
return b.bs.View(ctx, cid, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) Put(blk blocks.Block) error {
|
func (b *idstore) Put(ctx context.Context, blk blocks.Block) error {
|
||||||
inline, _, err := decodeCid(blk.Cid())
|
inline, _, err := decodeCid(blk.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error decoding Cid: %w", err)
|
return xerrors.Errorf("error decoding Cid: %w", err)
|
||||||
@@ -100,10 +100,10 @@ func (b *idstore) Put(blk blocks.Block) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.bs.Put(blk)
|
return b.bs.Put(ctx, blk)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) PutMany(blks []blocks.Block) error {
|
func (b *idstore) PutMany(ctx context.Context, blks []blocks.Block) error {
|
||||||
toPut := make([]blocks.Block, 0, len(blks))
|
toPut := make([]blocks.Block, 0, len(blks))
|
||||||
for _, blk := range blks {
|
for _, blk := range blks {
|
||||||
inline, _, err := decodeCid(blk.Cid())
|
inline, _, err := decodeCid(blk.Cid())
|
||||||
@@ -118,13 +118,13 @@ func (b *idstore) PutMany(blks []blocks.Block) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(toPut) > 0 {
|
if len(toPut) > 0 {
|
||||||
return b.bs.PutMany(toPut)
|
return b.bs.PutMany(ctx, toPut)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) DeleteBlock(cid cid.Cid) error {
|
func (b *idstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
|
||||||
inline, _, err := decodeCid(cid)
|
inline, _, err := decodeCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error decoding Cid: %w", err)
|
return xerrors.Errorf("error decoding Cid: %w", err)
|
||||||
@@ -134,10 +134,10 @@ func (b *idstore) DeleteBlock(cid cid.Cid) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.bs.DeleteBlock(cid)
|
return b.bs.DeleteBlock(ctx, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *idstore) DeleteMany(cids []cid.Cid) error {
|
func (b *idstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
|
||||||
toDelete := make([]cid.Cid, 0, len(cids))
|
toDelete := make([]cid.Cid, 0, len(cids))
|
||||||
for _, cid := range cids {
|
for _, cid := range cids {
|
||||||
inline, _, err := decodeCid(cid)
|
inline, _, err := decodeCid(cid)
|
||||||
@@ -152,7 +152,7 @@ func (b *idstore) DeleteMany(cids []cid.Cid) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(toDelete) > 0 {
|
if len(toDelete) > 0 {
|
||||||
return b.bs.DeleteMany(toDelete)
|
return b.bs.DeleteMany(ctx, toDelete)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+11
-11
@@ -79,12 +79,12 @@ func NewRemoteIPFSBlockstore(ctx context.Context, maddr multiaddr.Multiaddr, onl
|
|||||||
return Adapt(bs), nil
|
return Adapt(bs), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPFSBlockstore) DeleteBlock(cid cid.Cid) error {
|
func (i *IPFSBlockstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
|
||||||
return xerrors.Errorf("not supported")
|
return xerrors.Errorf("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPFSBlockstore) Has(cid cid.Cid) (bool, error) {
|
func (i *IPFSBlockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
|
||||||
_, err := i.offlineAPI.Block().Stat(i.ctx, path.IpldPath(cid))
|
_, err := i.offlineAPI.Block().Stat(ctx, path.IpldPath(cid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The underlying client is running in Offline mode.
|
// The underlying client is running in Offline mode.
|
||||||
// Stat() will fail with an err if the block isn't in the
|
// Stat() will fail with an err if the block isn't in the
|
||||||
@@ -99,8 +99,8 @@ func (i *IPFSBlockstore) Has(cid cid.Cid) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPFSBlockstore) Get(cid cid.Cid) (blocks.Block, error) {
|
func (i *IPFSBlockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
|
||||||
rd, err := i.api.Block().Get(i.ctx, path.IpldPath(cid))
|
rd, err := i.api.Block().Get(ctx, path.IpldPath(cid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting ipfs block: %w", err)
|
return nil, xerrors.Errorf("getting ipfs block: %w", err)
|
||||||
}
|
}
|
||||||
@@ -113,8 +113,8 @@ func (i *IPFSBlockstore) Get(cid cid.Cid) (blocks.Block, error) {
|
|||||||
return blocks.NewBlockWithCid(data, cid)
|
return blocks.NewBlockWithCid(data, cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPFSBlockstore) GetSize(cid cid.Cid) (int, error) {
|
func (i *IPFSBlockstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
|
||||||
st, err := i.api.Block().Stat(i.ctx, path.IpldPath(cid))
|
st, err := i.api.Block().Stat(ctx, path.IpldPath(cid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, xerrors.Errorf("getting ipfs block: %w", err)
|
return 0, xerrors.Errorf("getting ipfs block: %w", err)
|
||||||
}
|
}
|
||||||
@@ -122,23 +122,23 @@ func (i *IPFSBlockstore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
return st.Size(), nil
|
return st.Size(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPFSBlockstore) Put(block blocks.Block) error {
|
func (i *IPFSBlockstore) Put(ctx context.Context, block blocks.Block) error {
|
||||||
mhd, err := multihash.Decode(block.Cid().Hash())
|
mhd, err := multihash.Decode(block.Cid().Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = i.api.Block().Put(i.ctx, bytes.NewReader(block.RawData()),
|
_, err = i.api.Block().Put(ctx, bytes.NewReader(block.RawData()),
|
||||||
options.Block.Hash(mhd.Code, mhd.Length),
|
options.Block.Hash(mhd.Code, mhd.Length),
|
||||||
options.Block.Format(cid.CodecToStr[block.Cid().Type()]))
|
options.Block.Format(cid.CodecToStr[block.Cid().Type()]))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPFSBlockstore) PutMany(blocks []blocks.Block) error {
|
func (i *IPFSBlockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
|
||||||
// TODO: could be done in parallel
|
// TODO: could be done in parallel
|
||||||
|
|
||||||
for _, block := range blocks {
|
for _, block := range blocks {
|
||||||
if err := i.Put(block); err != nil {
|
if err := i.Put(ctx, block); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -15,24 +15,24 @@ func NewMemory() MemBlockstore {
|
|||||||
// MemBlockstore is a terminal blockstore that keeps blocks in memory.
|
// MemBlockstore is a terminal blockstore that keeps blocks in memory.
|
||||||
type MemBlockstore map[cid.Cid]blocks.Block
|
type MemBlockstore map[cid.Cid]blocks.Block
|
||||||
|
|
||||||
func (m MemBlockstore) DeleteBlock(k cid.Cid) error {
|
func (m MemBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
|
||||||
delete(m, k)
|
delete(m, k)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MemBlockstore) DeleteMany(ks []cid.Cid) error {
|
func (m MemBlockstore) DeleteMany(ctx context.Context, ks []cid.Cid) error {
|
||||||
for _, k := range ks {
|
for _, k := range ks {
|
||||||
delete(m, k)
|
delete(m, k)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MemBlockstore) Has(k cid.Cid) (bool, error) {
|
func (m MemBlockstore) Has(ctx context.Context, k cid.Cid) (bool, error) {
|
||||||
_, ok := m[k]
|
_, ok := m[k]
|
||||||
return ok, nil
|
return ok, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MemBlockstore) View(k cid.Cid, callback func([]byte) error) error {
|
func (m MemBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte) error) error {
|
||||||
b, ok := m[k]
|
b, ok := m[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
@@ -40,7 +40,7 @@ func (m MemBlockstore) View(k cid.Cid, callback func([]byte) error) error {
|
|||||||
return callback(b.RawData())
|
return callback(b.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MemBlockstore) Get(k cid.Cid) (blocks.Block, error) {
|
func (m MemBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
|
||||||
b, ok := m[k]
|
b, ok := m[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
@@ -49,7 +49,7 @@ func (m MemBlockstore) Get(k cid.Cid) (blocks.Block, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the CIDs mapped BlockSize
|
// GetSize returns the CIDs mapped BlockSize
|
||||||
func (m MemBlockstore) GetSize(k cid.Cid) (int, error) {
|
func (m MemBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
|
||||||
b, ok := m[k]
|
b, ok := m[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, ErrNotFound
|
return 0, ErrNotFound
|
||||||
@@ -58,7 +58,7 @@ func (m MemBlockstore) GetSize(k cid.Cid) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put puts a given block to the underlying datastore
|
// Put puts a given block to the underlying datastore
|
||||||
func (m MemBlockstore) Put(b blocks.Block) error {
|
func (m MemBlockstore) Put(ctx context.Context, b blocks.Block) error {
|
||||||
// Convert to a basic block for safety, but try to reuse the existing
|
// Convert to a basic block for safety, but try to reuse the existing
|
||||||
// block if it's already a basic block.
|
// block if it's already a basic block.
|
||||||
k := b.Cid()
|
k := b.Cid()
|
||||||
@@ -76,9 +76,9 @@ func (m MemBlockstore) Put(b blocks.Block) error {
|
|||||||
|
|
||||||
// PutMany puts a slice of blocks at the same time using batching
|
// PutMany puts a slice of blocks at the same time using batching
|
||||||
// capabilities of the underlying datastore whenever possible.
|
// capabilities of the underlying datastore whenever possible.
|
||||||
func (m MemBlockstore) PutMany(bs []blocks.Block) error {
|
func (m MemBlockstore) PutMany(ctx context.Context, bs []blocks.Block) error {
|
||||||
for _, b := range bs {
|
for _, b := range bs {
|
||||||
_ = m.Put(b) // can't fail
|
_ = m.Put(ctx, b) // can't fail
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,11 @@ These are options in the `[Chainstore.Splitstore]` section of the configuration:
|
|||||||
blockstore and discards writes; this is necessary to support syncing from a snapshot.
|
blockstore and discards writes; this is necessary to support syncing from a snapshot.
|
||||||
- `MarkSetType` -- specifies the type of markset to use during compaction.
|
- `MarkSetType` -- specifies the type of markset to use during compaction.
|
||||||
The markset is the data structure used by compaction/gc to track live objects.
|
The markset is the data structure used by compaction/gc to track live objects.
|
||||||
The default value is `"map"`, which will use an in-memory map; if you are limited
|
The default value is "badger", which will use a disk backed markset using badger.
|
||||||
in memory (or indeed see compaction run out of memory), you can also specify
|
If you have a lot of memory (48G or more) you can also use "map", which will use
|
||||||
`"badger"` which will use an disk backed markset, using badger. This will use
|
an in memory markset, speeding up compaction at the cost of higher memory usage.
|
||||||
much less memory, but will also make compaction slower.
|
Note: If you are using a VPS with a network volume, you need to provision at least
|
||||||
|
3000 IOPs with the badger markset.
|
||||||
- `HotStoreMessageRetention` -- specifies how many finalities, beyond the 4
|
- `HotStoreMessageRetention` -- specifies how many finalities, beyond the 4
|
||||||
finalities maintained by default, to maintain messages and message receipts in the
|
finalities maintained by default, to maintain messages and message receipts in the
|
||||||
hotstore. This is useful for assistive nodes that want to support syncing for other
|
hotstore. This is useful for assistive nodes that want to support syncing for other
|
||||||
@@ -105,6 +106,12 @@ Compaction works transactionally with the following algorithm:
|
|||||||
- We delete in small batches taking a lock; each batch is checked again for marks, from the concurrent transactional mark, so as to never delete anything live
|
- We delete in small batches taking a lock; each batch is checked again for marks, from the concurrent transactional mark, so as to never delete anything live
|
||||||
- We then end the transaction and compact/gc the hotstore.
|
- We then end the transaction and compact/gc the hotstore.
|
||||||
|
|
||||||
|
As of [#8008](https://github.com/filecoin-project/lotus/pull/8008) the compaction algorithm has been
|
||||||
|
modified to eliminate sorting and maintain the cold object set on disk. This drastically reduces
|
||||||
|
memory usage; in fact, when using badger as the markset compaction uses very little memory, and
|
||||||
|
it should be now possible to run splitstore with 32GB of RAM or less without danger of running out of
|
||||||
|
memory during compaction.
|
||||||
|
|
||||||
## Garbage Collection
|
## Garbage Collection
|
||||||
|
|
||||||
TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577)
|
TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577)
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package splitstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
cid "github.com/ipfs/go-cid"
|
||||||
|
mh "github.com/multiformats/go-multihash"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Checkpoint struct {
|
||||||
|
file *os.File
|
||||||
|
buf *bufio.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCheckpoint(path string) (*Checkpoint, error) {
|
||||||
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_SYNC, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error creating checkpoint: %w", err)
|
||||||
|
}
|
||||||
|
buf := bufio.NewWriter(file)
|
||||||
|
|
||||||
|
return &Checkpoint{
|
||||||
|
file: file,
|
||||||
|
buf: buf,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func OpenCheckpoint(path string) (*Checkpoint, cid.Cid, error) {
|
||||||
|
filein, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, cid.Undef, xerrors.Errorf("error opening checkpoint for reading: %w", err)
|
||||||
|
}
|
||||||
|
defer filein.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
bufin := bufio.NewReader(filein)
|
||||||
|
start, err := readRawCid(bufin, nil)
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
return nil, cid.Undef, xerrors.Errorf("error reading cid from checkpoint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileout, err := os.OpenFile(path, os.O_WRONLY|os.O_SYNC, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, cid.Undef, xerrors.Errorf("error opening checkpoint for writing: %w", err)
|
||||||
|
}
|
||||||
|
bufout := bufio.NewWriter(fileout)
|
||||||
|
|
||||||
|
return &Checkpoint{
|
||||||
|
file: fileout,
|
||||||
|
buf: bufout,
|
||||||
|
}, start, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *Checkpoint) Set(c cid.Cid) error {
|
||||||
|
if _, err := cp.file.Seek(0, io.SeekStart); err != nil {
|
||||||
|
return xerrors.Errorf("error seeking beginning of checkpoint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeRawCid(cp.buf, c, true); err != nil {
|
||||||
|
return xerrors.Errorf("error writing cid to checkpoint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *Checkpoint) Close() error {
|
||||||
|
if cp.file == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := cp.file.Close()
|
||||||
|
cp.file = nil
|
||||||
|
cp.buf = nil
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRawCid(buf *bufio.Reader, hbuf []byte) (cid.Cid, error) {
|
||||||
|
sz, err := buf.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err // don't wrap EOF as it is not an error here
|
||||||
|
}
|
||||||
|
|
||||||
|
if hbuf == nil {
|
||||||
|
hbuf = make([]byte, int(sz))
|
||||||
|
} else {
|
||||||
|
hbuf = hbuf[:int(sz)]
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.ReadFull(buf, hbuf); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("error reading hash: %w", err) // wrap EOF, it's corrupt
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := mh.Cast(hbuf)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("error casting multihash: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.NewCidV1(cid.Raw, hash), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeRawCid(buf *bufio.Writer, c cid.Cid, flush bool) error {
|
||||||
|
hash := c.Hash()
|
||||||
|
if err := buf.WriteByte(byte(len(hash))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := buf.Write(hash); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if flush {
|
||||||
|
return buf.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package splitstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/multiformats/go-multihash"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCheckpoint(t *testing.T) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
|
||||||
|
path := filepath.Join(dir, "checkpoint")
|
||||||
|
|
||||||
|
makeCid := func(key string) cid.Cid {
|
||||||
|
h, err := multihash.Sum([]byte(key), multihash.SHA2_256, -1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.NewCidV1(cid.Raw, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
k1 := makeCid("a")
|
||||||
|
k2 := makeCid("b")
|
||||||
|
k3 := makeCid("c")
|
||||||
|
k4 := makeCid("d")
|
||||||
|
|
||||||
|
cp, err := NewCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Set(k1); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := cp.Set(k2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cp, start, err := OpenCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !start.Equals(k2) {
|
||||||
|
t.Fatalf("expected start to be %s; got %s", k2, start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Set(k3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := cp.Set(k4); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cp, start, err = OpenCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !start.Equals(k4) {
|
||||||
|
t.Fatalf("expected start to be %s; got %s", k4, start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// also test correct operation with an empty checkpoint
|
||||||
|
cp, err = NewCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cp, start, err = OpenCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if start.Defined() {
|
||||||
|
t.Fatal("expected start to be undefined")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Set(k1); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := cp.Set(k2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cp, start, err = OpenCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !start.Equals(k2) {
|
||||||
|
t.Fatalf("expected start to be %s; got %s", k2, start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Set(k3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := cp.Set(k4); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cp, start, err = OpenCheckpoint(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !start.Equals(k4) {
|
||||||
|
t.Fatalf("expected start to be %s; got %s", k4, start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cp.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package splitstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
cid "github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ColdSetWriter struct {
|
||||||
|
file *os.File
|
||||||
|
buf *bufio.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColdSetReader struct {
|
||||||
|
file *os.File
|
||||||
|
buf *bufio.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewColdSetWriter(path string) (*ColdSetWriter, error) {
|
||||||
|
file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error creating coldset: %w", err)
|
||||||
|
}
|
||||||
|
buf := bufio.NewWriter(file)
|
||||||
|
|
||||||
|
return &ColdSetWriter{
|
||||||
|
file: file,
|
||||||
|
buf: buf,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewColdSetReader(path string) (*ColdSetReader, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error opening coldset: %w", err)
|
||||||
|
}
|
||||||
|
buf := bufio.NewReader(file)
|
||||||
|
|
||||||
|
return &ColdSetReader{
|
||||||
|
file: file,
|
||||||
|
buf: buf,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ColdSetWriter) Write(c cid.Cid) error {
|
||||||
|
return writeRawCid(s.buf, c, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ColdSetWriter) Close() error {
|
||||||
|
if s.file == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err1 := s.buf.Flush()
|
||||||
|
err2 := s.file.Close()
|
||||||
|
s.buf = nil
|
||||||
|
s.file = nil
|
||||||
|
|
||||||
|
if err1 != nil {
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ColdSetReader) ForEach(f func(cid.Cid) error) error {
|
||||||
|
hbuf := make([]byte, 256)
|
||||||
|
for {
|
||||||
|
next, err := readRawCid(s.buf, hbuf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return xerrors.Errorf("error reading coldset: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := f(next); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ColdSetReader) Reset() error {
|
||||||
|
_, err := s.file.Seek(0, io.SeekStart)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ColdSetReader) Close() error {
|
||||||
|
if s.file == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := s.file.Close()
|
||||||
|
s.file = nil
|
||||||
|
s.buf = nil
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package splitstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/multiformats/go-multihash"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestColdSet(t *testing.T) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
|
||||||
|
path := filepath.Join(dir, "coldset")
|
||||||
|
|
||||||
|
makeCid := func(i int) cid.Cid {
|
||||||
|
h, err := multihash.Sum([]byte(fmt.Sprintf("cid.%d", i)), multihash.SHA2_256, -1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.NewCidV1(cid.Raw, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
const count = 1000
|
||||||
|
cids := make([]cid.Cid, 0, count)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
cids = append(cids, makeCid(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
cw, err := NewColdSetWriter(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cids {
|
||||||
|
if err := cw.Write(c); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cw.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cr, err := NewColdSetReader(path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
index := 0
|
||||||
|
err = cr.ForEach(func(c cid.Cid) error {
|
||||||
|
if index >= count {
|
||||||
|
t.Fatal("too many cids")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.Equals(cids[index]) {
|
||||||
|
t.Fatalf("wrong cid %d; expected %s but got %s", index, cids[index], c)
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cr.Reset(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
err = cr.ForEach(func(c cid.Cid) error {
|
||||||
|
if index >= count {
|
||||||
|
t.Fatal("too many cids")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.Equals(cids[index]) {
|
||||||
|
t.Fatalf("wrong cid; expected %s but got %s", cids[index], c)
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,39 +10,36 @@ import (
|
|||||||
|
|
||||||
var errMarkSetClosed = errors.New("markset closed")
|
var errMarkSetClosed = errors.New("markset closed")
|
||||||
|
|
||||||
// MarkSet is a utility to keep track of seen CID, and later query for them.
|
// MarkSet is an interface for tracking CIDs during chain and object walks
|
||||||
//
|
|
||||||
// * If the expected dataset is large, it can be backed by a datastore (e.g. bbolt).
|
|
||||||
// * If a probabilistic result is acceptable, it can be backed by a bloom filter
|
|
||||||
type MarkSet interface {
|
type MarkSet interface {
|
||||||
|
ObjectVisitor
|
||||||
Mark(cid.Cid) error
|
Mark(cid.Cid) error
|
||||||
|
MarkMany([]cid.Cid) error
|
||||||
Has(cid.Cid) (bool, error)
|
Has(cid.Cid) (bool, error)
|
||||||
Close() error
|
Close() error
|
||||||
SetConcurrent()
|
|
||||||
}
|
|
||||||
|
|
||||||
type MarkSetVisitor interface {
|
// BeginCriticalSection ensures that the markset is persisted to disk for recovery in case
|
||||||
MarkSet
|
// of abnormal termination during the critical section span.
|
||||||
ObjectVisitor
|
BeginCriticalSection() error
|
||||||
|
// EndCriticalSection ends the critical section span.
|
||||||
|
EndCriticalSection()
|
||||||
}
|
}
|
||||||
|
|
||||||
type MarkSetEnv interface {
|
type MarkSetEnv interface {
|
||||||
// Create creates a new markset within the environment.
|
// New creates a new markset within the environment.
|
||||||
// name is a unique name for this markset, mapped to the filesystem in disk-backed environments
|
// name is a unique name for this markset, mapped to the filesystem for on-disk persistence.
|
||||||
// sizeHint is a hint about the expected size of the markset
|
// sizeHint is a hint about the expected size of the markset
|
||||||
Create(name string, sizeHint int64) (MarkSet, error)
|
New(name string, sizeHint int64) (MarkSet, error)
|
||||||
// CreateVisitor is like Create, but returns a wider interface that supports atomic visits.
|
// Recover recovers an existing markset persisted on-disk.
|
||||||
// It may not be supported by some markset types (e.g. bloom).
|
Recover(name string) (MarkSet, error)
|
||||||
CreateVisitor(name string, sizeHint int64) (MarkSetVisitor, error)
|
// Close closes the markset
|
||||||
// SupportsVisitor returns true if the marksets created by this environment support the visitor interface.
|
|
||||||
SupportsVisitor() bool
|
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenMarkSetEnv(path string, mtype string) (MarkSetEnv, error) {
|
func OpenMarkSetEnv(path string, mtype string) (MarkSetEnv, error) {
|
||||||
switch mtype {
|
switch mtype {
|
||||||
case "map":
|
case "map":
|
||||||
return NewMapMarkSetEnv()
|
return NewMapMarkSetEnv(path)
|
||||||
case "badger":
|
case "badger":
|
||||||
return NewBadgerMarkSetEnv(path)
|
return NewBadgerMarkSetEnv(path)
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package splitstore
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@@ -28,13 +29,13 @@ type BadgerMarkSet struct {
|
|||||||
writers int
|
writers int
|
||||||
seqno int
|
seqno int
|
||||||
version int
|
version int
|
||||||
|
persist bool
|
||||||
|
|
||||||
db *badger.DB
|
db *badger.DB
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ MarkSet = (*BadgerMarkSet)(nil)
|
var _ MarkSet = (*BadgerMarkSet)(nil)
|
||||||
var _ MarkSetVisitor = (*BadgerMarkSet)(nil)
|
|
||||||
|
|
||||||
var badgerMarkSetBatchSize = 16384
|
var badgerMarkSetBatchSize = 16384
|
||||||
|
|
||||||
@@ -48,11 +49,10 @@ func NewBadgerMarkSetEnv(path string) (MarkSetEnv, error) {
|
|||||||
return &BadgerMarkSetEnv{path: msPath}, nil
|
return &BadgerMarkSetEnv{path: msPath}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *BadgerMarkSetEnv) create(name string, sizeHint int64) (*BadgerMarkSet, error) {
|
func (e *BadgerMarkSetEnv) New(name string, sizeHint int64) (MarkSet, error) {
|
||||||
name += ".tmp"
|
|
||||||
path := filepath.Join(e.path, name)
|
path := filepath.Join(e.path, name)
|
||||||
|
|
||||||
db, err := openTransientBadgerDB(path)
|
db, err := openBadgerDB(path, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("error creating badger db: %w", err)
|
return nil, xerrors.Errorf("error creating badger db: %w", err)
|
||||||
}
|
}
|
||||||
@@ -68,18 +68,72 @@ func (e *BadgerMarkSetEnv) create(name string, sizeHint int64) (*BadgerMarkSet,
|
|||||||
return ms, nil
|
return ms, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *BadgerMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
|
func (e *BadgerMarkSetEnv) Recover(name string) (MarkSet, error) {
|
||||||
return e.create(name, sizeHint)
|
path := filepath.Join(e.path, name)
|
||||||
}
|
|
||||||
|
|
||||||
func (e *BadgerMarkSetEnv) CreateVisitor(name string, sizeHint int64) (MarkSetVisitor, error) {
|
if _, err := os.Stat(path); err != nil {
|
||||||
return e.create(name, sizeHint)
|
return nil, xerrors.Errorf("error stating badger db path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *BadgerMarkSetEnv) SupportsVisitor() bool { return true }
|
db, err := openBadgerDB(path, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error creating badger db: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ms := &BadgerMarkSet{
|
||||||
|
pend: make(map[string]struct{}),
|
||||||
|
writing: make(map[int]map[string]struct{}),
|
||||||
|
db: db,
|
||||||
|
path: path,
|
||||||
|
persist: true,
|
||||||
|
}
|
||||||
|
ms.cond.L = &ms.mx
|
||||||
|
|
||||||
|
return ms, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *BadgerMarkSetEnv) Close() error {
|
func (e *BadgerMarkSetEnv) Close() error {
|
||||||
return os.RemoveAll(e.path)
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *BadgerMarkSet) BeginCriticalSection() error {
|
||||||
|
s.mx.Lock()
|
||||||
|
|
||||||
|
if s.persist {
|
||||||
|
s.mx.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var write bool
|
||||||
|
var seqno int
|
||||||
|
if len(s.pend) > 0 {
|
||||||
|
write = true
|
||||||
|
seqno = s.nextBatch()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.persist = true
|
||||||
|
s.mx.Unlock()
|
||||||
|
|
||||||
|
if write {
|
||||||
|
// all writes sync once perist is true
|
||||||
|
return s.write(seqno)
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for any pending writes and sync
|
||||||
|
s.mx.Lock()
|
||||||
|
for s.writers > 0 {
|
||||||
|
s.cond.Wait()
|
||||||
|
}
|
||||||
|
s.mx.Unlock()
|
||||||
|
|
||||||
|
return s.db.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *BadgerMarkSet) EndCriticalSection() {
|
||||||
|
s.mx.Lock()
|
||||||
|
defer s.mx.Unlock()
|
||||||
|
|
||||||
|
s.persist = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BadgerMarkSet) Mark(c cid.Cid) error {
|
func (s *BadgerMarkSet) Mark(c cid.Cid) error {
|
||||||
@@ -99,6 +153,23 @@ func (s *BadgerMarkSet) Mark(c cid.Cid) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *BadgerMarkSet) MarkMany(batch []cid.Cid) error {
|
||||||
|
s.mx.Lock()
|
||||||
|
if s.pend == nil {
|
||||||
|
s.mx.Unlock()
|
||||||
|
return errMarkSetClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
write, seqno := s.putMany(batch)
|
||||||
|
s.mx.Unlock()
|
||||||
|
|
||||||
|
if write {
|
||||||
|
return s.write(seqno)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *BadgerMarkSet) Has(c cid.Cid) (bool, error) {
|
func (s *BadgerMarkSet) Has(c cid.Cid) (bool, error) {
|
||||||
s.mx.RLock()
|
s.mx.RLock()
|
||||||
defer s.mx.RUnlock()
|
defer s.mx.RUnlock()
|
||||||
@@ -204,16 +275,34 @@ func (s *BadgerMarkSet) tryDB(key []byte) (has bool, err error) {
|
|||||||
// writer holds the exclusive lock
|
// writer holds the exclusive lock
|
||||||
func (s *BadgerMarkSet) put(key string) (write bool, seqno int) {
|
func (s *BadgerMarkSet) put(key string) (write bool, seqno int) {
|
||||||
s.pend[key] = struct{}{}
|
s.pend[key] = struct{}{}
|
||||||
if len(s.pend) < badgerMarkSetBatchSize {
|
if !s.persist && len(s.pend) < badgerMarkSetBatchSize {
|
||||||
return false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
seqno = s.seqno
|
seqno = s.nextBatch()
|
||||||
|
return true, seqno
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *BadgerMarkSet) putMany(batch []cid.Cid) (write bool, seqno int) {
|
||||||
|
for _, c := range batch {
|
||||||
|
key := string(c.Hash())
|
||||||
|
s.pend[key] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !s.persist && len(s.pend) < badgerMarkSetBatchSize {
|
||||||
|
return false, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
seqno = s.nextBatch()
|
||||||
|
return true, seqno
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *BadgerMarkSet) nextBatch() int {
|
||||||
|
seqno := s.seqno
|
||||||
s.seqno++
|
s.seqno++
|
||||||
s.writing[seqno] = s.pend
|
s.writing[seqno] = s.pend
|
||||||
s.pend = make(map[string]struct{})
|
s.pend = make(map[string]struct{})
|
||||||
|
return seqno
|
||||||
return true, seqno
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BadgerMarkSet) write(seqno int) (err error) {
|
func (s *BadgerMarkSet) write(seqno int) (err error) {
|
||||||
@@ -258,6 +347,14 @@ func (s *BadgerMarkSet) write(seqno int) (err error) {
|
|||||||
return xerrors.Errorf("error flushing batch to badger markset: %w", err)
|
return xerrors.Errorf("error flushing batch to badger markset: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.mx.RLock()
|
||||||
|
persist := s.persist
|
||||||
|
s.mx.RUnlock()
|
||||||
|
|
||||||
|
if persist {
|
||||||
|
return s.db.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,26 +374,29 @@ func (s *BadgerMarkSet) Close() error {
|
|||||||
db := s.db
|
db := s.db
|
||||||
s.db = nil
|
s.db = nil
|
||||||
|
|
||||||
return closeTransientBadgerDB(db, s.path)
|
return closeBadgerDB(db, s.path, s.persist)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BadgerMarkSet) SetConcurrent() {}
|
func openBadgerDB(path string, recover bool) (*badger.DB, error) {
|
||||||
|
// if it is not a recovery, clean up first
|
||||||
|
if !recover {
|
||||||
|
err := os.RemoveAll(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error clearing markset directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
func openTransientBadgerDB(path string) (*badger.DB, error) {
|
err = os.MkdirAll(path, 0755) //nolint:gosec
|
||||||
// clean up first
|
if err != nil {
|
||||||
err := os.RemoveAll(path)
|
return nil, xerrors.Errorf("error creating markset directory: %w", err)
|
||||||
if err != nil {
|
}
|
||||||
return nil, xerrors.Errorf("error clearing markset directory: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.MkdirAll(path, 0755) //nolint:gosec
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("error creating markset directory: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := badger.DefaultOptions(path)
|
opts := badger.DefaultOptions(path)
|
||||||
|
// we manually sync when we are in critical section
|
||||||
opts.SyncWrites = false
|
opts.SyncWrites = false
|
||||||
|
// no need to do that
|
||||||
opts.CompactL0OnClose = false
|
opts.CompactL0OnClose = false
|
||||||
|
// we store hashes, not much to gain by compression
|
||||||
opts.Compression = options.None
|
opts.Compression = options.None
|
||||||
// Note: We use FileIO for loading modes to avoid memory thrashing and interference
|
// Note: We use FileIO for loading modes to avoid memory thrashing and interference
|
||||||
// between the system blockstore and the markset.
|
// between the system blockstore and the markset.
|
||||||
@@ -305,6 +405,15 @@ func openTransientBadgerDB(path string) (*badger.DB, error) {
|
|||||||
// exceeded 1GB in size.
|
// exceeded 1GB in size.
|
||||||
opts.TableLoadingMode = options.FileIO
|
opts.TableLoadingMode = options.FileIO
|
||||||
opts.ValueLogLoadingMode = options.FileIO
|
opts.ValueLogLoadingMode = options.FileIO
|
||||||
|
// We increase the number of L0 tables before compaction to make it unlikely to
|
||||||
|
// be necessary.
|
||||||
|
opts.NumLevelZeroTables = 20 // default is 5
|
||||||
|
opts.NumLevelZeroTablesStall = 30 // default is 10
|
||||||
|
// increase the number of compactors from default 2 so that if we ever have to
|
||||||
|
// compact, it is fast
|
||||||
|
if runtime.NumCPU()/2 > opts.NumCompactors {
|
||||||
|
opts.NumCompactors = runtime.NumCPU() / 2
|
||||||
|
}
|
||||||
opts.Logger = &badgerLogger{
|
opts.Logger = &badgerLogger{
|
||||||
SugaredLogger: log.Desugar().WithOptions(zap.AddCallerSkip(1)).Sugar(),
|
SugaredLogger: log.Desugar().WithOptions(zap.AddCallerSkip(1)).Sugar(),
|
||||||
skip2: log.Desugar().WithOptions(zap.AddCallerSkip(2)).Sugar(),
|
skip2: log.Desugar().WithOptions(zap.AddCallerSkip(2)).Sugar(),
|
||||||
@@ -313,12 +422,16 @@ func openTransientBadgerDB(path string) (*badger.DB, error) {
|
|||||||
return badger.Open(opts)
|
return badger.Open(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeTransientBadgerDB(db *badger.DB, path string) error {
|
func closeBadgerDB(db *badger.DB, path string, persist bool) error {
|
||||||
err := db.Close()
|
err := db.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error closing badger markset: %w", err)
|
return xerrors.Errorf("error closing badger markset: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if persist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
err = os.RemoveAll(path)
|
err = os.RemoveAll(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error deleting badger markset: %w", err)
|
return xerrors.Errorf("error deleting badger markset: %w", err)
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
package splitstore
|
package splitstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MapMarkSetEnv struct{}
|
type MapMarkSetEnv struct {
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
var _ MarkSetEnv = (*MapMarkSetEnv)(nil)
|
var _ MarkSetEnv = (*MapMarkSetEnv)(nil)
|
||||||
|
|
||||||
@@ -14,55 +22,194 @@ type MapMarkSet struct {
|
|||||||
mx sync.RWMutex
|
mx sync.RWMutex
|
||||||
set map[string]struct{}
|
set map[string]struct{}
|
||||||
|
|
||||||
ts bool
|
persist bool
|
||||||
|
file *os.File
|
||||||
|
buf *bufio.Writer
|
||||||
|
|
||||||
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ MarkSet = (*MapMarkSet)(nil)
|
var _ MarkSet = (*MapMarkSet)(nil)
|
||||||
var _ MarkSetVisitor = (*MapMarkSet)(nil)
|
|
||||||
|
|
||||||
func NewMapMarkSetEnv() (*MapMarkSetEnv, error) {
|
func NewMapMarkSetEnv(path string) (*MapMarkSetEnv, error) {
|
||||||
return &MapMarkSetEnv{}, nil
|
msPath := filepath.Join(path, "markset.map")
|
||||||
|
err := os.MkdirAll(msPath, 0755) //nolint:gosec
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error creating markset directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &MapMarkSetEnv{path: msPath}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *MapMarkSetEnv) create(name string, sizeHint int64) (*MapMarkSet, error) {
|
func (e *MapMarkSetEnv) New(name string, sizeHint int64) (MarkSet, error) {
|
||||||
|
path := filepath.Join(e.path, name)
|
||||||
return &MapMarkSet{
|
return &MapMarkSet{
|
||||||
set: make(map[string]struct{}, sizeHint),
|
set: make(map[string]struct{}, sizeHint),
|
||||||
|
path: path,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *MapMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
|
func (e *MapMarkSetEnv) Recover(name string) (MarkSet, error) {
|
||||||
return e.create(name, sizeHint)
|
path := filepath.Join(e.path, name)
|
||||||
}
|
s := &MapMarkSet{
|
||||||
|
set: make(map[string]struct{}),
|
||||||
|
path: path,
|
||||||
|
}
|
||||||
|
|
||||||
func (e *MapMarkSetEnv) CreateVisitor(name string, sizeHint int64) (MarkSetVisitor, error) {
|
in, err := os.Open(path)
|
||||||
return e.create(name, sizeHint)
|
if err != nil {
|
||||||
}
|
return nil, xerrors.Errorf("error opening markset file for read: %w", err)
|
||||||
|
}
|
||||||
|
defer in.Close() //nolint:errcheck
|
||||||
|
|
||||||
func (e *MapMarkSetEnv) SupportsVisitor() bool { return true }
|
// wrap a buffered reader to make this faster
|
||||||
|
buf := bufio.NewReader(in)
|
||||||
|
for {
|
||||||
|
var sz byte
|
||||||
|
if sz, err = buf.ReadByte(); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
key := make([]byte, int(sz))
|
||||||
|
if _, err = io.ReadFull(buf, key); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
s.set[string(key)] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != io.EOF {
|
||||||
|
return nil, xerrors.Errorf("error reading markset file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.OpenFile(s.path, os.O_WRONLY|os.O_APPEND, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("error opening markset file for write: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.persist = true
|
||||||
|
s.file = file
|
||||||
|
s.buf = bufio.NewWriter(file)
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *MapMarkSetEnv) Close() error {
|
func (e *MapMarkSetEnv) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MapMarkSet) Mark(cid cid.Cid) error {
|
func (s *MapMarkSet) BeginCriticalSection() error {
|
||||||
if s.ts {
|
s.mx.Lock()
|
||||||
s.mx.Lock()
|
defer s.mx.Unlock()
|
||||||
defer s.mx.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.set == nil {
|
if s.set == nil {
|
||||||
return errMarkSetClosed
|
return errMarkSetClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
s.set[string(cid.Hash())] = struct{}{}
|
if s.persist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.OpenFile(s.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error opening markset file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap a buffered writer to make this faster
|
||||||
|
s.buf = bufio.NewWriter(file)
|
||||||
|
for key := range s.set {
|
||||||
|
if err := s.writeKey([]byte(key), false); err != nil {
|
||||||
|
_ = file.Close()
|
||||||
|
s.buf = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := s.buf.Flush(); err != nil {
|
||||||
|
_ = file.Close()
|
||||||
|
s.buf = nil
|
||||||
|
return xerrors.Errorf("error flushing markset file buffer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.file = file
|
||||||
|
s.persist = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MapMarkSet) EndCriticalSection() {
|
||||||
|
s.mx.Lock()
|
||||||
|
defer s.mx.Unlock()
|
||||||
|
|
||||||
|
if !s.persist {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = s.file.Close()
|
||||||
|
_ = os.Remove(s.path)
|
||||||
|
s.file = nil
|
||||||
|
s.buf = nil
|
||||||
|
s.persist = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MapMarkSet) Mark(c cid.Cid) error {
|
||||||
|
s.mx.Lock()
|
||||||
|
defer s.mx.Unlock()
|
||||||
|
|
||||||
|
if s.set == nil {
|
||||||
|
return errMarkSetClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := c.Hash()
|
||||||
|
s.set[string(hash)] = struct{}{}
|
||||||
|
|
||||||
|
if s.persist {
|
||||||
|
if err := s.writeKey(hash, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.file.Sync(); err != nil {
|
||||||
|
return xerrors.Errorf("error syncing markset: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MapMarkSet) MarkMany(batch []cid.Cid) error {
|
||||||
|
s.mx.Lock()
|
||||||
|
defer s.mx.Unlock()
|
||||||
|
|
||||||
|
if s.set == nil {
|
||||||
|
return errMarkSetClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range batch {
|
||||||
|
hash := c.Hash()
|
||||||
|
s.set[string(hash)] = struct{}{}
|
||||||
|
|
||||||
|
if s.persist {
|
||||||
|
if err := s.writeKey(hash, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.persist {
|
||||||
|
if err := s.buf.Flush(); err != nil {
|
||||||
|
return xerrors.Errorf("error flushing markset buffer to disk: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.file.Sync(); err != nil {
|
||||||
|
return xerrors.Errorf("error syncing markset: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MapMarkSet) Has(cid cid.Cid) (bool, error) {
|
func (s *MapMarkSet) Has(cid cid.Cid) (bool, error) {
|
||||||
if s.ts {
|
s.mx.RLock()
|
||||||
s.mx.RLock()
|
defer s.mx.RUnlock()
|
||||||
defer s.mx.RUnlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.set == nil {
|
if s.set == nil {
|
||||||
return false, errMarkSetClosed
|
return false, errMarkSetClosed
|
||||||
@@ -73,33 +220,70 @@ func (s *MapMarkSet) Has(cid cid.Cid) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *MapMarkSet) Visit(c cid.Cid) (bool, error) {
|
func (s *MapMarkSet) Visit(c cid.Cid) (bool, error) {
|
||||||
if s.ts {
|
s.mx.Lock()
|
||||||
s.mx.Lock()
|
defer s.mx.Unlock()
|
||||||
defer s.mx.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.set == nil {
|
if s.set == nil {
|
||||||
return false, errMarkSetClosed
|
return false, errMarkSetClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
key := string(c.Hash())
|
hash := c.Hash()
|
||||||
|
key := string(hash)
|
||||||
if _, ok := s.set[key]; ok {
|
if _, ok := s.set[key]; ok {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.set[key] = struct{}{}
|
s.set[key] = struct{}{}
|
||||||
|
|
||||||
|
if s.persist {
|
||||||
|
if err := s.writeKey(hash, true); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if err := s.file.Sync(); err != nil {
|
||||||
|
return false, xerrors.Errorf("error syncing markset: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MapMarkSet) Close() error {
|
func (s *MapMarkSet) Close() error {
|
||||||
if s.ts {
|
s.mx.Lock()
|
||||||
s.mx.Lock()
|
defer s.mx.Unlock()
|
||||||
defer s.mx.Unlock()
|
|
||||||
|
if s.set == nil {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.set = nil
|
s.set = nil
|
||||||
|
|
||||||
|
if s.file != nil {
|
||||||
|
if err := s.file.Close(); err != nil {
|
||||||
|
log.Warnf("error closing markset file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !s.persist {
|
||||||
|
if err := os.Remove(s.path); err != nil {
|
||||||
|
log.Warnf("error removing markset file: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MapMarkSet) SetConcurrent() {
|
func (s *MapMarkSet) writeKey(k []byte, flush bool) error {
|
||||||
s.ts = true
|
if err := s.buf.WriteByte(byte(len(k))); err != nil {
|
||||||
|
return xerrors.Errorf("error writing markset key length to disk: %w", err)
|
||||||
|
}
|
||||||
|
if _, err := s.buf.Write(k); err != nil {
|
||||||
|
return xerrors.Errorf("error writing markset key to disk: %w", err)
|
||||||
|
}
|
||||||
|
if flush {
|
||||||
|
if err := s.buf.Flush(); err != nil {
|
||||||
|
return xerrors.Errorf("error flushing markset buffer to disk: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
//stm: #unit
|
||||||
package splitstore
|
package splitstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
@@ -10,31 +9,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMapMarkSet(t *testing.T) {
|
func TestMapMarkSet(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_MARKSET_CREATE_001, @SPLITSTORE_MARKSET_HAS_001, @@SPLITSTORE_MARKSET_MARK_001
|
||||||
|
//stm: @SPLITSTORE_MARKSET_CLOSE_001, @SPLITSTORE_MARKSET_CREATE_VISITOR_001
|
||||||
testMarkSet(t, "map")
|
testMarkSet(t, "map")
|
||||||
|
testMarkSetRecovery(t, "map")
|
||||||
|
testMarkSetMarkMany(t, "map")
|
||||||
testMarkSetVisitor(t, "map")
|
testMarkSetVisitor(t, "map")
|
||||||
|
testMarkSetVisitorRecovery(t, "map")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBadgerMarkSet(t *testing.T) {
|
func TestBadgerMarkSet(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_MARKSET_CREATE_001, @SPLITSTORE_MARKSET_HAS_001, @@SPLITSTORE_MARKSET_MARK_001
|
||||||
|
//stm: @SPLITSTORE_MARKSET_CLOSE_001, @SPLITSTORE_MARKSET_CREATE_VISITOR_001
|
||||||
bs := badgerMarkSetBatchSize
|
bs := badgerMarkSetBatchSize
|
||||||
badgerMarkSetBatchSize = 1
|
badgerMarkSetBatchSize = 1
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
badgerMarkSetBatchSize = bs
|
badgerMarkSetBatchSize = bs
|
||||||
})
|
})
|
||||||
testMarkSet(t, "badger")
|
testMarkSet(t, "badger")
|
||||||
|
testMarkSetRecovery(t, "badger")
|
||||||
|
testMarkSetMarkMany(t, "badger")
|
||||||
testMarkSetVisitor(t, "badger")
|
testMarkSetVisitor(t, "badger")
|
||||||
|
testMarkSetVisitorRecovery(t, "badger")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMarkSet(t *testing.T, lsType string) {
|
func testMarkSet(t *testing.T, lsType string) {
|
||||||
t.Helper()
|
path := t.TempDir()
|
||||||
|
|
||||||
path, err := ioutil.TempDir("", "markset.*")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.RemoveAll(path)
|
|
||||||
})
|
|
||||||
|
|
||||||
env, err := OpenMarkSetEnv(path, lsType)
|
env, err := OpenMarkSetEnv(path, lsType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -42,12 +42,13 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
}
|
}
|
||||||
defer env.Close() //nolint:errcheck
|
defer env.Close() //nolint:errcheck
|
||||||
|
|
||||||
hotSet, err := env.Create("hot", 0)
|
// stm: @SPLITSTORE_MARKSET_CREATE_001
|
||||||
|
hotSet, err := env.New("hot", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
coldSet, err := env.Create("cold", 0)
|
coldSet, err := env.New("cold", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -61,7 +62,9 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
return cid.NewCidV1(cid.Raw, h)
|
return cid.NewCidV1(cid.Raw, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stm: @SPLITSTORE_MARKSET_HAS_001
|
||||||
mustHave := func(s MarkSet, cid cid.Cid) {
|
mustHave := func(s MarkSet, cid cid.Cid) {
|
||||||
|
t.Helper()
|
||||||
has, err := s.Has(cid)
|
has, err := s.Has(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -73,6 +76,7 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mustNotHave := func(s MarkSet, cid cid.Cid) {
|
mustNotHave := func(s MarkSet, cid cid.Cid) {
|
||||||
|
t.Helper()
|
||||||
has, err := s.Has(cid)
|
has, err := s.Has(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -88,6 +92,7 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
k3 := makeCid("c")
|
k3 := makeCid("c")
|
||||||
k4 := makeCid("d")
|
k4 := makeCid("d")
|
||||||
|
|
||||||
|
// stm: @SPLITSTORE_MARKSET_MARK_001
|
||||||
hotSet.Mark(k1) //nolint
|
hotSet.Mark(k1) //nolint
|
||||||
hotSet.Mark(k2) //nolint
|
hotSet.Mark(k2) //nolint
|
||||||
coldSet.Mark(k3) //nolint
|
coldSet.Mark(k3) //nolint
|
||||||
@@ -114,12 +119,12 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hotSet, err = env.Create("hot", 0)
|
hotSet, err = env.New("hot", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
coldSet, err = env.Create("cold", 0)
|
coldSet, err = env.New("cold", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -138,6 +143,7 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
mustNotHave(coldSet, k3)
|
mustNotHave(coldSet, k3)
|
||||||
mustNotHave(coldSet, k4)
|
mustNotHave(coldSet, k4)
|
||||||
|
|
||||||
|
//stm: @SPLITSTORE_MARKSET_CLOSE_001
|
||||||
err = hotSet.Close()
|
err = hotSet.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -150,16 +156,7 @@ func testMarkSet(t *testing.T, lsType string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testMarkSetVisitor(t *testing.T, lsType string) {
|
func testMarkSetVisitor(t *testing.T, lsType string) {
|
||||||
t.Helper()
|
path := t.TempDir()
|
||||||
|
|
||||||
path, err := ioutil.TempDir("", "markset.*")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Cleanup(func() {
|
|
||||||
_ = os.RemoveAll(path)
|
|
||||||
})
|
|
||||||
|
|
||||||
env, err := OpenMarkSetEnv(path, lsType)
|
env, err := OpenMarkSetEnv(path, lsType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -167,7 +164,8 @@ func testMarkSetVisitor(t *testing.T, lsType string) {
|
|||||||
}
|
}
|
||||||
defer env.Close() //nolint:errcheck
|
defer env.Close() //nolint:errcheck
|
||||||
|
|
||||||
visitor, err := env.CreateVisitor("test", 0)
|
//stm: @SPLITSTORE_MARKSET_CREATE_VISITOR_001
|
||||||
|
visitor, err := env.New("test", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -219,3 +217,301 @@ func testMarkSetVisitor(t *testing.T, lsType string) {
|
|||||||
mustNotVisit(visitor, k3)
|
mustNotVisit(visitor, k3)
|
||||||
mustNotVisit(visitor, k4)
|
mustNotVisit(visitor, k4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testMarkSetVisitorRecovery(t *testing.T, lsType string) {
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
|
env, err := OpenMarkSetEnv(path, lsType)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer env.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
visitor, err := env.New("test", 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer visitor.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
makeCid := func(key string) cid.Cid {
|
||||||
|
h, err := multihash.Sum([]byte(key), multihash.SHA2_256, -1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.NewCidV1(cid.Raw, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustVisit := func(v ObjectVisitor, cid cid.Cid) {
|
||||||
|
visit, err := v.Visit(cid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !visit {
|
||||||
|
t.Fatal("object should be visited")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mustNotVisit := func(v ObjectVisitor, cid cid.Cid) {
|
||||||
|
visit, err := v.Visit(cid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if visit {
|
||||||
|
t.Fatal("unexpected visit")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k1 := makeCid("a")
|
||||||
|
k2 := makeCid("b")
|
||||||
|
k3 := makeCid("c")
|
||||||
|
k4 := makeCid("d")
|
||||||
|
|
||||||
|
mustVisit(visitor, k1)
|
||||||
|
mustVisit(visitor, k2)
|
||||||
|
|
||||||
|
if err := visitor.BeginCriticalSection(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustVisit(visitor, k3)
|
||||||
|
mustVisit(visitor, k4)
|
||||||
|
|
||||||
|
mustNotVisit(visitor, k1)
|
||||||
|
mustNotVisit(visitor, k2)
|
||||||
|
mustNotVisit(visitor, k3)
|
||||||
|
mustNotVisit(visitor, k4)
|
||||||
|
|
||||||
|
if err := visitor.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
visitor, err = env.Recover("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustNotVisit(visitor, k1)
|
||||||
|
mustNotVisit(visitor, k2)
|
||||||
|
mustNotVisit(visitor, k3)
|
||||||
|
mustNotVisit(visitor, k4)
|
||||||
|
|
||||||
|
visitor.EndCriticalSection()
|
||||||
|
|
||||||
|
if err := visitor.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = env.Recover("test")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected recovery to fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMarkSetRecovery(t *testing.T, lsType string) {
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
|
env, err := OpenMarkSetEnv(path, lsType)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer env.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
markSet, err := env.New("test", 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
makeCid := func(key string) cid.Cid {
|
||||||
|
h, err := multihash.Sum([]byte(key), multihash.SHA2_256, -1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.NewCidV1(cid.Raw, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave := func(s MarkSet, cid cid.Cid) {
|
||||||
|
t.Helper()
|
||||||
|
has, err := s.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has {
|
||||||
|
t.Fatal("mark not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mustNotHave := func(s MarkSet, cid cid.Cid) {
|
||||||
|
t.Helper()
|
||||||
|
has, err := s.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
t.Fatal("unexpected mark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k1 := makeCid("a")
|
||||||
|
k2 := makeCid("b")
|
||||||
|
k3 := makeCid("c")
|
||||||
|
k4 := makeCid("d")
|
||||||
|
|
||||||
|
if err := markSet.Mark(k1); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := markSet.Mark(k2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave(markSet, k1)
|
||||||
|
mustHave(markSet, k2)
|
||||||
|
mustNotHave(markSet, k3)
|
||||||
|
mustNotHave(markSet, k4)
|
||||||
|
|
||||||
|
if err := markSet.BeginCriticalSection(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := markSet.Mark(k3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := markSet.Mark(k4); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave(markSet, k1)
|
||||||
|
mustHave(markSet, k2)
|
||||||
|
mustHave(markSet, k3)
|
||||||
|
mustHave(markSet, k4)
|
||||||
|
|
||||||
|
if err := markSet.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
markSet, err = env.Recover("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave(markSet, k1)
|
||||||
|
mustHave(markSet, k2)
|
||||||
|
mustHave(markSet, k3)
|
||||||
|
mustHave(markSet, k4)
|
||||||
|
|
||||||
|
markSet.EndCriticalSection()
|
||||||
|
|
||||||
|
if err := markSet.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = env.Recover("test")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected recovery to fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMarkSetMarkMany(t *testing.T, lsType string) {
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
|
env, err := OpenMarkSetEnv(path, lsType)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer env.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
markSet, err := env.New("test", 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
makeCid := func(key string) cid.Cid {
|
||||||
|
h, err := multihash.Sum([]byte(key), multihash.SHA2_256, -1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.NewCidV1(cid.Raw, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave := func(s MarkSet, cid cid.Cid) {
|
||||||
|
t.Helper()
|
||||||
|
has, err := s.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has {
|
||||||
|
t.Fatal("mark not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mustNotHave := func(s MarkSet, cid cid.Cid) {
|
||||||
|
t.Helper()
|
||||||
|
has, err := s.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
t.Fatal("unexpected mark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k1 := makeCid("a")
|
||||||
|
k2 := makeCid("b")
|
||||||
|
k3 := makeCid("c")
|
||||||
|
k4 := makeCid("d")
|
||||||
|
|
||||||
|
if err := markSet.MarkMany([]cid.Cid{k1, k2}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave(markSet, k1)
|
||||||
|
mustHave(markSet, k2)
|
||||||
|
mustNotHave(markSet, k3)
|
||||||
|
mustNotHave(markSet, k4)
|
||||||
|
|
||||||
|
if err := markSet.BeginCriticalSection(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := markSet.MarkMany([]cid.Cid{k3, k4}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave(markSet, k1)
|
||||||
|
mustHave(markSet, k2)
|
||||||
|
mustHave(markSet, k3)
|
||||||
|
mustHave(markSet, k4)
|
||||||
|
|
||||||
|
if err := markSet.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
markSet, err = env.Recover("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mustHave(markSet, k1)
|
||||||
|
mustHave(markSet, k2)
|
||||||
|
mustHave(markSet, k3)
|
||||||
|
mustHave(markSet, k4)
|
||||||
|
|
||||||
|
markSet.EndCriticalSection()
|
||||||
|
|
||||||
|
if err := markSet.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = env.Recover("test")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected recovery to fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -129,8 +129,6 @@ type SplitStore struct {
|
|||||||
|
|
||||||
headChangeMx sync.Mutex
|
headChangeMx sync.Mutex
|
||||||
|
|
||||||
coldPurgeSize int
|
|
||||||
|
|
||||||
chain ChainAccessor
|
chain ChainAccessor
|
||||||
ds dstore.Datastore
|
ds dstore.Datastore
|
||||||
cold bstore.Blockstore
|
cold bstore.Blockstore
|
||||||
@@ -158,6 +156,17 @@ type SplitStore struct {
|
|||||||
txnRefsMx sync.Mutex
|
txnRefsMx sync.Mutex
|
||||||
txnRefs map[cid.Cid]struct{}
|
txnRefs map[cid.Cid]struct{}
|
||||||
txnMissing map[cid.Cid]struct{}
|
txnMissing map[cid.Cid]struct{}
|
||||||
|
txnMarkSet MarkSet
|
||||||
|
txnSyncMx sync.Mutex
|
||||||
|
txnSyncCond sync.Cond
|
||||||
|
txnSync bool
|
||||||
|
|
||||||
|
// background cold object reification
|
||||||
|
reifyWorkers sync.WaitGroup
|
||||||
|
reifyMx sync.Mutex
|
||||||
|
reifyCond sync.Cond
|
||||||
|
reifyPend map[cid.Cid]struct{}
|
||||||
|
reifyInProgress map[cid.Cid]struct{}
|
||||||
|
|
||||||
// registered protectors
|
// registered protectors
|
||||||
protectors []func(func(cid.Cid) error) error
|
protectors []func(func(cid.Cid) error) error
|
||||||
@@ -186,10 +195,6 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !markSetEnv.SupportsVisitor() {
|
|
||||||
return nil, xerrors.Errorf("markset type does not support atomic visitors")
|
|
||||||
}
|
|
||||||
|
|
||||||
// and now we can make a SplitStore
|
// and now we can make a SplitStore
|
||||||
ss := &SplitStore{
|
ss := &SplitStore{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
@@ -198,13 +203,16 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co
|
|||||||
cold: cold,
|
cold: cold,
|
||||||
hot: hots,
|
hot: hots,
|
||||||
markSetEnv: markSetEnv,
|
markSetEnv: markSetEnv,
|
||||||
|
|
||||||
coldPurgeSize: defaultColdPurgeSize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.txnViewsCond.L = &ss.txnViewsMx
|
ss.txnViewsCond.L = &ss.txnViewsMx
|
||||||
|
ss.txnSyncCond.L = &ss.txnSyncMx
|
||||||
ss.ctx, ss.cancel = context.WithCancel(context.Background())
|
ss.ctx, ss.cancel = context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
ss.reifyCond.L = &ss.reifyMx
|
||||||
|
ss.reifyPend = make(map[cid.Cid]struct{})
|
||||||
|
ss.reifyInProgress = make(map[cid.Cid]struct{})
|
||||||
|
|
||||||
if enableDebugLog {
|
if enableDebugLog {
|
||||||
ss.debug, err = openDebugLog(path)
|
ss.debug, err = openDebugLog(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -212,21 +220,29 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ss.checkpointExists() {
|
||||||
|
log.Info("found compaction checkpoint; resuming compaction")
|
||||||
|
if err := ss.completeCompaction(); err != nil {
|
||||||
|
markSetEnv.Close() //nolint:errcheck
|
||||||
|
return nil, xerrors.Errorf("error resuming compaction: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ss, nil
|
return ss, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blockstore interface
|
// Blockstore interface
|
||||||
func (s *SplitStore) DeleteBlock(_ cid.Cid) error {
|
func (s *SplitStore) DeleteBlock(_ context.Context, _ cid.Cid) error {
|
||||||
// afaict we don't seem to be using this method, so it's not implemented
|
// afaict we don't seem to be using this method, so it's not implemented
|
||||||
return errors.New("DeleteBlock not implemented on SplitStore; don't do this Luke!") //nolint
|
return errors.New("DeleteBlock not implemented on SplitStore; don't do this Luke!") //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) DeleteMany(_ []cid.Cid) error {
|
func (s *SplitStore) DeleteMany(_ context.Context, _ []cid.Cid) error {
|
||||||
// afaict we don't seem to be using this method, so it's not implemented
|
// afaict we don't seem to be using this method, so it's not implemented
|
||||||
return errors.New("DeleteMany not implemented on SplitStore; don't do this Luke!") //nolint
|
return errors.New("DeleteMany not implemented on SplitStore; don't do this Luke!") //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) Has(cid cid.Cid) (bool, error) {
|
func (s *SplitStore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
|
||||||
if isIdentiyCid(cid) {
|
if isIdentiyCid(cid) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
@@ -234,7 +250,21 @@ func (s *SplitStore) Has(cid cid.Cid) (bool, error) {
|
|||||||
s.txnLk.RLock()
|
s.txnLk.RLock()
|
||||||
defer s.txnLk.RUnlock()
|
defer s.txnLk.RUnlock()
|
||||||
|
|
||||||
has, err := s.hot.Has(cid)
|
// critical section
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
has, err := s.txnMarkSet.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
return s.has(cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.cold.Has(ctx, cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
has, err := s.hot.Has(ctx, cid)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return has, err
|
return has, err
|
||||||
@@ -245,10 +275,16 @@ func (s *SplitStore) Has(cid cid.Cid) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.cold.Has(cid)
|
has, err = s.cold.Has(ctx, cid)
|
||||||
|
if has && bstore.IsHotView(ctx) {
|
||||||
|
s.reifyColdObject(cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return has, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) Get(cid cid.Cid) (blocks.Block, error) {
|
func (s *SplitStore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
|
||||||
if isIdentiyCid(cid) {
|
if isIdentiyCid(cid) {
|
||||||
data, err := decodeIdentityCid(cid)
|
data, err := decodeIdentityCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -261,7 +297,21 @@ func (s *SplitStore) Get(cid cid.Cid) (blocks.Block, error) {
|
|||||||
s.txnLk.RLock()
|
s.txnLk.RLock()
|
||||||
defer s.txnLk.RUnlock()
|
defer s.txnLk.RUnlock()
|
||||||
|
|
||||||
blk, err := s.hot.Get(cid)
|
// critical section
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
has, err := s.txnMarkSet.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
return s.get(cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.cold.Get(ctx, cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
blk, err := s.hot.Get(ctx, cid)
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
@@ -273,10 +323,13 @@ func (s *SplitStore) Get(cid cid.Cid) (blocks.Block, error) {
|
|||||||
s.debug.LogReadMiss(cid)
|
s.debug.LogReadMiss(cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
blk, err = s.cold.Get(cid)
|
blk, err = s.cold.Get(ctx, cid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
|
if bstore.IsHotView(ctx) {
|
||||||
|
s.reifyColdObject(cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
|
||||||
}
|
}
|
||||||
return blk, err
|
return blk, err
|
||||||
|
|
||||||
@@ -285,7 +338,7 @@ func (s *SplitStore) Get(cid cid.Cid) (blocks.Block, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) GetSize(cid cid.Cid) (int, error) {
|
func (s *SplitStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
|
||||||
if isIdentiyCid(cid) {
|
if isIdentiyCid(cid) {
|
||||||
data, err := decodeIdentityCid(cid)
|
data, err := decodeIdentityCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -298,7 +351,21 @@ func (s *SplitStore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
s.txnLk.RLock()
|
s.txnLk.RLock()
|
||||||
defer s.txnLk.RUnlock()
|
defer s.txnLk.RUnlock()
|
||||||
|
|
||||||
size, err := s.hot.GetSize(cid)
|
// critical section
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
has, err := s.txnMarkSet.Has(cid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
return s.getSize(cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.cold.GetSize(ctx, cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
size, err := s.hot.GetSize(ctx, cid)
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
@@ -310,8 +377,12 @@ func (s *SplitStore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
s.debug.LogReadMiss(cid)
|
s.debug.LogReadMiss(cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
size, err = s.cold.GetSize(cid)
|
size, err = s.cold.GetSize(ctx, cid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
if bstore.IsHotView(ctx) {
|
||||||
|
s.reifyColdObject(cid)
|
||||||
|
}
|
||||||
|
|
||||||
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
|
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
|
||||||
}
|
}
|
||||||
return size, err
|
return size, err
|
||||||
@@ -321,7 +392,7 @@ func (s *SplitStore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) Put(blk blocks.Block) error {
|
func (s *SplitStore) Put(ctx context.Context, blk blocks.Block) error {
|
||||||
if isIdentiyCid(blk.Cid()) {
|
if isIdentiyCid(blk.Cid()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -329,18 +400,24 @@ func (s *SplitStore) Put(blk blocks.Block) error {
|
|||||||
s.txnLk.RLock()
|
s.txnLk.RLock()
|
||||||
defer s.txnLk.RUnlock()
|
defer s.txnLk.RUnlock()
|
||||||
|
|
||||||
err := s.hot.Put(blk)
|
err := s.hot.Put(ctx, blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.debug.LogWrite(blk)
|
s.debug.LogWrite(blk)
|
||||||
|
|
||||||
|
// critical section
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
s.markLiveRefs([]cid.Cid{blk.Cid()})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
s.trackTxnRef(blk.Cid())
|
s.trackTxnRef(blk.Cid())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) PutMany(blks []blocks.Block) error {
|
func (s *SplitStore) PutMany(ctx context.Context, blks []blocks.Block) error {
|
||||||
// filter identites
|
// filter identites
|
||||||
idcids := 0
|
idcids := 0
|
||||||
for _, blk := range blks {
|
for _, blk := range blks {
|
||||||
@@ -374,13 +451,19 @@ func (s *SplitStore) PutMany(blks []blocks.Block) error {
|
|||||||
s.txnLk.RLock()
|
s.txnLk.RLock()
|
||||||
defer s.txnLk.RUnlock()
|
defer s.txnLk.RUnlock()
|
||||||
|
|
||||||
err := s.hot.PutMany(blks)
|
err := s.hot.PutMany(ctx, blks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.debug.LogWriteMany(blks)
|
s.debug.LogWriteMany(blks)
|
||||||
|
|
||||||
|
// critical section
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
s.markLiveRefs(batch)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
s.trackTxnRefMany(batch)
|
s.trackTxnRefMany(batch)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -430,7 +513,7 @@ func (s *SplitStore) HashOnRead(enabled bool) {
|
|||||||
s.cold.HashOnRead(enabled)
|
s.cold.HashOnRead(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SplitStore) View(cid cid.Cid, cb func([]byte) error) error {
|
func (s *SplitStore) View(ctx context.Context, cid cid.Cid, cb func([]byte) error) error {
|
||||||
if isIdentiyCid(cid) {
|
if isIdentiyCid(cid) {
|
||||||
data, err := decodeIdentityCid(cid)
|
data, err := decodeIdentityCid(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -440,6 +523,23 @@ func (s *SplitStore) View(cid cid.Cid, cb func([]byte) error) error {
|
|||||||
return cb(data)
|
return cb(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// critical section
|
||||||
|
s.txnLk.RLock() // the lock is released in protectView if we are not in critical section
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
has, err := s.txnMarkSet.Has(cid)
|
||||||
|
s.txnLk.RUnlock()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
return s.view(cid, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.cold.View(ctx, cid, cb)
|
||||||
|
}
|
||||||
|
|
||||||
// views are (optimistically) protected two-fold:
|
// views are (optimistically) protected two-fold:
|
||||||
// - if there is an active transaction, then the reference is protected.
|
// - if there is an active transaction, then the reference is protected.
|
||||||
// - if there is no active transaction, active views are tracked in a
|
// - if there is no active transaction, active views are tracked in a
|
||||||
@@ -451,15 +551,19 @@ func (s *SplitStore) View(cid cid.Cid, cb func([]byte) error) error {
|
|||||||
s.protectView(cid)
|
s.protectView(cid)
|
||||||
defer s.viewDone()
|
defer s.viewDone()
|
||||||
|
|
||||||
err := s.hot.View(cid, cb)
|
err := s.hot.View(ctx, cid, cb)
|
||||||
switch err {
|
switch err {
|
||||||
case bstore.ErrNotFound:
|
case bstore.ErrNotFound:
|
||||||
if s.isWarm() {
|
if s.isWarm() {
|
||||||
s.debug.LogReadMiss(cid)
|
s.debug.LogReadMiss(cid)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.cold.View(cid, cb)
|
err = s.cold.View(ctx, cid, cb)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
if bstore.IsHotView(ctx) {
|
||||||
|
s.reifyColdObject(cid)
|
||||||
|
}
|
||||||
|
|
||||||
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
|
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -502,7 +606,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
|
|||||||
|
|
||||||
// load base epoch from metadata ds
|
// load base epoch from metadata ds
|
||||||
// if none, then use current epoch because it's a fresh start
|
// if none, then use current epoch because it's a fresh start
|
||||||
bs, err := s.ds.Get(baseEpochKey)
|
bs, err := s.ds.Get(s.ctx, baseEpochKey)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
s.baseEpoch = bytesToEpoch(bs)
|
s.baseEpoch = bytesToEpoch(bs)
|
||||||
@@ -523,7 +627,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load warmup epoch from metadata ds
|
// load warmup epoch from metadata ds
|
||||||
bs, err = s.ds.Get(warmupEpochKey)
|
bs, err = s.ds.Get(s.ctx, warmupEpochKey)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
s.warmupEpoch = bytesToEpoch(bs)
|
s.warmupEpoch = bytesToEpoch(bs)
|
||||||
@@ -536,7 +640,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load markSetSize from metadata ds to provide a size hint for marksets
|
// load markSetSize from metadata ds to provide a size hint for marksets
|
||||||
bs, err = s.ds.Get(markSetSizeKey)
|
bs, err = s.ds.Get(s.ctx, markSetSizeKey)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
s.markSetSize = bytesToInt64(bs)
|
s.markSetSize = bytesToInt64(bs)
|
||||||
@@ -547,7 +651,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load compactionIndex from metadata ds to provide a hint as to when to perform moving gc
|
// load compactionIndex from metadata ds to provide a hint as to when to perform moving gc
|
||||||
bs, err = s.ds.Get(compactionIndexKey)
|
bs, err = s.ds.Get(s.ctx, compactionIndexKey)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
s.compactionIndex = bytesToInt64(bs)
|
s.compactionIndex = bytesToInt64(bs)
|
||||||
@@ -569,6 +673,9 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spawn the reifier
|
||||||
|
go s.reifyOrchestrator()
|
||||||
|
|
||||||
// watch the chain
|
// watch the chain
|
||||||
chain.SubscribeHeadChanges(s.HeadChange)
|
chain.SubscribeHeadChanges(s.HeadChange)
|
||||||
|
|
||||||
@@ -589,12 +696,19 @@ func (s *SplitStore) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if atomic.LoadInt32(&s.compacting) == 1 {
|
if atomic.LoadInt32(&s.compacting) == 1 {
|
||||||
|
s.txnSyncMx.Lock()
|
||||||
|
s.txnSync = true
|
||||||
|
s.txnSyncCond.Broadcast()
|
||||||
|
s.txnSyncMx.Unlock()
|
||||||
|
|
||||||
log.Warn("close with ongoing compaction in progress; waiting for it to finish...")
|
log.Warn("close with ongoing compaction in progress; waiting for it to finish...")
|
||||||
for atomic.LoadInt32(&s.compacting) == 1 {
|
for atomic.LoadInt32(&s.compacting) == 1 {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.reifyCond.Broadcast()
|
||||||
|
s.reifyWorkers.Wait()
|
||||||
s.cancel()
|
s.cancel()
|
||||||
return multierr.Combine(s.markSetEnv.Close(), s.debug.Close())
|
return multierr.Combine(s.markSetEnv.Close(), s.debug.Close())
|
||||||
}
|
}
|
||||||
@@ -609,5 +723,5 @@ func (s *SplitStore) checkClosing() error {
|
|||||||
|
|
||||||
func (s *SplitStore) setBaseEpoch(epoch abi.ChainEpoch) error {
|
func (s *SplitStore) setBaseEpoch(epoch abi.ChainEpoch) error {
|
||||||
s.baseEpoch = epoch
|
s.baseEpoch = epoch
|
||||||
return s.ds.Put(baseEpochKey, epochToBytes(epoch))
|
return s.ds.Put(s.ctx, baseEpochKey, epochToBytes(epoch))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -67,7 +68,10 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
|
|||||||
}
|
}
|
||||||
defer output.Close() //nolint:errcheck
|
defer output.Close() //nolint:errcheck
|
||||||
|
|
||||||
|
var mx sync.Mutex
|
||||||
write := func(format string, args ...interface{}) {
|
write := func(format string, args ...interface{}) {
|
||||||
|
mx.Lock()
|
||||||
|
defer mx.Unlock()
|
||||||
_, err := fmt.Fprintf(output, format+"\n", args...)
|
_, err := fmt.Fprintf(output, format+"\n", args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("error writing check output: %s", err)
|
log.Warnf("error writing check output: %s", err)
|
||||||
@@ -82,9 +86,10 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
|
|||||||
write("compaction index: %d", s.compactionIndex)
|
write("compaction index: %d", s.compactionIndex)
|
||||||
write("--")
|
write("--")
|
||||||
|
|
||||||
var coldCnt, missingCnt int64
|
coldCnt := new(int64)
|
||||||
|
missingCnt := new(int64)
|
||||||
|
|
||||||
visitor, err := s.markSetEnv.CreateVisitor("check", 0)
|
visitor, err := s.markSetEnv.New("check", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error creating visitor: %w", err)
|
return xerrors.Errorf("error creating visitor: %w", err)
|
||||||
}
|
}
|
||||||
@@ -96,7 +101,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
|
|||||||
return errStopWalk
|
return errStopWalk
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := s.hot.Has(c)
|
has, err := s.hot.Has(s.ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error checking hotstore: %w", err)
|
return xerrors.Errorf("error checking hotstore: %w", err)
|
||||||
}
|
}
|
||||||
@@ -105,16 +110,16 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err = s.cold.Has(c)
|
has, err = s.cold.Has(s.ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error checking coldstore: %w", err)
|
return xerrors.Errorf("error checking coldstore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if has {
|
if has {
|
||||||
coldCnt++
|
atomic.AddInt64(coldCnt, 1)
|
||||||
write("cold object reference: %s", c)
|
write("cold object reference: %s", c)
|
||||||
} else {
|
} else {
|
||||||
missingCnt++
|
atomic.AddInt64(missingCnt, 1)
|
||||||
write("missing object reference: %s", c)
|
write("missing object reference: %s", c)
|
||||||
return errStopWalk
|
return errStopWalk
|
||||||
}
|
}
|
||||||
@@ -128,9 +133,9 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infow("check done", "cold", coldCnt, "missing", missingCnt)
|
log.Infow("check done", "cold", *coldCnt, "missing", *missingCnt)
|
||||||
write("--")
|
write("--")
|
||||||
write("cold: %d missing: %d", coldCnt, missingCnt)
|
write("cold: %d missing: %d", *coldCnt, *missingCnt)
|
||||||
write("DONE")
|
write("DONE")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -20,28 +20,28 @@ func (s *SplitStore) Expose() bstore.Blockstore {
|
|||||||
return &exposedSplitStore{s: s}
|
return &exposedSplitStore{s: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) DeleteBlock(_ cid.Cid) error {
|
func (es *exposedSplitStore) DeleteBlock(_ context.Context, _ cid.Cid) error {
|
||||||
return errors.New("DeleteBlock: operation not supported")
|
return errors.New("DeleteBlock: operation not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) DeleteMany(_ []cid.Cid) error {
|
func (es *exposedSplitStore) DeleteMany(_ context.Context, _ []cid.Cid) error {
|
||||||
return errors.New("DeleteMany: operation not supported")
|
return errors.New("DeleteMany: operation not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) Has(c cid.Cid) (bool, error) {
|
func (es *exposedSplitStore) Has(ctx context.Context, c cid.Cid) (bool, error) {
|
||||||
if isIdentiyCid(c) {
|
if isIdentiyCid(c) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := es.s.hot.Has(c)
|
has, err := es.s.hot.Has(ctx, c)
|
||||||
if has || err != nil {
|
if has || err != nil {
|
||||||
return has, err
|
return has, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return es.s.cold.Has(c)
|
return es.s.cold.Has(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) Get(c cid.Cid) (blocks.Block, error) {
|
func (es *exposedSplitStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
|
||||||
if isIdentiyCid(c) {
|
if isIdentiyCid(c) {
|
||||||
data, err := decodeIdentityCid(c)
|
data, err := decodeIdentityCid(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -51,16 +51,16 @@ func (es *exposedSplitStore) Get(c cid.Cid) (blocks.Block, error) {
|
|||||||
return blocks.NewBlockWithCid(data, c)
|
return blocks.NewBlockWithCid(data, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
blk, err := es.s.hot.Get(c)
|
blk, err := es.s.hot.Get(ctx, c)
|
||||||
switch err {
|
switch err {
|
||||||
case bstore.ErrNotFound:
|
case bstore.ErrNotFound:
|
||||||
return es.s.cold.Get(c)
|
return es.s.cold.Get(ctx, c)
|
||||||
default:
|
default:
|
||||||
return blk, err
|
return blk, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) GetSize(c cid.Cid) (int, error) {
|
func (es *exposedSplitStore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
|
||||||
if isIdentiyCid(c) {
|
if isIdentiyCid(c) {
|
||||||
data, err := decodeIdentityCid(c)
|
data, err := decodeIdentityCid(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -70,21 +70,21 @@ func (es *exposedSplitStore) GetSize(c cid.Cid) (int, error) {
|
|||||||
return len(data), nil
|
return len(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
size, err := es.s.hot.GetSize(c)
|
size, err := es.s.hot.GetSize(ctx, c)
|
||||||
switch err {
|
switch err {
|
||||||
case bstore.ErrNotFound:
|
case bstore.ErrNotFound:
|
||||||
return es.s.cold.GetSize(c)
|
return es.s.cold.GetSize(ctx, c)
|
||||||
default:
|
default:
|
||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) Put(blk blocks.Block) error {
|
func (es *exposedSplitStore) Put(ctx context.Context, blk blocks.Block) error {
|
||||||
return es.s.Put(blk)
|
return es.s.Put(ctx, blk)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) PutMany(blks []blocks.Block) error {
|
func (es *exposedSplitStore) PutMany(ctx context.Context, blks []blocks.Block) error {
|
||||||
return es.s.PutMany(blks)
|
return es.s.PutMany(ctx, blks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *exposedSplitStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
func (es *exposedSplitStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||||
@@ -93,7 +93,7 @@ func (es *exposedSplitStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, e
|
|||||||
|
|
||||||
func (es *exposedSplitStore) HashOnRead(enabled bool) {}
|
func (es *exposedSplitStore) HashOnRead(enabled bool) {}
|
||||||
|
|
||||||
func (es *exposedSplitStore) View(c cid.Cid, f func([]byte) error) error {
|
func (es *exposedSplitStore) View(ctx context.Context, c cid.Cid, f func([]byte) error) error {
|
||||||
if isIdentiyCid(c) {
|
if isIdentiyCid(c) {
|
||||||
data, err := decodeIdentityCid(c)
|
data, err := decodeIdentityCid(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -103,10 +103,10 @@ func (es *exposedSplitStore) View(c cid.Cid, f func([]byte) error) error {
|
|||||||
return f(data)
|
return f(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := es.s.hot.View(c, f)
|
err := es.s.hot.View(ctx, c, f)
|
||||||
switch err {
|
switch err {
|
||||||
case bstore.ErrNotFound:
|
case bstore.ErrNotFound:
|
||||||
return es.s.cold.View(c, f)
|
return es.s.cold.View(ctx, c, f)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
package splitstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"runtime"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
blocks "github.com/ipfs/go-block-format"
|
||||||
|
cid "github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errReifyLimit = errors.New("reification limit reached")
|
||||||
|
ReifyLimit = 16384
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *SplitStore) reifyColdObject(c cid.Cid) {
|
||||||
|
if !s.isWarm() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isUnitaryObject(c) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.reifyMx.Lock()
|
||||||
|
defer s.reifyMx.Unlock()
|
||||||
|
|
||||||
|
_, ok := s.reifyInProgress[c]
|
||||||
|
if ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.reifyPend[c] = struct{}{}
|
||||||
|
s.reifyCond.Broadcast()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SplitStore) reifyOrchestrator() {
|
||||||
|
workers := runtime.NumCPU() / 4
|
||||||
|
if workers < 2 {
|
||||||
|
workers = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
workch := make(chan cid.Cid, workers)
|
||||||
|
defer close(workch)
|
||||||
|
|
||||||
|
for i := 0; i < workers; i++ {
|
||||||
|
s.reifyWorkers.Add(1)
|
||||||
|
go s.reifyWorker(workch)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
s.reifyMx.Lock()
|
||||||
|
for len(s.reifyPend) == 0 && atomic.LoadInt32(&s.closing) == 0 {
|
||||||
|
s.reifyCond.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
if atomic.LoadInt32(&s.closing) != 0 {
|
||||||
|
s.reifyMx.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reifyPend := s.reifyPend
|
||||||
|
s.reifyPend = make(map[cid.Cid]struct{})
|
||||||
|
s.reifyMx.Unlock()
|
||||||
|
|
||||||
|
for c := range reifyPend {
|
||||||
|
select {
|
||||||
|
case workch <- c:
|
||||||
|
case <-s.ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SplitStore) reifyWorker(workch chan cid.Cid) {
|
||||||
|
defer s.reifyWorkers.Done()
|
||||||
|
for c := range workch {
|
||||||
|
s.doReify(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SplitStore) doReify(c cid.Cid) {
|
||||||
|
var toreify, totrack, toforget []cid.Cid
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
s.reifyMx.Lock()
|
||||||
|
defer s.reifyMx.Unlock()
|
||||||
|
|
||||||
|
for _, c := range toreify {
|
||||||
|
delete(s.reifyInProgress, c)
|
||||||
|
}
|
||||||
|
for _, c := range totrack {
|
||||||
|
delete(s.reifyInProgress, c)
|
||||||
|
}
|
||||||
|
for _, c := range toforget {
|
||||||
|
delete(s.reifyInProgress, c)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
s.txnLk.RLock()
|
||||||
|
defer s.txnLk.RUnlock()
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
err := s.walkObjectIncomplete(c, newTmpVisitor(),
|
||||||
|
func(c cid.Cid) error {
|
||||||
|
if isUnitaryObject(c) {
|
||||||
|
return errStopWalk
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
if count > ReifyLimit {
|
||||||
|
return errReifyLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
s.reifyMx.Lock()
|
||||||
|
_, inProgress := s.reifyInProgress[c]
|
||||||
|
if !inProgress {
|
||||||
|
s.reifyInProgress[c] = struct{}{}
|
||||||
|
}
|
||||||
|
s.reifyMx.Unlock()
|
||||||
|
|
||||||
|
if inProgress {
|
||||||
|
return errStopWalk
|
||||||
|
}
|
||||||
|
|
||||||
|
has, err := s.hot.Has(s.ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("error checking hotstore: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
hasMark, err := s.txnMarkSet.Has(c)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("error checking markset: %s", err)
|
||||||
|
} else if hasMark {
|
||||||
|
toforget = append(toforget, c)
|
||||||
|
return errStopWalk
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
totrack = append(totrack, c)
|
||||||
|
return errStopWalk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toreify = append(toreify, c)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
func(missing cid.Cid) error {
|
||||||
|
log.Warnf("missing reference while reifying %s: %s", c, missing)
|
||||||
|
return errStopWalk
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if xerrors.Is(err, errReifyLimit) {
|
||||||
|
log.Debug("reification aborted; reify limit reached")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Warnf("error walking cold object for reification (cid: %s): %s", c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("reifying %d objects rooted at %s", len(toreify), c)
|
||||||
|
|
||||||
|
// this should not get too big, maybe some 100s of objects.
|
||||||
|
batch := make([]blocks.Block, 0, len(toreify))
|
||||||
|
for _, c := range toreify {
|
||||||
|
blk, err := s.cold.Get(s.ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("error retrieving cold object for reification (cid: %s): %s", c, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.checkClosing(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
batch = append(batch, blk)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(batch) > 0 {
|
||||||
|
err = s.hot.PutMany(s.ctx, batch)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("error reifying cold object (cid: %s): %s", c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.txnMarkSet != nil {
|
||||||
|
if len(toreify) > 0 {
|
||||||
|
if err := s.txnMarkSet.MarkMany(toreify); err != nil {
|
||||||
|
log.Warnf("error marking reified objects: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(totrack) > 0 {
|
||||||
|
if err := s.txnMarkSet.MarkMany(totrack); err != nil {
|
||||||
|
log.Warnf("error marking tracked objects: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if txnActive is false these are noops
|
||||||
|
if len(toreify) > 0 {
|
||||||
|
s.trackTxnRefMany(toreify)
|
||||||
|
}
|
||||||
|
if len(totrack) > 0 {
|
||||||
|
s.trackTxnRefMany(totrack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
|
//stm: #unit
|
||||||
package splitstore
|
package splitstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -20,16 +22,19 @@ import (
|
|||||||
datastore "github.com/ipfs/go-datastore"
|
datastore "github.com/ipfs/go-datastore"
|
||||||
dssync "github.com/ipfs/go-datastore/sync"
|
dssync "github.com/ipfs/go-datastore/sync"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
mh "github.com/multiformats/go-multihash"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
CompactionThreshold = 5
|
CompactionThreshold = 5
|
||||||
CompactionBoundary = 2
|
CompactionBoundary = 2
|
||||||
WarmupBoundary = 0
|
WarmupBoundary = 0
|
||||||
|
SyncWaitTime = time.Millisecond
|
||||||
logging.SetLogLevel("splitstore", "DEBUG")
|
logging.SetLogLevel("splitstore", "DEBUG")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSplitStore(t *testing.T, cfg *Config) {
|
func testSplitStore(t *testing.T, cfg *Config) {
|
||||||
|
ctx := context.Background()
|
||||||
chain := &mockChain{t: t}
|
chain := &mockChain{t: t}
|
||||||
|
|
||||||
// the myriads of stores
|
// the myriads of stores
|
||||||
@@ -39,7 +44,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
|
|
||||||
// this is necessary to avoid the garbage mock puts in the blocks
|
// this is necessary to avoid the garbage mock puts in the blocks
|
||||||
garbage := blocks.NewBlock([]byte{1, 2, 3})
|
garbage := blocks.NewBlock([]byte{1, 2, 3})
|
||||||
err := cold.Put(garbage)
|
err := cold.Put(ctx, garbage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -60,27 +65,29 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cold.Put(blk)
|
err = cold.Put(ctx, blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a garbage block that is protected with a rgistered protector
|
// create a garbage block that is protected with a rgistered protector
|
||||||
protected := blocks.NewBlock([]byte("protected!"))
|
protected := blocks.NewBlock([]byte("protected!"))
|
||||||
err = hot.Put(protected)
|
err = hot.Put(ctx, protected)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// and another one that is not protected
|
// and another one that is not protected
|
||||||
unprotected := blocks.NewBlock([]byte("unprotected!"))
|
unprotected := blocks.NewBlock([]byte("unprotected!"))
|
||||||
err = hot.Put(unprotected)
|
err = hot.Put(ctx, unprotected)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
// open the splitstore
|
// open the splitstore
|
||||||
ss, err := Open("", ds, hot, cold, cfg)
|
ss, err := Open(path, ds, hot, cold, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -109,11 +116,11 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = ss.Put(stateRoot)
|
err = ss.Put(ctx, stateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = ss.Put(sblk)
|
err = ss.Put(ctx, sblk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -124,6 +131,10 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
waitForCompaction := func() {
|
waitForCompaction := func() {
|
||||||
|
ss.txnSyncMx.Lock()
|
||||||
|
ss.txnSync = true
|
||||||
|
ss.txnSyncCond.Broadcast()
|
||||||
|
ss.txnSyncMx.Unlock()
|
||||||
for atomic.LoadInt32(&ss.compacting) == 1 {
|
for atomic.LoadInt32(&ss.compacting) == 1 {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
@@ -176,7 +187,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure our protected block is still there
|
// ensure our protected block is still there
|
||||||
has, err := hot.Has(protected.Cid())
|
has, err := hot.Has(ctx, protected.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -186,7 +197,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure our unprotected block is in the coldstore now
|
// ensure our unprotected block is in the coldstore now
|
||||||
has, err = hot.Has(unprotected.Cid())
|
has, err = hot.Has(ctx, unprotected.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -195,7 +206,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
t.Fatal("unprotected block is still in hotstore")
|
t.Fatal("unprotected block is still in hotstore")
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err = cold.Has(unprotected.Cid())
|
has, err = cold.Has(ctx, unprotected.Cid())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -209,10 +220,16 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSplitStoreCompaction(t *testing.T) {
|
func TestSplitStoreCompaction(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_OPEN_001, @SPLITSTORE_SPLITSTORE_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_PUT_001, @SPLITSTORE_SPLITSTORE_ADD_PROTECTOR_001
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_CLOSE_001
|
||||||
testSplitStore(t, &Config{MarkSetType: "map"})
|
testSplitStore(t, &Config{MarkSetType: "map"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSplitStoreCompactionWithBadger(t *testing.T) {
|
func TestSplitStoreCompactionWithBadger(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_OPEN_001, @SPLITSTORE_SPLITSTORE_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_PUT_001, @SPLITSTORE_SPLITSTORE_ADD_PROTECTOR_001
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_CLOSE_001
|
||||||
bs := badgerMarkSetBatchSize
|
bs := badgerMarkSetBatchSize
|
||||||
badgerMarkSetBatchSize = 1
|
badgerMarkSetBatchSize = 1
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
@@ -222,6 +239,10 @@ func TestSplitStoreCompactionWithBadger(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_OPEN_001, @SPLITSTORE_SPLITSTORE_CLOSE_001
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_PUT_001, @SPLITSTORE_SPLITSTORE_ADD_PROTECTOR_001
|
||||||
|
//stm: @SPLITSTORE_SPLITSTORE_CLOSE_001
|
||||||
|
ctx := context.Background()
|
||||||
chain := &mockChain{t: t}
|
chain := &mockChain{t: t}
|
||||||
|
|
||||||
// the myriads of stores
|
// the myriads of stores
|
||||||
@@ -231,7 +252,7 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
|||||||
|
|
||||||
// this is necessary to avoid the garbage mock puts in the blocks
|
// this is necessary to avoid the garbage mock puts in the blocks
|
||||||
garbage := blocks.NewBlock([]byte{1, 2, 3})
|
garbage := blocks.NewBlock([]byte{1, 2, 3})
|
||||||
err := cold.Put(garbage)
|
err := cold.Put(ctx, garbage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -252,13 +273,15 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cold.Put(blk)
|
err = cold.Put(ctx, blk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
// open the splitstore
|
// open the splitstore
|
||||||
ss, err := Open("", ds, hot, cold, &Config{MarkSetType: "map"})
|
ss, err := Open(path, ds, hot, cold, &Config{MarkSetType: "map"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -288,11 +311,11 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = ss.Put(stateRoot)
|
err = ss.Put(ctx, stateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = ss.Put(sblk)
|
err = ss.Put(ctx, sblk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -303,6 +326,10 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
waitForCompaction := func() {
|
waitForCompaction := func() {
|
||||||
|
ss.txnSyncMx.Lock()
|
||||||
|
ss.txnSync = true
|
||||||
|
ss.txnSyncCond.Broadcast()
|
||||||
|
ss.txnSyncMx.Unlock()
|
||||||
for atomic.LoadInt32(&ss.compacting) == 1 {
|
for atomic.LoadInt32(&ss.compacting) == 1 {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
@@ -355,6 +382,221 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testSplitStoreReification(t *testing.T, f func(context.Context, blockstore.Blockstore, cid.Cid) error) {
|
||||||
|
ds := dssync.MutexWrap(datastore.NewMapDatastore())
|
||||||
|
hot := newMockStore()
|
||||||
|
cold := newMockStore()
|
||||||
|
|
||||||
|
mkRandomBlock := func() blocks.Block {
|
||||||
|
data := make([]byte, 128)
|
||||||
|
_, err := rand.Read(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks.NewBlock(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
block1 := mkRandomBlock()
|
||||||
|
block2 := mkRandomBlock()
|
||||||
|
block3 := mkRandomBlock()
|
||||||
|
|
||||||
|
hdr := mock.MkBlock(nil, 0, 0)
|
||||||
|
hdr.Messages = block1.Cid()
|
||||||
|
hdr.ParentMessageReceipts = block2.Cid()
|
||||||
|
hdr.ParentStateRoot = block3.Cid()
|
||||||
|
block4, err := hdr.ToStorageBlock()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allBlocks := []blocks.Block{block1, block2, block3, block4}
|
||||||
|
for _, blk := range allBlocks {
|
||||||
|
err := cold.Put(context.Background(), blk)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
|
ss, err := Open(path, ds, hot, cold, &Config{MarkSetType: "map"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer ss.Close() //nolint
|
||||||
|
|
||||||
|
ss.warmupEpoch = 1
|
||||||
|
go ss.reifyOrchestrator()
|
||||||
|
|
||||||
|
waitForReification := func() {
|
||||||
|
for {
|
||||||
|
ss.reifyMx.Lock()
|
||||||
|
ready := len(ss.reifyPend) == 0 && len(ss.reifyInProgress) == 0
|
||||||
|
ss.reifyMx.Unlock()
|
||||||
|
|
||||||
|
if ready {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// first access using the standard view
|
||||||
|
err = f(context.Background(), ss, block4.Cid())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing should be reified
|
||||||
|
waitForReification()
|
||||||
|
for _, blk := range allBlocks {
|
||||||
|
has, err := hot.Has(context.Background(), blk.Cid())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
t.Fatal("block unexpectedly reified")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now make the hot/reifying view and ensure access reifies
|
||||||
|
err = f(blockstore.WithHotView(context.Background()), ss, block4.Cid())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// everything should be reified
|
||||||
|
waitForReification()
|
||||||
|
for i, blk := range allBlocks {
|
||||||
|
has, err := hot.Has(context.Background(), blk.Cid())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has {
|
||||||
|
t.Fatalf("block%d was not reified", i+1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSplitStoreReificationLimit(t *testing.T, f func(context.Context, blockstore.Blockstore, cid.Cid) error) {
|
||||||
|
ds := dssync.MutexWrap(datastore.NewMapDatastore())
|
||||||
|
hot := newMockStore()
|
||||||
|
cold := newMockStore()
|
||||||
|
|
||||||
|
mkRandomBlock := func() blocks.Block {
|
||||||
|
data := make([]byte, 128)
|
||||||
|
_, err := rand.Read(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks.NewBlock(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
block1 := mkRandomBlock()
|
||||||
|
block2 := mkRandomBlock()
|
||||||
|
block3 := mkRandomBlock()
|
||||||
|
|
||||||
|
hdr := mock.MkBlock(nil, 0, 0)
|
||||||
|
hdr.Messages = block1.Cid()
|
||||||
|
hdr.ParentMessageReceipts = block2.Cid()
|
||||||
|
hdr.ParentStateRoot = block3.Cid()
|
||||||
|
block4, err := hdr.ToStorageBlock()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
allBlocks := []blocks.Block{block1, block2, block3, block4}
|
||||||
|
for _, blk := range allBlocks {
|
||||||
|
err := cold.Put(context.Background(), blk)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path := t.TempDir()
|
||||||
|
|
||||||
|
ss, err := Open(path, ds, hot, cold, &Config{MarkSetType: "map"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer ss.Close() //nolint
|
||||||
|
|
||||||
|
ss.warmupEpoch = 1
|
||||||
|
go ss.reifyOrchestrator()
|
||||||
|
|
||||||
|
waitForReification := func() {
|
||||||
|
for {
|
||||||
|
ss.reifyMx.Lock()
|
||||||
|
ready := len(ss.reifyPend) == 0 && len(ss.reifyInProgress) == 0
|
||||||
|
ss.reifyMx.Unlock()
|
||||||
|
|
||||||
|
if ready {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do a hot access -- nothing should be reified as the limit should be exceeded
|
||||||
|
oldReifyLimit := ReifyLimit
|
||||||
|
ReifyLimit = 2
|
||||||
|
t.Cleanup(func() {
|
||||||
|
ReifyLimit = oldReifyLimit
|
||||||
|
})
|
||||||
|
|
||||||
|
err = f(blockstore.WithHotView(context.Background()), ss, block4.Cid())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForReification()
|
||||||
|
|
||||||
|
for _, blk := range allBlocks {
|
||||||
|
has, err := hot.Has(context.Background(), blk.Cid())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if has {
|
||||||
|
t.Fatal("block unexpectedly reified")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitStoreReification(t *testing.T) {
|
||||||
|
t.Log("test reification with Has")
|
||||||
|
testSplitStoreReification(t, func(ctx context.Context, s blockstore.Blockstore, c cid.Cid) error {
|
||||||
|
_, err := s.Has(ctx, c)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
t.Log("test reification with Get")
|
||||||
|
testSplitStoreReification(t, func(ctx context.Context, s blockstore.Blockstore, c cid.Cid) error {
|
||||||
|
_, err := s.Get(ctx, c)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
t.Log("test reification with GetSize")
|
||||||
|
testSplitStoreReification(t, func(ctx context.Context, s blockstore.Blockstore, c cid.Cid) error {
|
||||||
|
_, err := s.GetSize(ctx, c)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
t.Log("test reification with View")
|
||||||
|
testSplitStoreReification(t, func(ctx context.Context, s blockstore.Blockstore, c cid.Cid) error {
|
||||||
|
return s.View(ctx, c, func(_ []byte) error { return nil })
|
||||||
|
})
|
||||||
|
t.Log("test reification limit")
|
||||||
|
testSplitStoreReificationLimit(t, func(ctx context.Context, s blockstore.Blockstore, c cid.Cid) error {
|
||||||
|
_, err := s.Has(ctx, c)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type mockChain struct {
|
type mockChain struct {
|
||||||
t testing.TB
|
t testing.TB
|
||||||
|
|
||||||
@@ -424,35 +666,43 @@ func (c *mockChain) SubscribeHeadChanges(change func(revert []*types.TipSet, app
|
|||||||
|
|
||||||
type mockStore struct {
|
type mockStore struct {
|
||||||
mx sync.Mutex
|
mx sync.Mutex
|
||||||
set map[cid.Cid]blocks.Block
|
set map[string]blocks.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMockStore() *mockStore {
|
func newMockStore() *mockStore {
|
||||||
return &mockStore{set: make(map[cid.Cid]blocks.Block)}
|
return &mockStore{set: make(map[string]blocks.Block)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) Has(cid cid.Cid) (bool, error) {
|
func (b *mockStore) keyOf(c cid.Cid) string {
|
||||||
|
return string(c.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *mockStore) cidOf(k string) cid.Cid {
|
||||||
|
return cid.NewCidV1(cid.Raw, mh.Multihash([]byte(k)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *mockStore) Has(_ context.Context, cid cid.Cid) (bool, error) {
|
||||||
b.mx.Lock()
|
b.mx.Lock()
|
||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
_, ok := b.set[cid]
|
_, ok := b.set[b.keyOf(cid)]
|
||||||
return ok, nil
|
return ok, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) HashOnRead(hor bool) {}
|
func (b *mockStore) HashOnRead(hor bool) {}
|
||||||
|
|
||||||
func (b *mockStore) Get(cid cid.Cid) (blocks.Block, error) {
|
func (b *mockStore) Get(_ context.Context, cid cid.Cid) (blocks.Block, error) {
|
||||||
b.mx.Lock()
|
b.mx.Lock()
|
||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
|
|
||||||
blk, ok := b.set[cid]
|
blk, ok := b.set[b.keyOf(cid)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, blockstore.ErrNotFound
|
return nil, blockstore.ErrNotFound
|
||||||
}
|
}
|
||||||
return blk, nil
|
return blk, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) GetSize(cid cid.Cid) (int, error) {
|
func (b *mockStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
|
||||||
blk, err := b.Get(cid)
|
blk, err := b.Get(ctx, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -460,46 +710,46 @@ func (b *mockStore) GetSize(cid cid.Cid) (int, error) {
|
|||||||
return len(blk.RawData()), nil
|
return len(blk.RawData()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) View(cid cid.Cid, f func([]byte) error) error {
|
func (b *mockStore) View(ctx context.Context, cid cid.Cid, f func([]byte) error) error {
|
||||||
blk, err := b.Get(cid)
|
blk, err := b.Get(ctx, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return f(blk.RawData())
|
return f(blk.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) Put(blk blocks.Block) error {
|
func (b *mockStore) Put(_ context.Context, blk blocks.Block) error {
|
||||||
b.mx.Lock()
|
b.mx.Lock()
|
||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
|
|
||||||
b.set[blk.Cid()] = blk
|
b.set[b.keyOf(blk.Cid())] = blk
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) PutMany(blks []blocks.Block) error {
|
func (b *mockStore) PutMany(_ context.Context, blks []blocks.Block) error {
|
||||||
b.mx.Lock()
|
b.mx.Lock()
|
||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
|
|
||||||
for _, blk := range blks {
|
for _, blk := range blks {
|
||||||
b.set[blk.Cid()] = blk
|
b.set[b.keyOf(blk.Cid())] = blk
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) DeleteBlock(cid cid.Cid) error {
|
func (b *mockStore) DeleteBlock(_ context.Context, cid cid.Cid) error {
|
||||||
b.mx.Lock()
|
b.mx.Lock()
|
||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
|
|
||||||
delete(b.set, cid)
|
delete(b.set, b.keyOf(cid))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockStore) DeleteMany(cids []cid.Cid) error {
|
func (b *mockStore) DeleteMany(_ context.Context, cids []cid.Cid) error {
|
||||||
b.mx.Lock()
|
b.mx.Lock()
|
||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
|
|
||||||
for _, c := range cids {
|
for _, c := range cids {
|
||||||
delete(b.set, c)
|
delete(b.set, b.keyOf(c))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -513,7 +763,7 @@ func (b *mockStore) ForEachKey(f func(cid.Cid) error) error {
|
|||||||
defer b.mx.Unlock()
|
defer b.mx.Unlock()
|
||||||
|
|
||||||
for c := range b.set {
|
for c := range b.set {
|
||||||
err := f(c)
|
err := f(b.cidOf(c))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package splitstore
|
package splitstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -55,12 +56,13 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
|
|||||||
if WarmupBoundary < epoch {
|
if WarmupBoundary < epoch {
|
||||||
boundaryEpoch = epoch - WarmupBoundary
|
boundaryEpoch = epoch - WarmupBoundary
|
||||||
}
|
}
|
||||||
|
var mx sync.Mutex
|
||||||
batchHot := make([]blocks.Block, 0, batchSize)
|
batchHot := make([]blocks.Block, 0, batchSize)
|
||||||
count := int64(0)
|
count := new(int64)
|
||||||
xcount := int64(0)
|
xcount := new(int64)
|
||||||
missing := int64(0)
|
missing := new(int64)
|
||||||
|
|
||||||
visitor, err := s.markSetEnv.CreateVisitor("warmup", 0)
|
visitor, err := s.markSetEnv.New("warmup", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error creating visitor: %w", err)
|
return xerrors.Errorf("error creating visitor: %w", err)
|
||||||
}
|
}
|
||||||
@@ -73,9 +75,9 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
|
|||||||
return errStopWalk
|
return errStopWalk
|
||||||
}
|
}
|
||||||
|
|
||||||
count++
|
atomic.AddInt64(count, 1)
|
||||||
|
|
||||||
has, err := s.hot.Has(c)
|
has, err := s.hot.Has(s.ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -84,25 +86,28 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
blk, err := s.cold.Get(c)
|
blk, err := s.cold.Get(s.ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bstore.ErrNotFound {
|
if err == bstore.ErrNotFound {
|
||||||
missing++
|
atomic.AddInt64(missing, 1)
|
||||||
return errStopWalk
|
return errStopWalk
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
xcount++
|
atomic.AddInt64(xcount, 1)
|
||||||
|
|
||||||
|
mx.Lock()
|
||||||
batchHot = append(batchHot, blk)
|
batchHot = append(batchHot, blk)
|
||||||
if len(batchHot) == batchSize {
|
if len(batchHot) == batchSize {
|
||||||
err = s.hot.PutMany(batchHot)
|
err = s.hot.PutMany(s.ctx, batchHot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
mx.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
batchHot = batchHot[:0]
|
batchHot = batchHot[:0]
|
||||||
}
|
}
|
||||||
|
mx.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -112,22 +117,22 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(batchHot) > 0 {
|
if len(batchHot) > 0 {
|
||||||
err = s.hot.PutMany(batchHot)
|
err = s.hot.PutMany(s.ctx, batchHot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infow("warmup stats", "visited", count, "warm", xcount, "missing", missing)
|
log.Infow("warmup stats", "visited", *count, "warm", *xcount, "missing", *missing)
|
||||||
|
|
||||||
s.markSetSize = count + count>>2 // overestimate a bit
|
s.markSetSize = *count + *count>>2 // overestimate a bit
|
||||||
err = s.ds.Put(markSetSizeKey, int64ToBytes(s.markSetSize))
|
err = s.ds.Put(s.ctx, markSetSizeKey, int64ToBytes(s.markSetSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("error saving mark set size: %s", err)
|
log.Warnf("error saving mark set size: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the warmup epoch
|
// save the warmup epoch
|
||||||
err = s.ds.Put(warmupEpochKey, epochToBytes(epoch))
|
err = s.ds.Put(s.ctx, warmupEpochKey, epochToBytes(epoch))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error saving warm up epoch: %w", err)
|
return xerrors.Errorf("error saving warm up epoch: %w", err)
|
||||||
}
|
}
|
||||||
@@ -136,7 +141,7 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
|
|||||||
s.mx.Unlock()
|
s.mx.Unlock()
|
||||||
|
|
||||||
// also save the compactionIndex, as this is used as an indicator of warmup for upgraded nodes
|
// also save the compactionIndex, as this is used as an indicator of warmup for upgraded nodes
|
||||||
err = s.ds.Put(compactionIndexKey, int64ToBytes(s.compactionIndex))
|
err = s.ds.Put(s.ctx, compactionIndexKey, int64ToBytes(s.compactionIndex))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("error saving compaction index: %w", err)
|
return xerrors.Errorf("error saving compaction index: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package splitstore
|
package splitstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,16 +19,42 @@ func (v *noopVisitor) Visit(_ cid.Cid) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type cidSetVisitor struct {
|
type tmpVisitor struct {
|
||||||
set *cid.Set
|
set *cid.Set
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ ObjectVisitor = (*cidSetVisitor)(nil)
|
var _ ObjectVisitor = (*tmpVisitor)(nil)
|
||||||
|
|
||||||
|
func (v *tmpVisitor) Visit(c cid.Cid) (bool, error) {
|
||||||
|
if isUnitaryObject(c) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v *cidSetVisitor) Visit(c cid.Cid) (bool, error) {
|
|
||||||
return v.set.Visit(c), nil
|
return v.set.Visit(c), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func tmpVisitor() ObjectVisitor {
|
func newTmpVisitor() ObjectVisitor {
|
||||||
return &cidSetVisitor{set: cid.NewSet()}
|
return &tmpVisitor{set: cid.NewSet()}
|
||||||
|
}
|
||||||
|
|
||||||
|
type concurrentVisitor struct {
|
||||||
|
mx sync.Mutex
|
||||||
|
set *cid.Set
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ObjectVisitor = (*concurrentVisitor)(nil)
|
||||||
|
|
||||||
|
func newConcurrentVisitor() *concurrentVisitor {
|
||||||
|
return &concurrentVisitor{set: cid.NewSet()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *concurrentVisitor) Visit(c cid.Cid) (bool, error) {
|
||||||
|
if isUnitaryObject(c) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v.mx.Lock()
|
||||||
|
defer v.mx.Unlock()
|
||||||
|
|
||||||
|
return v.set.Visit(c), nil
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-16
@@ -20,53 +20,53 @@ type SyncBlockstore struct {
|
|||||||
bs MemBlockstore // specifically use a memStore to save indirection overhead.
|
bs MemBlockstore // specifically use a memStore to save indirection overhead.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) DeleteBlock(k cid.Cid) error {
|
func (m *SyncBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
return m.bs.DeleteBlock(k)
|
return m.bs.DeleteBlock(ctx, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) DeleteMany(ks []cid.Cid) error {
|
func (m *SyncBlockstore) DeleteMany(ctx context.Context, ks []cid.Cid) error {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
return m.bs.DeleteMany(ks)
|
return m.bs.DeleteMany(ctx, ks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) Has(k cid.Cid) (bool, error) {
|
func (m *SyncBlockstore) Has(ctx context.Context, k cid.Cid) (bool, error) {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
return m.bs.Has(k)
|
return m.bs.Has(ctx, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) View(k cid.Cid, callback func([]byte) error) error {
|
func (m *SyncBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte) error) error {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.bs.View(k, callback)
|
return m.bs.View(ctx, k, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) Get(k cid.Cid) (blocks.Block, error) {
|
func (m *SyncBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
return m.bs.Get(k)
|
return m.bs.Get(ctx, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) GetSize(k cid.Cid) (int, error) {
|
func (m *SyncBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
return m.bs.GetSize(k)
|
return m.bs.GetSize(ctx, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) Put(b blocks.Block) error {
|
func (m *SyncBlockstore) Put(ctx context.Context, b blocks.Block) error {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
return m.bs.Put(b)
|
return m.bs.Put(ctx, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) PutMany(bs []blocks.Block) error {
|
func (m *SyncBlockstore) PutMany(ctx context.Context, bs []blocks.Block) error {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
return m.bs.PutMany(bs)
|
return m.bs.PutMany(ctx, bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SyncBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
func (m *SyncBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||||
|
|||||||
+20
-20
@@ -92,28 +92,28 @@ func (t *TimedCacheBlockstore) rotate() {
|
|||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) Put(b blocks.Block) error {
|
func (t *TimedCacheBlockstore) Put(ctx context.Context, b blocks.Block) error {
|
||||||
// Don't check the inactive set here. We want to keep this block for at
|
// Don't check the inactive set here. We want to keep this block for at
|
||||||
// least one interval.
|
// least one interval.
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
return t.active.Put(b)
|
return t.active.Put(ctx, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) PutMany(bs []blocks.Block) error {
|
func (t *TimedCacheBlockstore) PutMany(ctx context.Context, bs []blocks.Block) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
return t.active.PutMany(bs)
|
return t.active.PutMany(ctx, bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) View(k cid.Cid, callback func([]byte) error) error {
|
func (t *TimedCacheBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte) error) error {
|
||||||
// The underlying blockstore is always a "mem" blockstore so there's no difference,
|
// The underlying blockstore is always a "mem" blockstore so there's no difference,
|
||||||
// from a performance perspective, between view & get. So we call Get to avoid
|
// from a performance perspective, between view & get. So we call Get to avoid
|
||||||
// calling an arbitrary callback while holding a lock.
|
// calling an arbitrary callback while holding a lock.
|
||||||
t.mu.RLock()
|
t.mu.RLock()
|
||||||
block, err := t.active.Get(k)
|
block, err := t.active.Get(ctx, k)
|
||||||
if err == ErrNotFound {
|
if err == ErrNotFound {
|
||||||
block, err = t.inactive.Get(k)
|
block, err = t.inactive.Get(ctx, k)
|
||||||
}
|
}
|
||||||
t.mu.RUnlock()
|
t.mu.RUnlock()
|
||||||
|
|
||||||
@@ -123,51 +123,51 @@ func (t *TimedCacheBlockstore) View(k cid.Cid, callback func([]byte) error) erro
|
|||||||
return callback(block.RawData())
|
return callback(block.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) Get(k cid.Cid) (blocks.Block, error) {
|
func (t *TimedCacheBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
|
||||||
t.mu.RLock()
|
t.mu.RLock()
|
||||||
defer t.mu.RUnlock()
|
defer t.mu.RUnlock()
|
||||||
b, err := t.active.Get(k)
|
b, err := t.active.Get(ctx, k)
|
||||||
if err == ErrNotFound {
|
if err == ErrNotFound {
|
||||||
b, err = t.inactive.Get(k)
|
b, err = t.inactive.Get(ctx, k)
|
||||||
}
|
}
|
||||||
return b, err
|
return b, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) GetSize(k cid.Cid) (int, error) {
|
func (t *TimedCacheBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
|
||||||
t.mu.RLock()
|
t.mu.RLock()
|
||||||
defer t.mu.RUnlock()
|
defer t.mu.RUnlock()
|
||||||
size, err := t.active.GetSize(k)
|
size, err := t.active.GetSize(ctx, k)
|
||||||
if err == ErrNotFound {
|
if err == ErrNotFound {
|
||||||
size, err = t.inactive.GetSize(k)
|
size, err = t.inactive.GetSize(ctx, k)
|
||||||
}
|
}
|
||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) Has(k cid.Cid) (bool, error) {
|
func (t *TimedCacheBlockstore) Has(ctx context.Context, k cid.Cid) (bool, error) {
|
||||||
t.mu.RLock()
|
t.mu.RLock()
|
||||||
defer t.mu.RUnlock()
|
defer t.mu.RUnlock()
|
||||||
if has, err := t.active.Has(k); err != nil {
|
if has, err := t.active.Has(ctx, k); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
} else if has {
|
} else if has {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
return t.inactive.Has(k)
|
return t.inactive.Has(ctx, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) HashOnRead(_ bool) {
|
func (t *TimedCacheBlockstore) HashOnRead(_ bool) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) DeleteBlock(k cid.Cid) error {
|
func (t *TimedCacheBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
return multierr.Combine(t.active.DeleteBlock(k), t.inactive.DeleteBlock(k))
|
return multierr.Combine(t.active.DeleteBlock(ctx, k), t.inactive.DeleteBlock(ctx, k))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) DeleteMany(ks []cid.Cid) error {
|
func (t *TimedCacheBlockstore) DeleteMany(ctx context.Context, ks []cid.Cid) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
return multierr.Combine(t.active.DeleteMany(ks), t.inactive.DeleteMany(ks))
|
return multierr.Combine(t.active.DeleteMany(ctx, ks), t.inactive.DeleteMany(ctx, ks))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TimedCacheBlockstore) AllKeysChan(_ context.Context) (<-chan cid.Cid, error) {
|
func (t *TimedCacheBlockstore) AllKeysChan(_ context.Context) (<-chan cid.Cid, error) {
|
||||||
|
|||||||
+17
-11
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package blockstore
|
package blockstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -13,12 +14,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTimedCacheBlockstoreSimple(t *testing.T) {
|
func TestTimedCacheBlockstoreSimple(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_TIMED_BLOCKSTORE_START_001
|
||||||
|
//stm: @SPLITSTORE_TIMED_BLOCKSTORE_PUT_001, @SPLITSTORE_TIMED_BLOCKSTORE_HAS_001, @SPLITSTORE_TIMED_BLOCKSTORE_GET_001
|
||||||
|
//stm: @SPLITSTORE_TIMED_BLOCKSTORE_ALL_KEYS_CHAN_001
|
||||||
tc := NewTimedCacheBlockstore(10 * time.Millisecond)
|
tc := NewTimedCacheBlockstore(10 * time.Millisecond)
|
||||||
mClock := clock.NewMock()
|
mClock := clock.NewMock()
|
||||||
mClock.Set(time.Now())
|
mClock.Set(time.Now())
|
||||||
tc.clock = mClock
|
tc.clock = mClock
|
||||||
tc.doneRotatingCh = make(chan struct{})
|
tc.doneRotatingCh = make(chan struct{})
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
_ = tc.Start(context.Background())
|
_ = tc.Start(context.Background())
|
||||||
mClock.Add(1) // IDK why it is needed but it makes it work
|
mClock.Add(1) // IDK why it is needed but it makes it work
|
||||||
|
|
||||||
@@ -27,18 +33,18 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
b1 := blocks.NewBlock([]byte("foo"))
|
b1 := blocks.NewBlock([]byte("foo"))
|
||||||
require.NoError(t, tc.Put(b1))
|
require.NoError(t, tc.Put(ctx, b1))
|
||||||
|
|
||||||
b2 := blocks.NewBlock([]byte("bar"))
|
b2 := blocks.NewBlock([]byte("bar"))
|
||||||
require.NoError(t, tc.Put(b2))
|
require.NoError(t, tc.Put(ctx, b2))
|
||||||
|
|
||||||
b3 := blocks.NewBlock([]byte("baz"))
|
b3 := blocks.NewBlock([]byte("baz"))
|
||||||
|
|
||||||
b1out, err := tc.Get(b1.Cid())
|
b1out, err := tc.Get(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b1.RawData(), b1out.RawData())
|
require.Equal(t, b1.RawData(), b1out.RawData())
|
||||||
|
|
||||||
has, err := tc.Has(b1.Cid())
|
has, err := tc.Has(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
@@ -46,17 +52,17 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
|
|||||||
<-tc.doneRotatingCh
|
<-tc.doneRotatingCh
|
||||||
|
|
||||||
// We should still have everything.
|
// We should still have everything.
|
||||||
has, err = tc.Has(b1.Cid())
|
has, err = tc.Has(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, err = tc.Has(b2.Cid())
|
has, err = tc.Has(ctx, b2.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
// extend b2, add b3.
|
// extend b2, add b3.
|
||||||
require.NoError(t, tc.Put(b2))
|
require.NoError(t, tc.Put(ctx, b2))
|
||||||
require.NoError(t, tc.Put(b3))
|
require.NoError(t, tc.Put(ctx, b3))
|
||||||
|
|
||||||
// all keys once.
|
// all keys once.
|
||||||
allKeys, err := tc.AllKeysChan(context.Background())
|
allKeys, err := tc.AllKeysChan(context.Background())
|
||||||
@@ -71,15 +77,15 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
|
|||||||
<-tc.doneRotatingCh
|
<-tc.doneRotatingCh
|
||||||
// should still have b2, and b3, but not b1
|
// should still have b2, and b3, but not b1
|
||||||
|
|
||||||
has, err = tc.Has(b1.Cid())
|
has, err = tc.Has(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, has)
|
require.False(t, has)
|
||||||
|
|
||||||
has, err = tc.Has(b2.Cid())
|
has, err = tc.Has(ctx, b2.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, err = tc.Has(b3.Cid())
|
has, err = tc.Has(ctx, b3.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-16
@@ -19,72 +19,72 @@ func Union(stores ...Blockstore) Blockstore {
|
|||||||
return unionBlockstore(stores)
|
return unionBlockstore(stores)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) Has(cid cid.Cid) (has bool, err error) {
|
func (m unionBlockstore) Has(ctx context.Context, cid cid.Cid) (has bool, err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if has, err = bs.Has(cid); has || err != nil {
|
if has, err = bs.Has(ctx, cid); has || err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return has, err
|
return has, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) Get(cid cid.Cid) (blk blocks.Block, err error) {
|
func (m unionBlockstore) Get(ctx context.Context, cid cid.Cid) (blk blocks.Block, err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if blk, err = bs.Get(cid); err == nil || err != ErrNotFound {
|
if blk, err = bs.Get(ctx, cid); err == nil || err != ErrNotFound {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return blk, err
|
return blk, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) View(cid cid.Cid, callback func([]byte) error) (err error) {
|
func (m unionBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) (err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if err = bs.View(cid, callback); err == nil || err != ErrNotFound {
|
if err = bs.View(ctx, cid, callback); err == nil || err != ErrNotFound {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) GetSize(cid cid.Cid) (size int, err error) {
|
func (m unionBlockstore) GetSize(ctx context.Context, cid cid.Cid) (size int, err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if size, err = bs.GetSize(cid); err == nil || err != ErrNotFound {
|
if size, err = bs.GetSize(ctx, cid); err == nil || err != ErrNotFound {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) Put(block blocks.Block) (err error) {
|
func (m unionBlockstore) Put(ctx context.Context, block blocks.Block) (err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if err = bs.Put(block); err != nil {
|
if err = bs.Put(ctx, block); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) PutMany(blks []blocks.Block) (err error) {
|
func (m unionBlockstore) PutMany(ctx context.Context, blks []blocks.Block) (err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if err = bs.PutMany(blks); err != nil {
|
if err = bs.PutMany(ctx, blks); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) DeleteBlock(cid cid.Cid) (err error) {
|
func (m unionBlockstore) DeleteBlock(ctx context.Context, cid cid.Cid) (err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if err = bs.DeleteBlock(cid); err != nil {
|
if err = bs.DeleteBlock(ctx, cid); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m unionBlockstore) DeleteMany(cids []cid.Cid) (err error) {
|
func (m unionBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) (err error) {
|
||||||
for _, bs := range m {
|
for _, bs := range m {
|
||||||
if err = bs.DeleteMany(cids); err != nil {
|
if err = bs.DeleteMany(ctx, cids); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-19
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package blockstore
|
package blockstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -15,79 +16,85 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestUnionBlockstore_Get(t *testing.T) {
|
func TestUnionBlockstore_Get(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_UNION_BLOCKSTORE_GET_001
|
||||||
|
ctx := context.Background()
|
||||||
m1 := NewMemory()
|
m1 := NewMemory()
|
||||||
m2 := NewMemory()
|
m2 := NewMemory()
|
||||||
|
|
||||||
_ = m1.Put(b1)
|
_ = m1.Put(ctx, b1)
|
||||||
_ = m2.Put(b2)
|
_ = m2.Put(ctx, b2)
|
||||||
|
|
||||||
u := Union(m1, m2)
|
u := Union(m1, m2)
|
||||||
|
|
||||||
v1, err := u.Get(b1.Cid())
|
v1, err := u.Get(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b1.RawData(), v1.RawData())
|
require.Equal(t, b1.RawData(), v1.RawData())
|
||||||
|
|
||||||
v2, err := u.Get(b2.Cid())
|
v2, err := u.Get(ctx, b2.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b2.RawData(), v2.RawData())
|
require.Equal(t, b2.RawData(), v2.RawData())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnionBlockstore_Put_PutMany_Delete_AllKeysChan(t *testing.T) {
|
func TestUnionBlockstore_Put_PutMany_Delete_AllKeysChan(t *testing.T) {
|
||||||
|
//stm: @SPLITSTORE_UNION_BLOCKSTORE_PUT_001, @SPLITSTORE_UNION_BLOCKSTORE_HAS_001
|
||||||
|
//stm: @SPLITSTORE_UNION_BLOCKSTORE_PUT_MANY_001, @SPLITSTORE_UNION_BLOCKSTORE_DELETE_001
|
||||||
|
//stm: @SPLITSTORE_UNION_BLOCKSTORE_ALL_KEYS_CHAN_001
|
||||||
|
ctx := context.Background()
|
||||||
m1 := NewMemory()
|
m1 := NewMemory()
|
||||||
m2 := NewMemory()
|
m2 := NewMemory()
|
||||||
|
|
||||||
u := Union(m1, m2)
|
u := Union(m1, m2)
|
||||||
|
|
||||||
err := u.Put(b0)
|
err := u.Put(ctx, b0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var has bool
|
var has bool
|
||||||
|
|
||||||
// write was broadcasted to all stores.
|
// write was broadcasted to all stores.
|
||||||
has, _ = m1.Has(b0.Cid())
|
has, _ = m1.Has(ctx, b0.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, _ = m2.Has(b0.Cid())
|
has, _ = m2.Has(ctx, b0.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, _ = u.Has(b0.Cid())
|
has, _ = u.Has(ctx, b0.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
// put many.
|
// put many.
|
||||||
err = u.PutMany([]blocks.Block{b1, b2})
|
err = u.PutMany(ctx, []blocks.Block{b1, b2})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// write was broadcasted to all stores.
|
// write was broadcasted to all stores.
|
||||||
has, _ = m1.Has(b1.Cid())
|
has, _ = m1.Has(ctx, b1.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, _ = m1.Has(b2.Cid())
|
has, _ = m1.Has(ctx, b2.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, _ = m2.Has(b1.Cid())
|
has, _ = m2.Has(ctx, b1.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, _ = m2.Has(b2.Cid())
|
has, _ = m2.Has(ctx, b2.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
// also in the union store.
|
// also in the union store.
|
||||||
has, _ = u.Has(b1.Cid())
|
has, _ = u.Has(ctx, b1.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
has, _ = u.Has(b2.Cid())
|
has, _ = u.Has(ctx, b2.Cid())
|
||||||
require.True(t, has)
|
require.True(t, has)
|
||||||
|
|
||||||
// deleted from all stores.
|
// deleted from all stores.
|
||||||
err = u.DeleteBlock(b1.Cid())
|
err = u.DeleteBlock(ctx, b1.Cid())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
has, _ = u.Has(b1.Cid())
|
has, _ = u.Has(ctx, b1.Cid())
|
||||||
require.False(t, has)
|
require.False(t, has)
|
||||||
|
|
||||||
has, _ = m1.Has(b1.Cid())
|
has, _ = m1.Has(ctx, b1.Cid())
|
||||||
require.False(t, has)
|
require.False(t, has)
|
||||||
|
|
||||||
has, _ = m2.Has(b1.Cid())
|
has, _ = m2.Has(ctx, b1.Cid())
|
||||||
require.False(t, has)
|
require.False(t, has)
|
||||||
|
|
||||||
// check that AllKeysChan returns b0 and b2, twice (once per backing store)
|
// check that AllKeysChan returns b0 and b2, twice (once per backing store)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
/dns4/bootstrap-0.interop.fildev.network/tcp/1347/p2p/12D3KooWLGPq9JL1xwL6gHok7HSNxtK1Q5kyfg4Hk69ifRPghn4i
|
/dns4/bootstrap-0.interop.fildev.network/tcp/1347/p2p/12D3KooWPfaWdJjpPTQp5kSqsqvauJaM4cFz5NWja7qyjx7vVfjL
|
||||||
/dns4/bootstrap-1.interop.fildev.network/tcp/1347/p2p/12D3KooWFYS1f31zafv8mqqYu8U3hEqYvaZ6avWzYU3BmZdpyH3h
|
/dns4/bootstrap-1.interop.fildev.network/tcp/1347/p2p/12D3KooWS5tjcL6s4hHZ1HVRTgGKaXpKkiHfbBSJdjbzgejgJpEh
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -7,6 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestOpenRPCDiscoverJSON_Version(t *testing.T) {
|
func TestOpenRPCDiscoverJSON_Version(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_OPENRPC_VERSION_001
|
||||||
// openRPCDocVersion is the current OpenRPC version of the API docs.
|
// openRPCDocVersion is the current OpenRPC version of the API docs.
|
||||||
openRPCDocVersion := "1.2.6"
|
openRPCDocVersion := "1.2.6"
|
||||||
|
|
||||||
|
|||||||
+14
-10
@@ -13,13 +13,12 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const BootstrappersFile = "interopnet.pi"
|
const BootstrappersFile = "interopnet.pi"
|
||||||
const GenesisFile = "interopnet.car"
|
const GenesisFile = "interopnet.car"
|
||||||
|
|
||||||
const GenesisNetworkVersion = network.Version13
|
const GenesisNetworkVersion = network.Version15
|
||||||
|
|
||||||
var UpgradeBreezeHeight = abi.ChainEpoch(-1)
|
var UpgradeBreezeHeight = abi.ChainEpoch(-1)
|
||||||
|
|
||||||
@@ -54,15 +53,18 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
policy.SetSupportedProofTypes(
|
|
||||||
abi.RegisteredSealProof_StackedDrg2KiBV1,
|
|
||||||
abi.RegisteredSealProof_StackedDrg8MiBV1,
|
|
||||||
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
|
||||||
)
|
|
||||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
|
||||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||||
policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10))
|
policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10))
|
||||||
|
|
||||||
|
InsecurePoStValidation = true
|
||||||
|
|
||||||
|
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2 << 30))
|
||||||
|
policy.SetSupportedProofTypes(
|
||||||
|
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
||||||
|
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||||
|
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||||
|
)
|
||||||
|
|
||||||
getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch {
|
getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch {
|
||||||
hs, found := os.LookupEnv(ev)
|
hs, found := os.LookupEnv(ev)
|
||||||
if found {
|
if found {
|
||||||
@@ -93,6 +95,8 @@ func init() {
|
|||||||
UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight)
|
UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight)
|
||||||
UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight)
|
UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight)
|
||||||
UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight)
|
UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight)
|
||||||
|
UpgradeChocolateHeight = getUpgradeHeight("LOTUS_CHOCOLATE_HEIGHT", UpgradeChocolateHeight)
|
||||||
|
UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight)
|
||||||
|
|
||||||
BuildType |= BuildInteropnet
|
BuildType |= BuildInteropnet
|
||||||
SetAddressNetwork(address.Testnet)
|
SetAddressNetwork(address.Testnet)
|
||||||
@@ -100,9 +104,9 @@ func init() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
const BlockDelaySecs = uint64(5)
|
||||||
|
|
||||||
const PropagationDelaySecs = uint64(6)
|
const PropagationDelaySecs = uint64(1)
|
||||||
|
|
||||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||||
const BootstrapPeerThreshold = 2
|
const BootstrapPeerThreshold = 2
|
||||||
|
|||||||
@@ -13,6 +13,17 @@ import (
|
|||||||
|
|
||||||
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
||||||
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
|
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
|
||||||
|
func IndexerIngestTopic(netName dtypes.NetworkName) string {
|
||||||
|
|
||||||
|
nn := string(netName)
|
||||||
|
// The network name testnetnet is here for historical reasons.
|
||||||
|
// Going forward we aim to use the name `mainnet` where possible.
|
||||||
|
if nn == "testnetnet" {
|
||||||
|
nn = "mainnet"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "/indexer/ingest/" + nn
|
||||||
|
}
|
||||||
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
||||||
return protocol.ID("/fil/kad/" + string(netName))
|
return protocol.ID("/fil/kad/" + string(netName))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ func BuildTypeString() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildVersion is the local build version
|
// BuildVersion is the local build version
|
||||||
const BuildVersion = "1.14.2"
|
const BuildVersion = "1.15.2-dev"
|
||||||
|
|
||||||
func UserVersion() string {
|
func UserVersion() string {
|
||||||
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
|
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package adt
|
package adt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -44,6 +45,7 @@ func TestDiffAdtArray(t *testing.T) {
|
|||||||
|
|
||||||
changes := new(TestDiffArray)
|
changes := new(TestDiffArray)
|
||||||
|
|
||||||
|
//stm: @CHAIN_ADT_ARRAY_DIFF_001
|
||||||
assert.NoError(t, DiffAdtArray(arrA, arrB, changes))
|
assert.NoError(t, DiffAdtArray(arrA, arrB, changes))
|
||||||
assert.NotNil(t, changes)
|
assert.NotNil(t, changes)
|
||||||
|
|
||||||
@@ -98,6 +100,7 @@ func TestDiffAdtMap(t *testing.T) {
|
|||||||
|
|
||||||
changes := new(TestDiffMap)
|
changes := new(TestDiffMap)
|
||||||
|
|
||||||
|
//stm: @CHAIN_ADT_MAP_DIFF_001
|
||||||
assert.NoError(t, DiffAdtMap(mapA, mapB, changes))
|
assert.NoError(t, DiffAdtMap(mapA, mapB, changes))
|
||||||
assert.NotNil(t, changes)
|
assert.NotNil(t, changes)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package aerrors_test
|
package aerrors_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFatalError(t *testing.T) {
|
func TestFatalError(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_ACTOR_ERRORS_001
|
||||||
e1 := xerrors.New("out of disk space")
|
e1 := xerrors.New("out of disk space")
|
||||||
e2 := xerrors.Errorf("could not put node: %w", e1)
|
e2 := xerrors.Errorf("could not put node: %w", e1)
|
||||||
e3 := xerrors.Errorf("could not save head: %w", e2)
|
e3 := xerrors.Errorf("could not save head: %w", e2)
|
||||||
@@ -24,6 +26,7 @@ func TestFatalError(t *testing.T) {
|
|||||||
assert.True(t, IsFatal(aw4), "should be fatal")
|
assert.True(t, IsFatal(aw4), "should be fatal")
|
||||||
}
|
}
|
||||||
func TestAbsorbeError(t *testing.T) {
|
func TestAbsorbeError(t *testing.T) {
|
||||||
|
//stm: @OTHER_IMPLEMENTATION_ACTOR_ERRORS_001
|
||||||
e1 := xerrors.New("EOF")
|
e1 := xerrors.New("EOF")
|
||||||
e2 := xerrors.Errorf("could not decode: %w", e1)
|
e2 := xerrors.Errorf("could not decode: %w", e1)
|
||||||
ae := Absorb(e2, 35, "failed to decode CBOR")
|
ae := Absorb(e2, 35, "failed to decode CBOR")
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
verifreg7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -62,6 +63,11 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) {
|
|||||||
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RemoveDataCapProposal = verifreg{{.latestVersion}}.RemoveDataCapProposal
|
||||||
|
type RemoveDataCapRequest = verifreg{{.latestVersion}}.RemoveDataCapRequest
|
||||||
|
type RemoveDataCapParams = verifreg{{.latestVersion}}.RemoveDataCapParams
|
||||||
|
type RmDcProposalID = verifreg{{.latestVersion}}.RmDcProposalID
|
||||||
|
const SignatureDomainSeparation_RemoveDataCap = verifreg{{.latestVersion}}.SignatureDomainSeparation_RemoveDataCap
|
||||||
|
|
||||||
type State interface {
|
type State interface {
|
||||||
cbor.Marshaler
|
cbor.Marshaler
|
||||||
@@ -69,6 +75,7 @@ type State interface {
|
|||||||
RootKey() (address.Address, error)
|
RootKey() (address.Address, error)
|
||||||
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||||
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||||
|
RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error)
|
||||||
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||||
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||||
GetState() interface{}
|
GetState() interface{}
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ func (s *state{{.v}}) VerifierDataCap(addr address.Address) (bool, abi.StoragePo
|
|||||||
return getDataCap(s.store, actors.Version{{.v}}, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version{{.v}}, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state{{.v}}) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version{{.v}}, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state{{.v}}) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state{{.v}}) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version{{.v}}, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version{{.v}}, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -77,6 +81,11 @@ func (s *state{{.v}}) verifiers() (adt.Map, error) {
|
|||||||
return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
return adt{{.v}}.AsMap(s.store, s.Verifiers{{if (ge .v 3)}}, builtin{{.v}}.DefaultHamtBitwidth{{end}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state{{.v}}) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
{{if le .v 6}}return nil, nil
|
||||||
|
{{else}}return adt{{.v}}.AsMap(s.store, s.RemoveDataCapProposalIDs, builtin{{.v}}.DefaultHamtBitwidth){{end}}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state{{.v}}) GetState() interface{} {
|
func (s *state{{.v}}) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -50,3 +51,28 @@ func forEachCap(store adt.Store, ver actors.Version, root rootFunc, cb func(addr
|
|||||||
return cb(a, dcap)
|
return cb(a, dcap)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRemoveDataCapProposalID(store adt.Store, ver actors.Version, root rootFunc, verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
if verifier.Protocol() != address.ID {
|
||||||
|
return false, 0, xerrors.Errorf("can only look up ID addresses")
|
||||||
|
}
|
||||||
|
if client.Protocol() != address.ID {
|
||||||
|
return false, 0, xerrors.Errorf("can only look up ID addresses")
|
||||||
|
}
|
||||||
|
vh, err := root()
|
||||||
|
if err != nil {
|
||||||
|
return false, 0, xerrors.Errorf("loading verifreg: %w", err)
|
||||||
|
}
|
||||||
|
if vh == nil {
|
||||||
|
return false, 0, xerrors.Errorf("remove data cap proposal hamt not found. you are probably using an incompatible version of actors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var id verifreg.RmDcProposalID
|
||||||
|
if found, err := vh.Get(abi.NewAddrPairKey(verifier, client), &id); err != nil {
|
||||||
|
return false, 0, xerrors.Errorf("looking up addr pair: %w", err)
|
||||||
|
} else if !found {
|
||||||
|
return false, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, id.ProposalID, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version0, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version0, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state0) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version0, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version0, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version0, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -69,6 +73,11 @@ func (s *state0) verifiers() (adt.Map, error) {
|
|||||||
return adt0.AsMap(s.store, s.Verifiers)
|
return adt0.AsMap(s.store, s.Verifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state0) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state0) GetState() interface{} {
|
func (s *state0) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ func (s *state2) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version2, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version2, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state2) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version2, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state2) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state2) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version2, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version2, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -69,6 +73,11 @@ func (s *state2) verifiers() (adt.Map, error) {
|
|||||||
return adt2.AsMap(s.store, s.Verifiers)
|
return adt2.AsMap(s.store, s.Verifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state2) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state2) GetState() interface{} {
|
func (s *state2) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ func (s *state3) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version3, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version3, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state3) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version3, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state3) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state3) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version3, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version3, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -70,6 +74,11 @@ func (s *state3) verifiers() (adt.Map, error) {
|
|||||||
return adt3.AsMap(s.store, s.Verifiers, builtin3.DefaultHamtBitwidth)
|
return adt3.AsMap(s.store, s.Verifiers, builtin3.DefaultHamtBitwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state3) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state3) GetState() interface{} {
|
func (s *state3) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ func (s *state4) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version4, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version4, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state4) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version4, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state4) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state4) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version4, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version4, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -70,6 +74,11 @@ func (s *state4) verifiers() (adt.Map, error) {
|
|||||||
return adt4.AsMap(s.store, s.Verifiers, builtin4.DefaultHamtBitwidth)
|
return adt4.AsMap(s.store, s.Verifiers, builtin4.DefaultHamtBitwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state4) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state4) GetState() interface{} {
|
func (s *state4) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ func (s *state5) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version5, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version5, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state5) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version5, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state5) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state5) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version5, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version5, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -70,6 +74,11 @@ func (s *state5) verifiers() (adt.Map, error) {
|
|||||||
return adt5.AsMap(s.store, s.Verifiers, builtin5.DefaultHamtBitwidth)
|
return adt5.AsMap(s.store, s.Verifiers, builtin5.DefaultHamtBitwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state5) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state5) GetState() interface{} {
|
func (s *state5) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ func (s *state6) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version6, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version6, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state6) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version6, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state6) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state6) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version6, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version6, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -70,6 +74,11 @@ func (s *state6) verifiers() (adt.Map, error) {
|
|||||||
return adt6.AsMap(s.store, s.Verifiers, builtin6.DefaultHamtBitwidth)
|
return adt6.AsMap(s.store, s.Verifiers, builtin6.DefaultHamtBitwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state6) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state6) GetState() interface{} {
|
func (s *state6) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ func (s *state7) VerifierDataCap(addr address.Address) (bool, abi.StoragePower,
|
|||||||
return getDataCap(s.store, actors.Version7, s.verifiers, addr)
|
return getDataCap(s.store, actors.Version7, s.verifiers, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state7) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
|
||||||
|
return getRemoveDataCapProposalID(s.store, actors.Version7, s.removeDataCapProposalIDs, verifier, client)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state7) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state7) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, actors.Version7, s.verifiers, cb)
|
return forEachCap(s.store, actors.Version7, s.verifiers, cb)
|
||||||
}
|
}
|
||||||
@@ -70,6 +74,10 @@ func (s *state7) verifiers() (adt.Map, error) {
|
|||||||
return adt7.AsMap(s.store, s.Verifiers, builtin7.DefaultHamtBitwidth)
|
return adt7.AsMap(s.store, s.Verifiers, builtin7.DefaultHamtBitwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state7) removeDataCapProposalIDs() (adt.Map, error) {
|
||||||
|
return adt7.AsMap(s.store, s.RemoveDataCapProposalIDs, builtin7.DefaultHamtBitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state7) GetState() interface{} {
|
func (s *state7) GetState() interface{} {
|
||||||
return &s.State
|
return &s.State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
verifreg7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/verifreg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -151,12 +152,20 @@ func GetActorCodeID(av actors.Version) (cid.Cid, error) {
|
|||||||
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RemoveDataCapProposal = verifreg7.RemoveDataCapProposal
|
||||||
|
type RemoveDataCapRequest = verifreg7.RemoveDataCapRequest
|
||||||
|
type RemoveDataCapParams = verifreg7.RemoveDataCapParams
|
||||||
|
type RmDcProposalID = verifreg7.RmDcProposalID
|
||||||
|
|
||||||
|
const SignatureDomainSeparation_RemoveDataCap = verifreg7.SignatureDomainSeparation_RemoveDataCap
|
||||||
|
|
||||||
type State interface {
|
type State interface {
|
||||||
cbor.Marshaler
|
cbor.Marshaler
|
||||||
|
|
||||||
RootKey() (address.Address, error)
|
RootKey() (address.Address, error)
|
||||||
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||||
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||||
|
RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error)
|
||||||
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||||
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||||
GetState() interface{}
|
GetState() interface{}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package policy
|
package policy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -22,6 +23,7 @@ func TestSupportedProofTypes(t *testing.T) {
|
|||||||
for t := range miner0.SupportedProofTypes {
|
for t := range miner0.SupportedProofTypes {
|
||||||
oldTypes = append(oldTypes, t)
|
oldTypes = append(oldTypes, t)
|
||||||
}
|
}
|
||||||
|
//stm: @BLOCKCHAIN_POLICY_SET_MAX_SUPPORTED_PROOF_TYPES_001
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
SetSupportedProofTypes(oldTypes...)
|
SetSupportedProofTypes(oldTypes...)
|
||||||
})
|
})
|
||||||
@@ -33,6 +35,7 @@ func TestSupportedProofTypes(t *testing.T) {
|
|||||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
//stm: @BLOCKCHAIN_POLICY_ADD_MAX_SUPPORTED_PROOF_TYPES_001
|
||||||
AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1)
|
AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1)
|
||||||
require.EqualValues(t,
|
require.EqualValues(t,
|
||||||
miner0.SupportedProofTypes,
|
miner0.SupportedProofTypes,
|
||||||
@@ -45,6 +48,7 @@ func TestSupportedProofTypes(t *testing.T) {
|
|||||||
|
|
||||||
// Tests assumptions about policies being the same between actor versions.
|
// Tests assumptions about policies being the same between actor versions.
|
||||||
func TestAssumptions(t *testing.T) {
|
func TestAssumptions(t *testing.T) {
|
||||||
|
//stm: @BLOCKCHAIN_POLICY_ASSUMPTIONS_001
|
||||||
require.EqualValues(t, miner0.SupportedProofTypes, miner2.PreCommitSealProofTypesV0)
|
require.EqualValues(t, miner0.SupportedProofTypes, miner2.PreCommitSealProofTypesV0)
|
||||||
require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay)
|
require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay)
|
||||||
require.Equal(t, miner0.MaxSectorExpirationExtension, miner2.MaxSectorExpirationExtension)
|
require.Equal(t, miner0.MaxSectorExpirationExtension, miner2.MaxSectorExpirationExtension)
|
||||||
@@ -58,6 +62,7 @@ func TestAssumptions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPartitionSizes(t *testing.T) {
|
func TestPartitionSizes(t *testing.T) {
|
||||||
|
//stm: @CHAIN_ACTOR_PARTITION_SIZES_001
|
||||||
for _, p := range abi.SealProofInfos {
|
for _, p := range abi.SealProofInfos {
|
||||||
sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p.WindowPoStProof)
|
sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p.WindowPoStProof)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -71,6 +76,7 @@ func TestPartitionSizes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPoStSize(t *testing.T) {
|
func TestPoStSize(t *testing.T) {
|
||||||
|
//stm: @BLOCKCHAIN_POLICY_GET_MAX_POST_PARTITIONS_001
|
||||||
v12PoStSize, err := GetMaxPoStPartitions(network.Version12, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1)
|
v12PoStSize, err := GetMaxPoStPartitions(network.Version12, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1)
|
||||||
require.Equal(t, 4, v12PoStSize)
|
require.Equal(t, 4, v12PoStSize)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
start := build.Clock.Now()
|
start := build.Clock.Now()
|
||||||
log.Infow("start fetching randomness", "round", round)
|
log.Debugw("start fetching randomness", "round", round)
|
||||||
resp, err := db.client.Get(ctx, round)
|
resp, err := db.client.Get(ctx, round)
|
||||||
|
|
||||||
var br beacon.Response
|
var br beacon.Response
|
||||||
@@ -152,7 +152,7 @@ func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Re
|
|||||||
br.Entry.Round = resp.Round()
|
br.Entry.Round = resp.Round()
|
||||||
br.Entry.Data = resp.Signature()
|
br.Entry.Data = resp.Signature()
|
||||||
}
|
}
|
||||||
log.Infow("done fetching randomness", "round", round, "took", build.Clock.Since(start))
|
log.Debugw("done fetching randomness", "round", round, "took", build.Clock.Since(start))
|
||||||
out <- br
|
out <- br
|
||||||
close(out)
|
close(out)
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//stm: ignore
|
||||||
|
//Only tests external library behavior, therefore it should not be annotated
|
||||||
package drand
|
package drand
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
+4
-4
@@ -13,7 +13,7 @@ func (syncer *Syncer) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) e
|
|||||||
return xerrors.Errorf("called with empty tsk")
|
return xerrors.Errorf("called with empty tsk")
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, err := syncer.ChainStore().LoadTipSet(tsk)
|
ts, err := syncer.ChainStore().LoadTipSet(ctx, tsk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tss, err := syncer.Exchange.GetBlocks(ctx, tsk, 1)
|
tss, err := syncer.Exchange.GetBlocks(ctx, tsk, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -28,7 +28,7 @@ func (syncer *Syncer) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) e
|
|||||||
return xerrors.Errorf("failed to switch chain when syncing checkpoint: %w", err)
|
return xerrors.Errorf("failed to switch chain when syncing checkpoint: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := syncer.ChainStore().SetCheckpoint(ts); err != nil {
|
if err := syncer.ChainStore().SetCheckpoint(ctx, ts); err != nil {
|
||||||
return xerrors.Errorf("failed to set the chain checkpoint: %w", err)
|
return xerrors.Errorf("failed to set the chain checkpoint: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ func (syncer *Syncer) switchChain(ctx context.Context, ts *types.TipSet) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if anc, err := syncer.store.IsAncestorOf(ts, hts); err == nil && anc {
|
if anc, err := syncer.store.IsAncestorOf(ctx, ts, hts); err == nil && anc {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ func (syncer *Syncer) switchChain(ctx context.Context, ts *types.TipSet) error {
|
|||||||
return xerrors.Errorf("failed to collect chain for checkpoint: %w", err)
|
return xerrors.Errorf("failed to collect chain for checkpoint: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := syncer.ChainStore().SetHead(ts); err != nil {
|
if err := syncer.ChainStore().SetHead(ctx, ts); err != nil {
|
||||||
return xerrors.Errorf("failed to set the chain head: %w", err)
|
return xerrors.Errorf("failed to set the chain head: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package filcns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/rand"
|
"github.com/filecoin-project/lotus/chain/rand"
|
||||||
@@ -32,6 +33,7 @@ import (
|
|||||||
|
|
||||||
/* inline-gen end */
|
/* inline-gen end */
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/blockstore"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
@@ -92,29 +94,38 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
|||||||
partDone()
|
partDone()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) {
|
ctx = blockstore.WithHotView(ctx)
|
||||||
|
makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (vm.Interface, error) {
|
||||||
vmopt := &vm.VMOpts{
|
vmopt := &vm.VMOpts{
|
||||||
StateBase: base,
|
StateBase: base,
|
||||||
Epoch: epoch,
|
Epoch: e,
|
||||||
Rand: r,
|
Rand: r,
|
||||||
Bstore: sm.ChainStore().StateBlockstore(),
|
Bstore: sm.ChainStore().StateBlockstore(),
|
||||||
Actors: NewActorRegistry(),
|
Actors: NewActorRegistry(),
|
||||||
Syscalls: sm.Syscalls,
|
Syscalls: sm.Syscalls,
|
||||||
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
CircSupplyCalc: sm.GetVMCirculatingSupply,
|
||||||
NtwkVersion: sm.GetNtwkVersion,
|
NetworkVersion: sm.GetNetworkVersion(ctx, e),
|
||||||
BaseFee: baseFee,
|
BaseFee: baseFee,
|
||||||
LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts),
|
LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if os.Getenv("LOTUS_USE_FVM_EXPERIMENTAL") == "1" {
|
||||||
|
// This is needed so that the FVM does not have to duplicate the genesis vesting schedule, one
|
||||||
|
// of the components of the circ supply calc.
|
||||||
|
// This field is NOT needed by the LegacyVM, and also NOT needed by the FVM from v15 onwards.
|
||||||
|
filVested, err := sm.GetFilVested(ctx, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vmopt.FilVested = filVested
|
||||||
|
return vm.NewFVM(ctx, vmopt)
|
||||||
|
}
|
||||||
|
|
||||||
return sm.VMConstructor()(ctx, vmopt)
|
return sm.VMConstructor()(ctx, vmopt)
|
||||||
}
|
}
|
||||||
|
|
||||||
vmi, err := makeVmWithBaseState(pstate)
|
runCron := func(vmCron vm.Interface, epoch abi.ChainEpoch) error {
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
runCron := func(epoch abi.ChainEpoch) error {
|
|
||||||
cronMsg := &types.Message{
|
cronMsg := &types.Message{
|
||||||
To: cron.Address,
|
To: cron.Address,
|
||||||
From: builtin.SystemActorAddr,
|
From: builtin.SystemActorAddr,
|
||||||
@@ -126,59 +137,58 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
|||||||
Method: cron.Methods.EpochTick,
|
Method: cron.Methods.EpochTick,
|
||||||
Params: nil,
|
Params: nil,
|
||||||
}
|
}
|
||||||
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
|
ret, err := vmCron.ApplyImplicitMessage(ctx, cronMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("running cron: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if em != nil {
|
if em != nil {
|
||||||
if err := em.MessageApplied(ctx, ts, cronMsg.Cid(), cronMsg, ret, true); err != nil {
|
if err := em.MessageApplied(ctx, ts, cronMsg.Cid(), cronMsg, ret, true); err != nil {
|
||||||
return xerrors.Errorf("callback failed on cron message: %w", err)
|
return xerrors.Errorf("callback failed on cron message: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ret.ExitCode != 0 {
|
if ret.ExitCode != 0 {
|
||||||
return xerrors.Errorf("CheckProofSubmissions exit was non-zero: %d", ret.ExitCode)
|
return xerrors.Errorf("cron exit was non-zero: %d", ret.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := parentEpoch; i < epoch; i++ {
|
for i := parentEpoch; i < epoch; i++ {
|
||||||
|
var err error
|
||||||
if i > parentEpoch {
|
if i > parentEpoch {
|
||||||
// run cron for null rounds if any
|
vmCron, err := makeVmWithBaseStateAndEpoch(pstate, i)
|
||||||
if err := runCron(i); err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, err
|
return cid.Undef, cid.Undef, xerrors.Errorf("making cron vm: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pstate, err = vmi.Flush(ctx)
|
// run cron for null rounds if any
|
||||||
|
if err = runCron(vmCron, i); err != nil {
|
||||||
|
return cid.Undef, cid.Undef, xerrors.Errorf("running cron: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pstate, err = vmCron.Flush(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("flushing vm: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("flushing cron vm: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle state forks
|
// handle state forks
|
||||||
// XXX: The state tree
|
// XXX: The state tree
|
||||||
newState, err := sm.HandleStateForks(ctx, pstate, i, em, ts)
|
pstate, err = sm.HandleStateForks(ctx, pstate, i, em, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pstate != newState {
|
|
||||||
vmi, err = makeVmWithBaseState(newState)
|
|
||||||
if err != nil {
|
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = vmi.SetBlockHeight(ctx, i+1); err != nil {
|
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("error advancing vm an epoch: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pstate = newState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partDone()
|
partDone()
|
||||||
partDone = metrics.Timer(ctx, metrics.VMApplyMessages)
|
partDone = metrics.Timer(ctx, metrics.VMApplyMessages)
|
||||||
|
|
||||||
|
vmi, err := makeVmWithBaseStateAndEpoch(pstate, epoch)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
var receipts []cbg.CBORMarshaler
|
var receipts []cbg.CBORMarshaler
|
||||||
processedMsgs := make(map[cid.Cid]struct{})
|
processedMsgs := make(map[cid.Cid]struct{})
|
||||||
for _, b := range bms {
|
for _, b := range bms {
|
||||||
@@ -246,7 +256,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
|
|||||||
partDone()
|
partDone()
|
||||||
partDone = metrics.Timer(ctx, metrics.VMApplyCron)
|
partDone = metrics.Timer(ctx, metrics.VMApplyCron)
|
||||||
|
|
||||||
if err := runCron(epoch); err != nil {
|
if err := runCron(vmi, epoch); err != nil {
|
||||||
return cid.Cid{}, cid.Cid{}, err
|
return cid.Cid{}, cid.Cid{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +304,7 @@ func (t *TipSetExecutor) ExecuteTipSet(ctx context.Context, sm *stmgr.StateManag
|
|||||||
var parentEpoch abi.ChainEpoch
|
var parentEpoch abi.ChainEpoch
|
||||||
pstate := blks[0].ParentStateRoot
|
pstate := blks[0].ParentStateRoot
|
||||||
if blks[0].Height > 0 {
|
if blks[0].Height > 0 {
|
||||||
parent, err := sm.ChainStore().GetBlock(blks[0].Parents[0])
|
parent, err := sm.ChainStore().GetBlock(ctx, blks[0].Parents[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("getting parent block: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("getting parent block: %w", err)
|
||||||
}
|
}
|
||||||
@@ -302,9 +312,9 @@ func (t *TipSetExecutor) ExecuteTipSet(ctx context.Context, sm *stmgr.StateManag
|
|||||||
parentEpoch = parent.Height
|
parentEpoch = parent.Height
|
||||||
}
|
}
|
||||||
|
|
||||||
r := rand.NewStateRand(sm.ChainStore(), ts.Cids(), sm.Beacon())
|
r := rand.NewStateRand(sm.ChainStore(), ts.Cids(), sm.Beacon(), sm.GetNetworkVersion)
|
||||||
|
|
||||||
blkmsgs, err := sm.ChainStore().BlockMsgsForTipset(ts)
|
blkmsgs, err := sm.ChainStore().BlockMsgsForTipset(ctx, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("getting block messages for tipset: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("getting block messages for tipset: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,19 +90,19 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
|
|||||||
|
|
||||||
h := b.Header
|
h := b.Header
|
||||||
|
|
||||||
baseTs, err := filec.store.LoadTipSet(types.NewTipSetKey(h.Parents...))
|
baseTs, err := filec.store.LoadTipSet(ctx, types.NewTipSetKey(h.Parents...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
|
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
winPoStNv := filec.sm.GetNtwkVersion(ctx, baseTs.Height())
|
winPoStNv := filec.sm.GetNetworkVersion(ctx, baseTs.Height())
|
||||||
|
|
||||||
lbts, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, filec.sm, baseTs, h.Height)
|
lbts, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, filec.sm, baseTs, h.Height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to get lookback tipset for block: %w", err)
|
return xerrors.Errorf("failed to get lookback tipset for block: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prevBeacon, err := filec.store.GetLatestBeaconEntry(baseTs)
|
prevBeacon, err := filec.store.GetLatestBeaconEntry(ctx, baseTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
|
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if stateroot != h.ParentStateRoot {
|
if stateroot != h.ParentStateRoot {
|
||||||
msgs, err := filec.store.MessagesForTipset(baseTs)
|
msgs, err := filec.store.MessagesForTipset(ctx, baseTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
|
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
|
||||||
} else {
|
} else {
|
||||||
@@ -182,7 +182,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", stateroot, h.ParentStateRoot)
|
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", h.ParentStateRoot, stateroot)
|
||||||
}
|
}
|
||||||
|
|
||||||
if precp != h.ParentMessageReceipts {
|
if precp != h.ParentMessageReceipts {
|
||||||
@@ -458,7 +458,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
|
|
||||||
stateroot, _, err := filec.sm.TipSetState(ctx, baseTs)
|
stateroot, _, err := filec.sm.TipSetState(ctx, baseTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("failed to compute tipsettate for %s: %w", baseTs.Key(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
st, err := state.LoadStateTree(filec.store.ActorStore(ctx), stateroot)
|
st, err := state.LoadStateTree(filec.store.ActorStore(ctx), stateroot)
|
||||||
@@ -466,8 +466,8 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
return xerrors.Errorf("failed to load base state tree: %w", err)
|
return xerrors.Errorf("failed to load base state tree: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nv := filec.sm.GetNtwkVersion(ctx, b.Header.Height)
|
nv := filec.sm.GetNetworkVersion(ctx, b.Header.Height)
|
||||||
pl := vm.PricelistByEpoch(baseTs.Height())
|
pl := vm.PricelistByEpochAndNetworkVersion(b.Header.Height, nv)
|
||||||
var sumGasLimit int64
|
var sumGasLimit int64
|
||||||
checkMsg := func(msg types.ChainMsg) error {
|
checkMsg := func(msg types.ChainMsg) error {
|
||||||
m := msg.VMMessage()
|
m := msg.VMMessage()
|
||||||
@@ -475,7 +475,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
// Phase 1: syntactic validation, as defined in the spec
|
// Phase 1: syntactic validation, as defined in the spec
|
||||||
minGas := pl.OnChainMessage(msg.ChainLength())
|
minGas := pl.OnChainMessage(msg.ChainLength())
|
||||||
if err := m.ValidForBlockInclusion(minGas.Total(), nv); err != nil {
|
if err := m.ValidForBlockInclusion(minGas.Total(), nv); err != nil {
|
||||||
return err
|
return xerrors.Errorf("msg %s invalid for block inclusion: %w", m.Cid(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidForBlockInclusion checks if any single message does not exceed BlockGasLimit
|
// ValidForBlockInclusion checks if any single message does not exceed BlockGasLimit
|
||||||
@@ -488,10 +488,10 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
// Phase 2: (Partial) semantic validation:
|
// Phase 2: (Partial) semantic validation:
|
||||||
// the sender exists and is an account actor, and the nonces make sense
|
// the sender exists and is an account actor, and the nonces make sense
|
||||||
var sender address.Address
|
var sender address.Address
|
||||||
if filec.sm.GetNtwkVersion(ctx, b.Header.Height) >= network.Version13 {
|
if filec.sm.GetNetworkVersion(ctx, b.Header.Height) >= network.Version13 {
|
||||||
sender, err = st.LookupID(m.From)
|
sender, err = st.LookupID(m.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sender = m.From
|
sender = m.From
|
||||||
@@ -528,7 +528,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
|
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := store.PutMessage(tmpbs, m)
|
c, err := store.PutMessage(ctx, tmpbs, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
|
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
|
||||||
}
|
}
|
||||||
@@ -541,7 +541,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
|
|
||||||
smArr := blockadt.MakeEmptyArray(tmpstore)
|
smArr := blockadt.MakeEmptyArray(tmpstore)
|
||||||
for i, m := range b.SecpkMessages {
|
for i, m := range b.SecpkMessages {
|
||||||
if filec.sm.GetNtwkVersion(ctx, b.Header.Height) >= network.Version14 {
|
if filec.sm.GetNetworkVersion(ctx, b.Header.Height) >= network.Version14 {
|
||||||
if m.Signature.Type != crypto.SigTypeSecp256k1 {
|
if m.Signature.Type != crypto.SigTypeSecp256k1 {
|
||||||
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
|
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
|
||||||
}
|
}
|
||||||
@@ -562,7 +562,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
return xerrors.Errorf("secpk message %s has invalid signature: %w", m.Cid(), err)
|
return xerrors.Errorf("secpk message %s has invalid signature: %w", m.Cid(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := store.PutMessage(tmpbs, m)
|
c, err := store.PutMessage(ctx, tmpbs, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
|
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
|
||||||
}
|
}
|
||||||
@@ -574,12 +574,13 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
|
|
||||||
bmroot, err := bmArr.Root()
|
bmroot, err := bmArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("failed to root bls msgs: %w", err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smroot, err := smArr.Root()
|
smroot, err := smArr.Root()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("failed to root secp msgs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mrcid, err := tmpstore.Put(ctx, &types.MsgMeta{
|
mrcid, err := tmpstore.Put(ctx, &types.MsgMeta{
|
||||||
@@ -587,7 +588,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
SecpkMessages: smroot,
|
SecpkMessages: smroot,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("failed to put msg meta: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.Header.Messages != mrcid {
|
if b.Header.Messages != mrcid {
|
||||||
@@ -595,7 +596,12 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finally, flush.
|
// Finally, flush.
|
||||||
return vm.Copy(ctx, tmpbs, filec.store.ChainBlockstore(), mrcid)
|
err = vm.Copy(ctx, tmpbs, filec.store.ChainBlockstore(), mrcid)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to flush:%w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (filec *FilecoinEC) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool {
|
func (filec *FilecoinEC) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||||
pts, err := filec.sm.ChainStore().LoadTipSet(bt.Parents)
|
pts, err := filec.sm.ChainStore().LoadTipSet(ctx, bt.Parents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to load parent tipset: %w", err)
|
return nil, xerrors.Errorf("failed to load parent tipset: %w", err)
|
||||||
}
|
}
|
||||||
@@ -59,14 +59,14 @@ func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.
|
|||||||
blsSigs = append(blsSigs, msg.Signature)
|
blsSigs = append(blsSigs, msg.Signature)
|
||||||
blsMessages = append(blsMessages, &msg.Message)
|
blsMessages = append(blsMessages, &msg.Message)
|
||||||
|
|
||||||
c, err := filec.sm.ChainStore().PutMessage(&msg.Message)
|
c, err := filec.sm.ChainStore().PutMessage(ctx, &msg.Message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
blsMsgCids = append(blsMsgCids, c)
|
blsMsgCids = append(blsMsgCids, c)
|
||||||
} else if msg.Signature.Type == crypto.SigTypeSecp256k1 {
|
} else if msg.Signature.Type == crypto.SigTypeSecp256k1 {
|
||||||
c, err := filec.sm.ChainStore().PutMessage(msg)
|
c, err := filec.sm.ChainStore().PutMessage(ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ func splitGenesisMultisig0(ctx context.Context, em stmgr.ExecMonitor, addr addre
|
|||||||
|
|
||||||
// TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting
|
// TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting
|
||||||
func resetGenesisMsigs0(ctx context.Context, sm *stmgr.StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error {
|
func resetGenesisMsigs0(ctx context.Context, sm *stmgr.StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error {
|
||||||
gb, err := sm.ChainStore().GetGenesis()
|
gb, err := sm.ChainStore().GetGenesis(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting genesis block: %w", err)
|
return xerrors.Errorf("getting genesis block: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package events
|
package events
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -87,7 +88,7 @@ func (fcs *fakeCS) ChainGetPath(ctx context.Context, from, to types.TipSetKey) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copied from the chainstore
|
// copied from the chainstore
|
||||||
revert, apply, err := store.ReorgOps(func(tsk types.TipSetKey) (*types.TipSet, error) {
|
revert, apply, err := store.ReorgOps(ctx, func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||||
return fcs.ChainGetTipSet(ctx, tsk)
|
return fcs.ChainGetTipSet(ctx, tsk)
|
||||||
}, fromTs, toTs)
|
}, fromTs, toTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -358,6 +359,7 @@ func (fcs *fakeCS) advance(rev, app, drop int, msgs map[int]cid.Cid, nulls ...in
|
|||||||
var _ EventAPI = &fakeCS{}
|
var _ EventAPI = &fakeCS{}
|
||||||
|
|
||||||
func TestAt(t *testing.T) {
|
func TestAt(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -418,6 +420,7 @@ func TestAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtNullTrigger(t *testing.T) {
|
func TestAtNullTrigger(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -447,6 +450,7 @@ func TestAtNullTrigger(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtNullConf(t *testing.T) {
|
func TestAtNullConf(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -485,6 +489,7 @@ func TestAtNullConf(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtStart(t *testing.T) {
|
func TestAtStart(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -515,6 +520,7 @@ func TestAtStart(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtStartConfidence(t *testing.T) {
|
func TestAtStartConfidence(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -541,6 +547,7 @@ func TestAtStartConfidence(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtChained(t *testing.T) {
|
func TestAtChained(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -571,6 +578,7 @@ func TestAtChained(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtChainedConfidence(t *testing.T) {
|
func TestAtChainedConfidence(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -601,6 +609,7 @@ func TestAtChainedConfidence(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAtChainedConfidenceNull(t *testing.T) {
|
func TestAtChainedConfidenceNull(t *testing.T) {
|
||||||
|
//stm: @EVENTS_HEIGHT_CHAIN_AT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -632,6 +641,7 @@ func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Messag
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCalled(t *testing.T) {
|
func TestCalled(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -837,6 +847,7 @@ func TestCalled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCalledTimeout(t *testing.T) {
|
func TestCalledTimeout(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -897,6 +908,7 @@ func TestCalledTimeout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCalledOrder(t *testing.T) {
|
func TestCalledOrder(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -953,6 +965,7 @@ func TestCalledOrder(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCalledNull(t *testing.T) {
|
func TestCalledNull(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -1011,6 +1024,7 @@ func TestCalledNull(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveTriggersOnMessage(t *testing.T) {
|
func TestRemoveTriggersOnMessage(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -1094,6 +1108,7 @@ type testStateChange struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStateChanged(t *testing.T) {
|
func TestStateChanged(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -1179,6 +1194,7 @@ func TestStateChanged(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStateChangedRevert(t *testing.T) {
|
func TestStateChangedRevert(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -1255,6 +1271,7 @@ func TestStateChangedRevert(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStateChangedTimeout(t *testing.T) {
|
func TestStateChangedTimeout(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
timeoutHeight := abi.ChainEpoch(20)
|
timeoutHeight := abi.ChainEpoch(20)
|
||||||
confidence := 3
|
confidence := 3
|
||||||
|
|
||||||
@@ -1332,6 +1349,7 @@ func TestStateChangedTimeout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCalledMultiplePerEpoch(t *testing.T) {
|
func TestCalledMultiplePerEpoch(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
events, err := NewEvents(context.Background(), fcs)
|
events, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -1384,6 +1402,7 @@ func TestCalledMultiplePerEpoch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCachedSameBlock(t *testing.T) {
|
func TestCachedSameBlock(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
fcs := newFakeCS(t)
|
fcs := newFakeCS(t)
|
||||||
|
|
||||||
_, err := NewEvents(context.Background(), fcs)
|
_, err := NewEvents(context.Background(), fcs)
|
||||||
@@ -1418,6 +1437,7 @@ func (t *testObserver) Revert(_ context.Context, from, to *types.TipSet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestReconnect(t *testing.T) {
|
func TestReconnect(t *testing.T) {
|
||||||
|
//stm: @EVENTS_EVENTS_CALLED_001, @EVENTS_HEIGHT_REVERT_001
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ func NewMockAPI(bs blockstore.Blockstore) *MockAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
|
func (m *MockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
|
||||||
return m.bs.Has(c)
|
return m.bs.Has(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
func (m *MockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
||||||
blk, err := m.bs.Get(c)
|
blk, err := m.bs.Get(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("blockstore get: %w", err)
|
return nil, xerrors.Errorf("blockstore get: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -35,6 +36,12 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMarketPredicates(t *testing.T) {
|
func TestMarketPredicates(t *testing.T) {
|
||||||
|
//stm: @EVENTS_PREDICATES_ON_ACTOR_STATE_CHANGED_001, @EVENTS_PREDICATES_DEAL_STATE_CHANGED_001
|
||||||
|
//stm: @EVENTS_PREDICATES_DEAL_CHANGED_FOR_IDS
|
||||||
|
|
||||||
|
//stm: @EVENTS_PREDICATES_ON_BALANCE_CHANGED_001, @EVENTS_PREDICATES_BALANCE_CHANGED_FOR_ADDRESS_001
|
||||||
|
//stm: @EVENTS_PREDICATES_ON_DEAL_PROPOSAL_CHANGED_001, @EVENTS_PREDICATES_PROPOSAL_AMT_CHANGED_001
|
||||||
|
//stm: @EVENTS_PREDICATES_DEAL_STATE_CHANGED_001, @EVENTS_PREDICATES_DEAL_AMT_CHANGED_001
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := bstore.NewMemorySync()
|
bs := bstore.NewMemorySync()
|
||||||
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||||
@@ -333,6 +340,8 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMinerSectorChange(t *testing.T) {
|
func TestMinerSectorChange(t *testing.T) {
|
||||||
|
//stm: @EVENTS_PREDICATES_ON_ACTOR_STATE_CHANGED_001, @EVENTS_PREDICATES_MINER_ACTOR_CHANGE_001
|
||||||
|
//stm: @EVENTS_PREDICATES_MINER_SECTOR_CHANGE_001
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := bstore.NewMemorySync()
|
bs := bstore.NewMemorySync()
|
||||||
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package events
|
package events
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -92,6 +93,7 @@ func (h *cacheHarness) skip(n abi.ChainEpoch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTsCache(t *testing.T) {
|
func TestTsCache(t *testing.T) {
|
||||||
|
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001, @EVENTS_CACHE_GET_001, @EVENTS_CACHE_ADD_001
|
||||||
h := newCacheharness(t)
|
h := newCacheharness(t)
|
||||||
|
|
||||||
for i := 0; i < 9000; i++ {
|
for i := 0; i < 9000; i++ {
|
||||||
@@ -104,6 +106,8 @@ func TestTsCache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTsCacheNulls(t *testing.T) {
|
func TestTsCacheNulls(t *testing.T) {
|
||||||
|
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001, @EVENTS_CACHE_GET_CHAIN_TIPSET_BEFORE_001, @EVENTS_CACHE_GET_CHAIN_TIPSET_AFTER_001
|
||||||
|
//stm: @EVENTS_CACHE_GET_001, @EVENTS_CACHE_ADD_001
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
h := newCacheharness(t)
|
h := newCacheharness(t)
|
||||||
|
|
||||||
@@ -182,6 +186,7 @@ func (tc *tsCacheAPIStorageCallCounter) ChainGetTipSet(ctx context.Context, tsk
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTsCacheEmpty(t *testing.T) {
|
func TestTsCacheEmpty(t *testing.T) {
|
||||||
|
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001
|
||||||
// Calling best on an empty cache should just call out to the chain API
|
// Calling best on an empty cache should just call out to the chain API
|
||||||
callCounter := &tsCacheAPIStorageCallCounter{t: t}
|
callCounter := &tsCacheAPIStorageCallCounter{t: t}
|
||||||
tsc := newTSCache(callCounter, 50)
|
tsc := newTSCache(callCounter, 50)
|
||||||
@@ -191,6 +196,7 @@ func TestTsCacheEmpty(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTsCacheSkip(t *testing.T) {
|
func TestTsCacheSkip(t *testing.T) {
|
||||||
|
//stm: @EVENTS_CACHE_GET_CHAIN_HEAD_001, @EVENTS_CACHE_GET_001, @EVENTS_CACHE_ADD_001
|
||||||
h := newCacheharness(t)
|
h := newCacheharness(t)
|
||||||
|
|
||||||
ts, err := types.NewTipSet([]*types.BlockHeader{{
|
ts, err := types.NewTipSet([]*types.BlockHeader{{
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ func (s *server) serviceRequest(ctx context.Context, req *validatedRequest) (*Re
|
|||||||
_, span := trace.StartSpan(ctx, "chainxchg.ServiceRequest")
|
_, span := trace.StartSpan(ctx, "chainxchg.ServiceRequest")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
chain, err := collectChainSegment(s.cs, req)
|
chain, err := collectChainSegment(ctx, s.cs, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("block sync request: collectChainSegment failed: ", err)
|
log.Warn("block sync request: collectChainSegment failed: ", err)
|
||||||
return &Response{
|
return &Response{
|
||||||
@@ -156,13 +156,13 @@ func (s *server) serviceRequest(ctx context.Context, req *validatedRequest) (*Re
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectChainSegment(cs *store.ChainStore, req *validatedRequest) ([]*BSTipSet, error) {
|
func collectChainSegment(ctx context.Context, cs *store.ChainStore, req *validatedRequest) ([]*BSTipSet, error) {
|
||||||
var bstips []*BSTipSet
|
var bstips []*BSTipSet
|
||||||
|
|
||||||
cur := req.head
|
cur := req.head
|
||||||
for {
|
for {
|
||||||
var bst BSTipSet
|
var bst BSTipSet
|
||||||
ts, err := cs.LoadTipSet(cur)
|
ts, err := cs.LoadTipSet(ctx, cur)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed loading tipset %s: %w", cur, err)
|
return nil, xerrors.Errorf("failed loading tipset %s: %w", cur, err)
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ func collectChainSegment(cs *store.ChainStore, req *validatedRequest) ([]*BSTipS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if req.options.IncludeMessages {
|
if req.options.IncludeMessages {
|
||||||
bmsgs, bmincl, smsgs, smincl, err := gatherMessages(cs, ts)
|
bmsgs, bmincl, smsgs, smincl, err := gatherMessages(ctx, cs, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("gather messages failed: %w", err)
|
return nil, xerrors.Errorf("gather messages failed: %w", err)
|
||||||
}
|
}
|
||||||
@@ -197,14 +197,14 @@ func collectChainSegment(cs *store.ChainStore, req *validatedRequest) ([]*BSTipS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func gatherMessages(cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [][]uint64, []*types.SignedMessage, [][]uint64, error) {
|
func gatherMessages(ctx context.Context, cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [][]uint64, []*types.SignedMessage, [][]uint64, error) {
|
||||||
blsmsgmap := make(map[cid.Cid]uint64)
|
blsmsgmap := make(map[cid.Cid]uint64)
|
||||||
secpkmsgmap := make(map[cid.Cid]uint64)
|
secpkmsgmap := make(map[cid.Cid]uint64)
|
||||||
var secpkincl, blsincl [][]uint64
|
var secpkincl, blsincl [][]uint64
|
||||||
|
|
||||||
var blscids, secpkcids []cid.Cid
|
var blscids, secpkcids []cid.Cid
|
||||||
for _, block := range ts.Blocks() {
|
for _, block := range ts.Blocks() {
|
||||||
bc, sc, err := cs.ReadMsgMetaCids(block.Messages)
|
bc, sc, err := cs.ReadMsgMetaCids(ctx, block.Messages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -237,12 +237,12 @@ func gatherMessages(cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [
|
|||||||
secpkincl = append(secpkincl, smi)
|
secpkincl = append(secpkincl, smi)
|
||||||
}
|
}
|
||||||
|
|
||||||
blsmsgs, err := cs.LoadMessagesFromCids(blscids)
|
blsmsgs, err := cs.LoadMessagesFromCids(ctx, blscids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
secpkmsgs, err := cs.LoadSignedMessagesFromCids(secpkcids)
|
secpkmsgs, err := cs.LoadSignedMessagesFromCids(ctx, secpkcids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -241,7 +241,7 @@ func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeS
|
|||||||
genfb := &types.FullBlock{Header: genb.Genesis}
|
genfb := &types.FullBlock{Header: genb.Genesis}
|
||||||
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
|
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
|
||||||
|
|
||||||
if err := cs.SetGenesis(genb.Genesis); err != nil {
|
if err := cs.SetGenesis(context.TODO(), genb.Genesis); err != nil {
|
||||||
return nil, xerrors.Errorf("set genesis failed: %w", err)
|
return nil, xerrors.Errorf("set genesis failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,7 +471,7 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessagesAndNulls(base *types.TipSet,
|
|||||||
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
|
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cg.cs.PersistBlockHeaders(fblk.Header); err != nil {
|
if err := cg.cs.PersistBlockHeaders(context.TODO(), fblk.Header); err != nil {
|
||||||
return nil, xerrors.Errorf("chainstore AddBlock: %w", err)
|
return nil, xerrors.Errorf("chainstore AddBlock: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//stm: #unit
|
||||||
package gen
|
package gen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -34,6 +35,7 @@ func testGeneration(t testing.TB, n int, msgs int, sectors int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestChainGeneration(t *testing.T) {
|
func TestChainGeneration(t *testing.T) {
|
||||||
|
//stm: @CHAIN_GEN_NEW_GEN_WITH_SECTORS_001, @CHAIN_GEN_NEXT_TIPSET_001
|
||||||
t.Run("10-20-1", func(t *testing.T) { testGeneration(t, 10, 20, 1) })
|
t.Run("10-20-1", func(t *testing.T) { testGeneration(t, 10, 20, 1) })
|
||||||
t.Run("10-20-25", func(t *testing.T) { testGeneration(t, 10, 20, 25) })
|
t.Run("10-20-25", func(t *testing.T) { testGeneration(t, 10, 20, 25) })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -491,14 +491,13 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, sys vm.Sysca
|
|||||||
Actors: filcns.NewActorRegistry(),
|
Actors: filcns.NewActorRegistry(),
|
||||||
Syscalls: mkFakedSigSyscalls(sys),
|
Syscalls: mkFakedSigSyscalls(sys),
|
||||||
CircSupplyCalc: csc,
|
CircSupplyCalc: csc,
|
||||||
NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version {
|
FilVested: big.Zero(),
|
||||||
return nv
|
NetworkVersion: nv,
|
||||||
},
|
BaseFee: big.Zero(),
|
||||||
BaseFee: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
vm, err := vm.NewVM(ctx, &vmopt)
|
vm, err := vm.NewLegacyVM(ctx, &vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewLegacyVM: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for mi, m := range template.Miners {
|
for mi, m := range template.Miners {
|
||||||
@@ -595,7 +594,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("serializing msgmeta failed: %w", err)
|
return nil, xerrors.Errorf("serializing msgmeta failed: %w", err)
|
||||||
}
|
}
|
||||||
if err := bs.Put(mmb); err != nil {
|
if err := bs.Put(ctx, mmb); err != nil {
|
||||||
return nil, xerrors.Errorf("putting msgmeta block to blockstore: %w", err)
|
return nil, xerrors.Errorf("putting msgmeta block to blockstore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,7 +624,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
|
|||||||
return nil, xerrors.Errorf("filecoinGenesisCid != gblk.Cid")
|
return nil, xerrors.Errorf("filecoinGenesisCid != gblk.Cid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bs.Put(gblk); err != nil {
|
if err := bs.Put(ctx, gblk); err != nil {
|
||||||
return nil, xerrors.Errorf("failed writing filecoin genesis block to blockstore: %w", err)
|
return nil, xerrors.Errorf("failed writing filecoin genesis block to blockstore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,7 +655,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
|
|||||||
return nil, xerrors.Errorf("serializing block header failed: %w", err)
|
return nil, xerrors.Errorf("serializing block header failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bs.Put(sb); err != nil {
|
if err := bs.Put(ctx, sb); err != nil {
|
||||||
return nil, xerrors.Errorf("putting header to blockstore: %w", err)
|
return nil, xerrors.Errorf("putting header to blockstore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-30
@@ -94,15 +94,14 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
|
|||||||
Actors: filcns.NewActorRegistry(),
|
Actors: filcns.NewActorRegistry(),
|
||||||
Syscalls: mkFakedSigSyscalls(sys),
|
Syscalls: mkFakedSigSyscalls(sys),
|
||||||
CircSupplyCalc: csc,
|
CircSupplyCalc: csc,
|
||||||
NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version {
|
NetworkVersion: nv,
|
||||||
return nv
|
BaseFee: big.Zero(),
|
||||||
},
|
FilVested: big.Zero(),
|
||||||
BaseFee: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vm, err := vm.NewVM(ctx, vmopt)
|
vm, err := vm.NewLegacyVM(ctx, vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewLegacyVM: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(miners) == 0 {
|
if len(miners) == 0 {
|
||||||
@@ -510,37 +509,19 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
|
|||||||
// TODO: copied from actors test harness, deduplicate or remove from here
|
// TODO: copied from actors test harness, deduplicate or remove from here
|
||||||
type fakeRand struct{}
|
type fakeRand struct{}
|
||||||
|
|
||||||
func (fr *fakeRand) GetChainRandomnessV2(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
func (fr *fakeRand) GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||||
out := make([]byte, 32)
|
out := make([]byte, 32)
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
|
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fr *fakeRand) GetChainRandomnessV1(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||||
out := make([]byte, 32)
|
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fr *fakeRand) GetBeaconRandomnessV3(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
|
||||||
out := make([]byte, 32)
|
out := make([]byte, 32)
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fr *fakeRand) GetBeaconRandomnessV2(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
func currentTotalPower(ctx context.Context, vm *vm.LegacyVM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
||||||
out := make([]byte, 32)
|
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fr *fakeRand) GetBeaconRandomnessV1(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
|
||||||
out := make([]byte, 32)
|
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
|
||||||
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil)
|
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -553,7 +534,7 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*
|
|||||||
return &pwr, nil
|
return &pwr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) {
|
func dealWeight(ctx context.Context, vm *vm.LegacyVM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch, av actors.Version) (abi.DealWeight, abi.DealWeight, error) {
|
||||||
// TODO: This hack should move to market actor wrapper
|
// TODO: This hack should move to market actor wrapper
|
||||||
if av <= actors.Version2 {
|
if av <= actors.Version2 {
|
||||||
params := &market0.VerifyDealsForActivationParams{
|
params := &market0.VerifyDealsForActivationParams{
|
||||||
@@ -613,7 +594,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
|
|||||||
return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil
|
return dealWeights.Sectors[0].DealWeight, dealWeights.Sectors[0].VerifiedDealWeight, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) {
|
func currentEpochBlockReward(ctx context.Context, vm *vm.LegacyVM, maddr address.Address, av actors.Version) (abi.StoragePower, builtin.FilterEstimate, error) {
|
||||||
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil)
|
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), reward.Methods.ThisEpochReward, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return big.Zero(), builtin.FilterEstimate{}, err
|
return big.Zero(), builtin.FilterEstimate{}, err
|
||||||
@@ -648,7 +629,7 @@ func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Addre
|
|||||||
return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil
|
return epochReward.ThisEpochBaselinePower, builtin.FilterEstimate(epochReward.ThisEpochRewardSmoothed), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.TokenAmount {
|
func circSupply(ctx context.Context, vmi *vm.LegacyVM, maddr address.Address) abi.TokenAmount {
|
||||||
unsafeVM := &vm.UnsafeVM{VM: vmi}
|
unsafeVM := &vm.UnsafeVM{VM: vmi}
|
||||||
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
||||||
GasLimit: 1_000_000_000,
|
GasLimit: 1_000_000_000,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
|
|||||||
return enc
|
return enc
|
||||||
}
|
}
|
||||||
|
|
||||||
func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value types.BigInt, method abi.MethodNum, params []byte) ([]byte, error) {
|
func doExecValue(ctx context.Context, vm *vm.LegacyVM, to, from address.Address, value types.BigInt, method abi.MethodNum, params []byte) ([]byte, error) {
|
||||||
act, err := vm.StateTree().GetActor(from)
|
act, err := vm.StateTree().GetActor(from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("doExec failed to get from actor (%s): %w", from, err)
|
return nil, xerrors.Errorf("doExec failed to get from actor (%s): %w", from, err)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package slashfilter
|
package slashfilter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
@@ -27,7 +28,7 @@ func New(dstore ds.Batching) *SlashFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpoch) error {
|
func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, parentEpoch abi.ChainEpoch) error {
|
||||||
if build.IsNearUpgrade(bh.Height, build.UpgradeOrangeHeight) {
|
if build.IsNearUpgrade(bh.Height, build.UpgradeOrangeHeight) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -35,7 +36,7 @@ func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpo
|
|||||||
epochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, bh.Height))
|
epochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, bh.Height))
|
||||||
{
|
{
|
||||||
// double-fork mining (2 blocks at one epoch)
|
// double-fork mining (2 blocks at one epoch)
|
||||||
if err := checkFault(f.byEpoch, epochKey, bh, "double-fork mining faults"); err != nil {
|
if err := checkFault(ctx, f.byEpoch, epochKey, bh, "double-fork mining faults"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +44,7 @@ func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpo
|
|||||||
parentsKey := ds.NewKey(fmt.Sprintf("/%s/%x", bh.Miner, types.NewTipSetKey(bh.Parents...).Bytes()))
|
parentsKey := ds.NewKey(fmt.Sprintf("/%s/%x", bh.Miner, types.NewTipSetKey(bh.Parents...).Bytes()))
|
||||||
{
|
{
|
||||||
// time-offset mining faults (2 blocks with the same parents)
|
// time-offset mining faults (2 blocks with the same parents)
|
||||||
if err := checkFault(f.byParents, parentsKey, bh, "time-offset mining faults"); err != nil {
|
if err := checkFault(ctx, f.byParents, parentsKey, bh, "time-offset mining faults"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,14 +54,14 @@ func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpo
|
|||||||
|
|
||||||
// First check if we have mined a block on the parent epoch
|
// First check if we have mined a block on the parent epoch
|
||||||
parentEpochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, parentEpoch))
|
parentEpochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, parentEpoch))
|
||||||
have, err := f.byEpoch.Has(parentEpochKey)
|
have, err := f.byEpoch.Has(ctx, parentEpochKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if have {
|
if have {
|
||||||
// If we had, make sure it's in our parent tipset
|
// If we had, make sure it's in our parent tipset
|
||||||
cidb, err := f.byEpoch.Get(parentEpochKey)
|
cidb, err := f.byEpoch.Get(ctx, parentEpochKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting other block cid: %w", err)
|
return xerrors.Errorf("getting other block cid: %w", err)
|
||||||
}
|
}
|
||||||
@@ -83,25 +84,25 @@ func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := f.byParents.Put(parentsKey, bh.Cid().Bytes()); err != nil {
|
if err := f.byParents.Put(ctx, parentsKey, bh.Cid().Bytes()); err != nil {
|
||||||
return xerrors.Errorf("putting byEpoch entry: %w", err)
|
return xerrors.Errorf("putting byEpoch entry: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := f.byEpoch.Put(epochKey, bh.Cid().Bytes()); err != nil {
|
if err := f.byEpoch.Put(ctx, epochKey, bh.Cid().Bytes()); err != nil {
|
||||||
return xerrors.Errorf("putting byEpoch entry: %w", err)
|
return xerrors.Errorf("putting byEpoch entry: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkFault(t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType string) error {
|
func checkFault(ctx context.Context, t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType string) error {
|
||||||
fault, err := t.Has(key)
|
fault, err := t.Has(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if fault {
|
if fault {
|
||||||
cidb, err := t.Get(key)
|
cidb, err := t.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting other block cid: %w", err)
|
return xerrors.Errorf("getting other block cid: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user