Compare commits
848
Commits
v1.1.3-pre2
...
v1.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5324440f7d | ||
|
|
d04c01939d | ||
|
|
f2aea11971 | ||
|
|
1f754bdb78 | ||
|
|
46e5cc9317 | ||
|
|
6c6711e638 | ||
|
|
3d52c087cc | ||
|
|
0d72d742b4 | ||
|
|
884e20f637 | ||
|
|
210216a94f | ||
|
|
2af1283c65 | ||
|
|
d2b7e7b2ab | ||
|
|
3fa51f08e1 | ||
|
|
446b1cc883 | ||
|
|
3c7f5f7629 | ||
|
|
dc8ff27b36 | ||
|
|
65b921c62c | ||
|
|
c61f341b22 | ||
|
|
e33f873df8 | ||
|
|
46a5013dc1 | ||
|
|
53a6c4eac6 | ||
|
|
2e154ef6d0 | ||
|
|
47346907dd | ||
|
|
0cb2f51549 | ||
|
|
564b88af52 | ||
|
|
d347e7ab8f | ||
|
|
46c7f047d4 | ||
|
|
58729b7fd6 | ||
|
|
4767773d1b | ||
|
|
c9b489437d | ||
|
|
e07059e73d | ||
|
|
0570306bb6 | ||
|
|
0f08da3272 | ||
|
|
d4582fb32e | ||
|
|
3c50baaf5b | ||
|
|
e1be89b442 | ||
|
|
2ce5a29004 | ||
|
|
39e73e1cb4 | ||
|
|
bc9b5cb5fc | ||
|
|
9990d440e9 | ||
|
|
c6f5214657 | ||
|
|
696469aae7 | ||
|
|
d3fa728894 | ||
|
|
6ca5caef31 | ||
|
|
689b93dc0e | ||
|
|
72cb130e17 | ||
|
|
a999e41677 | ||
|
|
6b1c54162a | ||
|
|
5c37c9d8e9 | ||
|
|
b7975dcd9a | ||
|
|
3beebe5dc8 | ||
|
|
d56170d70e | ||
|
|
d9e3cc0374 | ||
|
|
a5a72a41eb | ||
|
|
2514c96cff | ||
|
|
88bd757024 | ||
|
|
1e6aa4b129 | ||
|
|
daca99687c | ||
|
|
65abeb066d | ||
|
|
13c8a235b6 | ||
|
|
b13226bc2f | ||
|
|
07afd93443 | ||
|
|
dc06d30f52 | ||
|
|
90a31fde9f | ||
|
|
f9cbf6d526 | ||
|
|
b190c3492a | ||
|
|
da5e1b319f | ||
|
|
ba7854d645 | ||
|
|
d844938a92 | ||
|
|
58695dc1bc | ||
|
|
1502ca6460 | ||
|
|
178691e37f | ||
|
|
93d26195f1 | ||
|
|
a584fcb935 | ||
|
|
bf93dfbc3b | ||
|
|
d033f8aab1 | ||
|
|
e34a759889 | ||
|
|
2ef8acdfc8 | ||
|
|
562f5839b7 | ||
|
|
c3a0feef96 | ||
|
|
2fd93a55ac | ||
|
|
783971d2c8 | ||
|
|
f74a1b70ab | ||
|
|
7246ef273f | ||
|
|
e8a5e0d2fe | ||
|
|
a415e49fdb | ||
|
|
655aea1018 | ||
|
|
9707c82285 | ||
|
|
370817eb60 | ||
|
|
97dd082585 | ||
|
|
3196b2cfd5 | ||
|
|
289ef910a0 | ||
|
|
95eaf13b5a | ||
|
|
c6f85886bf | ||
|
|
b6046924b3 | ||
|
|
bc14d0820f | ||
|
|
64e30808f8 | ||
|
|
28420b9eb0 | ||
|
|
b28ed5887c | ||
|
|
827ec75f5f | ||
|
|
c31774b08e | ||
|
|
be9f7b88b2 | ||
|
|
15c4793fe0 | ||
|
|
42cecbd879 | ||
|
|
00e5ace818 | ||
|
|
82b5cb89cd | ||
|
|
b7436cd300 | ||
|
|
715c32ff77 | ||
|
|
44d929c084 | ||
|
|
4b1d6bfcca | ||
|
|
614f45dcfb | ||
|
|
354b5af55a | ||
|
|
fc5120621b | ||
|
|
c4a6b94b9c | ||
|
|
054327b72a | ||
|
|
cb044f83a7 | ||
|
|
f1291f137c | ||
|
|
6bbb8ecafc | ||
|
|
ec08e27af2 | ||
|
|
c5a8b7076c | ||
|
|
4d019f16e4 | ||
|
|
ceea03cd40 | ||
|
|
32065f551e | ||
|
|
7bab281449 | ||
|
|
a8cdb8adc7 | ||
|
|
2be9836196 | ||
|
|
0439e95aa3 | ||
|
|
2e5843a0ee | ||
|
|
751568a4dd | ||
|
|
6dea0a6281 | ||
|
|
a4f3758f4c | ||
|
|
3e143cac4b | ||
|
|
0386cc5d48 | ||
|
|
e02a366419 | ||
|
|
d15ef9ac9b | ||
|
|
70732ac423 | ||
|
|
b18bc90dbc | ||
|
|
8382977e21 | ||
|
|
f4913c19b1 | ||
|
|
660ac26dd9 | ||
|
|
65d50c76d6 | ||
|
|
e8d2560581 | ||
|
|
dc7c7608df | ||
|
|
13a5b7f539 | ||
|
|
0c1592f2d3 | ||
|
|
61485beb22 | ||
|
|
01ad4c0514 | ||
|
|
09b9dfc3ce | ||
|
|
c66e594046 | ||
|
|
9ade05b33b | ||
|
|
13ff98416f | ||
|
|
4f675b76ad | ||
|
|
a6658a858f | ||
|
|
bfb5bad124 | ||
|
|
3672053ae9 | ||
|
|
4dfec7b232 | ||
|
|
23c7728edb | ||
|
|
aa278443d3 | ||
|
|
42173e29d6 | ||
|
|
32c159fa3a | ||
|
|
fad250058d | ||
|
|
2304ea0077 | ||
|
|
6df0340136 | ||
|
|
41d370557f | ||
|
|
dfb769c505 | ||
|
|
b916ac83cb | ||
|
|
74f040f9d5 | ||
|
|
fcec665267 | ||
|
|
506624f509 | ||
|
|
1f9ca1958e | ||
|
|
91259c29d4 | ||
|
|
e2278ebe6a | ||
|
|
eeb38fa649 | ||
|
|
ba87cb4fa9 | ||
|
|
65653a1747 | ||
|
|
663b3f4f21 | ||
|
|
d15d9b0fb9 | ||
|
|
86e25e7969 | ||
|
|
2e544e3e6a | ||
|
|
7904f135ff | ||
|
|
89493fe2b8 | ||
|
|
23bf3349d7 | ||
|
|
6166204bac | ||
|
|
97a76a4b9a | ||
|
|
f1948d54f0 | ||
|
|
cd7580e6d8 | ||
|
|
15aa8e5253 | ||
|
|
0c7962ce5f | ||
|
|
694834e8d5 | ||
|
|
47a4128311 | ||
|
|
239e180683 | ||
|
|
25070314ce | ||
|
|
214f46bc88 | ||
|
|
a63ef1dcd5 | ||
|
|
5ed79fa73e | ||
|
|
2e85b42665 | ||
|
|
eb2be69ace | ||
|
|
9cef300535 | ||
|
|
5f28c12f2e | ||
|
|
f850d77f1e | ||
|
|
7c831101f3 | ||
|
|
8b8449faee | ||
|
|
fe92a6e2d4 | ||
|
|
1f9c0f8040 | ||
|
|
7c0b6f41d8 | ||
|
|
bb25eb980d | ||
|
|
afec58f780 | ||
|
|
52da5acc96 | ||
|
|
fd640864cb | ||
|
|
3f151351aa | ||
|
|
844c0a3527 | ||
|
|
83b1009837 | ||
|
|
85e592bbe2 | ||
|
|
e2a6b99144 | ||
|
|
be2a5942fb | ||
|
|
ffa96389bc | ||
|
|
a145819004 | ||
|
|
0e39e760e5 | ||
|
|
721120fc60 | ||
|
|
3634ca50ca | ||
|
|
c965696586 | ||
|
|
53c39b1176 | ||
|
|
7e2d05cfd7 | ||
|
|
f601d1bf6b | ||
|
|
6ce14132cc | ||
|
|
c13ade3fbf | ||
|
|
7d540905ac | ||
|
|
4a8df0c3fa | ||
|
|
2d2ebdcc4b | ||
|
|
f3838a47c7 | ||
|
|
e7f3554c62 | ||
|
|
2609342356 | ||
|
|
9fe3649dd2 | ||
|
|
9b199f0476 | ||
|
|
b6893b0a3f | ||
|
|
69bfe7b7a8 | ||
|
|
218f7c2c5d | ||
|
|
375b7a1c4c | ||
|
|
3113b15217 | ||
|
|
34bca28416 | ||
|
|
99972c9e34 | ||
|
|
91a3d1d34a | ||
|
|
71dfc2e338 | ||
|
|
e9fae0425f | ||
|
|
17597fdd8f | ||
|
|
9613acd46b | ||
|
|
4b507f5be1 | ||
|
|
8508cdc00b | ||
|
|
4483d94db3 | ||
|
|
94763c2aaa | ||
|
|
d033042d6b | ||
|
|
54637d5093 | ||
|
|
7d4bc90d42 | ||
|
|
a13690dcf1 | ||
|
|
f0eac01a3c | ||
|
|
ef444676c2 | ||
|
|
853f9da457 | ||
|
|
bb9d2b5af4 | ||
|
|
7aec500384 | ||
|
|
b10b6fdd11 | ||
|
|
2d9123a618 | ||
|
|
96f004032b | ||
|
|
463a647118 | ||
|
|
df66f48f64 | ||
|
|
89ffd368b8 | ||
|
|
44040f0f3f | ||
|
|
1999156d06 | ||
|
|
b4fa099257 | ||
|
|
b7a282decc | ||
|
|
9f807f4aeb | ||
|
|
16dbbadddf | ||
|
|
648f02cbd6 | ||
|
|
880204045b | ||
|
|
9d2208e0e8 | ||
|
|
55061ae6fb | ||
|
|
2b611b3a99 | ||
|
|
de9cef62f7 | ||
|
|
ba56d02a1c | ||
|
|
e7b8511622 | ||
|
|
b1afa2022b | ||
|
|
3737a8f3cc | ||
|
|
7b39c3a907 | ||
|
|
62d20f2191 | ||
|
|
e9664a997e | ||
|
|
6d1bac7f70 | ||
|
|
dc3d17c9ea | ||
|
|
e061a8d163 | ||
|
|
9f34f98368 | ||
|
|
226efe28e5 | ||
|
|
452c85de98 | ||
|
|
09c996d572 | ||
|
|
adee4b2a5e | ||
|
|
322f34c6c6 | ||
|
|
49f8590578 | ||
|
|
016f5e44c0 | ||
|
|
9305947547 | ||
|
|
b92ce76a78 | ||
|
|
379100b470 | ||
|
|
8575f5518c | ||
|
|
707f9e31df | ||
|
|
52d34c8a5e | ||
|
|
68a16afeda | ||
|
|
50146fb9b9 | ||
|
|
c5470ee17e | ||
|
|
00335878ab | ||
|
|
4982de89b2 | ||
|
|
9328d98f84 | ||
|
|
3536ec9f85 | ||
|
|
8191654089 | ||
|
|
e23170d194 | ||
|
|
e7549dbf2c | ||
|
|
65202668af | ||
|
|
51e93feb9a | ||
|
|
c8d985b5c7 | ||
|
|
7ce4e5342b | ||
|
|
f580892e9e | ||
|
|
080a1165ee | ||
|
|
1413d6d4b7 | ||
|
|
9b64dba4a1 | ||
|
|
f9771c67fb | ||
|
|
238174cfca | ||
|
|
f130cd6fca | ||
|
|
336aa95ab5 | ||
|
|
c40c513508 | ||
|
|
bfbdbc04ba | ||
|
|
b242d69805 | ||
|
|
b8853aa4d5 | ||
|
|
fe448e706d | ||
|
|
193630f7b6 | ||
|
|
c597c43724 | ||
|
|
425ad9c5fa | ||
|
|
693bbee953 | ||
|
|
92b765bd21 | ||
|
|
7838752352 | ||
|
|
596b31fb9e | ||
|
|
2219bff1c9 | ||
|
|
5c791cd93b | ||
|
|
ce9146916a | ||
|
|
dff88b63b2 | ||
|
|
a2abeef727 | ||
|
|
dd9682f2be | ||
|
|
a152d98af8 | ||
|
|
27c0ce4a3a | ||
|
|
0c6072a1a0 | ||
|
|
d25e5d1c08 | ||
|
|
e0ade92b29 | ||
|
|
8db9c19e1c | ||
|
|
bc05618fd1 | ||
|
|
444239a643 | ||
|
|
bead8ac38e | ||
|
|
638900f97f | ||
|
|
d8afd71f4c | ||
|
|
869867e92e | ||
|
|
508375a55c | ||
|
|
1f91e7267d | ||
|
|
c8ff58aae1 | ||
|
|
4f33c91f81 | ||
|
|
423ff0631d | ||
|
|
948ee53080 | ||
|
|
4d8327c29a | ||
|
|
cd0cb1407d | ||
|
|
915c5e0fdd | ||
|
|
2a7e4af5ee | ||
|
|
931979809f | ||
|
|
584907269a | ||
|
|
05db5ce426 | ||
|
|
219c695967 | ||
|
|
4544d2118e | ||
|
|
d7c2c073a3 | ||
|
|
6bea9dd178 | ||
|
|
0a169357f7 | ||
|
|
b13a41a44d | ||
|
|
470538b082 | ||
|
|
bac51dd4e3 | ||
|
|
d7b4f92f1f | ||
|
|
87d6daf745 | ||
|
|
49d3bb9497 | ||
|
|
d4f6e1ddb4 | ||
|
|
b63687795d | ||
|
|
96d56ec096 | ||
|
|
6d0b3978b9 | ||
|
|
afe6c51016 | ||
|
|
09be3f0a01 | ||
|
|
6667220a27 | ||
|
|
1af1ceb1e0 | ||
|
|
ae76711ab4 | ||
|
|
fe339d46eb | ||
|
|
91e2530e11 | ||
|
|
f9fc601567 | ||
|
|
2b68ba5f1d | ||
|
|
4b187b85eb | ||
|
|
b8884adaf1 | ||
|
|
b71f069854 | ||
|
|
5a0b9f4197 | ||
|
|
4b1d1b6540 | ||
|
|
15fe726e65 | ||
|
|
17c2c0d1c8 | ||
|
|
2971dd4317 | ||
|
|
6742a74260 | ||
|
|
41af94f1b7 | ||
|
|
6bb67f2fe9 | ||
|
|
961a25298b | ||
|
|
5f1737379a | ||
|
|
c5c0185943 | ||
|
|
8fdb9148e4 | ||
|
|
d3d5f8d7f0 | ||
|
|
99031bae17 | ||
|
|
56373b0d46 | ||
|
|
7921f8d713 | ||
|
|
6d3e59e047 | ||
|
|
63f13977ce | ||
|
|
408183c7a6 | ||
|
|
11b041224e | ||
|
|
36b78b1891 | ||
|
|
a6d061d0f6 | ||
|
|
bf547112de | ||
|
|
5d9c79811f | ||
|
|
28ffa8ca06 | ||
|
|
55240b3e07 | ||
|
|
697a0a3b95 | ||
|
|
26e12e6f6a | ||
|
|
0e3e449bf8 | ||
|
|
f3922e7485 | ||
|
|
fb05bb7f07 | ||
|
|
8246149544 | ||
|
|
d525acdeda | ||
|
|
2f0075752d | ||
|
|
8409e155d4 | ||
|
|
29817b6617 | ||
|
|
7be7a9b5e3 | ||
|
|
11ed015dca | ||
|
|
c6b9e4951f | ||
|
|
1301fd6ddb | ||
|
|
3a3270b37c | ||
|
|
72a3b41315 | ||
|
|
8c8396af59 | ||
|
|
7b8158b1af | ||
|
|
bf500711b3 | ||
|
|
f7f5a27ebf | ||
|
|
1f678c17d3 | ||
|
|
d98e989417 | ||
|
|
7f47bf452a | ||
|
|
dab20efc99 | ||
|
|
0e40a04975 | ||
|
|
c6cd699f0d | ||
|
|
3306bdec29 | ||
|
|
32b7797394 | ||
|
|
cde0e58e39 | ||
|
|
3e7efad0fd | ||
|
|
9270ac6358 | ||
|
|
3c2cd506ec | ||
|
|
cdfa869ea6 | ||
|
|
a8430088b2 | ||
|
|
881e37ec02 | ||
|
|
194c9d6e07 | ||
|
|
2613e837a9 | ||
|
|
20c57fcd0e | ||
|
|
fbe76d0fa1 | ||
|
|
619ee1e6f9 | ||
|
|
0e88f32d66 | ||
|
|
546614455f | ||
|
|
0b9499a00f | ||
|
|
448ca6e43c | ||
|
|
c9955c0635 | ||
|
|
768d2db114 | ||
|
|
79d94c4771 | ||
|
|
a3e26233b2 | ||
|
|
bc1f18b73a | ||
|
|
cc8a0f8022 | ||
|
|
c3a405eac7 | ||
|
|
e4209d86f6 | ||
|
|
fcb9dea501 | ||
|
|
c810b157cf | ||
|
|
c458f6e826 | ||
|
|
c99e223cb1 | ||
|
|
5c27d6aeee | ||
|
|
1a64caaa4d | ||
|
|
4cc1fcb37b | ||
|
|
44af7e43b6 | ||
|
|
2a6e05b776 | ||
|
|
fe1ef154cf | ||
|
|
6b3ffdbd3d | ||
|
|
0017ea8fd0 | ||
|
|
a5b57068d4 | ||
|
|
6b5f8a6b1d | ||
|
|
bc7f20e179 | ||
|
|
400af0d2fa | ||
|
|
41ab87e904 | ||
|
|
1a7aea1906 | ||
|
|
3207bc4704 | ||
|
|
60e950015c | ||
|
|
08fc0b7aec | ||
|
|
48b7945714 | ||
|
|
c507f409a5 | ||
|
|
72537b6614 | ||
|
|
c839c5721c | ||
|
|
f21ca8591c | ||
|
|
80619fa8a0 | ||
|
|
9a0d5cd739 | ||
|
|
36b8a017bd | ||
|
|
1c9257d537 | ||
|
|
ea56e56ec1 | ||
|
|
ed7423b2b5 | ||
|
|
77a956cda4 | ||
|
|
a9253837ac | ||
|
|
63f903a3fb | ||
|
|
f702ce331a | ||
|
|
8b7e7d438c | ||
|
|
097d82535d | ||
|
|
20a0f7ac68 | ||
|
|
6cff57ab43 | ||
|
|
172204c933 | ||
|
|
77000db747 | ||
|
|
6563a68ae2 | ||
|
|
d9bcdfe61b | ||
|
|
d3f6657032 | ||
|
|
ed12b83b4e | ||
|
|
6be293e848 | ||
|
|
9cebb09a5f | ||
|
|
f6f3ffc254 | ||
|
|
497bda21b2 | ||
|
|
6164d16f19 | ||
|
|
328cd14897 | ||
|
|
6954e6cb0e | ||
|
|
ad17dc227c | ||
|
|
955b445723 | ||
|
|
b2adc12287 | ||
|
|
0afeed6108 | ||
|
|
b2c2a7b5d0 | ||
|
|
acbb80920b | ||
|
|
9ba87d4613 | ||
|
|
99f466e35e | ||
|
|
ffe3019561 | ||
|
|
47f0ef0eae | ||
|
|
be5bd41640 | ||
|
|
de62012a7f | ||
|
|
a793824d2c | ||
|
|
52cf367a92 | ||
|
|
81ea0ec5f3 | ||
|
|
7d118e1b12 | ||
|
|
fd35438a30 | ||
|
|
8203a5d2c3 | ||
|
|
9c8ced1fc6 | ||
|
|
f97c9e08c0 | ||
|
|
8a59bf7c45 | ||
|
|
5353210814 | ||
|
|
17f0b4a2e1 | ||
|
|
163721651a | ||
|
|
b7e3b4ff77 | ||
|
|
62a9982b76 | ||
|
|
42ef5d3460 | ||
|
|
700a121ccd | ||
|
|
0dc490979f | ||
|
|
0d0fc2d433 | ||
|
|
7af5ab5445 | ||
|
|
510f6bb830 | ||
|
|
e0e4432703 | ||
|
|
48a2161306 | ||
|
|
2c3d473193 | ||
|
|
a50cdda7a5 | ||
|
|
58558f2e1d | ||
|
|
36c722731b | ||
|
|
1cf77d2172 | ||
|
|
5d40607cf9 | ||
|
|
4caecf34ae | ||
|
|
f20b25a123 | ||
|
|
f19148d765 | ||
|
|
6e45d6b68d | ||
|
|
3e06729877 | ||
|
|
b6994b9615 | ||
|
|
4227f2d9dc | ||
|
|
3dbea4b0b7 | ||
|
|
31af5419a2 | ||
|
|
0efcf1b622 | ||
|
|
a1166d6fdb | ||
|
|
ac5fc72347 | ||
|
|
97a17bd587 | ||
|
|
daee5ab1d3 | ||
|
|
645da2b749 | ||
|
|
4926a788c1 | ||
|
|
735c1ecc2a | ||
|
|
8a2a5e7e85 | ||
|
|
6a45211a00 | ||
|
|
f46375a50a | ||
|
|
69332e1189 | ||
|
|
6eb5e24988 | ||
|
|
cb3697cb5a | ||
|
|
5aac474737 | ||
|
|
99b6bb324d | ||
|
|
5d1d7335b0 | ||
|
|
e899da0063 | ||
|
|
0df9b57d48 | ||
|
|
e244f8d3b2 | ||
|
|
c77cd13c97 | ||
|
|
300d401686 | ||
|
|
8a4b6473f4 | ||
|
|
00cc982bcb | ||
|
|
4dea3f41a2 | ||
|
|
1c9b867593 | ||
|
|
920e6f5049 | ||
|
|
00d837d454 | ||
|
|
733f2aa87f | ||
|
|
2ca9e9f937 | ||
|
|
dd3d04fed2 | ||
|
|
4ce21af7de | ||
|
|
db383b6a8b | ||
|
|
b906c492a2 | ||
|
|
8d5a8b0927 | ||
|
|
887bf0511f | ||
|
|
f529f3b14d | ||
|
|
75b842b430 | ||
|
|
1289bca9d8 | ||
|
|
e7271cfd0b | ||
|
|
f4568fc819 | ||
|
|
f062b55cfc | ||
|
|
f7715ab1ba | ||
|
|
84cf7d8c14 | ||
|
|
cd3dbf615f | ||
|
|
7a5f1390d1 | ||
|
|
027b80f5af | ||
|
|
89e413dba7 | ||
|
|
9027161453 | ||
|
|
20b4375f25 | ||
|
|
aa90a8a989 | ||
|
|
eadb49c56d | ||
|
|
9148b0f865 | ||
|
|
3aacb7c377 | ||
|
|
1beb8faa26 | ||
|
|
8708f31c45 | ||
|
|
d867f0c04e | ||
|
|
84bc071179 | ||
|
|
7258ad00f4 | ||
|
|
483a98fc8c | ||
|
|
c3a13240ab | ||
|
|
a223f80992 | ||
|
|
06e5c42541 | ||
|
|
2ed7540dfb | ||
|
|
26ad4dabd1 | ||
|
|
6c14fdaca7 | ||
|
|
91d389330e | ||
|
|
62f1e47bd1 | ||
|
|
2b6c1e0187 | ||
|
|
faeee03dd1 | ||
|
|
7e63197e97 | ||
|
|
65cc1a4c01 | ||
|
|
b6c830c254 | ||
|
|
19ce23e907 | ||
|
|
122926ad49 | ||
|
|
01d6554a00 | ||
|
|
22005d642f | ||
|
|
b601fd12f7 | ||
|
|
740741b129 | ||
|
|
6d0c0b4323 | ||
|
|
1623917bc4 | ||
|
|
9c6b6e61fe | ||
|
|
bcd3e79557 | ||
|
|
fee13a6daf | ||
|
|
619f3fd60b | ||
|
|
4eb2218cf3 | ||
|
|
45f20b8505 | ||
|
|
561b10a62b | ||
|
|
e66d439cb4 | ||
|
|
83313ead4f | ||
|
|
e6bc6aafdf | ||
|
|
c7f95280e4 | ||
|
|
459cd657d3 | ||
|
|
ea6dbc912b | ||
|
|
a8841a8b76 | ||
|
|
167a30fcb9 | ||
|
|
274b07f50a | ||
|
|
e7488209c8 | ||
|
|
11bde71b92 | ||
|
|
cecdb0c896 | ||
|
|
4cd197cb13 | ||
|
|
72426d21fb | ||
|
|
4ac2de1ee5 | ||
|
|
e14b716643 | ||
|
|
f0c636f243 | ||
|
|
8aef427fd8 | ||
|
|
6c4e83f8a2 | ||
|
|
04311d6c1a | ||
|
|
9cb809ac60 | ||
|
|
79b0472924 | ||
|
|
818bdd49b8 | ||
|
|
8ec4eb8030 | ||
|
|
45068f601a | ||
|
|
406bd5da84 | ||
|
|
0b386f21d5 | ||
|
|
8469f67a38 | ||
|
|
e01b887bc8 | ||
|
|
de6d927914 | ||
|
|
e5d6751b09 | ||
|
|
81f8451a23 | ||
|
|
436fe158c9 | ||
|
|
7f3716504b | ||
|
|
035bf8b7db | ||
|
|
af582aff02 | ||
|
|
46beab3cf1 | ||
|
|
0a9af6ad5c | ||
|
|
e3d2d2e7c1 | ||
|
|
903b1ea914 | ||
|
|
b62878c260 | ||
|
|
63bce1a426 | ||
|
|
954ad1f396 | ||
|
|
33e60df301 | ||
|
|
204714a01f | ||
|
|
eec5c23671 | ||
|
|
4595ded0d3 | ||
|
|
36f82ab9fe | ||
|
|
62f63a29b5 | ||
|
|
24730e158b | ||
|
|
6b44e6d0d8 | ||
|
|
79246e6ee9 | ||
|
|
cced69e496 | ||
|
|
da85855a6b | ||
|
|
6c8abeb067 | ||
|
|
b3b89b2072 | ||
|
|
05e5c42f33 | ||
|
|
b47641f1c2 | ||
|
|
22ac7debb9 | ||
|
|
50b9a7f212 | ||
|
|
ea2935e4d7 | ||
|
|
0ec247de8c | ||
|
|
c4347c0485 | ||
|
|
909c12c6b4 | ||
|
|
222d718ccd | ||
|
|
666023f804 | ||
|
|
38132cdb94 | ||
|
|
ba645cfbea | ||
|
|
2b9a6d8574 | ||
|
|
0d908c18b4 | ||
|
|
0487d60d0e | ||
|
|
018406b50c | ||
|
|
e388d96073 | ||
|
|
5fa2c1c410 | ||
|
|
f91364fb3e | ||
|
|
943d9a27ec | ||
|
|
3ff084b720 | ||
|
|
d7631fb997 | ||
|
|
2256a7237c | ||
|
|
b7403fd93c | ||
|
|
3d5f58c8b8 | ||
|
|
f7af27f1d2 | ||
|
|
119defc5e7 | ||
|
|
2a8333e0e4 | ||
|
|
95c3229f89 | ||
|
|
909e0e401f | ||
|
|
b1159b657d | ||
|
|
30a6361a8f | ||
|
|
eb65f1e441 | ||
|
|
a612b77cee | ||
|
|
16149b9198 | ||
|
|
00f137ba3e | ||
|
|
71503cce8b | ||
|
|
1c2af85b20 | ||
|
|
3ff9045178 | ||
|
|
c66dfe1c03 | ||
|
|
19f0aa75eb | ||
|
|
8b0f6c355c | ||
|
|
3cbf5efddd | ||
|
|
fda66f5bd9 | ||
|
|
3f15146c19 | ||
|
|
f11d726ddc | ||
|
|
75ff8d0689 | ||
|
|
e225a644f4 | ||
|
|
4a337785b5 | ||
|
|
1230430c94 | ||
|
|
b0c3963506 | ||
|
|
050a0c1000 | ||
|
|
8588cce4d5 | ||
|
|
fa224271a1 | ||
|
|
7898451236 | ||
|
|
67b1bb6178 | ||
|
|
548ee4a206 | ||
|
|
0c00b8b2ab | ||
|
|
889b440bb1 | ||
|
|
6f298b929e | ||
|
|
1eeeff82d1 | ||
|
|
b476bc86ce | ||
|
|
58923fe2ff | ||
|
|
5cccc81abf | ||
|
|
831cd2e71d | ||
|
|
9f9c30d406 | ||
|
|
1cb087c99e | ||
|
|
ae3fcca543 | ||
|
|
801a4f79b9 | ||
|
|
98bc576888 | ||
|
|
bb758854fb | ||
|
|
f460d24f65 | ||
|
|
b026160c5c | ||
|
|
fe842823a9 | ||
|
|
65dff05008 | ||
|
|
d4f883c1b0 | ||
|
|
e8f037cac8 | ||
|
|
cca568112d | ||
|
|
db19764130 | ||
|
|
2379ff1740 | ||
|
|
f6da7679b8 | ||
|
|
b0d0a7a04a | ||
|
|
f1181ce9c2 | ||
|
|
e9402da131 | ||
|
|
04a945531c | ||
|
|
ebd0e85d65 | ||
|
|
2bfbc6a314 | ||
|
|
0e924edf0e | ||
|
|
448bbf3710 | ||
|
|
1907fe2a91 | ||
|
|
021c0386f8 | ||
|
|
f72616981e | ||
|
|
6eddd62a73 | ||
|
|
306efa66c7 | ||
|
|
0bfaa46ce7 | ||
|
|
91b9cdfae5 | ||
|
|
6f12d797d2 | ||
|
|
86a4d6f607 | ||
|
|
a60a4c507a | ||
|
|
7bbde459f3 | ||
|
|
4a961401fc | ||
|
|
9eab4cfa0d | ||
|
|
92409c321c | ||
|
|
9e348c049b | ||
|
|
c9dbf908b5 | ||
|
|
202cdda358 | ||
|
|
6eae66728b | ||
|
|
e262320348 | ||
|
|
9323fd896a | ||
|
|
f29141b855 | ||
|
|
6f8706818d | ||
|
|
512915b4c9 | ||
|
|
c176f24d05 | ||
|
|
087e60299b | ||
|
|
73c5153ef1 | ||
|
|
2863b5a8c6 | ||
|
|
1b92795d93 | ||
|
|
3cc6fb6c6e | ||
|
|
3ca1593919 | ||
|
|
6f4599be9a | ||
|
|
4b6a677b57 | ||
|
|
6e9dbf4c18 | ||
|
|
3d891e26dd | ||
|
|
139f7f6322 | ||
|
|
a5e4bf63c5 | ||
|
|
2af3fd4a8c | ||
|
|
69ae58f7ba | ||
|
|
7e7b19b904 | ||
|
|
f4e6231358 | ||
|
|
0c909251aa | ||
|
|
2ef46a3165 |
+38
-10
@@ -5,7 +5,7 @@ orbs:
|
||||
executors:
|
||||
golang:
|
||||
docker:
|
||||
- image: circleci/golang:1.14.6
|
||||
- image: circleci/golang:1.15.5
|
||||
resource_class: 2xlarge
|
||||
ubuntu:
|
||||
docker:
|
||||
@@ -264,22 +264,44 @@ jobs:
|
||||
path: /tmp/test-artifacts/conformance-coverage.html
|
||||
build-lotus-soup:
|
||||
description: |
|
||||
Compile `lotus-soup` Testground test plan using the current version of Lotus.
|
||||
Compile `lotus-soup` Testground test plan
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: cd extern/oni && git submodule sync
|
||||
- run: cd extern/oni && git submodule update --init
|
||||
- run: cd extern/filecoin-ffi && make
|
||||
- run:
|
||||
name: "replace lotus, filecoin-ffi, blst and fil-blst deps"
|
||||
command: cd extern/oni/lotus-soup && go mod edit -replace github.com/filecoin-project/lotus=../../../ && go mod edit -replace github.com/filecoin-project/filecoin-ffi=../../filecoin-ffi && go mod edit -replace github.com/supranational/blst=../../blst
|
||||
- run:
|
||||
name: "build lotus-soup testplan"
|
||||
command: pushd extern/oni/lotus-soup && go build -tags=testground .
|
||||
command: pushd testplans/lotus-soup && go build -tags=testground .
|
||||
trigger-testplans:
|
||||
description: |
|
||||
Trigger `lotus-soup` test cases on TaaS
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
name: "download testground"
|
||||
command: wget https://gist.github.com/nonsense/5fbf3167cac79945f658771aed32fc44/raw/2e17eb0debf7ec6bdf027c1bdafc2c92dd97273b/testground-d3e9603 -O ~/testground-cli && chmod +x ~/testground-cli
|
||||
- run:
|
||||
name: "prepare .env.toml"
|
||||
command: pushd testplans/lotus-soup && mkdir -p $HOME/testground && cp env-ci.toml $HOME/testground/.env.toml && echo 'endpoint="https://ci.testground.ipfs.team"' >> $HOME/testground/.env.toml && echo 'user="circleci"' >> $HOME/testground/.env.toml
|
||||
- run:
|
||||
name: "prepare testground home dir"
|
||||
command: mkdir -p $HOME/testground/plans && mv testplans/lotus-soup testplans/graphsync $HOME/testground/plans/
|
||||
- run:
|
||||
name: "trigger deals baseline testplan on taas"
|
||||
command: ~/testground-cli run composition -f $HOME/testground/plans/lotus-soup/_compositions/baseline-k8s-3-1.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH
|
||||
- run:
|
||||
name: "trigger payment channel stress testplan on taas"
|
||||
command: ~/testground-cli run composition -f $HOME/testground/plans/lotus-soup/_compositions/paych-stress-k8s.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH
|
||||
- run:
|
||||
name: "trigger graphsync testplan on taas"
|
||||
command: ~/testground-cli run composition -f $HOME/testground/plans/graphsync/_compositions/stress-k8s.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH
|
||||
|
||||
|
||||
build-macos:
|
||||
@@ -294,8 +316,8 @@ jobs:
|
||||
- run:
|
||||
name: Install go
|
||||
command: |
|
||||
curl -O https://dl.google.com/go/go1.14.2.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.14.2.darwin-amd64.pkg -target /
|
||||
curl -O https://dl.google.com/go/go1.15.5.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.15.5.darwin-amd64.pkg -target /
|
||||
- run:
|
||||
name: Install pkg-config
|
||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config
|
||||
@@ -359,6 +381,7 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: make deps
|
||||
- run: make docsgen
|
||||
- run: git --no-pager diff
|
||||
- run: git --no-pager diff --quiet
|
||||
@@ -472,6 +495,11 @@ workflows:
|
||||
packages: "./conformance"
|
||||
vectors-branch: master
|
||||
- build-lotus-soup
|
||||
- trigger-testplans:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- build-debug
|
||||
- build-all:
|
||||
requires:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
/lotus-gateway
|
||||
/lotus-pcr
|
||||
/lotus-wallet
|
||||
/lotus-keygen
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
[submodule "extern/test-vectors"]
|
||||
path = extern/test-vectors
|
||||
url = https://github.com/filecoin-project/test-vectors.git
|
||||
[submodule "extern/oni"]
|
||||
path = extern/oni
|
||||
url = https://github.com/filecoin-project/oni.git
|
||||
[submodule "extern/blst"]
|
||||
path = extern/blst
|
||||
url = https://github.com/supranational/blst.git
|
||||
|
||||
+293
@@ -1,5 +1,298 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 1.3.0 / 2020-12-16
|
||||
|
||||
This is a mandatory release of Lotus that introduces the third post-liftoff upgrade to the Filecoin network. The network upgrade occurs at height 343200, before which time all nodes must have updated to this release (or later). The change that breaks consensus is an implementation of FIP-0009(https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0009.md).
|
||||
|
||||
## Changes
|
||||
|
||||
- Disable gas burning for window post messages (https://github.com/filecoin-project/lotus/pull/5200)
|
||||
- fix lock propose (https://github.com/filecoin-project/lotus/pull/5197)
|
||||
|
||||
# 1.2.3 / 2020-12-15
|
||||
|
||||
This is an optional Lotus release that introduces many performance improvements, bugfixes, and UX improvements.
|
||||
|
||||
## Changes
|
||||
|
||||
- When waiting for deal commit messages, ignore unsuccessful messages (https://github.com/filecoin-project/lotus/pull/5189)
|
||||
- Bigger copy buffer size for stores (https://github.com/filecoin-project/lotus/pull/5177)
|
||||
- Print MinPieceSize when querying ask (https://github.com/filecoin-project/lotus/pull/5178)
|
||||
- Optimize miner info & sectors list loading (https://github.com/filecoin-project/lotus/pull/5176)
|
||||
- Allow miners to filter (un)verified deals (https://github.com/filecoin-project/lotus/pull/5094)
|
||||
- Fix curSealing out of MaxSealingSectors limit (https://github.com/filecoin-project/lotus/pull/5166)
|
||||
- Add mpool pending from / to filter (https://github.com/filecoin-project/lotus/pull/5169)
|
||||
- Add metrics for delayed blocks (https://github.com/filecoin-project/lotus/pull/5171)
|
||||
- Fix PushUntrusted publishing -- the message is local (https://github.com/filecoin-project/lotus/pull/5173)
|
||||
- Avoid potential hang in events API when starting event listener (https://github.com/filecoin-project/lotus/pull/5159)
|
||||
- Show data transfer ID in list-deals (https://github.com/filecoin-project/lotus/pull/5150)
|
||||
- Fix events API mutex locking (https://github.com/filecoin-project/lotus/pull/5160)
|
||||
- Message pool refactors (https://github.com/filecoin-project/lotus/pull/5162)
|
||||
- Fix lotus-shed cid output (https://github.com/filecoin-project/lotus/pull/5072)
|
||||
- Use FundManager to withdraw funds, add MarketWithdraw API (https://github.com/filecoin-project/lotus/pull/5112)
|
||||
- Add keygen outfile (https://github.com/filecoin-project/lotus/pull/5118)
|
||||
- Update sr2 stat aggregation (https://github.com/filecoin-project/lotus/pull/5114)
|
||||
- Fix miner control address lookup (https://github.com/filecoin-project/lotus/pull/5119)
|
||||
- Fix send with declared nonce 0 (https://github.com/filecoin-project/lotus/pull/5111)
|
||||
- Introduce memory watchdog; LOTUS_MAX_HEAP (https://github.com/filecoin-project/lotus/pull/5101)
|
||||
- Miner control address config for (pre)commits (https://github.com/filecoin-project/lotus/pull/5103)
|
||||
- Delete repeated call func (https://github.com/filecoin-project/lotus/pull/5099)
|
||||
- lotus-shed ledger show command (https://github.com/filecoin-project/lotus/pull/5098)
|
||||
- Log a message when there aren't enough peers for sync (https://github.com/filecoin-project/lotus/pull/5105)
|
||||
- Miner code cleanup (https://github.com/filecoin-project/lotus/pull/5107)
|
||||
|
||||
# 1.2.2 / 2020-12-03
|
||||
|
||||
This is an optional Lotus release that introduces various improvements to the mining logic and deal-making workflow, as well as several new UX features.
|
||||
|
||||
## Changes
|
||||
|
||||
- Set lower feecap on PoSt messages with low balance (https://github.com/filecoin-project/lotus/pull/4217)
|
||||
- Add options to set BlockProfileRate and MutexProfileFraction (https://github.com/filecoin-project/lotus/pull/4140)
|
||||
- Shed/post find (https://github.com/filecoin-project/lotus/pull/4355)
|
||||
- tvx extract: make it work with secp messages.(https://github.com/filecoin-project/lotus/pull/4583)
|
||||
- update go from 1.14 to 1.15 (https://github.com/filecoin-project/lotus/pull/4909)
|
||||
- print multiple blocks from miner cid (https://github.com/filecoin-project/lotus/pull/4767)
|
||||
- Connection Gater support (https://github.com/filecoin-project/lotus/pull/4849)
|
||||
- just return storedask.NewStoredAsk to reduce unuseful code (https://github.com/filecoin-project/lotus/pull/4902)
|
||||
- add go main version (https://github.com/filecoin-project/lotus/pull/4910)
|
||||
- Use version0 when pre-sealing (https://github.com/filecoin-project/lotus/pull/4911)
|
||||
- optimize code UpgradeTapeHeight and go fmt (https://github.com/filecoin-project/lotus/pull/4913)
|
||||
- CLI to get network version (https://github.com/filecoin-project/lotus/pull/4914)
|
||||
- Improve error for ActorsVersionPredicate (https://github.com/filecoin-project/lotus/pull/4915)
|
||||
- upgrade to go-fil-markets 1.0.5 (https://github.com/filecoin-project/lotus/pull/4916)
|
||||
- bug:replace with func recordFailure (https://github.com/filecoin-project/lotus/pull/4919)
|
||||
- Remove unused key (https://github.com/filecoin-project/lotus/pull/4924)
|
||||
- change typeV7 make len (https://github.com/filecoin-project/lotus/pull/4943)
|
||||
- emit events for peer disconnections and act upon them in the blocksync tracker (https://github.com/filecoin-project/lotus/pull/4754)
|
||||
- Fix lotus bench error (https://github.com/filecoin-project/lotus/pull/4305)
|
||||
- Reduce badger ValueTreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
|
||||
- Downgrade duplicate nonce logs to debug (https://github.com/filecoin-project/lotus/pull/4933)
|
||||
- readme update golang version from 1.14.7 to 1.15.5 (https://github.com/filecoin-project/lotus/pull/4974)
|
||||
- add data transfer logging (https://github.com/filecoin-project/lotus/pull/4975)
|
||||
- Remove all temp file generation for deals (https://github.com/filecoin-project/lotus/pull/4929)
|
||||
- fix get sector bug (https://github.com/filecoin-project/lotus/pull/4976)
|
||||
- fix nil pointer in StateSectorPreCommitInfo (https://github.com/filecoin-project/lotus/pull/4082)
|
||||
- Add logging on data-transfer to miner (https://github.com/filecoin-project/lotus/pull/4980)
|
||||
- bugfix: fixup devnet script (https://github.com/filecoin-project/lotus/pull/4956)
|
||||
- modify for unsafe (https://github.com/filecoin-project/lotus/pull/4024)
|
||||
- move testground/lotus-soup testplan from oni to lotus (https://github.com/filecoin-project/lotus/pull/4727)
|
||||
- Setup remainder msig signers when parsing genesis template (https://github.com/filecoin-project/lotus/pull/4904)
|
||||
- Update JSON RPC server to enforce a maximum request size (https://github.com/filecoin-project/lotus/pull/4923)
|
||||
- New SR-specific lotus-shed cmd (https://github.com/filecoin-project/lotus/pull/4971)
|
||||
- update index to sectorNumber (https://github.com/filecoin-project/lotus/pull/4987)
|
||||
- storagefsm: Fix expired ticket retry loop (https://github.com/filecoin-project/lotus/pull/4876)
|
||||
- add .sec scale to measurements; humanize for metric tags (https://github.com/filecoin-project/lotus/pull/4989)
|
||||
- Support seal proof type switching (https://github.com/filecoin-project/lotus/pull/4873)
|
||||
- fix log format (https://github.com/filecoin-project/lotus/pull/4984)
|
||||
- Format workerID as string (https://github.com/filecoin-project/lotus/pull/4973)
|
||||
- miner: Winning PoSt Warmup (https://github.com/filecoin-project/lotus/pull/4824)
|
||||
- Default StartDealParams's fast retrieval field to true over JSON (https://github.com/filecoin-project/lotus/pull/4998)
|
||||
- Fix actor not found in chain inspect-usage (https://github.com/filecoin-project/lotus/pull/5010)
|
||||
- storagefsm: Improve new deal sector logic (https://github.com/filecoin-project/lotus/pull/5007)
|
||||
- Configure simultaneous requests (https://github.com/filecoin-project/lotus/pull/4996)
|
||||
- miner: log winningPoSt duration separately (https://github.com/filecoin-project/lotus/pull/5005)
|
||||
- fix wallet dead lock (https://github.com/filecoin-project/lotus/pull/5002)
|
||||
- Update go-jsonrpc to v0.1.2 (https://github.com/filecoin-project/lotus/pull/5015)
|
||||
- markets - separate watching for pre-commit from prove-commit (https://github.com/filecoin-project/lotus/pull/4945)
|
||||
- storagefsm: Add missing planners (https://github.com/filecoin-project/lotus/pull/5016)
|
||||
- fix wallet delete address where address is default (https://github.com/filecoin-project/lotus/pull/5019)
|
||||
- worker: More robust remote checks (https://github.com/filecoin-project/lotus/pull/5008)
|
||||
- Add new booststrappers (https://github.com/filecoin-project/lotus/pull/4007)
|
||||
- add a tooling to make filecoin accounting a little easier (https://github.com/filecoin-project/lotus/pull/5025)
|
||||
- fix: start a new line in print miner-info to avoid ambiguous display (https://github.com/filecoin-project/lotus/pull/5029)
|
||||
- Print gas limit sum in mpool stat (https://github.com/filecoin-project/lotus/pull/5035)
|
||||
- Fix chainstore tipset leak (https://github.com/filecoin-project/lotus/pull/5037)
|
||||
- shed rpc: Allow calling with args (https://github.com/filecoin-project/lotus/pull/5036)
|
||||
- Make --gas-limit optional in mpool replace cli (https://github.com/filecoin-project/lotus/pull/5059)
|
||||
- client list-asks --by-ping (https://github.com/filecoin-project/lotus/pull/5060)
|
||||
- Ledger signature verification (https://github.com/filecoin-project/lotus/pull/5068)
|
||||
- Fix helptext for verified-deal default in client deal (https://github.com/filecoin-project/lotus/pull/5074)
|
||||
- worker: Support setting task types at runtime (https://github.com/filecoin-project/lotus/pull/5023)
|
||||
- Enable Callers tracing when GasTracing is enabled (https://github.com/filecoin-project/lotus/pull/5080)
|
||||
- Cancel transfer cancels storage deal (https://github.com/filecoin-project/lotus/pull/5032)
|
||||
- Sector check command (https://github.com/filecoin-project/lotus/pull/5041)
|
||||
- add commp-to-cid base64 decode (https://github.com/filecoin-project/lotus/pull/5079)
|
||||
- miner info cli improvements (https://github.com/filecoin-project/lotus/pull/5083)
|
||||
- miner: Add slow mode to proving check (https://github.com/filecoin-project/lotus/pull/5086)
|
||||
- Error out deals that are not activated by proposed deal start epoch (https://github.com/filecoin-project/lotus/pull/5061)
|
||||
|
||||
# 1.2.1 / 2020-11-20
|
||||
|
||||
This is a very small release of Lotus that fixes an issue users are experiencing when importing snapshots. There is no need to upgrade unless you experience an issue with creating a new datastore directory in the Lotus repo.
|
||||
|
||||
## Changes
|
||||
|
||||
- fix blockstore directory not created automatically (https://github.com/filecoin-project/lotus/pull/4922)
|
||||
- WindowPoStScheduler.checkSectors() delete useless judgment (https://github.com/filecoin-project/lotus/pull/4918)
|
||||
|
||||
|
||||
# 1.2.0 / 2020-11-18
|
||||
|
||||
This is a mandatory release of Lotus that introduces the second post-liftoff upgrade to the Filecoin network. The network upgrade occurs at height 265200, before which time all nodes must have updated to this release (or later). This release also bumps the required version of Go to 1.15.
|
||||
|
||||
The changes that break consensus are:
|
||||
|
||||
- Upgrading to sepcs-actors 2.3.2 (https://github.com/filecoin-project/specs-actors/releases/tag/v2.3.2)
|
||||
- Introducing proofs v5.4.0 (https://github.com/filecoin-project/rust-fil-proofs/releases/tag/storage-proofs-v5.4.0), and switching between the proof types (https://github.com/filecoin-project/lotus/pull/4873)
|
||||
- Don't use terminated sectors for winning PoSt (https://github.com/filecoin-project/lotus/pull/4770)
|
||||
- Various small VM-level edge-case handling (https://github.com/filecoin-project/lotus/pull/4783)
|
||||
- Correction of the VM circulating supply calculation (https://github.com/filecoin-project/lotus/pull/4862)
|
||||
- Retuning gas costs (https://github.com/filecoin-project/lotus/pull/4830)
|
||||
- Avoid sending messages to the zero BLS address (https://github.com/filecoin-project/lotus/pull/4888)
|
||||
|
||||
## Other Changes
|
||||
|
||||
- delayed pubsub subscribe for messages topic (https://github.com/filecoin-project/lotus/pull/3646)
|
||||
- add chain base64 decode params (https://github.com/filecoin-project/lotus/pull/4748)
|
||||
- chore(dep): update bitswap to fix an initialization race that could panic (https://github.com/filecoin-project/lotus/pull/4855)
|
||||
- Chore/blockstore nits (https://github.com/filecoin-project/lotus/pull/4813)
|
||||
- Print Consensus Faults in miner info (https://github.com/filecoin-project/lotus/pull/4853)
|
||||
- Truncate genesis file before generating (https://github.com/filecoin-project/lotus/pull/4851)
|
||||
- miner: Winning PoSt Warmup (https://github.com/filecoin-project/lotus/pull/4824)
|
||||
- Fix init actor address map diffing (https://github.com/filecoin-project/lotus/pull/4875)
|
||||
- Bump API versions to 1.0.0 (https://github.com/filecoin-project/lotus/pull/4884)
|
||||
- Fix cid recording issue (https://github.com/filecoin-project/lotus/pull/4874)
|
||||
- Speed up worker key retrieval (https://github.com/filecoin-project/lotus/pull/4885)
|
||||
- Add error codes to worker return (https://github.com/filecoin-project/lotus/pull/4890)
|
||||
- Update go to 1.15.5 (https://github.com/filecoin-project/lotus/pull/4896)
|
||||
- Fix MaxSealingSectrosForDeals getting reset to 0 (https://github.com/filecoin-project/lotus/pull/4879)
|
||||
- add sanity check for maximum block size (https://github.com/filecoin-project/lotus/pull/3171)
|
||||
- Check (pre)commit receipt before other checks in failed states (https://github.com/filecoin-project/lotus/pull/4712)
|
||||
- fix badger double open on daemon --import-snapshot; chainstore lifecycle (https://github.com/filecoin-project/lotus/pull/4872)
|
||||
- Update to ipfs-blockstore 1.0.3 (https://github.com/filecoin-project/lotus/pull/4897)
|
||||
- break loop when found warm up sector (https://github.com/filecoin-project/lotus/pull/4869)
|
||||
- Tweak handling of bad beneficaries in DeleteActor (https://github.com/filecoin-project/lotus/pull/4903)
|
||||
- cap maximum number of messages per block in selection (https://github.com/filecoin-project/lotus/pull/4905)
|
||||
- Set Calico epoch (https://github.com/filecoin-project/lotus/pull/4889)
|
||||
|
||||
# 1.1.3 / 2020-11-13
|
||||
|
||||
This is an optional release of Lotus that upgrades Lotus dependencies, and includes many performance enhancements, bugfixes, and UX improvements.
|
||||
|
||||
## Highlights
|
||||
|
||||
- Refactored much of the miner code (https://github.com/filecoin-project/lotus/pull/3618), improving its recovery from restarts and overall sector success rate
|
||||
- Updated [proofs](https://github.com/filecoin-project/rust-fil-proofs) to v5.3.0, which brings significant performance improvements
|
||||
- Updated [markets](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.0.4) to v1.0.4, which reduces failures due to reorgs (https://github.com/filecoin-project/lotus/pull/4730) and uses the newly refactored fund manager (https://github.com/filecoin-project/lotus/pull/4736)
|
||||
|
||||
## Changes
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- polish: add Equals method to MinerInfo shim (https://github.com/filecoin-project/lotus/pull/4604)
|
||||
- Fix messagepool accounting (https://github.com/filecoin-project/lotus/pull/4668)
|
||||
- Prep for gas balancing (https://github.com/filecoin-project/lotus/pull/4651)
|
||||
- Reduce badger ValueThreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
|
||||
- Config for default max gas fee (https://github.com/filecoin-project/lotus/pull/4652)
|
||||
- bootstrap: don't return early when one drand resolution fails (https://github.com/filecoin-project/lotus/pull/4626)
|
||||
- polish: add ClaimsChanged and DiffClaims method to power shim (https://github.com/filecoin-project/lotus/pull/4628)
|
||||
- Simplify chain event Called API (https://github.com/filecoin-project/lotus/pull/4664)
|
||||
- Cache deal states for most recent old/new tipset (https://github.com/filecoin-project/lotus/pull/4623)
|
||||
- Add miner available balance and power info to state miner info (https://github.com/filecoin-project/lotus/pull/4618)
|
||||
- Call GetHeaviestTipSet() only once when syncing (https://github.com/filecoin-project/lotus/pull/4696)
|
||||
- modify runtime gasUsed printf (https://github.com/filecoin-project/lotus/pull/4704)
|
||||
- Rename builtin actor generators (https://github.com/filecoin-project/lotus/pull/4697)
|
||||
- Move gas multiplier as property of pricelist (https://github.com/filecoin-project/lotus/pull/4728)
|
||||
- polish: add msig pendingtxn diffing and comp (https://github.com/filecoin-project/lotus/pull/4719)
|
||||
- Optional chain Bitswap (https://github.com/filecoin-project/lotus/pull/4717)
|
||||
- rewrite sync manager (https://github.com/filecoin-project/lotus/pull/4599)
|
||||
- async connect to bootstrappers (https://github.com/filecoin-project/lotus/pull/4785)
|
||||
- head change coalescer (https://github.com/filecoin-project/lotus/pull/4688)
|
||||
- move to native badger blockstore; leverage zero-copy View() to deserialize in-place (https://github.com/filecoin-project/lotus/pull/4681)
|
||||
- badger blockstore: minor improvements (https://github.com/filecoin-project/lotus/pull/4811)
|
||||
- Do not fail wallet delete because of pre-existing trashed key (https://github.com/filecoin-project/lotus/pull/4589)
|
||||
- Correctly delete the default wallet address (https://github.com/filecoin-project/lotus/pull/4705)
|
||||
- Reduce badger ValueTreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
|
||||
- predicates: Fast StateGetActor wrapper (https://github.com/filecoin-project/lotus/pull/4835)
|
||||
|
||||
#### Mining
|
||||
|
||||
- worker key should change when set sender found key not equal with the value on chain (https://github.com/filecoin-project/lotus/pull/4595)
|
||||
- extern/sector-storage: fix GPU usage overwrite bug (https://github.com/filecoin-project/lotus/pull/4627)
|
||||
- sectorstorage: Fix manager restart edge-case (https://github.com/filecoin-project/lotus/pull/4645)
|
||||
- storagefsm: Fix GetTicket loop when the sector is already precommitted (https://github.com/filecoin-project/lotus/pull/4643)
|
||||
- Debug flag to force running sealing scheduler (https://github.com/filecoin-project/lotus/pull/4662)
|
||||
- Fix worker reenabling, handle multiple restarts in worker (https://github.com/filecoin-project/lotus/pull/4666)
|
||||
- keep retrying the proof until we run out of sectors to skip (https://github.com/filecoin-project/lotus/pull/4633)
|
||||
- worker: Commands to pause/resume task processing (https://github.com/filecoin-project/lotus/pull/4615)
|
||||
- struct name incorrect (https://github.com/filecoin-project/lotus/pull/4699)
|
||||
- optimize code replace strings with constants (https://github.com/filecoin-project/lotus/pull/4769)
|
||||
- optimize pledge sector (https://github.com/filecoin-project/lotus/pull/4765)
|
||||
- Track sealing processes across lotus-miner restarts (https://github.com/filecoin-project/lotus/pull/3618)
|
||||
- Fix scheduler lockups after storage is freed (https://github.com/filecoin-project/lotus/pull/4778)
|
||||
- storage: Track worker hostnames with work (https://github.com/filecoin-project/lotus/pull/4779)
|
||||
- Expand sched-diag; Command to abort sealing calls (https://github.com/filecoin-project/lotus/pull/4804)
|
||||
- miner: Winning PoSt Warmup (https://github.com/filecoin-project/lotus/pull/4824)
|
||||
- docsgen: Support miner/worker (https://github.com/filecoin-project/lotus/pull/4817)
|
||||
- miner: Basic storage cleanup command (https://github.com/filecoin-project/lotus/pull/4834)
|
||||
|
||||
#### Markets and Data Transfer
|
||||
|
||||
- Flesh out data transfer features (https://github.com/filecoin-project/lotus/pull/4572)
|
||||
- Fix memory leaks in data transfer (https://github.com/filecoin-project/lotus/pull/4619)
|
||||
- Handle deal id changes in OnDealSectorCommitted (https://github.com/filecoin-project/lotus/pull/4730)
|
||||
- Refactor FundManager (https://github.com/filecoin-project/lotus/pull/4736)
|
||||
- refactor: integrate new FundManager (https://github.com/filecoin-project/lotus/pull/4787)
|
||||
- Fix race in paych manager when req context is cancelled (https://github.com/filecoin-project/lotus/pull/4803)
|
||||
- fix race in paych manager add funds (https://github.com/filecoin-project/lotus/pull/4597)
|
||||
- Fix panic in FundManager (https://github.com/filecoin-project/lotus/pull/4808)
|
||||
- Fix: dont crash on startup if funds migration fails (https://github.com/filecoin-project/lotus/pull/4827)
|
||||
|
||||
#### UX
|
||||
|
||||
- Make EarlyExpiration in sectors list less scary (https://github.com/filecoin-project/lotus/pull/4600)
|
||||
- Add commands to change the worker key (https://github.com/filecoin-project/lotus/pull/4513)
|
||||
- Expose ClientDealSize via CLI (https://github.com/filecoin-project/lotus/pull/4569)
|
||||
- client deal: Cache CommD when creating multiple deals (https://github.com/filecoin-project/lotus/pull/4535)
|
||||
- miner sectors list: flags for events/seal time (https://github.com/filecoin-project/lotus/pull/4649)
|
||||
- make IPFS online mode configurable (https://github.com/filecoin-project/lotus/pull/4650)
|
||||
- Add sync status to miner info command (https://github.com/filecoin-project/lotus/pull/4669)
|
||||
- Add a StateDecodeParams method (https://github.com/filecoin-project/lotus/pull/4105)
|
||||
- sched: Interactive RPC Shell (https://github.com/filecoin-project/lotus/pull/4692)
|
||||
- Add api for getting status given a code (https://github.com/filecoin-project/lotus/pull/4210)
|
||||
- Update lotus-stats with a richer cli (https://github.com/filecoin-project/lotus/pull/4718)
|
||||
- Use TSK passed to GasEstimateGasLimit (https://github.com/filecoin-project/lotus/pull/4739)
|
||||
- match data type for reward state api (https://github.com/filecoin-project/lotus/pull/4745)
|
||||
- Add `termination-estimate` to get an estimation for how much a termination penalty will be (https://github.com/filecoin-project/lotus/pull/4617)
|
||||
- Restrict `ParseFIL` input length (https://github.com/filecoin-project/lotus/pull/4780)
|
||||
- cmd sectors commitIDs len debug (https://github.com/filecoin-project/lotus/pull/4786)
|
||||
- Add client deal-stats CLI (https://github.com/filecoin-project/lotus/pull/4788)
|
||||
- Modify printf format (https://github.com/filecoin-project/lotus/pull/4795)
|
||||
- Updated msig inspect (https://github.com/filecoin-project/lotus/pull/4533)
|
||||
- Delete the duplicate output (https://github.com/filecoin-project/lotus/pull/4819)
|
||||
- miner: Storage list sectors command (https://github.com/filecoin-project/lotus/pull/4831)
|
||||
- drop a few logs down to debug (https://github.com/filecoin-project/lotus/pull/4832)
|
||||
|
||||
#### Testing and Tooling
|
||||
|
||||
- refactor: share code between CLI tests (https://github.com/filecoin-project/lotus/pull/4598)
|
||||
- Fix flaky TestCLIDealFlow (https://github.com/filecoin-project/lotus/pull/4608)
|
||||
- Fix flaky testMiningReal (https://github.com/filecoin-project/lotus/pull/4609)
|
||||
- Add election run-dummy command (https://github.com/filecoin-project/lotus/pull/4498)
|
||||
- Fix .gitmodules (https://github.com/filecoin-project/lotus/pull/4713)
|
||||
- fix metrics wiring.(https://github.com/filecoin-project/lotus/pull/4691)
|
||||
- shed: Util for creating ID CIDs (https://github.com/filecoin-project/lotus/pull/4726)
|
||||
- Run kumquat upgrade on devnets (https://github.com/filecoin-project/lotus/pull/4734)
|
||||
- Make pond work again (https://github.com/filecoin-project/lotus/pull/4775)
|
||||
- lotus-stats: fix influx flags (https://github.com/filecoin-project/lotus/pull/4810)
|
||||
- 2k sync BootstrapPeerThreshold (https://github.com/filecoin-project/lotus/pull/4797)
|
||||
- test for FundManager panic to ensure it is fixed (https://github.com/filecoin-project/lotus/pull/4825)
|
||||
- Stop mining at the end of tests (https://github.com/filecoin-project/lotus/pull/4826)
|
||||
- Make some logs quieter (https://github.com/filecoin-project/lotus/pull/4709)
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- update filecoin-ffi in go mod (https://github.com/filecoin-project/lotus/pull/4584)
|
||||
- Update FFI (https://github.com/filecoin-project/lotus/pull/4613)
|
||||
- feat: integrate new optional blst backend and verification optimizations from proofs (https://github.com/filecoin-project/lotus/pull/4630)
|
||||
- Use https for blst submodule (https://github.com/filecoin-project/lotus/pull/4710)
|
||||
- Update go-bitfield (https://github.com/filecoin-project/lotus/pull/4756)
|
||||
- Update Yamux (https://github.com/filecoin-project/lotus/pull/4758)
|
||||
- Update to latest go-bitfield (https://github.com/filecoin-project/lotus/pull/4793)
|
||||
- Update to latest go-address (https://github.com/filecoin-project/lotus/pull/4798)
|
||||
- update libp2p for stream interface changes (https://github.com/filecoin-project/lotus/pull/4814)
|
||||
|
||||
# 1.1.2 / 2020-10-24
|
||||
|
||||
This is a patch release of Lotus that builds on the fixes involving worker keys that was introduced in v1.1.1. Miners and node operators should update to this release as soon as possible in order to ensure their blocks are propagated and validated.
|
||||
|
||||
@@ -5,10 +5,10 @@ all: build
|
||||
|
||||
unexport GOFLAGS
|
||||
|
||||
GOVERSION:=$(shell go version | cut -d' ' -f 3 | cut -d. -f 2)
|
||||
ifeq ($(shell expr $(GOVERSION) \< 14), 1)
|
||||
$(warning Your Golang version is go 1.$(GOVERSION))
|
||||
$(error Update Golang to version $(shell grep '^go' go.mod))
|
||||
GOVERSION:=$(shell go version | cut -d' ' -f 3 | sed 's/^go//' | awk -F. '{printf "%d%03d%03d", $$1, $$2, $$3}')
|
||||
ifeq ($(shell expr $(GOVERSION) \< 1015005), 1)
|
||||
$(warning Your Golang version is go$(shell expr $(GOVERSION) / 1000000).$(shell expr $(GOVERSION) % 1000000 / 1000).$(shell expr $(GOVERSION) % 1000))
|
||||
$(error Update Golang to version to at least 1.15.5)
|
||||
endif
|
||||
|
||||
# git modules that need to be loaded
|
||||
@@ -204,6 +204,12 @@ lotus-wallet:
|
||||
.PHONY: lotus-wallet
|
||||
BINS+=lotus-wallet
|
||||
|
||||
lotus-keygen:
|
||||
rm -f lotus-keygen
|
||||
go build -o lotus-keygen ./cmd/lotus-keygen
|
||||
.PHONY: lotus-keygen
|
||||
BINS+=lotus-keygen
|
||||
|
||||
testground:
|
||||
go build -tags testground -o /dev/null ./cmd/lotus
|
||||
.PHONY: testground
|
||||
@@ -304,7 +310,9 @@ method-gen:
|
||||
gen: type-gen method-gen
|
||||
|
||||
docsgen:
|
||||
go run ./api/docgen > documentation/en/api-methods.md
|
||||
go run ./api/docgen "api/api_full.go" "FullNode" > documentation/en/api-methods.md
|
||||
go run ./api/docgen "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md
|
||||
go run ./api/docgen "api/api_worker.go" "WorkerAPI" > documentation/en/api-methods-worker.md
|
||||
|
||||
print-%:
|
||||
@echo $*=$($*)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<a href="https://circleci.com/gh/filecoin-project/lotus"><img src="https://circleci.com/gh/filecoin-project/lotus.svg?style=svg"></a>
|
||||
<a href="https://codecov.io/gh/filecoin-project/lotus"><img src="https://codecov.io/gh/filecoin-project/lotus/branch/master/graph/badge.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/filecoin-project/lotus"><img src="https://goreportcard.com/badge/github.com/filecoin-project/lotus" /></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.14.7-blue.svg" /></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.15.5-blue.svg" /></a>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -46,6 +46,11 @@ type Common interface {
|
||||
// usage and current rate per protocol
|
||||
NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error)
|
||||
|
||||
// ConnectionGater API
|
||||
NetBlockAdd(ctx context.Context, acl NetBlockList) error
|
||||
NetBlockRemove(ctx context.Context, acl NetBlockList) error
|
||||
NetBlockList(ctx context.Context) (NetBlockList, error)
|
||||
|
||||
// MethodGroup: Common
|
||||
|
||||
// ID returns peerID of libp2p node backing this API
|
||||
|
||||
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -518,6 +519,8 @@ type FullNode interface {
|
||||
MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
||||
// MarketReleaseFunds releases funds reserved by MarketReserveFunds
|
||||
MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error
|
||||
// MarketWithdraw withdraws unlocked funds from the market actor
|
||||
MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
||||
|
||||
// MethodGroup: Paych
|
||||
// The Paych methods are for interacting with and managing payment channels
|
||||
@@ -591,6 +594,9 @@ type DealInfo struct {
|
||||
|
||||
CreationTime time.Time
|
||||
Verified bool
|
||||
|
||||
TransferChannelID *datatransfer.ChannelID
|
||||
DataTransfer *DataTransferChannel
|
||||
}
|
||||
|
||||
type MsgLookup struct {
|
||||
@@ -785,6 +791,22 @@ type StartDealParams struct {
|
||||
VerifiedDeal bool
|
||||
}
|
||||
|
||||
func (s *StartDealParams) UnmarshalJSON(raw []byte) (err error) {
|
||||
type sdpAlias StartDealParams
|
||||
|
||||
sdp := sdpAlias{
|
||||
FastRetrieval: true,
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(raw, &sdp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*s = StartDealParams(sdp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type IpldObject struct {
|
||||
Cid cid.Cid
|
||||
Obj interface{}
|
||||
|
||||
@@ -39,6 +39,7 @@ type GatewayAPI interface {
|
||||
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
}
|
||||
|
||||
+29
-1
@@ -5,16 +5,18 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-fil-markets/piecestore"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
@@ -28,6 +30,7 @@ type StorageMiner interface {
|
||||
ActorAddress(context.Context) (address.Address, error)
|
||||
|
||||
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error)
|
||||
ActorAddressConfig(ctx context.Context) (AddressConfig, error)
|
||||
|
||||
MiningBase(context.Context) (*types.TipSet, error)
|
||||
|
||||
@@ -40,6 +43,12 @@ type StorageMiner interface {
|
||||
// List all staged sectors
|
||||
SectorsList(context.Context) ([]abi.SectorNumber, error)
|
||||
|
||||
// Get summary info of sectors
|
||||
SectorsSummary(ctx context.Context) (map[SectorState]int, error)
|
||||
|
||||
// List sectors in particular states
|
||||
SectorsListInStates(context.Context, []SectorState) ([]abi.SectorNumber, error)
|
||||
|
||||
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
||||
|
||||
// SectorStartSealing can be called on sectors in Empty or WaitDeals states
|
||||
@@ -103,6 +112,10 @@ type StorageMiner interface {
|
||||
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error
|
||||
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error
|
||||
DealsConsiderVerifiedStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderVerifiedStorageDeals(context.Context, bool) error
|
||||
DealsConsiderUnverifiedStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderUnverifiedStorageDeals(context.Context, bool) error
|
||||
|
||||
StorageAddLocal(ctx context.Context, path string) error
|
||||
|
||||
@@ -116,6 +129,8 @@ type StorageMiner interface {
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
// the path specified when calling CreateBackup is within the base path
|
||||
CreateBackup(ctx context.Context, fpath string) error
|
||||
|
||||
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error)
|
||||
}
|
||||
|
||||
type SealRes struct {
|
||||
@@ -195,3 +210,16 @@ func (st *SealSeed) Equals(ost *SealSeed) bool {
|
||||
}
|
||||
|
||||
type SectorState string
|
||||
|
||||
type AddrUse int
|
||||
|
||||
const (
|
||||
PreCommitAddr AddrUse = iota
|
||||
CommitAddr
|
||||
PoStAddr
|
||||
)
|
||||
|
||||
type AddressConfig struct {
|
||||
PreCommitControl []address.Address
|
||||
CommitControl []address.Address
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ type WorkerAPI interface {
|
||||
|
||||
storiface.WorkerCalls
|
||||
|
||||
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error
|
||||
TaskEnable(ctx context.Context, tt sealtasks.TaskType) error
|
||||
|
||||
// Storage / Other
|
||||
Remove(ctx context.Context, sector abi.SectorID) error
|
||||
|
||||
|
||||
+135
-58
@@ -60,6 +60,9 @@ type CommonStruct struct {
|
||||
NetBandwidthStatsByPeer func(ctx context.Context) (map[string]metrics.Stats, error) `perm:"read"`
|
||||
NetBandwidthStatsByProtocol func(ctx context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"`
|
||||
NetAgentVersion func(ctx context.Context, p peer.ID) (string, error) `perm:"read"`
|
||||
NetBlockAdd func(ctx context.Context, acl api.NetBlockList) error `perm:"admin"`
|
||||
NetBlockRemove func(ctx context.Context, acl api.NetBlockList) error `perm:"admin"`
|
||||
NetBlockList func(ctx context.Context) (api.NetBlockList, error) `perm:"read"`
|
||||
|
||||
ID func(context.Context) (peer.ID, error) `perm:"read"`
|
||||
Version func(context.Context) (api.Version, error) `perm:"read"`
|
||||
@@ -243,6 +246,7 @@ type FullNodeStruct struct {
|
||||
|
||||
MarketReserveFunds func(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MarketReleaseFunds func(ctx context.Context, addr address.Address, amt types.BigInt) error `perm:"sign"`
|
||||
MarketWithdraw func(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
PaychGet func(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
|
||||
PaychGetWaitReady func(context.Context, cid.Cid) (address.Address, error) `perm:"sign"`
|
||||
@@ -274,8 +278,9 @@ type StorageMinerStruct struct {
|
||||
CommonStruct
|
||||
|
||||
Internal struct {
|
||||
ActorAddress func(context.Context) (address.Address, error) `perm:"read"`
|
||||
ActorSectorSize func(context.Context, address.Address) (abi.SectorSize, error) `perm:"read"`
|
||||
ActorAddress func(context.Context) (address.Address, error) `perm:"read"`
|
||||
ActorSectorSize func(context.Context, address.Address) (abi.SectorSize, error) `perm:"read"`
|
||||
ActorAddressConfig func(ctx context.Context) (api.AddressConfig, error) `perm:"read"`
|
||||
|
||||
MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
@@ -297,6 +302,8 @@ type StorageMinerStruct struct {
|
||||
|
||||
SectorsStatus func(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (api.SectorInfo, error) `perm:"read"`
|
||||
SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"`
|
||||
SectorsListInStates func(context.Context, []api.SectorState) ([]abi.SectorNumber, error) `perm:"read"`
|
||||
SectorsSummary func(ctx context.Context) (map[api.SectorState]int, error) `perm:"read"`
|
||||
SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"`
|
||||
SectorStartSealing func(context.Context, abi.SectorNumber) error `perm:"write"`
|
||||
SectorSetSealDelay func(context.Context, time.Duration) error `perm:"write"`
|
||||
@@ -311,17 +318,17 @@ type StorageMinerStruct struct {
|
||||
WorkerStats func(context.Context) (map[uuid.UUID]storiface.WorkerStats, error) `perm:"admin"`
|
||||
WorkerJobs func(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"`
|
||||
|
||||
ReturnAddPiece func(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnSealPreCommit1 func(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnSealPreCommit2 func(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnSealCommit1 func(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnSealCommit2 func(ctx context.Context, callID storiface.CallID, proof storage.Proof, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnFinalizeSector func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnReleaseUnsealed func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnMoveStorage func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnUnsealPiece func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnReadPiece func(ctx context.Context, callID storiface.CallID, ok bool, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnFetch func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
|
||||
ReturnAddPiece func(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnSealPreCommit1 func(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnSealPreCommit2 func(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnSealCommit1 func(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnSealCommit2 func(ctx context.Context, callID storiface.CallID, proof storage.Proof, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnFinalizeSector func(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnReleaseUnsealed func(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnMoveStorage func(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnUnsealPiece func(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnReadPiece func(ctx context.Context, callID storiface.CallID, ok bool, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
ReturnFetch func(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error `perm:"admin" retry:"true"`
|
||||
|
||||
SealingSchedDiag func(context.Context, bool) (interface{}, error) `perm:"admin"`
|
||||
SealingAbort func(ctx context.Context, call storiface.CallID) error `perm:"admin"`
|
||||
@@ -339,18 +346,22 @@ type StorageMinerStruct struct {
|
||||
StorageLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error `perm:"admin"`
|
||||
StorageTryLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) `perm:"admin"`
|
||||
|
||||
DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
|
||||
DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
|
||||
DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOfflineStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOfflineRetrievalDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"read"`
|
||||
DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"admin"`
|
||||
DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
|
||||
DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
|
||||
DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOnlineRetrievalDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOfflineStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOfflineStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOfflineRetrievalDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOfflineRetrievalDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderVerifiedStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderVerifiedStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderUnverifiedStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderUnverifiedStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsPieceCidBlocklist func(context.Context) ([]cid.Cid, error) `perm:"read"`
|
||||
DealsSetPieceCidBlocklist func(context.Context, []cid.Cid) error `perm:"admin"`
|
||||
|
||||
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
|
||||
|
||||
@@ -360,6 +371,8 @@ type StorageMinerStruct struct {
|
||||
PiecesGetCIDInfo func(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"`
|
||||
|
||||
CreateBackup func(ctx context.Context, fpath string) error `perm:"admin"`
|
||||
|
||||
CheckProvable func(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) `perm:"admin"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,17 +386,20 @@ type WorkerStruct struct {
|
||||
Paths func(context.Context) ([]stores.StoragePath, error) `perm:"admin"`
|
||||
Info func(context.Context) (storiface.WorkerInfo, error) `perm:"admin"`
|
||||
|
||||
AddPiece func(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) `perm:"admin"`
|
||||
SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"`
|
||||
SealPreCommit2 func(ctx context.Context, sector abi.SectorID, pc1o storage.PreCommit1Out) (storiface.CallID, error) `perm:"admin"`
|
||||
SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) `perm:"admin"`
|
||||
SealCommit2 func(ctx context.Context, sector abi.SectorID, c1o storage.Commit1Out) (storiface.CallID, error) `perm:"admin"`
|
||||
FinalizeSector func(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) (storiface.CallID, error) `perm:"admin"`
|
||||
ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) (storiface.CallID, error) `perm:"admin"`
|
||||
MoveStorage func(ctx context.Context, sector abi.SectorID, types storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"`
|
||||
UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) `perm:"admin"`
|
||||
ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"`
|
||||
Fetch func(context.Context, abi.SectorID, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"`
|
||||
AddPiece func(ctx context.Context, sector storage.SectorRef, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) `perm:"admin"`
|
||||
SealPreCommit1 func(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"`
|
||||
SealPreCommit2 func(ctx context.Context, sector storage.SectorRef, pc1o storage.PreCommit1Out) (storiface.CallID, error) `perm:"admin"`
|
||||
SealCommit1 func(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) `perm:"admin"`
|
||||
SealCommit2 func(ctx context.Context, sector storage.SectorRef, c1o storage.Commit1Out) (storiface.CallID, error) `perm:"admin"`
|
||||
FinalizeSector func(ctx context.Context, sector storage.SectorRef, keepUnsealed []storage.Range) (storiface.CallID, error) `perm:"admin"`
|
||||
ReleaseUnsealed func(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) `perm:"admin"`
|
||||
MoveStorage func(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"`
|
||||
UnsealPiece func(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) `perm:"admin"`
|
||||
ReadPiece func(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"`
|
||||
Fetch func(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"`
|
||||
|
||||
TaskDisable func(ctx context.Context, tt sealtasks.TaskType) error `perm:"admin"`
|
||||
TaskEnable func(ctx context.Context, tt sealtasks.TaskType) error `perm:"admin"`
|
||||
|
||||
Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
|
||||
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
|
||||
@@ -424,6 +440,7 @@ type GatewayStruct struct {
|
||||
StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
|
||||
StateMarketStorageDeal func(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
|
||||
StateNetworkVersion func(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error)
|
||||
StateSectorGetInfo func(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StateVerifiedClientStatus func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateWaitMsg func(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
||||
}
|
||||
@@ -495,6 +512,18 @@ func (c *CommonStruct) NetBandwidthStatsByProtocol(ctx context.Context) (map[pro
|
||||
return c.Internal.NetBandwidthStatsByProtocol(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetBlockAdd(ctx context.Context, acl api.NetBlockList) error {
|
||||
return c.Internal.NetBlockAdd(ctx, acl)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetBlockRemove(ctx context.Context, acl api.NetBlockList) error {
|
||||
return c.Internal.NetBlockRemove(ctx, acl)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetBlockList(ctx context.Context) (api.NetBlockList, error) {
|
||||
return c.Internal.NetBlockList(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetAgentVersion(ctx context.Context, p peer.ID) (string, error) {
|
||||
return c.Internal.NetAgentVersion(ctx, p)
|
||||
}
|
||||
@@ -1127,6 +1156,10 @@ func (c *FullNodeStruct) MarketReleaseFunds(ctx context.Context, addr address.Ad
|
||||
return c.Internal.MarketReleaseFunds(ctx, addr, amt)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketWithdraw(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) {
|
||||
return c.Internal.MarketWithdraw(ctx, wallet, addr, amt)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) {
|
||||
return c.Internal.PaychGet(ctx, from, to, amt)
|
||||
}
|
||||
@@ -1209,6 +1242,10 @@ func (c *StorageMinerStruct) ActorSectorSize(ctx context.Context, addr address.A
|
||||
return c.Internal.ActorSectorSize(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ActorAddressConfig(ctx context.Context) (api.AddressConfig, error) {
|
||||
return c.Internal.ActorAddressConfig(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) PledgeSector(ctx context.Context) error {
|
||||
return c.Internal.PledgeSector(ctx)
|
||||
}
|
||||
@@ -1223,6 +1260,14 @@ func (c *StorageMinerStruct) SectorsList(ctx context.Context) ([]abi.SectorNumbe
|
||||
return c.Internal.SectorsList(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorsListInStates(ctx context.Context, states []api.SectorState) ([]abi.SectorNumber, error) {
|
||||
return c.Internal.SectorsListInStates(ctx, states)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) {
|
||||
return c.Internal.SectorsSummary(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]api.SealedRef, error) {
|
||||
return c.Internal.SectorsRefs(ctx)
|
||||
}
|
||||
@@ -1271,47 +1316,47 @@ func (c *StorageMinerStruct) WorkerJobs(ctx context.Context) (map[uuid.UUID][]st
|
||||
return c.Internal.WorkerJobs(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnAddPiece(ctx, callID, pi, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnSealPreCommit1(ctx, callID, p1o, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnSealPreCommit2(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnSealPreCommit2(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnSealPreCommit2(ctx, callID, sealed, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnSealCommit1(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnSealCommit1(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnSealCommit1(ctx, callID, out, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnSealCommit2(ctx context.Context, callID storiface.CallID, proof storage.Proof, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnSealCommit2(ctx context.Context, callID storiface.CallID, proof storage.Proof, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnSealCommit2(ctx, callID, proof, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnFinalizeSector(ctx context.Context, callID storiface.CallID, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnFinalizeSector(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnFinalizeSector(ctx, callID, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnReleaseUnsealed(ctx context.Context, callID storiface.CallID, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnReleaseUnsealed(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnReleaseUnsealed(ctx, callID, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnMoveStorage(ctx context.Context, callID storiface.CallID, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnMoveStorage(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnMoveStorage(ctx, callID, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnUnsealPiece(ctx context.Context, callID storiface.CallID, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnUnsealPiece(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnUnsealPiece(ctx, callID, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnReadPiece(ctx context.Context, callID storiface.CallID, ok bool, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnReadPiece(ctx context.Context, callID storiface.CallID, ok bool, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnReadPiece(ctx, callID, ok, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ReturnFetch(ctx context.Context, callID storiface.CallID, err string) error {
|
||||
func (c *StorageMinerStruct) ReturnFetch(ctx context.Context, callID storiface.CallID, err *storiface.CallError) error {
|
||||
return c.Internal.ReturnFetch(ctx, callID, err)
|
||||
}
|
||||
|
||||
@@ -1471,6 +1516,22 @@ func (c *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(ctx context.C
|
||||
return c.Internal.DealsSetConsiderOfflineRetrievalDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(ctx context.Context) (bool, error) {
|
||||
return c.Internal.DealsConsiderVerifiedStorageDeals(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(ctx context.Context, b bool) error {
|
||||
return c.Internal.DealsSetConsiderVerifiedStorageDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(ctx context.Context) (bool, error) {
|
||||
return c.Internal.DealsConsiderUnverifiedStorageDeals(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(ctx context.Context, b bool) error {
|
||||
return c.Internal.DealsSetConsiderUnverifiedStorageDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error {
|
||||
return c.Internal.StorageAddLocal(ctx, path)
|
||||
}
|
||||
@@ -1495,6 +1556,10 @@ func (c *StorageMinerStruct) CreateBackup(ctx context.Context, fpath string) err
|
||||
return c.Internal.CreateBackup(ctx, fpath)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) {
|
||||
return c.Internal.CheckProvable(ctx, pp, sectors, expensive)
|
||||
}
|
||||
|
||||
// WorkerStruct
|
||||
|
||||
func (w *WorkerStruct) Version(ctx context.Context) (build.Version, error) {
|
||||
@@ -1513,50 +1578,58 @@ func (w *WorkerStruct) Info(ctx context.Context) (storiface.WorkerInfo, error) {
|
||||
return w.Internal.Info(ctx)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) AddPiece(ctx context.Context, sector storage.SectorRef, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) {
|
||||
return w.Internal.AddPiece(ctx, sector, pieceSizes, newPieceSize, pieceData)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) SealPreCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) SealPreCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) {
|
||||
return w.Internal.SealPreCommit1(ctx, sector, ticket, pieces)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) SealPreCommit2(ctx context.Context, sector abi.SectorID, pc1o storage.PreCommit1Out) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) SealPreCommit2(ctx context.Context, sector storage.SectorRef, pc1o storage.PreCommit1Out) (storiface.CallID, error) {
|
||||
return w.Internal.SealPreCommit2(ctx, sector, pc1o)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) SealCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) SealCommit1(ctx context.Context, sector storage.SectorRef, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) {
|
||||
return w.Internal.SealCommit1(ctx, sector, ticket, seed, pieces, cids)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) SealCommit2(ctx context.Context, sector abi.SectorID, c1o storage.Commit1Out) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) SealCommit2(ctx context.Context, sector storage.SectorRef, c1o storage.Commit1Out) (storiface.CallID, error) {
|
||||
return w.Internal.SealCommit2(ctx, sector, c1o)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector storage.SectorRef, keepUnsealed []storage.Range) (storiface.CallID, error) {
|
||||
return w.Internal.FinalizeSector(ctx, sector, keepUnsealed)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) ReleaseUnsealed(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) {
|
||||
return w.Internal.ReleaseUnsealed(ctx, sector, safeToFree)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID, types storiface.SectorFileType) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) {
|
||||
return w.Internal.MoveStorage(ctx, sector, types)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) UnsealPiece(ctx context.Context, sector abi.SectorID, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, c cid.Cid) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) UnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, c cid.Cid) (storiface.CallID, error) {
|
||||
return w.Internal.UnsealPiece(ctx, sector, offset, size, ticket, c)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) ReadPiece(ctx context.Context, sink io.Writer, sector abi.SectorID, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) ReadPiece(ctx context.Context, sink io.Writer, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) {
|
||||
return w.Internal.ReadPiece(ctx, sink, sector, offset, size)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType storiface.SectorFileType, ptype storiface.PathType, am storiface.AcquireMode) (storiface.CallID, error) {
|
||||
func (w *WorkerStruct) Fetch(ctx context.Context, id storage.SectorRef, fileType storiface.SectorFileType, ptype storiface.PathType, am storiface.AcquireMode) (storiface.CallID, error) {
|
||||
return w.Internal.Fetch(ctx, id, fileType, ptype, am)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) TaskDisable(ctx context.Context, tt sealtasks.TaskType) error {
|
||||
return w.Internal.TaskDisable(ctx, tt)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) TaskEnable(ctx context.Context, tt sealtasks.TaskType) error {
|
||||
return w.Internal.TaskEnable(ctx, tt)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Remove(ctx context.Context, sector abi.SectorID) error {
|
||||
return w.Internal.Remove(ctx, sector)
|
||||
}
|
||||
@@ -1681,6 +1754,10 @@ func (g GatewayStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSet
|
||||
return g.Internal.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) {
|
||||
return g.Internal.StateSectorGetInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
|
||||
return g.Internal.StateVerifiedClientStatus(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
+130
-28
@@ -6,12 +6,14 @@ import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-filestore"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
@@ -24,6 +26,7 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
filestore2 "github.com/filecoin-project/go-fil-markets/filestore"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
@@ -36,6 +39,10 @@ import (
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"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"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
@@ -83,7 +90,7 @@ func init() {
|
||||
addExample(&pid)
|
||||
|
||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1)
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1_1)
|
||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
||||
addExample(abi.ChainEpoch(10101))
|
||||
addExample(crypto.SigTypeBLS)
|
||||
@@ -117,17 +124,17 @@ func init() {
|
||||
addExample(network.ReachabilityPublic)
|
||||
addExample(build.NewestNetworkVersion)
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
Msg: exampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
})
|
||||
addExample(map[string]types.Actor{
|
||||
"t01236": exampleValue(reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
"t01236": exampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
})
|
||||
addExample(map[string]api.MarketDeal{
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
})
|
||||
addExample(map[string]api.MarketBalance{
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
})
|
||||
addExample(map[string]*pubsub.TopicScoreSnapshot{
|
||||
"/blocks": {
|
||||
@@ -162,9 +169,89 @@ func init() {
|
||||
// because reflect.TypeOf(maddr) returns the concrete type...
|
||||
ExampleValues[reflect.TypeOf(struct{ A multiaddr.Multiaddr }{}).Field(0).Type] = maddr
|
||||
|
||||
// miner specific
|
||||
addExample(filestore2.Path(".lotusminer/fstmp123"))
|
||||
si := multistore.StoreID(12)
|
||||
addExample(&si)
|
||||
addExample(retrievalmarket.DealID(5))
|
||||
addExample(abi.ActorID(1000))
|
||||
addExample(map[string][]api.SealedRef{
|
||||
"98000": {
|
||||
api.SealedRef{
|
||||
SectorID: 100,
|
||||
Offset: 10 << 20,
|
||||
Size: 1 << 20,
|
||||
},
|
||||
},
|
||||
})
|
||||
addExample(api.SectorState(sealing.Proving))
|
||||
addExample(stores.ID("76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8"))
|
||||
addExample(storiface.FTUnsealed)
|
||||
addExample(storiface.PathSealing)
|
||||
addExample(map[stores.ID][]stores.Decl{
|
||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": {
|
||||
{
|
||||
SectorID: abi.SectorID{Miner: 1000, Number: 100},
|
||||
SectorFileType: storiface.FTSealed,
|
||||
},
|
||||
},
|
||||
})
|
||||
addExample(map[stores.ID]string{
|
||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": "/data/path",
|
||||
})
|
||||
addExample(map[uuid.UUID][]storiface.WorkerJob{
|
||||
uuid.MustParse("ef8d99a2-6865-4189-8ffa-9fef0f806eee"): {
|
||||
{
|
||||
ID: storiface.CallID{
|
||||
Sector: abi.SectorID{Miner: 1000, Number: 100},
|
||||
ID: uuid.MustParse("76081ba0-61bd-45a5-bc08-af05f1c26e5d"),
|
||||
},
|
||||
Sector: abi.SectorID{Miner: 1000, Number: 100},
|
||||
Task: sealtasks.TTPreCommit2,
|
||||
RunWait: 0,
|
||||
Start: time.Unix(1605172927, 0).UTC(),
|
||||
Hostname: "host",
|
||||
},
|
||||
},
|
||||
})
|
||||
addExample(map[uuid.UUID]storiface.WorkerStats{
|
||||
uuid.MustParse("ef8d99a2-6865-4189-8ffa-9fef0f806eee"): {
|
||||
Info: storiface.WorkerInfo{
|
||||
Hostname: "host",
|
||||
Resources: storiface.WorkerResources{
|
||||
MemPhysical: 256 << 30,
|
||||
MemSwap: 120 << 30,
|
||||
MemReserved: 2 << 30,
|
||||
CPUs: 64,
|
||||
GPUs: []string{"aGPU 1337"},
|
||||
},
|
||||
},
|
||||
Enabled: true,
|
||||
MemUsedMin: 0,
|
||||
MemUsedMax: 0,
|
||||
GpuUsed: false,
|
||||
CpuUse: 0,
|
||||
},
|
||||
})
|
||||
addExample(storiface.ErrorCode(0))
|
||||
addExample(map[abi.SectorNumber]string{
|
||||
123: "can't acquire read lock",
|
||||
})
|
||||
addExample(map[api.SectorState]int{
|
||||
api.SectorState(sealing.Proving): 120,
|
||||
})
|
||||
addExample([]abi.SectorNumber{123, 124})
|
||||
|
||||
// worker specific
|
||||
addExample(storiface.AcquireMove)
|
||||
addExample(storiface.UnpaddedByteIndex(abi.PaddedPieceSize(1 << 20).Unpadded()))
|
||||
addExample(map[sealtasks.TaskType]struct{}{
|
||||
sealtasks.TTPreCommit2: {},
|
||||
})
|
||||
addExample(sealtasks.TTCommit2)
|
||||
}
|
||||
|
||||
func exampleValue(t, parent reflect.Type) interface{} {
|
||||
func exampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
v, ok := ExampleValues[t]
|
||||
if ok {
|
||||
return v
|
||||
@@ -173,25 +260,25 @@ func exampleValue(t, parent reflect.Type) interface{} {
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
out := reflect.New(t).Elem()
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem(), t)))
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||
return out.Interface()
|
||||
case reflect.Chan:
|
||||
return exampleValue(t.Elem(), nil)
|
||||
return exampleValue(method, t.Elem(), nil)
|
||||
case reflect.Struct:
|
||||
es := exampleStruct(t, parent)
|
||||
es := exampleStruct(method, t, parent)
|
||||
v := reflect.ValueOf(es).Elem().Interface()
|
||||
ExampleValues[t] = v
|
||||
return v
|
||||
case reflect.Array:
|
||||
out := reflect.New(t).Elem()
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem(), t)))
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||
}
|
||||
return out.Interface()
|
||||
|
||||
case reflect.Ptr:
|
||||
if t.Elem().Kind() == reflect.Struct {
|
||||
es := exampleStruct(t.Elem(), t)
|
||||
es := exampleStruct(method, t.Elem(), t)
|
||||
//ExampleValues[t] = es
|
||||
return es
|
||||
}
|
||||
@@ -199,10 +286,10 @@ func exampleValue(t, parent reflect.Type) interface{} {
|
||||
return struct{}{}
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("No example value for type: %s", t))
|
||||
panic(fmt.Sprintf("No example value for type: %s (method '%s')", t, method))
|
||||
}
|
||||
|
||||
func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
func exampleStruct(method string, t, parent reflect.Type) interface{} {
|
||||
ns := reflect.New(t)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
@@ -210,7 +297,7 @@ func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
continue
|
||||
}
|
||||
if strings.Title(f.Name) == f.Name {
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type, t)))
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(method, f.Type, t)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +305,7 @@ func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
}
|
||||
|
||||
type Visitor struct {
|
||||
Root string
|
||||
Methods map[string]ast.Node
|
||||
}
|
||||
|
||||
@@ -227,7 +315,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
return v
|
||||
}
|
||||
|
||||
if st.Name.Name != "FullNode" {
|
||||
if st.Name.Name != v.Root {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -243,7 +331,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
|
||||
const noComment = "There are not yet any comments for this method."
|
||||
|
||||
func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
||||
func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]string) { //nolint:golint
|
||||
fset := token.NewFileSet()
|
||||
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
||||
if err != nil {
|
||||
@@ -252,11 +340,11 @@ func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
||||
|
||||
ap := pkgs["api"]
|
||||
|
||||
f := ap.Files["api/api_full.go"]
|
||||
f := ap.Files[apiFile]
|
||||
|
||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
||||
|
||||
v := &Visitor{make(map[string]ast.Node)}
|
||||
v := &Visitor{iface, make(map[string]ast.Node)}
|
||||
ast.Walk(v, pkgs["api"])
|
||||
|
||||
groupDocs := make(map[string]string)
|
||||
@@ -312,13 +400,30 @@ func methodGroupFromName(mn string) string {
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
comments, groupComments := parseApiASTInfo()
|
||||
comments, groupComments := parseApiASTInfo(os.Args[1], os.Args[2])
|
||||
|
||||
groups := make(map[string]*MethodGroup)
|
||||
|
||||
var api struct{ api.FullNode }
|
||||
t := reflect.TypeOf(api)
|
||||
var t reflect.Type
|
||||
var permStruct, commonPermStruct reflect.Type
|
||||
|
||||
switch os.Args[2] {
|
||||
case "FullNode":
|
||||
t = reflect.TypeOf(new(struct{ api.FullNode })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "StorageMiner":
|
||||
t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "WorkerAPI":
|
||||
t = reflect.TypeOf(new(struct{ api.WorkerAPI })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
default:
|
||||
panic("unknown type")
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
m := t.Method(i)
|
||||
|
||||
@@ -336,7 +441,7 @@ func main() {
|
||||
ft := m.Func.Type()
|
||||
for j := 2; j < ft.NumIn(); j++ {
|
||||
inp := ft.In(j)
|
||||
args = append(args, exampleValue(inp, nil))
|
||||
args = append(args, exampleValue(m.Name, inp, nil))
|
||||
}
|
||||
|
||||
v, err := json.MarshalIndent(args, "", " ")
|
||||
@@ -344,7 +449,7 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
outv := exampleValue(ft.Out(0), nil)
|
||||
outv := exampleValue(m.Name, ft.Out(0), nil)
|
||||
|
||||
ov, err := json.MarshalIndent(outv, "", " ")
|
||||
if err != nil {
|
||||
@@ -377,9 +482,6 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
permStruct := reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
||||
commonPermStruct := reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
|
||||
for _, g := range groupslice {
|
||||
g := g
|
||||
fmt.Printf("## %s\n", g.GroupName)
|
||||
|
||||
@@ -37,7 +37,12 @@ func (bm *BlockMiner) MineBlocks() {
|
||||
go func() {
|
||||
defer close(bm.done)
|
||||
for atomic.LoadInt64(&bm.mine) == 1 {
|
||||
time.Sleep(bm.blocktime)
|
||||
select {
|
||||
case <-bm.ctx.Done():
|
||||
return
|
||||
case <-time.After(bm.blocktime):
|
||||
}
|
||||
|
||||
nulls := atomic.SwapInt64(&bm.nulls, 0)
|
||||
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
|
||||
InjectNulls: abi.ChainEpoch(nulls),
|
||||
|
||||
@@ -31,7 +31,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
|
||||
func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) {
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithUpgradeAt(upgradeHeight)}, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -89,7 +89,7 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
MakeDeal(t, ctx, 6, client, miner, false, false)
|
||||
MakeDeal(t, ctx, 6, client, miner, false, false, 0)
|
||||
|
||||
// Validate upgrade
|
||||
|
||||
|
||||
+18
-15
@@ -12,6 +12,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -31,7 +33,7 @@ import (
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
)
|
||||
|
||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool) {
|
||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
@@ -60,14 +62,14 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
|
||||
}
|
||||
}()
|
||||
|
||||
MakeDeal(t, ctx, 6, client, miner, carExport, fastRet)
|
||||
MakeDeal(t, ctx, 6, client, miner, carExport, fastRet, startEpoch)
|
||||
|
||||
atomic.AddInt64(&mine, -1)
|
||||
fmt.Println("shutting down mining")
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
@@ -97,15 +99,15 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
}
|
||||
}()
|
||||
|
||||
MakeDeal(t, ctx, 6, client, miner, false, false)
|
||||
MakeDeal(t, ctx, 7, client, miner, false, false)
|
||||
MakeDeal(t, ctx, 6, client, miner, false, false, startEpoch)
|
||||
MakeDeal(t, ctx, 7, client, miner, false, false, startEpoch)
|
||||
|
||||
atomic.AddInt64(&mine, -1)
|
||||
fmt.Println("shutting down mining")
|
||||
<-done
|
||||
}
|
||||
|
||||
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool) {
|
||||
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||
res, data, err := CreateClientFile(ctx, client, rseed)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -114,7 +116,7 @@ func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode,
|
||||
fcid := res.Root
|
||||
fmt.Println("FILE CID: ", fcid)
|
||||
|
||||
deal := startDeal(t, ctx, miner, client, fcid, fastRet)
|
||||
deal := startDeal(t, ctx, miner, client, fcid, fastRet, startEpoch)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
@@ -149,7 +151,7 @@ func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api
|
||||
return res, data, nil
|
||||
}
|
||||
|
||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
@@ -189,7 +191,7 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
||||
|
||||
fmt.Println("FILE CID: ", fcid)
|
||||
|
||||
deal := startDeal(t, ctx, miner, client, fcid, true)
|
||||
deal := startDeal(t, ctx, miner, client, fcid, true, startEpoch)
|
||||
|
||||
waitDealPublished(t, ctx, miner, deal)
|
||||
fmt.Println("deal published, retrieving")
|
||||
@@ -203,7 +205,7 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
func TestSecondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
@@ -252,13 +254,13 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deal1 := startDeal(t, ctx, miner, client, fcid1, true)
|
||||
deal1 := startDeal(t, ctx, miner, client, fcid1, true, 0)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
waitDealSealed(t, ctx, miner, client, deal1, true)
|
||||
|
||||
deal2 := startDeal(t, ctx, miner, client, fcid2, true)
|
||||
deal2 := startDeal(t, ctx, miner, client, fcid2, true, 0)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
waitDealSealed(t, ctx, miner, client, deal2, false)
|
||||
@@ -278,7 +280,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
|
||||
<-done
|
||||
}
|
||||
|
||||
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool) *cid.Cid {
|
||||
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid {
|
||||
maddr, err := miner.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -296,6 +298,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
|
||||
Wallet: addr,
|
||||
Miner: maddr,
|
||||
EpochPrice: types.NewInt(1000000),
|
||||
DealStartEpoch: startEpoch,
|
||||
MinBlocksDuration: uint64(build.MinDealDuration),
|
||||
FastRetrieval: fastRet,
|
||||
})
|
||||
@@ -313,7 +316,7 @@ loop:
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch di.State {
|
||||
case storagemarket.StorageDealSealing:
|
||||
case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing:
|
||||
if noseal {
|
||||
return
|
||||
}
|
||||
@@ -353,7 +356,7 @@ func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode,
|
||||
t.Fatal("deal failed")
|
||||
case storagemarket.StorageDealError:
|
||||
t.Fatal("deal errored", di.Message)
|
||||
case storagemarket.StorageDealFinalizing, storagemarket.StorageDealSealing, storagemarket.StorageDealActive:
|
||||
case storagemarket.StorageDealFinalizing, storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing, storagemarket.StorageDealActive:
|
||||
fmt.Println("COMPLETE", di)
|
||||
return
|
||||
}
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
|
||||
}
|
||||
}()
|
||||
|
||||
deal := startDeal(t, ctx, provider, client, fcid, false)
|
||||
deal := startDeal(t, ctx, provider, client, fcid, false, 0)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
|
||||
+20
-1
@@ -109,7 +109,7 @@ var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
||||
var OneFull = DefaultFullOpts(1)
|
||||
var TwoFull = DefaultFullOpts(2)
|
||||
|
||||
var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
var FullNodeWithActorsV2At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
return FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
@@ -122,6 +122,25 @@ var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
}
|
||||
}
|
||||
|
||||
var FullNodeWithSDRAt = func(calico, persian abi.ChainEpoch) FullNodeOpts {
|
||||
return FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
Network: network.Version6,
|
||||
Height: 1,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}, {
|
||||
Network: network.Version7,
|
||||
Height: calico,
|
||||
Migration: stmgr.UpgradeCalico,
|
||||
}, {
|
||||
Network: network.Version8,
|
||||
Height: persian,
|
||||
}})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var MineNext = miner.MineReq{
|
||||
InjectNulls: 0,
|
||||
Done: func(bool, abi.ChainEpoch, error) {},
|
||||
|
||||
+104
-10
@@ -3,18 +3,22 @@ package test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@@ -23,6 +27,90 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
)
|
||||
|
||||
func TestSDRUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithSDRAt(500, 1000)}, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
addrinfo, err := client.NetAddrsListen(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
build.Clock.Sleep(time.Second)
|
||||
|
||||
pledge := make(chan struct{})
|
||||
mine := int64(1)
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
round := 0
|
||||
for atomic.LoadInt64(&mine) != 0 {
|
||||
build.Clock.Sleep(blocktime)
|
||||
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
|
||||
|
||||
}}); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// 3 sealing rounds: before, during after.
|
||||
if round >= 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
head, err := client.ChainHead(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// rounds happen every 100 blocks, with a 50 block offset.
|
||||
if head.Height() >= abi.ChainEpoch(round*500+50) {
|
||||
round++
|
||||
pledge <- struct{}{}
|
||||
|
||||
ver, err := client.StateNetworkVersion(ctx, head.Key())
|
||||
assert.NoError(t, err)
|
||||
switch round {
|
||||
case 1:
|
||||
assert.Equal(t, network.Version6, ver)
|
||||
case 2:
|
||||
assert.Equal(t, network.Version7, ver)
|
||||
case 3:
|
||||
assert.Equal(t, network.Version8, ver)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
// before.
|
||||
pledgeSectors(t, ctx, miner, 9, 0, pledge)
|
||||
|
||||
s, err := miner.SectorsList(ctx)
|
||||
require.NoError(t, err)
|
||||
sort.Slice(s, func(i, j int) bool {
|
||||
return s[i] < s[j]
|
||||
})
|
||||
|
||||
for i, id := range s {
|
||||
info, err := miner.SectorsStatus(ctx, id, true)
|
||||
require.NoError(t, err)
|
||||
expectProof := abi.RegisteredSealProof_StackedDrg2KiBV1
|
||||
if i >= 3 {
|
||||
// after
|
||||
expectProof = abi.RegisteredSealProof_StackedDrg2KiBV1_1
|
||||
}
|
||||
assert.Equal(t, expectProof, info.SealProof, "sector %d, id %d", i, id)
|
||||
}
|
||||
|
||||
atomic.StoreInt64(&mine, 0)
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@@ -63,11 +151,13 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
|
||||
|
||||
func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) {
|
||||
for i := 0; i < n; i++ {
|
||||
err := miner.PledgeSector(ctx)
|
||||
require.NoError(t, err)
|
||||
if i%3 == 0 && blockNotif != nil {
|
||||
<-blockNotif
|
||||
log.Errorf("WAIT")
|
||||
}
|
||||
log.Errorf("PLEDGING %d", i)
|
||||
err := miner.PledgeSector(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
for {
|
||||
@@ -126,7 +216,7 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithUpgradeAt(upgradeHeight)}, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
@@ -209,15 +299,17 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
|
||||
// Drop the partition
|
||||
err = secs.ForEach(func(sid uint64) error {
|
||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sid),
|
||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sid),
|
||||
},
|
||||
}, true)
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
var s abi.SectorID
|
||||
var s storage.SectorRef
|
||||
|
||||
// Drop 1 sectors from deadline 3 partition 0
|
||||
{
|
||||
@@ -238,9 +330,11 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
require.NoError(t, err)
|
||||
fmt.Println("the sectors", all)
|
||||
|
||||
s = abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sn),
|
||||
s = storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sn),
|
||||
},
|
||||
}
|
||||
|
||||
err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true)
|
||||
|
||||
+6
-14
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -51,19 +50,6 @@ type MessageSendSpec struct {
|
||||
MaxFee abi.TokenAmount
|
||||
}
|
||||
|
||||
var DefaultMessageSendSpec = MessageSendSpec{
|
||||
// MaxFee of 0.1FIL
|
||||
MaxFee: abi.NewTokenAmount(int64(build.FilecoinPrecision) / 10),
|
||||
}
|
||||
|
||||
func (ms *MessageSendSpec) Get() MessageSendSpec {
|
||||
if ms == nil {
|
||||
return DefaultMessageSendSpec
|
||||
}
|
||||
|
||||
return *ms
|
||||
}
|
||||
|
||||
type DataTransferChannel struct {
|
||||
TransferID datatransfer.TransferID
|
||||
Status datatransfer.Status
|
||||
@@ -107,3 +93,9 @@ func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelSta
|
||||
}
|
||||
return channel
|
||||
}
|
||||
|
||||
type NetBlockList struct {
|
||||
Peers []peer.ID
|
||||
IPAddrs []string
|
||||
IPSubnets []string
|
||||
}
|
||||
|
||||
+5
-1
@@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
@@ -23,6 +22,9 @@ var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
||||
|
||||
const UpgradeKumquatHeight = 15
|
||||
const UpgradeCalicoHeight = 20
|
||||
const UpgradePersianHeight = 25
|
||||
const UpgradeClausHeight = 30
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
@@ -53,3 +55,5 @@ const SlashablePowerDelay = 20
|
||||
|
||||
// Epochs
|
||||
const InteractivePoRepConfidence = 6
|
||||
|
||||
const BootstrapPeerThreshold = 1
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
)
|
||||
|
||||
@@ -39,12 +38,14 @@ const UpgradeLiftoffHeight = 148888
|
||||
|
||||
const UpgradeKumquatHeight = 170000
|
||||
|
||||
const UpgradeCalicoHeight = 265200
|
||||
const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
|
||||
|
||||
// 2020-12-22T02:00:00Z
|
||||
const UpgradeClausHeight = 343200
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
)
|
||||
|
||||
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
||||
SetAddressNetwork(address.Mainnet)
|
||||
@@ -60,3 +61,6 @@ func init() {
|
||||
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
||||
|
||||
const PropagationDelaySecs = uint64(6)
|
||||
|
||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||
const BootstrapPeerThreshold = 4
|
||||
|
||||
@@ -19,3 +19,12 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
||||
func SetAddressNetwork(n address.Network) {
|
||||
address.CurrentNetwork = n
|
||||
}
|
||||
|
||||
func MustParseAddress(addr string) address.Address {
|
||||
ret, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024
|
||||
// Consensus / Network
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version6
|
||||
const NewestNetworkVersion = network.Version8
|
||||
const ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
// Epochs
|
||||
@@ -61,6 +61,9 @@ const TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||
|
||||
const AddressMainnetEnvVar = "_mainnet_"
|
||||
|
||||
// the 'f' prefix doesn't matter
|
||||
var ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||
|
||||
// /////
|
||||
// Devnet settings
|
||||
|
||||
|
||||
@@ -88,13 +88,19 @@ var (
|
||||
UpgradeActorsV2Height abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -7
|
||||
UpgradePersianHeight abi.ChainEpoch = -8
|
||||
UpgradeClausHeight abi.ChainEpoch = -9
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
NewestNetworkVersion = network.Version5
|
||||
NewestNetworkVersion = network.Version8
|
||||
ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
Devnet = true
|
||||
Devnet = true
|
||||
ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||
)
|
||||
|
||||
const BootstrapPeerThreshold = 1
|
||||
|
||||
+4
-4
@@ -29,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "1.1.2"
|
||||
const BuildVersion = "1.3.0"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
@@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
|
||||
|
||||
// semver versions of the rpc api exposed
|
||||
var (
|
||||
FullAPIVersion = newVer(0, 17, 0)
|
||||
MinerAPIVersion = newVer(0, 17, 0)
|
||||
WorkerAPIVersion = newVer(0, 16, 0)
|
||||
FullAPIVersion = newVer(1, 0, 0)
|
||||
MinerAPIVersion = newVer(1, 0, 0)
|
||||
WorkerAPIVersion = newVer(1, 0, 0)
|
||||
)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
)
|
||||
|
||||
func DiffAddressMap(pre, cur State) (*AddressMapChanges, error) {
|
||||
prem, err := pre.addressMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curm, err := cur.addressMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
preRoot, err := prem.Root()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curRoot, err := curm.Root()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := new(AddressMapChanges)
|
||||
// no change.
|
||||
if curRoot.Equals(preRoot) {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
err = adt.DiffAdtMap(prem, curm, &addressMapDiffer{results, pre, cur})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type addressMapDiffer struct {
|
||||
Results *AddressMapChanges
|
||||
pre, adter State
|
||||
}
|
||||
|
||||
type AddressMapChanges struct {
|
||||
Added []AddressPair
|
||||
Modified []AddressChange
|
||||
Removed []AddressPair
|
||||
}
|
||||
|
||||
func (i *addressMapDiffer) AsKey(key string) (abi.Keyer, error) {
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return abi.AddrKey(addr), nil
|
||||
}
|
||||
|
||||
func (i *addressMapDiffer) Add(key string, val *typegen.Deferred) error {
|
||||
pkAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := new(typegen.CborInt)
|
||||
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
idAddr, err := address.NewIDAddress(uint64(*id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Results.Added = append(i.Results.Added, AddressPair{
|
||||
ID: idAddr,
|
||||
PK: pkAddr,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *addressMapDiffer) Modify(key string, from, to *typegen.Deferred) error {
|
||||
pkAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fromID := new(typegen.CborInt)
|
||||
if err := fromID.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
fromIDAddr, err := address.NewIDAddress(uint64(*fromID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toID := new(typegen.CborInt)
|
||||
if err := toID.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
toIDAddr, err := address.NewIDAddress(uint64(*toID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Results.Modified = append(i.Results.Modified, AddressChange{
|
||||
From: AddressPair{
|
||||
ID: fromIDAddr,
|
||||
PK: pkAddr,
|
||||
},
|
||||
To: AddressPair{
|
||||
ID: toIDAddr,
|
||||
PK: pkAddr,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *addressMapDiffer) Remove(key string, val *typegen.Deferred) error {
|
||||
pkAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := new(typegen.CborInt)
|
||||
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
idAddr, err := address.NewIDAddress(uint64(*id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Results.Removed = append(i.Results.Removed, AddressPair{
|
||||
ID: idAddr,
|
||||
PK: pkAddr,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
type AddressChange struct {
|
||||
From AddressPair
|
||||
To AddressPair
|
||||
}
|
||||
|
||||
type AddressPair struct {
|
||||
ID address.Address
|
||||
PK address.Address
|
||||
}
|
||||
@@ -57,4 +57,6 @@ type State interface {
|
||||
|
||||
// Sets the network's name. This should only be used on upgrade/fork.
|
||||
SetNetworkName(name string) error
|
||||
|
||||
addressMap() (adt.Map, error)
|
||||
}
|
||||
|
||||
@@ -79,3 +79,7 @@ func (s *state0) Remove(addrs ...address.Address) (err error) {
|
||||
s.State.AddressMap = amr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *state0) addressMap() (adt.Map, error) {
|
||||
return adt0.AsMap(s.store, s.AddressMap)
|
||||
}
|
||||
|
||||
@@ -79,3 +79,7 @@ func (s *state2) Remove(addrs ...address.Address) (err error) {
|
||||
s.State.AddressMap = amr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *state2) addressMap() (adt.Map, error) {
|
||||
return adt2.AsMap(s.store, s.AddressMap)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
)
|
||||
|
||||
func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) (bitfield.BitField, error) {
|
||||
@@ -26,3 +28,42 @@ func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error))
|
||||
|
||||
return bitfield.MultiMerge(parts...)
|
||||
}
|
||||
|
||||
// SealProofTypeFromSectorSize returns preferred seal proof type for creating
|
||||
// new miner actors and new sectors
|
||||
func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.RegisteredSealProof, error) {
|
||||
switch {
|
||||
case nv < network.Version7:
|
||||
switch ssize {
|
||||
case 2 << 10:
|
||||
return abi.RegisteredSealProof_StackedDrg2KiBV1, nil
|
||||
case 8 << 20:
|
||||
return abi.RegisteredSealProof_StackedDrg8MiBV1, nil
|
||||
case 512 << 20:
|
||||
return abi.RegisteredSealProof_StackedDrg512MiBV1, nil
|
||||
case 32 << 30:
|
||||
return abi.RegisteredSealProof_StackedDrg32GiBV1, nil
|
||||
case 64 << 30:
|
||||
return abi.RegisteredSealProof_StackedDrg64GiBV1, nil
|
||||
default:
|
||||
return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
|
||||
}
|
||||
case nv >= network.Version7:
|
||||
switch ssize {
|
||||
case 2 << 10:
|
||||
return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
|
||||
case 8 << 20:
|
||||
return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
|
||||
case 512 << 20:
|
||||
return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
|
||||
case 32 << 30:
|
||||
return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
|
||||
case 64 << 30:
|
||||
return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
|
||||
default:
|
||||
return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
|
||||
}
|
||||
}
|
||||
|
||||
return 0, xerrors.Errorf("unsupported network version")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package actors
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
@@ -11,7 +13,7 @@ func SerializeParams(i cbg.CBORMarshaler) ([]byte, aerrors.ActorError) {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := i.MarshalCBOR(buf); err != nil {
|
||||
// TODO: shouldnt this be a fatal error?
|
||||
return nil, aerrors.Absorb(err, 1, "failed to encode parameter")
|
||||
return nil, aerrors.Absorb(err, exitcode.ErrSerialization, "failed to encode parameter")
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
@@ -26,22 +26,29 @@ const (
|
||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
newTypes := make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
for _, t := range types {
|
||||
newTypes[t] = struct{}{}
|
||||
}
|
||||
// Set for all miner versions.
|
||||
miner0.SupportedProofTypes = newTypes
|
||||
miner2.SupportedProofTypes = newTypes
|
||||
miner0.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
miner2.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
miner2.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
|
||||
miner2.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
|
||||
AddSupportedProofTypes(types...)
|
||||
}
|
||||
|
||||
// AddSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
for _, t := range types {
|
||||
if t >= abi.RegisteredSealProof_StackedDrg2KiBV1_1 {
|
||||
panic("must specify v1 proof types only")
|
||||
}
|
||||
// Set for all miner versions.
|
||||
miner0.SupportedProofTypes[t] = struct{}{}
|
||||
miner2.SupportedProofTypes[t] = struct{}{}
|
||||
miner2.PreCommitSealProofTypesV0[t] = struct{}{}
|
||||
|
||||
miner2.PreCommitSealProofTypesV7[t] = struct{}{}
|
||||
miner2.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||
|
||||
miner2.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +140,9 @@ func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
|
||||
}
|
||||
|
||||
func GetDefaultSectorSize() abi.SectorSize {
|
||||
// supported proof types are the same across versions.
|
||||
szs := make([]abi.SectorSize, 0, len(miner2.SupportedProofTypes))
|
||||
for spt := range miner2.SupportedProofTypes {
|
||||
// supported sector sizes are the same across versions.
|
||||
szs := make([]abi.SectorSize, 0, len(miner2.PreCommitSealProofTypesV8))
|
||||
for spt := range miner2.PreCommitSealProofTypesV8 {
|
||||
ss, err := spt.SectorSize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -44,7 +44,7 @@ func TestSupportedProofTypes(t *testing.T) {
|
||||
|
||||
// Tests assumptions about policies being the same between actor versions.
|
||||
func TestAssumptions(t *testing.T) {
|
||||
require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes)
|
||||
require.EqualValues(t, miner0.SupportedProofTypes, miner2.PreCommitSealProofTypesV0)
|
||||
require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay)
|
||||
require.Equal(t, miner0.MaxSectorExpirationExtension, miner2.MaxSectorExpirationExtension)
|
||||
require.Equal(t, miner0.ChainFinality, miner2.ChainFinality)
|
||||
@@ -57,10 +57,10 @@ func TestAssumptions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPartitionSizes(t *testing.T) {
|
||||
for p := range abi.PoStSealProofTypes {
|
||||
sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p)
|
||||
for _, p := range abi.SealProofInfos {
|
||||
sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p.WindowPoStProof)
|
||||
require.NoError(t, err)
|
||||
sizeOld, err := builtin0.PoStProofWindowPoStPartitionSectors(p)
|
||||
sizeOld, err := builtin0.PoStProofWindowPoStPartitionSectors(p.WindowPoStProof)
|
||||
if err != nil {
|
||||
// new proof type.
|
||||
continue
|
||||
|
||||
@@ -18,7 +18,7 @@ func VersionForNetwork(version network.Version) Version {
|
||||
switch version {
|
||||
case network.Version0, network.Version1, network.Version2, network.Version3:
|
||||
return Version0
|
||||
case network.Version4, network.Version5, network.Version6:
|
||||
case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8:
|
||||
return Version2
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||
|
||||
+26
-15
@@ -20,8 +20,10 @@ import (
|
||||
var log = logging.Logger("events")
|
||||
|
||||
// HeightHandler `curH`-`ts.Height` = `confidence`
|
||||
type HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error
|
||||
type RevertHandler func(ctx context.Context, ts *types.TipSet) error
|
||||
type (
|
||||
HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error
|
||||
RevertHandler func(ctx context.Context, ts *types.TipSet) error
|
||||
)
|
||||
|
||||
type heightHandler struct {
|
||||
confidence int
|
||||
@@ -48,7 +50,7 @@ type Events struct {
|
||||
tsc *tipSetCache
|
||||
lk sync.Mutex
|
||||
|
||||
ready sync.WaitGroup
|
||||
ready chan struct{}
|
||||
readyOnce sync.Once
|
||||
|
||||
heightEvents
|
||||
@@ -76,15 +78,16 @@ func NewEvents(ctx context.Context, api eventAPI) *Events {
|
||||
},
|
||||
|
||||
hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
|
||||
ready: make(chan struct{}),
|
||||
}
|
||||
|
||||
e.ready.Add(1)
|
||||
|
||||
go e.listenHeadChanges(ctx)
|
||||
|
||||
e.ready.Wait()
|
||||
|
||||
// TODO: cleanup/gc goroutine
|
||||
// Wait for the first tipset to be seen or bail if shutting down
|
||||
select {
|
||||
case <-e.ready:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
@@ -111,13 +114,21 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
|
||||
|
||||
notifs, err := e.api.ChainNotify(ctx)
|
||||
if err != nil {
|
||||
// TODO: retry
|
||||
// Retry is handled by caller
|
||||
return xerrors.Errorf("listenHeadChanges ChainNotify call failed: %w", err)
|
||||
}
|
||||
|
||||
cur, ok := <-notifs // TODO: timeout?
|
||||
if !ok {
|
||||
return xerrors.Errorf("notification channel closed")
|
||||
var cur []*api.HeadChange
|
||||
var ok bool
|
||||
|
||||
// Wait for first tipset or bail
|
||||
select {
|
||||
case cur, ok = <-notifs:
|
||||
if !ok {
|
||||
return xerrors.Errorf("notification channel closed")
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
if len(cur) != 1 {
|
||||
@@ -129,13 +140,13 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
|
||||
}
|
||||
|
||||
if err := e.tsc.add(cur[0].Val); err != nil {
|
||||
log.Warn("tsc.add: adding current tipset failed: %w", err)
|
||||
log.Warnf("tsc.add: adding current tipset failed: %v", err)
|
||||
}
|
||||
|
||||
e.readyOnce.Do(func() {
|
||||
e.lastTs = cur[0].Val
|
||||
|
||||
e.ready.Done()
|
||||
// Signal that we have seen first tipset
|
||||
close(e.ready)
|
||||
})
|
||||
|
||||
for notif := range notifs {
|
||||
|
||||
@@ -153,6 +153,7 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence
|
||||
|
||||
best, err := e.tsc.best()
|
||||
if err != nil {
|
||||
e.lk.Unlock()
|
||||
return xerrors.Errorf("error getting best tipset: %w", err)
|
||||
}
|
||||
|
||||
@@ -177,6 +178,7 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence
|
||||
e.lk.Lock()
|
||||
best, err = e.tsc.best()
|
||||
if err != nil {
|
||||
e.lk.Unlock()
|
||||
return xerrors.Errorf("error getting best tipset: %w", err)
|
||||
}
|
||||
bestH = best.Height()
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type FastChainApiAPI interface {
|
||||
ChainAPI
|
||||
|
||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
||||
}
|
||||
|
||||
type fastAPI struct {
|
||||
FastChainApiAPI
|
||||
}
|
||||
|
||||
func WrapFastAPI(api FastChainApiAPI) ChainAPI {
|
||||
return &fastAPI{
|
||||
api,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *fastAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
ts, err := a.FastChainApiAPI.ChainGetTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a.FastChainApiAPI.StateGetActor(ctx, actor, ts.Parents())
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
@@ -10,7 +9,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
@@ -419,179 +417,17 @@ type AddressPair struct {
|
||||
PK address.Address
|
||||
}
|
||||
|
||||
type InitActorAddressChanges struct {
|
||||
Added []AddressPair
|
||||
Modified []AddressChange
|
||||
Removed []AddressPair
|
||||
}
|
||||
|
||||
type AddressChange struct {
|
||||
From AddressPair
|
||||
To AddressPair
|
||||
}
|
||||
|
||||
type DiffInitActorStateFunc func(ctx context.Context, oldState init_.State, newState init_.State) (changed bool, user UserData, err error)
|
||||
|
||||
func (i *InitActorAddressChanges) AsKey(key string) (abi.Keyer, error) {
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return abi.AddrKey(addr), nil
|
||||
}
|
||||
|
||||
func (i *InitActorAddressChanges) Add(key string, val *typegen.Deferred) error {
|
||||
pkAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := new(typegen.CborInt)
|
||||
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
idAddr, err := address.NewIDAddress(uint64(*id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Added = append(i.Added, AddressPair{
|
||||
ID: idAddr,
|
||||
PK: pkAddr,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *InitActorAddressChanges) Modify(key string, from, to *typegen.Deferred) error {
|
||||
pkAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fromID := new(typegen.CborInt)
|
||||
if err := fromID.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
fromIDAddr, err := address.NewIDAddress(uint64(*fromID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toID := new(typegen.CborInt)
|
||||
if err := toID.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
toIDAddr, err := address.NewIDAddress(uint64(*toID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Modified = append(i.Modified, AddressChange{
|
||||
From: AddressPair{
|
||||
ID: fromIDAddr,
|
||||
PK: pkAddr,
|
||||
},
|
||||
To: AddressPair{
|
||||
ID: toIDAddr,
|
||||
PK: pkAddr,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *InitActorAddressChanges) Remove(key string, val *typegen.Deferred) error {
|
||||
pkAddr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := new(typegen.CborInt)
|
||||
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
idAddr, err := address.NewIDAddress(uint64(*id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Removed = append(i.Removed, AddressPair{
|
||||
ID: idAddr,
|
||||
PK: pkAddr,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
|
||||
addressChanges := &InitActorAddressChanges{
|
||||
Added: []AddressPair{},
|
||||
Modified: []AddressChange{},
|
||||
Removed: []AddressPair{},
|
||||
}
|
||||
|
||||
err = oldState.ForEachActor(func(oldId abi.ActorID, oldAddress address.Address) error {
|
||||
oldIdAddress, err := address.NewIDAddress(uint64(oldId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newIdAddress, found, err := newState.ResolveAddress(oldAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
addressChanges.Removed = append(addressChanges.Removed, AddressPair{
|
||||
ID: oldIdAddress,
|
||||
PK: oldAddress,
|
||||
})
|
||||
}
|
||||
|
||||
if oldIdAddress != newIdAddress {
|
||||
addressChanges.Modified = append(addressChanges.Modified, AddressChange{
|
||||
From: AddressPair{
|
||||
ID: oldIdAddress,
|
||||
PK: oldAddress,
|
||||
},
|
||||
To: AddressPair{
|
||||
ID: newIdAddress,
|
||||
PK: oldAddress,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
addressChanges, err := init_.DiffAddressMap(oldState, newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
err = newState.ForEachActor(func(newId abi.ActorID, newAddress address.Address) error {
|
||||
newIdAddress, err := address.NewIDAddress(uint64(newId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, found, err := newState.ResolveAddress(newAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !found {
|
||||
addressChanges.Added = append(addressChanges.Added, AddressPair{
|
||||
ID: newIdAddress,
|
||||
PK: newAddress,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if len(addressChanges.Added)+len(addressChanges.Removed)+len(addressChanges.Modified) == 0 {
|
||||
if len(addressChanges.Added)+len(addressChanges.Modified)+len(addressChanges.Removed) == 0 {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
return true, addressChanges, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -412,11 +411,7 @@ func (c *client) sendRequestToPeer(ctx context.Context, peer peer.ID, req *Reque
|
||||
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
go helpers.FullClose(stream) //nolint:errcheck
|
||||
}()
|
||||
defer stream.Close() //nolint:errcheck
|
||||
|
||||
// Write request.
|
||||
_ = stream.SetWriteDeadline(time.Now().Add(WriteReqDeadline))
|
||||
|
||||
@@ -38,20 +38,26 @@ func newPeerTracker(lc fx.Lifecycle, h host.Host, pmgr *peermgr.PeerMgr) *bsPeer
|
||||
pmgr: pmgr,
|
||||
}
|
||||
|
||||
sub, err := h.EventBus().Subscribe(new(peermgr.NewFilPeer))
|
||||
evtSub, err := h.EventBus().Subscribe(new(peermgr.FilPeerEvt))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for newPeer := range sub.Out() {
|
||||
bsPt.addPeer(newPeer.(peermgr.NewFilPeer).Id)
|
||||
for evt := range evtSub.Out() {
|
||||
pEvt := evt.(peermgr.FilPeerEvt)
|
||||
switch pEvt.Type {
|
||||
case peermgr.AddFilPeerEvt:
|
||||
bsPt.addPeer(pEvt.ID)
|
||||
case peermgr.RemoveFilPeerEvt:
|
||||
bsPt.removePeer(pEvt.ID)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return sub.Close()
|
||||
return evtSub.Close()
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
)
|
||||
|
||||
@@ -40,16 +39,14 @@ func (s *server) HandleStream(stream inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "chainxchg.HandleStream")
|
||||
defer span.End()
|
||||
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
defer helpers.FullClose(stream) //nolint:errcheck
|
||||
defer stream.Close() //nolint:errcheck
|
||||
|
||||
var req Request
|
||||
if err := cborutil.ReadCborRPC(bufio.NewReader(stream), &req); err != nil {
|
||||
log.Warnf("failed to read block sync request: %s", err)
|
||||
return
|
||||
}
|
||||
log.Infow("block sync request",
|
||||
log.Debugw("block sync request",
|
||||
"start", req.Head, "len", req.Length)
|
||||
|
||||
resp, err := s.processRequest(ctx, &req)
|
||||
|
||||
+2
-8
@@ -347,14 +347,8 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
return nil, nil, nil, xerrors.Errorf("get miner base info: %w", err)
|
||||
}
|
||||
|
||||
prev := mbi.PrevBeaconEntry
|
||||
|
||||
entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, round, pts.Height(), prev)
|
||||
if err != nil {
|
||||
return nil, nil, nil, xerrors.Errorf("get beacon entries for block: %w", err)
|
||||
}
|
||||
|
||||
rbase := prev
|
||||
entries := mbi.BeaconEntries
|
||||
rbase := mbi.PrevBeaconEntry
|
||||
if len(entries) > 0 {
|
||||
rbase = entries[len(entries)-1]
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
)
|
||||
|
||||
func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor) (int64, *types.Actor, map[address.Address]address.Address, error) {
|
||||
func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor, remainder genesis.Actor) (int64, *types.Actor, map[address.Address]address.Address, error) {
|
||||
if len(initialActors) > MaxAccounts {
|
||||
return 0, nil, nil, xerrors.New("too many initial actors")
|
||||
}
|
||||
@@ -90,6 +90,33 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
|
||||
}
|
||||
}
|
||||
|
||||
setupMsig := func(meta json.RawMessage) error {
|
||||
var ainfo genesis.MultisigMeta
|
||||
if err := json.Unmarshal(meta, &ainfo); err != nil {
|
||||
return xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
for _, e := range ainfo.Signers {
|
||||
if _, ok := keyToId[e]; ok {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("init set %s t0%d\n", e, counter)
|
||||
|
||||
value := cbg.CborInt(counter)
|
||||
if err := amap.Put(abi.AddrKey(e), &value); err != nil {
|
||||
return err
|
||||
}
|
||||
counter = counter + 1
|
||||
var err error
|
||||
keyToId[e], err = address.NewIDAddress(uint64(value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if rootVerifier.Type == genesis.TAccount {
|
||||
var ainfo genesis.AccountMeta
|
||||
if err := json.Unmarshal(rootVerifier.Meta, &ainfo); err != nil {
|
||||
@@ -100,28 +127,15 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
} else if rootVerifier.Type == genesis.TMultisig {
|
||||
var ainfo genesis.MultisigMeta
|
||||
if err := json.Unmarshal(rootVerifier.Meta, &ainfo); err != nil {
|
||||
return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
err := setupMsig(rootVerifier.Meta)
|
||||
if err != nil {
|
||||
return 0, nil, nil, xerrors.Errorf("setting up root verifier msig: %w", err)
|
||||
}
|
||||
for _, e := range ainfo.Signers {
|
||||
if _, ok := keyToId[e]; ok {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("init set %s t0%d\n", e, counter)
|
||||
}
|
||||
|
||||
value := cbg.CborInt(counter)
|
||||
if err := amap.Put(abi.AddrKey(e), &value); err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
counter = counter + 1
|
||||
var err error
|
||||
keyToId[e], err = address.NewIDAddress(uint64(value))
|
||||
if err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
|
||||
}
|
||||
err := setupMsig(remainder.Meta)
|
||||
if err != nil {
|
||||
return 0, nil, nil, xerrors.Errorf("setting up remainder msig: %w", err)
|
||||
}
|
||||
|
||||
amapaddr, err := amap.Root()
|
||||
|
||||
@@ -134,7 +134,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
|
||||
// Create init actor
|
||||
|
||||
idStart, initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey)
|
||||
idStart, initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey, template.RemainderAccount)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
@@ -101,7 +99,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
i := i
|
||||
m := m
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(m.SectorSize)
|
||||
spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, GenesisNetworkVersion)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
@@ -552,6 +552,53 @@ func TestFundManagerRestart(t *testing.T) {
|
||||
checkAddMessageFields(t, msg3, s.walletAddr, acctAddr2, amt3)
|
||||
}
|
||||
|
||||
// TestFundManagerReleaseAfterPublish verifies that release is successful in
|
||||
// the following scenario:
|
||||
// 1. Deal A adds 5 to addr1: reserved 0 -> 5 available 0 -> 5
|
||||
// 2. Deal B adds 7 to addr1: reserved 5 -> 12 available 5 -> 12
|
||||
// 3. Deal B completes, reducing addr1 by 7: reserved 12 available 12 -> 5
|
||||
// 4. Deal A releases 5 from addr1: reserved 12 -> 7 available 5
|
||||
func TestFundManagerReleaseAfterPublish(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
// Deal A: Reserve 5
|
||||
// balance: 0 -> 5
|
||||
// reserved: 0 -> 5
|
||||
amt := abi.NewTokenAmount(5)
|
||||
sentinel, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Deal B: Reserve 7
|
||||
// balance: 5 -> 12
|
||||
// reserved: 5 -> 12
|
||||
amt = abi.NewTokenAmount(7)
|
||||
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Deal B: Publish (removes Deal B amount from balance)
|
||||
// balance: 12 -> 5
|
||||
// reserved: 12
|
||||
amt = abi.NewTokenAmount(7)
|
||||
s.mockApi.publish(s.acctAddr, amt)
|
||||
|
||||
// Deal A: Release 5
|
||||
// balance: 5
|
||||
// reserved: 12 -> 7
|
||||
amt = abi.NewTokenAmount(5)
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Deal B: Release 7
|
||||
// balance: 5
|
||||
// reserved: 12 -> 7
|
||||
amt = abi.NewTokenAmount(5)
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
type scaffold struct {
|
||||
ctx context.Context
|
||||
ds *ds_sync.MutexDatastore
|
||||
@@ -731,6 +778,21 @@ func (mapi *mockFundManagerAPI) getEscrow(a address.Address) abi.TokenAmount {
|
||||
return escrow
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) publish(addr address.Address, amt abi.TokenAmount) {
|
||||
mapi.lk.Lock()
|
||||
defer mapi.lk.Unlock()
|
||||
|
||||
escrow := mapi.escrow[addr]
|
||||
if escrow.Nil() {
|
||||
return
|
||||
}
|
||||
escrow = types.BigSub(escrow, amt)
|
||||
if escrow.LessThan(abi.NewTokenAmount(0)) {
|
||||
escrow = abi.NewTokenAmount(0)
|
||||
}
|
||||
mapi.escrow[addr] = escrow
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
res := &api.MsgLookup{
|
||||
Message: c,
|
||||
|
||||
@@ -181,7 +181,20 @@ func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
|
||||
return types.BigAdd(minPrice, types.NewInt(1))
|
||||
}
|
||||
|
||||
func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, maxFee abi.TokenAmount) {
|
||||
func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, sendSepc *api.MessageSendSpec) {
|
||||
var maxFee abi.TokenAmount
|
||||
if sendSepc != nil {
|
||||
maxFee = sendSepc.MaxFee
|
||||
}
|
||||
if maxFee.Int == nil || maxFee.Equals(big.Zero()) {
|
||||
mf, err := mff()
|
||||
if err != nil {
|
||||
log.Errorf("failed to get default max gas fee: %+v", err)
|
||||
mf = big.Zero()
|
||||
}
|
||||
maxFee = mf
|
||||
}
|
||||
|
||||
if maxFee.Equals(big.Zero()) {
|
||||
mf, err := mff()
|
||||
if err != nil {
|
||||
@@ -240,10 +253,13 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict, untrusted
|
||||
// check if RBF passes
|
||||
minPrice := ComputeMinRBF(exms.Message.GasPremium)
|
||||
if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 {
|
||||
log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium,
|
||||
log.Debugw("add with RBF", "oldpremium", exms.Message.GasPremium,
|
||||
"newpremium", m.Message.GasPremium, "addr", m.Message.From, "nonce", m.Message.Nonce)
|
||||
} else {
|
||||
log.Info("add with duplicate nonce")
|
||||
log.Debugf("add with duplicate nonce. message from %s with nonce %d already in mpool,"+
|
||||
" increase GasPremium to %s from %s to trigger replace by fee: %s",
|
||||
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPremium,
|
||||
ErrRBFTooLowPremium)
|
||||
return false, xerrors.Errorf("message from %s with nonce %d already in mpool,"+
|
||||
" increase GasPremium to %s from %s to trigger replace by fee: %w",
|
||||
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPremium,
|
||||
@@ -264,7 +280,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict, untrusted
|
||||
}
|
||||
|
||||
if strict && nonceGap {
|
||||
log.Warnf("adding nonce-gapped message from %s (nonce: %d, nextNonce: %d)",
|
||||
log.Debugf("adding nonce-gapped message from %s (nonce: %d, nextNonce: %d)",
|
||||
m.Message.From, m.Message.Nonce, nextNonce)
|
||||
}
|
||||
|
||||
@@ -465,7 +481,7 @@ func (mp *MessagePool) verifyMsgBeforeAdd(m *types.SignedMessage, curTs *types.T
|
||||
epoch := curTs.Height()
|
||||
minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength())
|
||||
|
||||
if err := m.VMMessage().ValidForBlockInclusion(minGas.Total()); err != nil {
|
||||
if err := m.VMMessage().ValidForBlockInclusion(minGas.Total(), build.NewestNetworkVersion); err != nil {
|
||||
return false, xerrors.Errorf("message will not be included in a block: %w", err)
|
||||
}
|
||||
|
||||
@@ -546,7 +562,7 @@ func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
|
||||
}
|
||||
|
||||
// Perform syntactic validation, minGas=0 as we check the actual mingas before we add it
|
||||
if err := m.Message.ValidForBlockInclusion(0); err != nil {
|
||||
if err := m.Message.ValidForBlockInclusion(0, build.NewestNetworkVersion); err != nil {
|
||||
return xerrors.Errorf("message not valid for block inclusion: %w", err)
|
||||
}
|
||||
|
||||
@@ -855,7 +871,7 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) {
|
||||
}()
|
||||
|
||||
mp.curTsLk.Lock()
|
||||
publish, err := mp.addTs(m, mp.curTs, false, true)
|
||||
publish, err := mp.addTs(m, mp.curTs, true, true)
|
||||
if err != nil {
|
||||
mp.curTsLk.Unlock()
|
||||
return cid.Undef, err
|
||||
@@ -1219,7 +1235,7 @@ func (mp *MessagePool) MessagesForBlocks(blks []*types.BlockHeader) ([]*types.Si
|
||||
if smsg != nil {
|
||||
out = append(out, smsg)
|
||||
} else {
|
||||
log.Warnf("could not recover signature for bls message %s", msg.Cid())
|
||||
log.Debugf("could not recover signature for bls message %s", msg.Cid())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ loop:
|
||||
// check the baseFee lower bound -- only republish messages that can be included in the chain
|
||||
// within the next 20 blocks.
|
||||
for _, m := range chain.msgs {
|
||||
if !allowNegativeChains(ts.Height()) && m.Message.GasFeeCap.LessThan(baseFeeLowerBound) {
|
||||
if m.Message.GasFeeCap.LessThan(baseFeeLowerBound) {
|
||||
chain.Invalidate()
|
||||
continue loop
|
||||
}
|
||||
@@ -115,7 +115,7 @@ loop:
|
||||
|
||||
// we can't fit the current chain but there is gas to spare
|
||||
// trim it and push it down
|
||||
chain.Trim(gasLimit, mp, baseFee, true)
|
||||
chain.Trim(gasLimit, mp, baseFee)
|
||||
for j := i; j < len(chains)-1; j++ {
|
||||
if chains[j].Before(chains[j+1]) {
|
||||
break
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
tbig "github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@@ -21,11 +20,7 @@ import (
|
||||
|
||||
var bigBlockGasLimit = big.NewInt(build.BlockGasLimit)
|
||||
|
||||
// this is *temporary* mutilation until we have implemented uncapped miner penalties -- it will go
|
||||
// away in the next fork.
|
||||
func allowNegativeChains(epoch abi.ChainEpoch) bool {
|
||||
return epoch < build.UpgradeBreezeHeight+5
|
||||
}
|
||||
var MaxBlockMessages = 16000
|
||||
|
||||
const MaxBlocks = 15
|
||||
|
||||
@@ -43,7 +38,7 @@ type msgChain struct {
|
||||
prev *msgChain
|
||||
}
|
||||
|
||||
func (mp *MessagePool) SelectMessages(ts *types.TipSet, tq float64) ([]*types.SignedMessage, error) {
|
||||
func (mp *MessagePool) SelectMessages(ts *types.TipSet, tq float64) (msgs []*types.SignedMessage, err error) {
|
||||
mp.curTsLk.Lock()
|
||||
defer mp.curTsLk.Unlock()
|
||||
|
||||
@@ -54,10 +49,20 @@ func (mp *MessagePool) SelectMessages(ts *types.TipSet, tq float64) ([]*types.Si
|
||||
// than any other block, then we don't bother with optimal selection because the
|
||||
// first block will always have higher effective performance
|
||||
if tq > 0.84 {
|
||||
return mp.selectMessagesGreedy(mp.curTs, ts)
|
||||
msgs, err = mp.selectMessagesGreedy(mp.curTs, ts)
|
||||
} else {
|
||||
msgs, err = mp.selectMessagesOptimal(mp.curTs, ts, tq)
|
||||
}
|
||||
|
||||
return mp.selectMessagesOptimal(mp.curTs, ts, tq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(msgs) > MaxBlockMessages {
|
||||
msgs = msgs[:MaxBlockMessages]
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64) ([]*types.SignedMessage, error) {
|
||||
@@ -109,7 +114,7 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64
|
||||
return chains[i].Before(chains[j])
|
||||
})
|
||||
|
||||
if !allowNegativeChains(curTs.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||
if len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||
log.Warnw("all messages in mpool have non-positive gas performance", "bestGasPerf", chains[0].gasPerf)
|
||||
return result, nil
|
||||
}
|
||||
@@ -162,7 +167,7 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64
|
||||
last := len(chains)
|
||||
for i, chain := range chains {
|
||||
// did we run out of performing chains?
|
||||
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -228,7 +233,7 @@ tailLoop:
|
||||
for gasLimit >= minGas && last < len(chains) {
|
||||
// trim if necessary
|
||||
if chains[last].gasLimit > gasLimit {
|
||||
chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
|
||||
chains[last].Trim(gasLimit, mp, baseFee)
|
||||
}
|
||||
|
||||
// push down if it hasn't been invalidated
|
||||
@@ -254,7 +259,7 @@ tailLoop:
|
||||
}
|
||||
|
||||
// if gasPerf < 0 we have no more profitable chains
|
||||
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
break tailLoop
|
||||
}
|
||||
|
||||
@@ -295,7 +300,7 @@ tailLoop:
|
||||
}
|
||||
|
||||
// dependencies fit, just trim it
|
||||
chain.Trim(gasLimit-depGasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
|
||||
chain.Trim(gasLimit-depGasLimit, mp, baseFee)
|
||||
last += i
|
||||
continue tailLoop
|
||||
}
|
||||
@@ -328,7 +333,7 @@ tailLoop:
|
||||
}
|
||||
|
||||
// is it negative?
|
||||
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -350,7 +355,7 @@ tailLoop:
|
||||
|
||||
// do they fit as is? if it doesn't, trim to make it fit if possible
|
||||
if chainGasLimit > gasLimit {
|
||||
chain.Trim(gasLimit-depGasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
|
||||
chain.Trim(gasLimit-depGasLimit, mp, baseFee)
|
||||
|
||||
if !chain.valid {
|
||||
continue
|
||||
@@ -433,7 +438,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S
|
||||
return chains[i].Before(chains[j])
|
||||
})
|
||||
|
||||
if !allowNegativeChains(curTs.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||
if len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||
log.Warnw("all messages in mpool have non-positive gas performance", "bestGasPerf", chains[0].gasPerf)
|
||||
return result, nil
|
||||
}
|
||||
@@ -444,7 +449,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S
|
||||
last := len(chains)
|
||||
for i, chain := range chains {
|
||||
// did we run out of performing chains?
|
||||
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -473,7 +478,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S
|
||||
tailLoop:
|
||||
for gasLimit >= minGas && last < len(chains) {
|
||||
// trim
|
||||
chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
|
||||
chains[last].Trim(gasLimit, mp, baseFee)
|
||||
|
||||
// push down if it hasn't been invalidated
|
||||
if chains[last].valid {
|
||||
@@ -493,7 +498,7 @@ tailLoop:
|
||||
}
|
||||
|
||||
// if gasPerf < 0 we have no more profitable chains
|
||||
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
break tailLoop
|
||||
}
|
||||
|
||||
@@ -555,7 +560,7 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui
|
||||
return chains[i].Before(chains[j])
|
||||
})
|
||||
|
||||
if !allowNegativeChains(ts.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||
if len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||
log.Warnw("all priority messages in mpool have negative gas performance", "bestGasPerf", chains[0].gasPerf)
|
||||
return nil, gasLimit
|
||||
}
|
||||
@@ -563,7 +568,7 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui
|
||||
// 3. Merge chains until the block limit, as long as they have non-negative gas performance
|
||||
last := len(chains)
|
||||
for i, chain := range chains {
|
||||
if !allowNegativeChains(ts.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -581,7 +586,7 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui
|
||||
tailLoop:
|
||||
for gasLimit >= minGas && last < len(chains) {
|
||||
// trim, discarding negative performing messages
|
||||
chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(ts.Height()))
|
||||
chains[last].Trim(gasLimit, mp, baseFee)
|
||||
|
||||
// push down if it hasn't been invalidated
|
||||
if chains[last].valid {
|
||||
@@ -601,7 +606,7 @@ tailLoop:
|
||||
}
|
||||
|
||||
// if gasPerf < 0 we have no more profitable chains
|
||||
if !allowNegativeChains(ts.Height()) && chain.gasPerf < 0 {
|
||||
if chain.gasPerf < 0 {
|
||||
break tailLoop
|
||||
}
|
||||
|
||||
@@ -677,6 +682,10 @@ func (*MessagePool) getGasReward(msg *types.SignedMessage, baseFee types.BigInt)
|
||||
}
|
||||
|
||||
gasReward := tbig.Mul(maxPremium, types.NewInt(uint64(msg.Message.GasLimit)))
|
||||
if gasReward.Sign() == -1 {
|
||||
// penalty multiplier
|
||||
gasReward = tbig.Mul(gasReward, types.NewInt(3))
|
||||
}
|
||||
return gasReward.Int
|
||||
}
|
||||
|
||||
@@ -752,9 +761,6 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
|
||||
balance = new(big.Int).Sub(balance, required)
|
||||
|
||||
value := m.Message.Value.Int
|
||||
if balance.Cmp(value) < 0 {
|
||||
break
|
||||
}
|
||||
balance = new(big.Int).Sub(balance, value)
|
||||
|
||||
gasReward := mp.getGasReward(m, baseFee)
|
||||
@@ -858,9 +864,9 @@ func (mc *msgChain) Before(other *msgChain) bool {
|
||||
(mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0)
|
||||
}
|
||||
|
||||
func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, allowNegative bool) {
|
||||
func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt) {
|
||||
i := len(mc.msgs) - 1
|
||||
for i >= 0 && (mc.gasLimit > gasLimit || (!allowNegative && mc.gasPerf < 0)) {
|
||||
for i >= 0 && (mc.gasLimit > gasLimit || mc.gasPerf < 0) {
|
||||
gasReward := mp.getGasReward(mc.msgs[i], baseFee)
|
||||
mc.gasReward = new(big.Int).Sub(mc.gasReward, gasReward)
|
||||
mc.gasLimit -= mc.msgs[i].Message.GasLimit
|
||||
|
||||
@@ -736,8 +736,6 @@ func TestPriorityMessageSelection2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPriorityMessageSelection3(t *testing.T) {
|
||||
t.Skip("reenable after removing allow negative")
|
||||
|
||||
mp, tma := makeTestMpool()
|
||||
|
||||
// the actors
|
||||
@@ -1241,6 +1239,9 @@ func TestCompetitiveMessageSelectionExp(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCompetitiveMessageSelectionZipf(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping in short mode")
|
||||
}
|
||||
var capacityBoost, rewardBoost, tqReward float64
|
||||
seeds := []int64{1947, 1976, 2020, 2100, 10000, 143324, 432432, 131, 32, 45}
|
||||
for _, seed := range seeds {
|
||||
@@ -1268,9 +1269,9 @@ func TestGasReward(t *testing.T) {
|
||||
GasReward int64
|
||||
}{
|
||||
{Premium: 100, FeeCap: 200, BaseFee: 100, GasReward: 100},
|
||||
{Premium: 100, FeeCap: 200, BaseFee: 210, GasReward: -10},
|
||||
{Premium: 100, FeeCap: 200, BaseFee: 210, GasReward: -10 * 3},
|
||||
{Premium: 200, FeeCap: 250, BaseFee: 210, GasReward: 40},
|
||||
{Premium: 200, FeeCap: 250, BaseFee: 2000, GasReward: -1750},
|
||||
{Premium: 200, FeeCap: 250, BaseFee: 2000, GasReward: -1750 * 3},
|
||||
}
|
||||
|
||||
mp := new(MessagePool)
|
||||
|
||||
+66
-18
@@ -6,27 +6,13 @@ import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/migration/nv3"
|
||||
m2 "github.com/filecoin-project/specs-actors/v2/actors/migration"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
@@ -35,6 +21,17 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/bufbstore"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/migration/nv3"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/filecoin-project/specs-actors/v2/actors/migration/nv4"
|
||||
"github.com/filecoin-project/specs-actors/v2/actors/migration/nv7"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// UpgradeFunc is a migration function run at every upgrade.
|
||||
@@ -80,8 +77,9 @@ func DefaultUpgradeSchedule() UpgradeSchedule {
|
||||
Expensive: true,
|
||||
Migration: UpgradeActorsV2,
|
||||
}, {
|
||||
Height: build.UpgradeTapeHeight,
|
||||
Network: network.Version5,
|
||||
Height: build.UpgradeTapeHeight,
|
||||
Network: network.Version5,
|
||||
Migration: nil,
|
||||
}, {
|
||||
Height: build.UpgradeLiftoffHeight,
|
||||
Network: network.Version5,
|
||||
@@ -90,6 +88,14 @@ func DefaultUpgradeSchedule() UpgradeSchedule {
|
||||
Height: build.UpgradeKumquatHeight,
|
||||
Network: network.Version6,
|
||||
Migration: nil,
|
||||
}, {
|
||||
Height: build.UpgradeCalicoHeight,
|
||||
Network: network.Version7,
|
||||
Migration: UpgradeCalico,
|
||||
}, {
|
||||
Height: build.UpgradePersianHeight,
|
||||
Network: network.Version8,
|
||||
Migration: nil,
|
||||
}}
|
||||
|
||||
if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade
|
||||
@@ -601,7 +607,7 @@ func UpgradeActorsV2(ctx context.Context, sm *StateManager, cb ExecCallback, roo
|
||||
return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err)
|
||||
}
|
||||
|
||||
newHamtRoot, err := m2.MigrateStateTree(ctx, store, root, epoch, m2.DefaultConfig())
|
||||
newHamtRoot, err := nv4.MigrateStateTree(ctx, store, root, epoch, nv4.DefaultConfig())
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err)
|
||||
}
|
||||
@@ -652,6 +658,48 @@ func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root
|
||||
return tree.Flush(ctx)
|
||||
}
|
||||
|
||||
func UpgradeCalico(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
|
||||
store := sm.cs.Store(ctx)
|
||||
var stateRoot types.StateRoot
|
||||
if err := store.Get(ctx, root, &stateRoot); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err)
|
||||
}
|
||||
|
||||
if stateRoot.Version != types.StateTreeVersion1 {
|
||||
return cid.Undef, xerrors.Errorf(
|
||||
"expected state root version 1 for calico upgrade, got %d",
|
||||
stateRoot.Version,
|
||||
)
|
||||
}
|
||||
|
||||
newHamtRoot, err := nv7.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, nv7.DefaultConfig())
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("running nv7 migration: %w", err)
|
||||
}
|
||||
|
||||
newRoot, err := store.Put(ctx, &types.StateRoot{
|
||||
Version: stateRoot.Version,
|
||||
Actors: newHamtRoot,
|
||||
Info: stateRoot.Info,
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
|
||||
}
|
||||
|
||||
// perform some basic sanity checks to make sure everything still works.
|
||||
if newSm, err := state.LoadStateTree(store, newRoot); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err)
|
||||
} else if newRoot2, err := newSm.Flush(ctx); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err)
|
||||
} else if newRoot2 != newRoot {
|
||||
return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2)
|
||||
} else if _, err := newSm.GetActor(builtin0.InitActorAddr); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err)
|
||||
}
|
||||
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, name string) error {
|
||||
ia, err := tree.GetActor(builtin0.InitActorAddr)
|
||||
if err != nil {
|
||||
|
||||
+93
-205
@@ -72,13 +72,17 @@ type StateManager struct {
|
||||
// ErrExpensiveFork.
|
||||
expensiveUpgrades map[abi.ChainEpoch]struct{}
|
||||
|
||||
stCache map[string][]cid.Cid
|
||||
compWait map[string]chan struct{}
|
||||
stlk sync.Mutex
|
||||
genesisMsigLk sync.Mutex
|
||||
newVM func(context.Context, *vm.VMOpts) (*vm.VM, error)
|
||||
preIgnitionGenInfos *genesisInfo
|
||||
postIgnitionGenInfos *genesisInfo
|
||||
stCache map[string][]cid.Cid
|
||||
compWait map[string]chan struct{}
|
||||
stlk sync.Mutex
|
||||
genesisMsigLk sync.Mutex
|
||||
newVM func(context.Context, *vm.VMOpts) (*vm.VM, error)
|
||||
preIgnitionVesting []msig0.State
|
||||
postIgnitionVesting []msig0.State
|
||||
postCalicoVesting []msig0.State
|
||||
|
||||
genesisPledge abi.TokenAmount
|
||||
genesisMarketFunds abi.TokenAmount
|
||||
}
|
||||
|
||||
func NewStateManager(cs *store.ChainStore) *StateManager {
|
||||
@@ -889,23 +893,8 @@ func (sm *StateManager) SetVMConstructor(nvm func(context.Context, *vm.VMOpts) (
|
||||
sm.newVM = nvm
|
||||
}
|
||||
|
||||
type genesisInfo struct {
|
||||
genesisMsigs []msig0.State
|
||||
// info about the Accounts in the genesis state
|
||||
genesisActors []genesisActor
|
||||
genesisPledge abi.TokenAmount
|
||||
genesisMarketFunds abi.TokenAmount
|
||||
}
|
||||
|
||||
type genesisActor struct {
|
||||
addr address.Address
|
||||
initBal abi.TokenAmount
|
||||
}
|
||||
|
||||
// sets up information about the actors in the genesis state
|
||||
func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
|
||||
|
||||
gi := genesisInfo{}
|
||||
// sets up information about the vesting schedule
|
||||
func (sm *StateManager) setupGenesisVestingSchedule(ctx context.Context) error {
|
||||
|
||||
gb, err := sm.cs.GetGenesis()
|
||||
if err != nil {
|
||||
@@ -928,127 +917,18 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
|
||||
return xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree)
|
||||
gmf, err := getFilMarketLocked(ctx, sTree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting up genesis market funds: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisPledge, err = getFilPowerLocked(ctx, sTree)
|
||||
gp, err := getFilPowerLocked(ctx, sTree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting up genesis pledge: %w", err)
|
||||
}
|
||||
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
err = sTree.ForEach(func(kaddr address.Address, act *types.Actor) error {
|
||||
if builtin.IsMultisigActor(act.Code) {
|
||||
s, err := multisig.Load(sm.cs.Store(ctx), act)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
se, err := s.StartEpoch()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if se != 0 {
|
||||
return xerrors.New("genesis multisig doesn't start vesting at epoch 0!")
|
||||
}
|
||||
|
||||
ud, err := s.UnlockDuration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ib, err := s.InitialBalance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ot, f := totalsByEpoch[ud]
|
||||
if f {
|
||||
totalsByEpoch[ud] = big.Add(ot, ib)
|
||||
} else {
|
||||
totalsByEpoch[ud] = ib
|
||||
}
|
||||
|
||||
} else if builtin.IsAccountActor(act.Code) {
|
||||
// should exclude burnt funds actor and "remainder account actor"
|
||||
// should only ever be "faucet" accounts in testnets
|
||||
if kaddr == builtin.BurntFundsActorAddr {
|
||||
return nil
|
||||
}
|
||||
|
||||
kid, err := sTree.LookupID(kaddr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("resolving address: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisActors = append(gi.genesisActors, genesisActor{
|
||||
addr: kid,
|
||||
initBal: act.Balance,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error setting up genesis infos: %w", err)
|
||||
}
|
||||
|
||||
// TODO: use network upgrade abstractions or always start at actors v0?
|
||||
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := msig0.State{
|
||||
InitialBalance: v,
|
||||
UnlockDuration: k,
|
||||
PendingTxns: cid.Undef,
|
||||
}
|
||||
gi.genesisMsigs = append(gi.genesisMsigs, ns)
|
||||
}
|
||||
|
||||
sm.preIgnitionGenInfos = &gi
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sets up information about the actors in the genesis state
|
||||
// For testnet we use a hardcoded set of multisig states, instead of what's actually in the genesis multisigs
|
||||
// We also do not consider ANY account actors (including the faucet)
|
||||
func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context) error {
|
||||
|
||||
gi := genesisInfo{}
|
||||
|
||||
gb, err := sm.cs.GetGenesis()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis block: %w", err)
|
||||
}
|
||||
|
||||
gts, err := types.NewTipSet([]*types.BlockHeader{gb})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis tipset: %w", err)
|
||||
}
|
||||
|
||||
st, _, err := sm.TipSetState(ctx, gts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis tipset state: %w", err)
|
||||
}
|
||||
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
sTree, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting up genesis market funds: %w", err)
|
||||
}
|
||||
|
||||
gi.genesisPledge, err = getFilPowerLocked(ctx, sTree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting up genesis pledge: %w", err)
|
||||
}
|
||||
sm.genesisMarketFunds = gmf
|
||||
sm.genesisPledge = gp
|
||||
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
|
||||
@@ -1074,58 +954,21 @@ func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context
|
||||
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
|
||||
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
|
||||
|
||||
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
sm.preIgnitionVesting = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := msig0.State{
|
||||
InitialBalance: v,
|
||||
UnlockDuration: k,
|
||||
PendingTxns: cid.Undef,
|
||||
}
|
||||
gi.genesisMsigs = append(gi.genesisMsigs, ns)
|
||||
sm.preIgnitionVesting = append(sm.preIgnitionVesting, ns)
|
||||
}
|
||||
|
||||
sm.preIgnitionGenInfos = &gi
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sets up information about the actors in the genesis state, post the ignition fork
|
||||
func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) error {
|
||||
|
||||
gi := genesisInfo{}
|
||||
|
||||
gb, err := sm.cs.GetGenesis()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis block: %w", err)
|
||||
}
|
||||
|
||||
gts, err := types.NewTipSet([]*types.BlockHeader{gb})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis tipset: %w", err)
|
||||
}
|
||||
|
||||
st, _, err := sm.TipSetState(ctx, gts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting genesis tipset state: %w", err)
|
||||
}
|
||||
|
||||
cst := cbor.NewCborStore(sm.cs.Blockstore())
|
||||
sTree, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
// Unnecessary, should be removed
|
||||
gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting up genesis market funds: %w", err)
|
||||
}
|
||||
|
||||
// Unnecessary, should be removed
|
||||
gi.genesisPledge, err = getFilPowerLocked(ctx, sTree)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("setting up genesis pledge: %w", err)
|
||||
}
|
||||
// sets up information about the vesting schedule post the ignition upgrade
|
||||
func (sm *StateManager) setupPostIgnitionVesting(ctx context.Context) error {
|
||||
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
|
||||
@@ -1151,7 +994,7 @@ func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) erro
|
||||
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
|
||||
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
|
||||
|
||||
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
sm.postIgnitionVesting = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := msig0.State{
|
||||
// In the pre-ignition logic, we incorrectly set this value in Fil, not attoFil, an off-by-10^18 error
|
||||
@@ -1161,10 +1004,56 @@ func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) erro
|
||||
// In the pre-ignition logic, the start epoch was 0. This changes in the fork logic of the Ignition upgrade itself.
|
||||
StartEpoch: build.UpgradeLiftoffHeight,
|
||||
}
|
||||
gi.genesisMsigs = append(gi.genesisMsigs, ns)
|
||||
sm.postIgnitionVesting = append(sm.postIgnitionVesting, ns)
|
||||
}
|
||||
|
||||
sm.postIgnitionGenInfos = &gi
|
||||
return nil
|
||||
}
|
||||
|
||||
// sets up information about the vesting schedule post the calico upgrade
|
||||
func (sm *StateManager) setupPostCalicoVesting(ctx context.Context) error {
|
||||
|
||||
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
|
||||
|
||||
// 0 days
|
||||
zeroDays := abi.ChainEpoch(0)
|
||||
totalsByEpoch[zeroDays] = big.NewInt(10_632_000)
|
||||
|
||||
// 6 months
|
||||
sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
|
||||
totalsByEpoch[sixMonths] = big.NewInt(19_015_887)
|
||||
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
|
||||
|
||||
// 1 year
|
||||
oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
|
||||
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
|
||||
totalsByEpoch[oneYear] = big.Add(totalsByEpoch[oneYear], big.NewInt(9_400_000))
|
||||
|
||||
// 2 years
|
||||
twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
|
||||
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
|
||||
|
||||
// 3 years
|
||||
threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
|
||||
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
|
||||
totalsByEpoch[threeYears] = big.Add(totalsByEpoch[threeYears], big.NewInt(898_958))
|
||||
|
||||
// 6 years
|
||||
sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay)
|
||||
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
|
||||
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
|
||||
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(9_805_053))
|
||||
|
||||
sm.postCalicoVesting = make([]msig0.State, 0, len(totalsByEpoch))
|
||||
for k, v := range totalsByEpoch {
|
||||
ns := msig0.State{
|
||||
InitialBalance: big.Mul(v, big.NewInt(int64(build.FilecoinPrecision))),
|
||||
UnlockDuration: k,
|
||||
PendingTxns: cid.Undef,
|
||||
StartEpoch: build.UpgradeLiftoffHeight,
|
||||
}
|
||||
sm.postCalicoVesting = append(sm.postCalicoVesting, ns)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1175,12 +1064,19 @@ func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) erro
|
||||
func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
|
||||
vf := big.Zero()
|
||||
if height <= build.UpgradeIgnitionHeight {
|
||||
for _, v := range sm.preIgnitionGenInfos.genesisMsigs {
|
||||
for _, v := range sm.preIgnitionVesting {
|
||||
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
|
||||
vf = big.Add(vf, au)
|
||||
}
|
||||
} else if height <= build.UpgradeCalicoHeight {
|
||||
for _, v := range sm.postIgnitionVesting {
|
||||
// In the pre-ignition logic, we simply called AmountLocked(height), assuming startEpoch was 0.
|
||||
// The start epoch changed in the Ignition upgrade.
|
||||
au := big.Sub(v.InitialBalance, v.AmountLocked(height-v.StartEpoch))
|
||||
vf = big.Add(vf, au)
|
||||
}
|
||||
} else {
|
||||
for _, v := range sm.postIgnitionGenInfos.genesisMsigs {
|
||||
for _, v := range sm.postCalicoVesting {
|
||||
// In the pre-ignition logic, we simply called AmountLocked(height), assuming startEpoch was 0.
|
||||
// The start epoch changed in the Ignition upgrade.
|
||||
au := big.Sub(v.InitialBalance, v.AmountLocked(height-v.StartEpoch))
|
||||
@@ -1188,26 +1084,12 @@ func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch,
|
||||
}
|
||||
}
|
||||
|
||||
// there should not be any such accounts in testnet (and also none in mainnet?)
|
||||
// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
|
||||
for _, v := range sm.preIgnitionGenInfos.genesisActors {
|
||||
act, err := st.GetActor(v.addr)
|
||||
if err != nil {
|
||||
return big.Zero(), xerrors.Errorf("failed to get actor: %w", err)
|
||||
}
|
||||
|
||||
diff := big.Sub(v.initBal, act.Balance)
|
||||
if diff.GreaterThan(big.Zero()) {
|
||||
vf = big.Add(vf, diff)
|
||||
}
|
||||
}
|
||||
|
||||
// After UpgradeActorsV2Height these funds are accounted for in GetFilReserveDisbursed
|
||||
if height <= build.UpgradeActorsV2Height {
|
||||
// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
|
||||
vf = big.Add(vf, sm.preIgnitionGenInfos.genesisPledge)
|
||||
vf = big.Add(vf, sm.genesisPledge)
|
||||
// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
|
||||
vf = big.Add(vf, sm.preIgnitionGenInfos.genesisMarketFunds)
|
||||
vf = big.Add(vf, sm.genesisMarketFunds)
|
||||
}
|
||||
|
||||
return vf, nil
|
||||
@@ -1301,16 +1183,22 @@ func (sm *StateManager) GetVMCirculatingSupply(ctx context.Context, height abi.C
|
||||
func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
|
||||
sm.genesisMsigLk.Lock()
|
||||
defer sm.genesisMsigLk.Unlock()
|
||||
if sm.preIgnitionGenInfos == nil {
|
||||
err := sm.setupPreIgnitionGenesisActorsTestnet(ctx)
|
||||
if sm.preIgnitionVesting == nil || sm.genesisPledge.IsZero() || sm.genesisMarketFunds.IsZero() {
|
||||
err := sm.setupGenesisVestingSchedule(ctx)
|
||||
if err != nil {
|
||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup pre-ignition genesis information: %w", err)
|
||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup pre-ignition vesting schedule: %w", err)
|
||||
}
|
||||
}
|
||||
if sm.postIgnitionGenInfos == nil {
|
||||
err := sm.setupPostIgnitionGenesisActors(ctx)
|
||||
if sm.postIgnitionVesting == nil {
|
||||
err := sm.setupPostIgnitionVesting(ctx)
|
||||
if err != nil {
|
||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-ignition genesis information: %w", err)
|
||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-ignition vesting schedule: %w", err)
|
||||
}
|
||||
}
|
||||
if sm.postCalicoVesting == nil {
|
||||
err := sm.setupPostCalicoVesting(ctx)
|
||||
if err != nil {
|
||||
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-calico vesting schedule: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
-23
@@ -158,7 +158,7 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
|
||||
return mas.LoadSectors(snos)
|
||||
}
|
||||
|
||||
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]builtin.SectorInfo, error) {
|
||||
func GetSectorsForWinningPoSt(ctx context.Context, nv network.Version, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]builtin.SectorInfo, error) {
|
||||
act, err := sm.LoadActorRaw(ctx, maddr, st)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
|
||||
@@ -169,21 +169,27 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
return nil, xerrors.Errorf("failed to load miner actor state: %w", err)
|
||||
}
|
||||
|
||||
// TODO (!!): Actor Update: Make this active sectors
|
||||
var provingSectors bitfield.BitField
|
||||
if nv < network.Version7 {
|
||||
allSectors, err := miner.AllPartSectors(mas, miner.Partition.AllSectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get all sectors: %w", err)
|
||||
}
|
||||
|
||||
allSectors, err := miner.AllPartSectors(mas, miner.Partition.AllSectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get all sectors: %w", err)
|
||||
}
|
||||
faultySectors, err := miner.AllPartSectors(mas, miner.Partition.FaultySectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get faulty sectors: %w", err)
|
||||
}
|
||||
|
||||
faultySectors, err := miner.AllPartSectors(mas, miner.Partition.FaultySectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get faulty sectors: %w", err)
|
||||
}
|
||||
|
||||
provingSectors, err := bitfield.SubtractBitField(allSectors, faultySectors) // TODO: This is wrong, as it can contain faaults, change to just ActiveSectors in an upgrade
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("calc proving sectors: %w", err)
|
||||
provingSectors, err = bitfield.SubtractBitField(allSectors, faultySectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("calc proving sectors: %w", err)
|
||||
}
|
||||
} else {
|
||||
provingSectors, err = miner.AllPartSectors(mas, miner.Partition.ActiveSectors)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get active sectors sectors: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
numProvSect, err := provingSectors.Count()
|
||||
@@ -201,12 +207,7 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
return nil, xerrors.Errorf("getting miner info: %w", err)
|
||||
}
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(info.SectorSize)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting seal proof type: %w", err)
|
||||
}
|
||||
|
||||
wpt, err := spt.RegisteredWinningPoStProof()
|
||||
wpt, err := info.SealProofType.RegisteredWinningPoStProof()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting window proof type: %w", err)
|
||||
}
|
||||
@@ -246,7 +247,7 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
|
||||
out := make([]builtin.SectorInfo, len(sectors))
|
||||
for i, sinfo := range sectors {
|
||||
out[i] = builtin.SectorInfo{
|
||||
SealProof: spt,
|
||||
SealProof: sinfo.SealProof,
|
||||
SectorNumber: sinfo.SectorNumber,
|
||||
SealedCID: sinfo.SealedCID,
|
||||
}
|
||||
@@ -299,7 +300,11 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !found {
|
||||
return nil, xerrors.Errorf("deal %d not found", dealID)
|
||||
return nil, xerrors.Errorf(
|
||||
"deal %d not found "+
|
||||
"- deal may not have completed sealing before deal proposal "+
|
||||
"start epoch, or deal may have been slashed",
|
||||
dealID)
|
||||
}
|
||||
|
||||
states, err := state.States()
|
||||
@@ -497,7 +502,9 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
||||
return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err)
|
||||
}
|
||||
|
||||
sectors, err := GetSectorsForWinningPoSt(ctx, pv, sm, lbst, maddr, prand)
|
||||
nv := sm.GetNtwkVersion(ctx, ts.Height())
|
||||
|
||||
sectors, err := GetSectorsForWinningPoSt(ctx, nv, pv, sm, lbst, maddr, prand)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting winning post proving set: %w", err)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ func TestIndexSeeks(t *testing.T) {
|
||||
|
||||
nbs := blockstore.NewTemporarySync()
|
||||
cs := store.NewChainStore(nbs, nbs, syncds.MutexWrap(datastore.NewMapDatastore()), nil, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
_, err = cs.Import(bytes.NewReader(gencar))
|
||||
if err != nil {
|
||||
|
||||
+78
-17
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -59,6 +60,8 @@ var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation")
|
||||
var DefaultTipSetCacheSize = 8192
|
||||
var DefaultMsgMetaCacheSize = 2048
|
||||
|
||||
var ErrNotifeeDone = errors.New("notifee is done and should be removed")
|
||||
|
||||
func init() {
|
||||
if s := os.Getenv("LOTUS_CHAIN_TIPSET_CACHE"); s != "" {
|
||||
tscs, err := strconv.Atoi(s)
|
||||
@@ -131,24 +134,30 @@ type ChainStore struct {
|
||||
|
||||
evtTypes [1]journal.EventType
|
||||
journal journal.Journal
|
||||
|
||||
cancelFn context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
// localbs is guaranteed to fail Get* if requested block isn't stored locally
|
||||
func NewChainStore(bs bstore.Blockstore, localbs bstore.Blockstore, ds dstore.Batching, vmcalls vm.SyscallBuilder, j journal.Journal) *ChainStore {
|
||||
c, _ := lru.NewARC(DefaultMsgMetaCacheSize)
|
||||
tsc, _ := lru.NewARC(DefaultTipSetCacheSize)
|
||||
mmCache, _ := lru.NewARC(DefaultMsgMetaCacheSize)
|
||||
tsCache, _ := lru.NewARC(DefaultTipSetCacheSize)
|
||||
if j == nil {
|
||||
j = journal.NilJournal()
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cs := &ChainStore{
|
||||
bs: bs,
|
||||
localbs: localbs,
|
||||
ds: ds,
|
||||
bestTips: pubsub.New(64),
|
||||
tipsets: make(map[abi.ChainEpoch][]cid.Cid),
|
||||
mmCache: c,
|
||||
tsCache: tsc,
|
||||
mmCache: mmCache,
|
||||
tsCache: tsCache,
|
||||
vmcalls: vmcalls,
|
||||
cancelFn: cancel,
|
||||
journal: j,
|
||||
}
|
||||
|
||||
@@ -188,19 +197,24 @@ func NewChainStore(bs bstore.Blockstore, localbs bstore.Blockstore, ds dstore.Ba
|
||||
}
|
||||
|
||||
hcmetric := func(rev, app []*types.TipSet) error {
|
||||
ctx := context.Background()
|
||||
for _, r := range app {
|
||||
stats.Record(ctx, metrics.ChainNodeHeight.M(int64(r.Height())))
|
||||
stats.Record(context.Background(), metrics.ChainNodeHeight.M(int64(r.Height())))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
cs.reorgNotifeeCh = make(chan ReorgNotifee)
|
||||
cs.reorgCh = cs.reorgWorker(context.TODO(), []ReorgNotifee{hcnf, hcmetric})
|
||||
cs.reorgCh = cs.reorgWorker(ctx, []ReorgNotifee{hcnf, hcmetric})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
func (cs *ChainStore) Close() error {
|
||||
cs.cancelFn()
|
||||
cs.wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cs *ChainStore) Load() error {
|
||||
head, err := cs.ds.Get(chainHeadKey)
|
||||
if err == dstore.ErrNotFound {
|
||||
@@ -268,7 +282,7 @@ func (cs *ChainStore) SubHeadChanges(ctx context.Context) chan []*api.HeadChange
|
||||
log.Warn("chain head sub exit loop")
|
||||
return
|
||||
}
|
||||
if len(out) > 0 {
|
||||
if len(out) > 5 {
|
||||
log.Warnf("head change sub is slow, has %d buffered entries", len(out))
|
||||
}
|
||||
select {
|
||||
@@ -380,7 +394,7 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
|
||||
// particular tipset to carry out a benchmark, verification, etc. on a chain
|
||||
// segment.
|
||||
func (cs *ChainStore) ForceHeadSilent(_ context.Context, ts *types.TipSet) error {
|
||||
log.Warnf("(!!!) forcing a new head silently; only use this only for testing; new head: %s", ts)
|
||||
log.Warnf("(!!!) forcing a new head silently; new head: %s", ts)
|
||||
|
||||
cs.heaviestLk.Lock()
|
||||
defer cs.heaviestLk.Unlock()
|
||||
@@ -403,7 +417,9 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo
|
||||
notifees := make([]ReorgNotifee, len(initialNotifees))
|
||||
copy(notifees, initialNotifees)
|
||||
|
||||
cs.wg.Add(1)
|
||||
go func() {
|
||||
defer cs.wg.Done()
|
||||
defer log.Warn("reorgWorker quit")
|
||||
|
||||
for {
|
||||
@@ -435,11 +451,36 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo
|
||||
apply[i], apply[opp] = apply[opp], apply[i]
|
||||
}
|
||||
|
||||
for _, hcf := range notifees {
|
||||
if err := hcf(revert, apply); err != nil {
|
||||
var toremove map[int]struct{}
|
||||
for i, hcf := range notifees {
|
||||
err := hcf(revert, apply)
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
|
||||
case ErrNotifeeDone:
|
||||
if toremove == nil {
|
||||
toremove = make(map[int]struct{})
|
||||
}
|
||||
toremove[i] = struct{}{}
|
||||
|
||||
default:
|
||||
log.Error("head change func errored (BAD): ", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(toremove) > 0 {
|
||||
newNotifees := make([]ReorgNotifee, 0, len(notifees)-len(toremove))
|
||||
for i, hcf := range notifees {
|
||||
_, remove := toremove[i]
|
||||
if remove {
|
||||
continue
|
||||
}
|
||||
newNotifees = append(newNotifees, hcf)
|
||||
}
|
||||
notifees = newNotifees
|
||||
}
|
||||
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
@@ -685,12 +726,32 @@ func (cs *ChainStore) AddToTipSetTracker(b *types.BlockHeader) error {
|
||||
log.Debug("tried to add block to tipset tracker that was already there")
|
||||
return nil
|
||||
}
|
||||
h, err := cs.GetBlock(oc)
|
||||
if err == nil && h != nil {
|
||||
if h.Miner == b.Miner {
|
||||
log.Warnf("Have multiple blocks from miner %s at height %d in our tipset cache %s-%s", b.Miner, b.Height, b.Cid(), h.Cid())
|
||||
}
|
||||
}
|
||||
}
|
||||
// This function is called 5 times per epoch on average
|
||||
// It is also called with tipsets that are done with initial validation
|
||||
// so they cannot be from the future.
|
||||
// We are guaranteed not to use tipsets older than 900 epochs (fork limit)
|
||||
// This means that we ideally want to keep only most recent 900 epochs in here
|
||||
// Golang's map iteration starts at a random point in a map.
|
||||
// With 5 tries per epoch, and 900 entries to keep, on average we will have
|
||||
// ~136 garbage entires in the `cs.tipsets` map. (solve for 1-(1-x/(900+x))^5 == 0.5)
|
||||
// Seems good enough to me
|
||||
|
||||
for height := range cs.tipsets {
|
||||
if height < b.Height-build.Finality {
|
||||
delete(cs.tipsets, height)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
cs.tipsets[b.Height] = append(tss, b.Cid())
|
||||
|
||||
// TODO: do we want to look for slashable submissions here? might as well...
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -756,7 +817,7 @@ func (cs *ChainStore) expandTipset(b *types.BlockHeader) (*types.TipSet, error)
|
||||
return types.NewTipSet(all)
|
||||
}
|
||||
|
||||
inclMiners := map[address.Address]bool{b.Miner: true}
|
||||
inclMiners := map[address.Address]cid.Cid{b.Miner: b.Cid()}
|
||||
for _, bhc := range tsets {
|
||||
if bhc == b.Cid() {
|
||||
continue
|
||||
@@ -767,14 +828,14 @@ func (cs *ChainStore) expandTipset(b *types.BlockHeader) (*types.TipSet, error)
|
||||
return nil, xerrors.Errorf("failed to load block (%s) for tipset expansion: %w", bhc, err)
|
||||
}
|
||||
|
||||
if inclMiners[h.Miner] {
|
||||
log.Warnf("Have multiple blocks from miner %s at height %d in our tipset cache", h.Miner, h.Height)
|
||||
if cid, found := inclMiners[h.Miner]; found {
|
||||
log.Warnf("Have multiple blocks from miner %s at height %d in our tipset cache %s-%s", h.Miner, h.Height, h.Cid(), cid)
|
||||
continue
|
||||
}
|
||||
|
||||
if types.CidArrsEqual(h.Parents, b.Parents) {
|
||||
all = append(all, h)
|
||||
inclMiners[h.Miner] = true
|
||||
inclMiners[h.Miner] = bhc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ func BenchmarkGetRandomness(b *testing.B) {
|
||||
}
|
||||
|
||||
cs := store.NewChainStore(bs, bs, mds, nil, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
@@ -105,6 +106,7 @@ func TestChainExportImport(t *testing.T) {
|
||||
|
||||
nbs := blockstore.NewTemporary()
|
||||
cs := store.NewChainStore(nbs, nbs, datastore.NewMapDatastore(), nil, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
root, err := cs.Import(buf)
|
||||
if err != nil {
|
||||
@@ -139,6 +141,8 @@ func TestChainExportImportFull(t *testing.T) {
|
||||
|
||||
nbs := blockstore.NewTemporary()
|
||||
cs := store.NewChainStore(nbs, nbs, datastore.NewMapDatastore(), nil, nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
root, err := cs.Import(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
+27
-18
@@ -6,9 +6,18 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
address "github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
"github.com/filecoin-project/lotus/node/impl/client"
|
||||
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
bserv "github.com/ipfs/go-blockservice"
|
||||
@@ -21,19 +30,7 @@ import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"go.opencensus.io/stats"
|
||||
"go.opencensus.io/tag"
|
||||
|
||||
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
"github.com/filecoin-project/lotus/node/impl/client"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var log = logging.Logger("sub")
|
||||
@@ -95,8 +92,15 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
|
||||
}
|
||||
|
||||
took := build.Clock.Since(start)
|
||||
log.Infow("new block over pubsub", "cid", blk.Header.Cid(), "source", msg.GetFrom(), "msgfetch", took)
|
||||
log.Debugw("new block over pubsub", "cid", blk.Header.Cid(), "source", msg.GetFrom(), "msgfetch", took)
|
||||
if took > 3*time.Second {
|
||||
log.Warnw("Slow msg fetch", "cid", blk.Header.Cid(), "source", msg.GetFrom(), "msgfetch", took)
|
||||
}
|
||||
if delay := build.Clock.Now().Unix() - int64(blk.Header.Timestamp); delay > 5 {
|
||||
_ = stats.RecordWithTags(ctx,
|
||||
[]tag.Mutator{tag.Insert(metrics.MinerID, blk.Header.Miner.String())},
|
||||
metrics.BlockDelay.M(delay),
|
||||
)
|
||||
log.Warnf("Received block with large delay %d from miner %s", delay, blk.Header.Miner)
|
||||
}
|
||||
|
||||
@@ -337,11 +341,16 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
|
||||
func (bv *BlockValidator) validateLocalBlock(ctx context.Context, msg *pubsub.Message) pubsub.ValidationResult {
|
||||
stats.Record(ctx, metrics.BlockPublished.M(1))
|
||||
|
||||
if size := msg.Size(); size > 1<<20-1<<15 {
|
||||
log.Errorf("ignoring oversize block (%dB)", size)
|
||||
recordFailure(ctx, metrics.BlockValidationFailure, "oversize_block")
|
||||
return pubsub.ValidationIgnore
|
||||
}
|
||||
|
||||
blk, what, err := bv.decodeAndCheckBlock(msg)
|
||||
if err != nil {
|
||||
log.Errorf("got invalid local block: %s", err)
|
||||
ctx, _ = tag.New(ctx, tag.Insert(metrics.FailureType, what))
|
||||
stats.Record(ctx, metrics.BlockValidationFailure.M(1))
|
||||
recordFailure(ctx, metrics.BlockValidationFailure, what)
|
||||
return pubsub.ValidationIgnore
|
||||
}
|
||||
|
||||
|
||||
+9
-6
@@ -32,6 +32,7 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
blst "github.com/supranational/blst/bindings/go"
|
||||
|
||||
@@ -278,7 +279,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
|
||||
for _, blk := range fts.TipSet().Blocks() {
|
||||
miners = append(miners, blk.Miner.String())
|
||||
}
|
||||
log.Infow("incoming tipset does not appear to be better than our best chain, ignoring for now", "miners", miners, "bestPweight", bestPweight, "bestTS", hts.Cids(), "incomingWeight", targetWeight, "incomingTS", fts.TipSet().Cids())
|
||||
log.Debugw("incoming tipset does not appear to be better than our best chain, ignoring for now", "miners", miners, "bestPweight", bestPweight, "bestTS", hts.Cids(), "incomingWeight", targetWeight, "incomingTS", fts.TipSet().Cids())
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -731,6 +732,8 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use
|
||||
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
|
||||
}
|
||||
|
||||
winPoStNv := syncer.sm.GetNtwkVersion(ctx, baseTs.Height())
|
||||
|
||||
lbts, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, syncer.sm, baseTs, h.Height)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get lookback tipset for block: %w", err)
|
||||
@@ -924,7 +927,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use
|
||||
})
|
||||
|
||||
wproofCheck := async.Err(func() error {
|
||||
if err := syncer.VerifyWinningPoStProof(ctx, h, *prevBeacon, lbst, waddr); err != nil {
|
||||
if err := syncer.VerifyWinningPoStProof(ctx, winPoStNv, h, *prevBeacon, lbst, waddr); err != nil {
|
||||
return xerrors.Errorf("invalid election post: %w", err)
|
||||
}
|
||||
return nil
|
||||
@@ -976,7 +979,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use
|
||||
return nil
|
||||
}
|
||||
|
||||
func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.BlockHeader, prevBeacon types.BeaconEntry, lbst cid.Cid, waddr address.Address) error {
|
||||
func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, nv network.Version, h *types.BlockHeader, prevBeacon types.BeaconEntry, lbst cid.Cid, waddr address.Address) error {
|
||||
if build.InsecurePoStValidation {
|
||||
if len(h.WinPoStProof) == 0 {
|
||||
return xerrors.Errorf("[INSECURE-POST-VALIDATION] No winning post proof given")
|
||||
@@ -1008,7 +1011,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block
|
||||
return xerrors.Errorf("failed to get ID from miner address %s: %w", h.Miner, err)
|
||||
}
|
||||
|
||||
sectors, err := stmgr.GetSectorsForWinningPoSt(ctx, syncer.verifier, syncer.sm, lbst, h.Miner, rand)
|
||||
sectors, err := stmgr.GetSectorsForWinningPoSt(ctx, nv, syncer.verifier, syncer.sm, lbst, h.Miner, rand)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting winning post sector set: %w", err)
|
||||
}
|
||||
@@ -1072,7 +1075,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
||||
|
||||
// Phase 1: syntactic validation, as defined in the spec
|
||||
minGas := pl.OnChainMessage(msg.ChainLength())
|
||||
if err := m.ValidForBlockInclusion(minGas.Total()); err != nil {
|
||||
if err := m.ValidForBlockInclusion(minGas.Total(), syncer.sm.GetNtwkVersion(ctx, b.Header.Height)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1328,7 +1331,7 @@ loop:
|
||||
continue
|
||||
}
|
||||
if !xerrors.Is(err, bstore.ErrNotFound) {
|
||||
log.Warn("loading local tipset: %s", err)
|
||||
log.Warnf("loading local tipset: %s", err)
|
||||
}
|
||||
|
||||
// NB: GetBlocks validates that the blocks are in-fact the ones we
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
BootstrapPeerThreshold = 4
|
||||
BootstrapPeerThreshold = build.BootstrapPeerThreshold
|
||||
|
||||
RecentSyncBufferSize = 10
|
||||
MaxSyncWorkers = 5
|
||||
@@ -194,7 +194,7 @@ func (sm *syncManager) scheduler() {
|
||||
}
|
||||
|
||||
func (sm *syncManager) handlePeerHead(head peerHead) {
|
||||
log.Infof("new peer head: %s %s", head.p, head.ts)
|
||||
log.Debugf("new peer head: %s %s", head.p, head.ts)
|
||||
|
||||
// have we started syncing yet?
|
||||
if sm.nextWorker == 0 {
|
||||
@@ -203,6 +203,7 @@ func (sm *syncManager) handlePeerHead(head peerHead) {
|
||||
|
||||
// not yet; do we have enough peers?
|
||||
if len(sm.heads) < BootstrapPeerThreshold {
|
||||
log.Debugw("not tracking enough peers to start sync worker", "have", len(sm.heads), "need", BootstrapPeerThreshold)
|
||||
// not enough peers; track it and wait
|
||||
return
|
||||
}
|
||||
@@ -410,7 +411,7 @@ func (sm *syncManager) addSyncTarget(ts *types.TipSet) (*types.TipSet, bool, err
|
||||
// if we have not finished the initial sync or have too many workers, add it to the deferred queue;
|
||||
// it will be processed once a worker is freed from syncing a chain (or the initial sync finishes)
|
||||
if !sm.initialSyncDone || len(sm.state) >= MaxSyncWorkers {
|
||||
log.Infof("deferring sync on %s", ts)
|
||||
log.Debugf("deferring sync on %s", ts)
|
||||
sm.deferred.Insert(ts)
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
@@ -23,6 +23,29 @@ func (f FIL) Unitless() string {
|
||||
return strings.TrimRight(strings.TrimRight(r.FloatString(18), "0"), ".")
|
||||
}
|
||||
|
||||
var unitPrefixes = []string{"a", "f", "p", "n", "μ", "m"}
|
||||
|
||||
func (f FIL) Short() string {
|
||||
n := BigInt(f)
|
||||
|
||||
dn := uint64(1)
|
||||
var prefix string
|
||||
for _, p := range unitPrefixes {
|
||||
if n.LessThan(NewInt(dn * 1000)) {
|
||||
prefix = p
|
||||
break
|
||||
}
|
||||
dn *= 1000
|
||||
}
|
||||
|
||||
r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(dn)))
|
||||
if r.Sign() == 0 {
|
||||
return "0"
|
||||
}
|
||||
|
||||
return strings.TrimRight(strings.TrimRight(r.FloatString(3), "0"), ".") + " " + prefix + "FIL"
|
||||
}
|
||||
|
||||
func (f FIL) Format(s fmt.State, ch rune) {
|
||||
switch ch {
|
||||
case 's', 'v':
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFilShort(t *testing.T) {
|
||||
for _, s := range []struct {
|
||||
fil string
|
||||
expect string
|
||||
}{
|
||||
|
||||
{fil: "1", expect: "1 FIL"},
|
||||
{fil: "1.1", expect: "1.1 FIL"},
|
||||
{fil: "12", expect: "12 FIL"},
|
||||
{fil: "123", expect: "123 FIL"},
|
||||
{fil: "123456", expect: "123456 FIL"},
|
||||
{fil: "123.23", expect: "123.23 FIL"},
|
||||
{fil: "123456.234", expect: "123456.234 FIL"},
|
||||
{fil: "123456.2341234", expect: "123456.234 FIL"},
|
||||
{fil: "123456.234123445", expect: "123456.234 FIL"},
|
||||
|
||||
{fil: "0.1", expect: "100 mFIL"},
|
||||
{fil: "0.01", expect: "10 mFIL"},
|
||||
{fil: "0.001", expect: "1 mFIL"},
|
||||
|
||||
{fil: "0.0001", expect: "100 μFIL"},
|
||||
{fil: "0.00001", expect: "10 μFIL"},
|
||||
{fil: "0.000001", expect: "1 μFIL"},
|
||||
|
||||
{fil: "0.0000001", expect: "100 nFIL"},
|
||||
{fil: "0.00000001", expect: "10 nFIL"},
|
||||
{fil: "0.000000001", expect: "1 nFIL"},
|
||||
|
||||
{fil: "0.0000000001", expect: "100 pFIL"},
|
||||
{fil: "0.00000000001", expect: "10 pFIL"},
|
||||
{fil: "0.000000000001", expect: "1 pFIL"},
|
||||
|
||||
{fil: "0.0000000000001", expect: "100 fFIL"},
|
||||
{fil: "0.00000000000001", expect: "10 fFIL"},
|
||||
{fil: "0.000000000000001", expect: "1 fFIL"},
|
||||
|
||||
{fil: "0.0000000000000001", expect: "100 aFIL"},
|
||||
{fil: "0.00000000000000001", expect: "10 aFIL"},
|
||||
{fil: "0.000000000000000001", expect: "1 aFIL"},
|
||||
|
||||
{fil: "0.0000012", expect: "1.2 μFIL"},
|
||||
{fil: "0.00000123", expect: "1.23 μFIL"},
|
||||
{fil: "0.000001234", expect: "1.234 μFIL"},
|
||||
{fil: "0.0000012344", expect: "1.234 μFIL"},
|
||||
{fil: "0.00000123444", expect: "1.234 μFIL"},
|
||||
|
||||
{fil: "0.0002212", expect: "221.2 μFIL"},
|
||||
{fil: "0.00022123", expect: "221.23 μFIL"},
|
||||
{fil: "0.000221234", expect: "221.234 μFIL"},
|
||||
{fil: "0.0002212344", expect: "221.234 μFIL"},
|
||||
{fil: "0.00022123444", expect: "221.234 μFIL"},
|
||||
} {
|
||||
s := s
|
||||
t.Run(s.fil, func(t *testing.T) {
|
||||
f, err := ParseFIL(s.fil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, s.expect, f.Short())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@@ -144,7 +146,7 @@ func (m *Message) EqualCall(o *Message) bool {
|
||||
return (&m1).Equals(&m2)
|
||||
}
|
||||
|
||||
func (m *Message) ValidForBlockInclusion(minGas int64) error {
|
||||
func (m *Message) ValidForBlockInclusion(minGas int64, version network.Version) error {
|
||||
if m.Version != 0 {
|
||||
return xerrors.New("'Version' unsupported")
|
||||
}
|
||||
@@ -153,6 +155,10 @@ func (m *Message) ValidForBlockInclusion(minGas int64) error {
|
||||
return xerrors.New("'To' address cannot be empty")
|
||||
}
|
||||
|
||||
if m.To == build.ZeroAddress && version >= network.Version7 {
|
||||
return xerrors.New("invalid 'To' address")
|
||||
}
|
||||
|
||||
if m.From == address.Undef {
|
||||
return xerrors.New("'From' address cannot be empty")
|
||||
}
|
||||
|
||||
+7
-2
@@ -67,7 +67,7 @@ func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
|
||||
return gasLimit - gasUsed - gasToBurn.Int64(), gasToBurn.Int64()
|
||||
}
|
||||
|
||||
func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount) GasOutputs {
|
||||
func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount, chargeNetworkFee bool) GasOutputs {
|
||||
gasUsedBig := big.NewInt(gasUsed)
|
||||
out := ZeroGasOutputs()
|
||||
|
||||
@@ -76,7 +76,12 @@ func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.
|
||||
baseFeeToPay = feeCap
|
||||
out.MinerPenalty = big.Mul(big.Sub(baseFee, feeCap), gasUsedBig)
|
||||
}
|
||||
out.BaseFeeBurn = big.Mul(baseFeeToPay, gasUsedBig)
|
||||
|
||||
// If chargeNetworkFee is disabled, just skip computing the BaseFeeBurn. However,
|
||||
// we charge all the other fees regardless.
|
||||
if chargeNetworkFee {
|
||||
out.BaseFeeBurn = big.Mul(baseFeeToPay, gasUsedBig)
|
||||
}
|
||||
|
||||
minerTip := gasPremium
|
||||
if big.Cmp(big.Add(baseFeeToPay, minerTip), feeCap) > 0 {
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestGasOutputs(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
||||
output := ComputeGasOutputs(test.used, test.limit, baseFee, types.NewInt(test.feeCap), types.NewInt(test.premium))
|
||||
output := ComputeGasOutputs(test.used, test.limit, baseFee, types.NewInt(test.feeCap), types.NewInt(test.premium), true)
|
||||
i2s := func(i uint64) string {
|
||||
return fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
+51
-7
@@ -3,21 +3,17 @@ package vm
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
vmr2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
|
||||
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
addr "github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
vmr2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
|
||||
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
const (
|
||||
GasStorageMulti = 1000
|
||||
GasComputeMulti = 1
|
||||
)
|
||||
|
||||
type GasCharge struct {
|
||||
Name string
|
||||
Extra interface{}
|
||||
@@ -132,6 +128,54 @@ var prices = map[abi.ChainEpoch]Pricelist{
|
||||
verifyPostDiscount: true,
|
||||
verifyConsensusFault: 495422,
|
||||
},
|
||||
abi.ChainEpoch(build.UpgradeCalicoHeight): &pricelistV0{
|
||||
computeGasMulti: 1,
|
||||
storageGasMulti: 1300,
|
||||
|
||||
onChainMessageComputeBase: 38863,
|
||||
onChainMessageStorageBase: 36,
|
||||
onChainMessageStoragePerByte: 1,
|
||||
|
||||
onChainReturnValuePerByte: 1,
|
||||
|
||||
sendBase: 29233,
|
||||
sendTransferFunds: 27500,
|
||||
sendTransferOnlyPremium: 159672,
|
||||
sendInvokeMethod: -5377,
|
||||
|
||||
ipldGetBase: 114617,
|
||||
ipldPutBase: 353640,
|
||||
ipldPutPerByte: 1,
|
||||
|
||||
createActorCompute: 1108454,
|
||||
createActorStorage: 36 + 40,
|
||||
deleteActor: -(36 + 40), // -createActorStorage
|
||||
|
||||
verifySignature: map[crypto.SigType]int64{
|
||||
crypto.SigTypeBLS: 16598605,
|
||||
crypto.SigTypeSecp256k1: 1637292,
|
||||
},
|
||||
|
||||
hashingBase: 31355,
|
||||
computeUnsealedSectorCidBase: 98647,
|
||||
verifySealBase: 2000, // TODO gas , it VerifySeal syscall is not used
|
||||
verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{
|
||||
abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: {
|
||||
flat: 117680921,
|
||||
scale: 43780,
|
||||
},
|
||||
abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: {
|
||||
flat: 117680921,
|
||||
scale: 43780,
|
||||
},
|
||||
abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: {
|
||||
flat: 117680921,
|
||||
scale: 43780,
|
||||
},
|
||||
},
|
||||
verifyPostDiscount: false,
|
||||
verifyConsensusFault: 495422,
|
||||
},
|
||||
}
|
||||
|
||||
// PricelistByEpoch finds the latest prices for the given epoch
|
||||
|
||||
+3
-2
@@ -133,13 +133,13 @@ func (pl *pricelistV0) OnMethodInvocation(value abi.TokenAmount, methodNum abi.M
|
||||
|
||||
// OnIpldGet returns the gas used for storing an object
|
||||
func (pl *pricelistV0) OnIpldGet() GasCharge {
|
||||
return newGasCharge("OnIpldGet", pl.ipldGetBase, 0)
|
||||
return newGasCharge("OnIpldGet", pl.ipldGetBase, 0).WithVirtual(114617, 0)
|
||||
}
|
||||
|
||||
// OnIpldPut returns the gas used for storing an object
|
||||
func (pl *pricelistV0) OnIpldPut(dataSize int) GasCharge {
|
||||
return newGasCharge("OnIpldPut", pl.ipldPutBase, int64(dataSize)*pl.ipldPutPerByte*pl.storageGasMulti).
|
||||
WithExtra(dataSize)
|
||||
WithExtra(dataSize).WithVirtual(400000, int64(dataSize)*1300)
|
||||
}
|
||||
|
||||
// OnCreateActor returns the gas used for creating an actor
|
||||
@@ -209,6 +209,7 @@ func (pl *pricelistV0) OnVerifyPost(info proof2.WindowPoStVerifyInfo) GasCharge
|
||||
}
|
||||
|
||||
return newGasCharge("OnVerifyPost", gasUsed, 0).
|
||||
WithVirtual(117680921+43780*int64(len(info.ChallengedSectors)), 0).
|
||||
WithExtra(map[string]interface{}{
|
||||
"type": sectorSize,
|
||||
"size": len(info.ChallengedSectors),
|
||||
|
||||
+11
-5
@@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -34,9 +36,9 @@ type ActorPredicate func(vmr.Runtime, rtt.VMActor) error
|
||||
|
||||
func ActorsVersionPredicate(ver actors.Version) ActorPredicate {
|
||||
return func(rt vmr.Runtime, v rtt.VMActor) error {
|
||||
nver := actors.VersionForNetwork(rt.NetworkVersion())
|
||||
if nver != ver {
|
||||
return xerrors.Errorf("actor %s is a version %d actor; chain only supports actor version %d at height %d", v.Code(), ver, nver, rt.CurrEpoch())
|
||||
aver := actors.VersionForNetwork(rt.NetworkVersion())
|
||||
if aver != ver {
|
||||
return xerrors.Errorf("actor %s is a version %d actor; chain only supports actor version %d at height %d and nver %d", v.Code(), ver, aver, rt.CurrEpoch(), rt.NetworkVersion())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -173,9 +175,14 @@ func (*ActorRegistry) transform(instance invokee) (nativeCode, error) {
|
||||
paramT := meth.Type().In(1).Elem()
|
||||
param := reflect.New(paramT)
|
||||
|
||||
rt := in[0].Interface().(*Runtime)
|
||||
inBytes := in[1].Interface().([]byte)
|
||||
if err := DecodeParams(inBytes, param.Interface()); err != nil {
|
||||
aerr := aerrors.Absorb(err, 1, "failed to decode parameters")
|
||||
ec := exitcode.ErrSerialization
|
||||
if rt.NetworkVersion() < network.Version7 {
|
||||
ec = 1
|
||||
}
|
||||
aerr := aerrors.Absorb(err, ec, "failed to decode parameters")
|
||||
return []reflect.Value{
|
||||
reflect.ValueOf([]byte{}),
|
||||
// Below is a hack, fixed in Go 1.13
|
||||
@@ -183,7 +190,6 @@ func (*ActorRegistry) transform(instance invokee) (nativeCode, error) {
|
||||
reflect.ValueOf(&aerr).Elem(),
|
||||
}
|
||||
}
|
||||
rt := in[0].Interface().(*Runtime)
|
||||
rval, aerror := rt.shimCall(func() interface{} {
|
||||
ret := meth.Call([]reflect.Value{
|
||||
reflect.ValueOf(rt),
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/stretchr/testify/assert"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -105,10 +108,27 @@ func TestInvokerBasic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
_, aerr := code[1](&Runtime{}, []byte{99})
|
||||
if aerrors.IsFatal(aerr) {
|
||||
t.Fatal("err should not be fatal")
|
||||
{
|
||||
_, aerr := code[1](&Runtime{
|
||||
vm: &VM{ntwkVersion: func(ctx context.Context, epoch abi.ChainEpoch) network.Version {
|
||||
return network.Version0
|
||||
}},
|
||||
}, []byte{99})
|
||||
if aerrors.IsFatal(aerr) {
|
||||
t.Fatal("err should not be fatal")
|
||||
}
|
||||
assert.Equal(t, exitcode.ExitCode(1), aerrors.RetCode(aerr), "return code should be 1")
|
||||
}
|
||||
assert.Equal(t, exitcode.ExitCode(1), aerrors.RetCode(aerr), "return code should be 1")
|
||||
|
||||
{
|
||||
_, aerr := code[1](&Runtime{
|
||||
vm: &VM{ntwkVersion: func(ctx context.Context, epoch abi.ChainEpoch) network.Version {
|
||||
return network.Version7
|
||||
}},
|
||||
}, []byte{99})
|
||||
if aerrors.IsFatal(aerr) {
|
||||
t.Fatal("err should not be fatal")
|
||||
}
|
||||
assert.Equal(t, exitcode.ErrSerialization, aerrors.RetCode(aerr), "return code should be %s", 1)
|
||||
}
|
||||
}
|
||||
|
||||
+30
-6
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
gruntime "runtime"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -244,20 +245,23 @@ func (rt *Runtime) NewActorAddress() address.Address {
|
||||
return addr
|
||||
}
|
||||
|
||||
func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
||||
func (rt *Runtime) CreateActor(codeID cid.Cid, addr address.Address) {
|
||||
if addr == address.Undef && rt.NetworkVersion() >= network.Version7 {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "CreateActor with Undef address")
|
||||
}
|
||||
act, aerr := rt.vm.areg.Create(codeID, rt)
|
||||
if aerr != nil {
|
||||
rt.Abortf(aerr.RetCode(), aerr.Error())
|
||||
}
|
||||
|
||||
_, err := rt.state.GetActor(address)
|
||||
_, err := rt.state.GetActor(addr)
|
||||
if err == nil {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "Actor address already exists")
|
||||
}
|
||||
|
||||
rt.chargeGas(rt.Pricelist().OnCreateActor())
|
||||
|
||||
err = rt.state.SetActor(address, act)
|
||||
err = rt.state.SetActor(addr, act)
|
||||
if err != nil {
|
||||
panic(aerrors.Fatalf("creating actor entry: %v", err))
|
||||
}
|
||||
@@ -266,7 +270,7 @@ func (rt *Runtime) CreateActor(codeID cid.Cid, address address.Address) {
|
||||
|
||||
// DeleteActor deletes the executing actor from the state tree, transferring
|
||||
// any balance to beneficiary.
|
||||
// Aborts if the beneficiary does not exist.
|
||||
// Aborts if the beneficiary does not exist or is the calling actor.
|
||||
// May only be called by the actor itself.
|
||||
func (rt *Runtime) DeleteActor(beneficiary address.Address) {
|
||||
rt.chargeGas(rt.Pricelist().OnDeleteActor())
|
||||
@@ -278,6 +282,19 @@ func (rt *Runtime) DeleteActor(beneficiary address.Address) {
|
||||
panic(aerrors.Fatalf("failed to get actor: %s", err))
|
||||
}
|
||||
if !act.Balance.IsZero() {
|
||||
// TODO: Should be safe to drop the version-check,
|
||||
// since only the paych actor called this pre-version 7, but let's leave it for now
|
||||
if rt.NetworkVersion() >= network.Version7 {
|
||||
beneficiaryId, found := rt.ResolveAddress(beneficiary)
|
||||
if !found {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "beneficiary doesn't exist")
|
||||
}
|
||||
|
||||
if beneficiaryId == rt.Receiver() {
|
||||
rt.Abortf(exitcode.SysErrorIllegalArgument, "benefactor cannot be beneficiary")
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer the executing actor's balance to the beneficiary
|
||||
if err := rt.vm.transfer(rt.Receiver(), beneficiary, act.Balance); err != nil {
|
||||
panic(aerrors.Fatalf("failed to transfer balance to beneficiary actor: %s", err))
|
||||
@@ -518,7 +535,7 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError
|
||||
if EnableGasTracing {
|
||||
var callers [10]uintptr
|
||||
|
||||
cout := 0 //gruntime.Callers(2+skip, callers[:])
|
||||
cout := gruntime.Callers(2+skip, callers[:])
|
||||
|
||||
now := build.Clock.Now()
|
||||
if rt.lastGasCharge != nil {
|
||||
@@ -533,12 +550,19 @@ func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError
|
||||
ComputeGas: gas.ComputeGas,
|
||||
StorageGas: gas.StorageGas,
|
||||
|
||||
TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti,
|
||||
VirtualComputeGas: gas.VirtualCompute,
|
||||
VirtualStorageGas: gas.VirtualStorage,
|
||||
|
||||
Callers: callers[:cout],
|
||||
}
|
||||
if gasTrace.VirtualStorageGas == 0 {
|
||||
gasTrace.VirtualStorageGas = gasTrace.StorageGas
|
||||
}
|
||||
if gasTrace.VirtualComputeGas == 0 {
|
||||
gasTrace.VirtualComputeGas = gasTrace.ComputeGas
|
||||
}
|
||||
gasTrace.TotalVirtualGas = gasTrace.VirtualComputeGas + gasTrace.VirtualStorageGas
|
||||
|
||||
rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace)
|
||||
rt.lastGasChargeTime = now
|
||||
rt.lastGasCharge = &gasTrace
|
||||
|
||||
+19
-10
@@ -7,25 +7,26 @@ import (
|
||||
goruntime "runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/minio/blake2b-simd"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
|
||||
runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
|
||||
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
|
||||
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -40,7 +41,9 @@ func Syscalls(verifier ffiwrapper.Verifier) SyscallBuilder {
|
||||
return func(ctx context.Context, rt *Runtime) runtime2.Syscalls {
|
||||
|
||||
return &syscallShim{
|
||||
ctx: ctx,
|
||||
ctx: ctx,
|
||||
epoch: rt.CurrEpoch(),
|
||||
networkVersion: rt.NetworkVersion(),
|
||||
|
||||
actor: rt.Receiver(),
|
||||
cstate: rt.state,
|
||||
@@ -55,11 +58,13 @@ func Syscalls(verifier ffiwrapper.Verifier) SyscallBuilder {
|
||||
type syscallShim struct {
|
||||
ctx context.Context
|
||||
|
||||
lbState LookbackStateGetter
|
||||
actor address.Address
|
||||
cstate *state.StateTree
|
||||
cst cbor.IpldStore
|
||||
verifier ffiwrapper.Verifier
|
||||
epoch abi.ChainEpoch
|
||||
networkVersion network.Version
|
||||
lbState LookbackStateGetter
|
||||
actor address.Address
|
||||
cstate *state.StateTree
|
||||
cst cbor.IpldStore
|
||||
verifier ffiwrapper.Verifier
|
||||
}
|
||||
|
||||
func (ss *syscallShim) ComputeUnsealedSectorCID(st abi.RegisteredSealProof, pieces []abi.PieceInfo) (cid.Cid, error) {
|
||||
@@ -202,6 +207,10 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error {
|
||||
}
|
||||
|
||||
func (ss *syscallShim) workerKeyAtLookback(height abi.ChainEpoch) (address.Address, error) {
|
||||
if ss.networkVersion >= network.Version7 && height < ss.epoch-policy.ChainFinality {
|
||||
return address.Undef, xerrors.Errorf("cannot get worker key (currEpoch %d, height %d)", ss.epoch, height)
|
||||
}
|
||||
|
||||
lbState, err := ss.lbState(ss.ctx, height)
|
||||
if err != nil {
|
||||
return address.Undef, err
|
||||
@@ -294,7 +303,7 @@ func (ss *syscallShim) BatchVerifySeals(inp map[address.Address][]proof2.SealVer
|
||||
sema <- struct{}{}
|
||||
|
||||
if err := ss.VerifySeal(svi); err != nil {
|
||||
log.Warnw("seal verify in batch failed", "miner", ma, "index", ix, "err", err)
|
||||
log.Warnw("seal verify in batch failed", "miner", ma, "sectorNumber", svi.SectorID.Number, "err", err)
|
||||
res[ix] = false
|
||||
} else {
|
||||
res[ix] = true
|
||||
|
||||
+82
-10
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/metrics"
|
||||
|
||||
block "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"go.opencensus.io/stats"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@@ -30,6 +32,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/account"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -138,6 +141,10 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runti
|
||||
}
|
||||
|
||||
if parent != nil {
|
||||
// TODO: The version check here should be unnecessary, but we can wait to take it out
|
||||
if !parent.allowInternal && rt.NetworkVersion() >= network.Version7 {
|
||||
rt.Abortf(exitcode.SysErrForbidden, "internal calls currently disabled")
|
||||
}
|
||||
rt.gasUsed = parent.gasUsed
|
||||
rt.origin = parent.origin
|
||||
rt.originNonce = parent.originNonce
|
||||
@@ -555,7 +562,13 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
if gasUsed < 0 {
|
||||
gasUsed = 0
|
||||
}
|
||||
gasOutputs := ComputeGasOutputs(gasUsed, msg.GasLimit, vm.baseFee, msg.GasFeeCap, msg.GasPremium)
|
||||
|
||||
burn, err := vm.shouldBurn(st, msg, errcode)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("deciding whether should burn failed: %w", err)
|
||||
}
|
||||
|
||||
gasOutputs := ComputeGasOutputs(gasUsed, msg.GasLimit, vm.baseFee, msg.GasFeeCap, msg.GasPremium, burn)
|
||||
|
||||
if err := vm.transferFromGasHolder(builtin.BurntFundsActorAddr, gasHolder,
|
||||
gasOutputs.BaseFeeBurn); err != nil {
|
||||
@@ -593,6 +606,29 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (vm *VM) shouldBurn(st *state.StateTree, msg *types.Message, errcode exitcode.ExitCode) (bool, error) {
|
||||
// Check to see if we should burn funds. We avoid burning on successful
|
||||
// window post. This won't catch _indirect_ window post calls, but this
|
||||
// is the best we can get for now.
|
||||
if vm.blockHeight > build.UpgradeClausHeight && errcode == exitcode.Ok && msg.Method == miner.Methods.SubmitWindowedPoSt {
|
||||
// Ok, we've checked the _method_, but we still need to check
|
||||
// the target actor. It would be nice if we could just look at
|
||||
// the trace, but I'm not sure if that's safe?
|
||||
if toActor, err := st.GetActor(msg.To); err != nil {
|
||||
// If the actor wasn't found, we probably deleted it or something. Move on.
|
||||
if !xerrors.Is(err, types.ErrActorNotFound) {
|
||||
// Otherwise, this should never fail and something is very wrong.
|
||||
return false, xerrors.Errorf("failed to lookup target actor: %w", err)
|
||||
}
|
||||
} else if builtin.IsStorageMinerActor(toActor.Code) {
|
||||
// Ok, this is a storage miner and we've processed a window post. Remove the burn.
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (vm *VM) ActorBalance(addr address.Address) (types.BigInt, aerrors.ActorError) {
|
||||
act, err := vm.cstate.GetActor(addr)
|
||||
if err != nil {
|
||||
@@ -602,6 +638,8 @@ func (vm *VM) ActorBalance(addr address.Address) (types.BigInt, aerrors.ActorErr
|
||||
return act.Balance, nil
|
||||
}
|
||||
|
||||
type vmFlushKey struct{}
|
||||
|
||||
func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
_, span := trace.StartSpan(ctx, "vm.Flush")
|
||||
defer span.End()
|
||||
@@ -614,7 +652,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
|
||||
return cid.Undef, xerrors.Errorf("flushing vm: %w", err)
|
||||
}
|
||||
|
||||
if err := Copy(ctx, from, to, root); err != nil {
|
||||
if err := Copy(context.WithValue(ctx, vmFlushKey{}, true), from, to, root); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("copying tree: %w", err)
|
||||
}
|
||||
|
||||
@@ -671,21 +709,48 @@ func linksForObj(blk block.Block, cb func(cid.Cid)) error {
|
||||
func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) error {
|
||||
ctx, span := trace.StartSpan(ctx, "vm.Copy") // nolint
|
||||
defer span.End()
|
||||
start := time.Now()
|
||||
|
||||
var numBlocks int
|
||||
var totalCopySize int
|
||||
|
||||
var batch []block.Block
|
||||
const batchSize = 128
|
||||
const bufCount = 3
|
||||
freeBufs := make(chan []block.Block, bufCount)
|
||||
toFlush := make(chan []block.Block, bufCount)
|
||||
for i := 0; i < bufCount; i++ {
|
||||
freeBufs <- make([]block.Block, 0, batchSize)
|
||||
}
|
||||
|
||||
errFlushChan := make(chan error)
|
||||
|
||||
go func() {
|
||||
for b := range toFlush {
|
||||
if err := to.PutMany(b); err != nil {
|
||||
close(freeBufs)
|
||||
errFlushChan <- xerrors.Errorf("batch put in copy: %w", err)
|
||||
return
|
||||
}
|
||||
freeBufs <- b[:0]
|
||||
}
|
||||
close(errFlushChan)
|
||||
close(freeBufs)
|
||||
}()
|
||||
|
||||
var batch = <-freeBufs
|
||||
batchCp := func(blk block.Block) error {
|
||||
numBlocks++
|
||||
totalCopySize += len(blk.RawData())
|
||||
|
||||
batch = append(batch, blk)
|
||||
if len(batch) > 100 {
|
||||
if err := to.PutMany(batch); err != nil {
|
||||
return xerrors.Errorf("batch put in copy: %w", err)
|
||||
|
||||
if len(batch) >= batchSize {
|
||||
toFlush <- batch
|
||||
var ok bool
|
||||
batch, ok = <-freeBufs
|
||||
if !ok {
|
||||
return <-errFlushChan
|
||||
}
|
||||
batch = batch[:0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -695,15 +760,22 @@ func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) err
|
||||
}
|
||||
|
||||
if len(batch) > 0 {
|
||||
if err := to.PutMany(batch); err != nil {
|
||||
return xerrors.Errorf("batch put in copy: %w", err)
|
||||
}
|
||||
toFlush <- batch
|
||||
}
|
||||
close(toFlush) // close the toFlush triggering the loop to end
|
||||
err := <-errFlushChan // get error out or get nil if it was closed
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
span.AddAttributes(
|
||||
trace.Int64Attribute("numBlocks", int64(numBlocks)),
|
||||
trace.Int64Attribute("copySize", int64(totalCopySize)),
|
||||
)
|
||||
if yes, ok := ctx.Value(vmFlushKey{}).(bool); yes && ok {
|
||||
took := metrics.SinceInMilliseconds(start)
|
||||
stats.Record(ctx, metrics.VMFlushCopyCount.M(int64(numBlocks)), metrics.VMFlushCopyDuration.M(took))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+23
-14
@@ -6,18 +6,16 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures
|
||||
)
|
||||
|
||||
var log = logging.Logger("wallet")
|
||||
@@ -270,7 +268,7 @@ func (w *LocalWallet) WalletHas(ctx context.Context, addr address.Address) (bool
|
||||
return k != nil, nil
|
||||
}
|
||||
|
||||
func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) error {
|
||||
func (w *LocalWallet) walletDelete(ctx context.Context, addr address.Address) error {
|
||||
k, err := w.findKey(addr)
|
||||
|
||||
if err != nil {
|
||||
@@ -305,18 +303,29 @@ func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) er
|
||||
|
||||
delete(w.keys, addr)
|
||||
|
||||
def, err := w.GetDefault()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting default address: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if def == addr {
|
||||
err = w.SetDefault(address.Undef)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("unsetting default address: %w", err)
|
||||
func (w *LocalWallet) deleteDefault() {
|
||||
w.lk.Lock()
|
||||
defer w.lk.Unlock()
|
||||
if err := w.keystore.Delete(KDefault); err != nil {
|
||||
if !xerrors.Is(err, types.ErrKeyInfoNotFound) {
|
||||
log.Warnf("failed to unregister current default key: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) error {
|
||||
if err := w.walletDelete(ctx, addr); err != nil {
|
||||
return xerrors.Errorf("wallet delete: %w", err)
|
||||
}
|
||||
|
||||
if def, err := w.GetDefault(); err == nil {
|
||||
if def == addr {
|
||||
w.deleteDefault()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+26
-7
@@ -3,6 +3,7 @@ package cli
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -465,6 +466,9 @@ var chainInspectUsage = &cli.Command{
|
||||
|
||||
code, err := lookupActorCode(m.Message.To)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1246,14 +1250,19 @@ var chainDecodeCmd = &cli.Command{
|
||||
}
|
||||
|
||||
var chainDecodeParamsCmd = &cli.Command{
|
||||
Name: "params",
|
||||
Usage: "Decode message params",
|
||||
Name: "params",
|
||||
Usage: "Decode message params",
|
||||
ArgsUsage: "[toAddr method params]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "tipset",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "encoding",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
ArgsUsage: "[toAddr method hexParams]",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
@@ -1276,11 +1285,21 @@ var chainDecodeParamsCmd = &cli.Command{
|
||||
return xerrors.Errorf("parsing method id: %w", err)
|
||||
}
|
||||
|
||||
params, err := hex.DecodeString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing hex params: %w", err)
|
||||
var params []byte
|
||||
switch cctx.String("encoding") {
|
||||
case "base64":
|
||||
params, err = base64.StdEncoding.DecodeString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding base64 value: %w", err)
|
||||
}
|
||||
case "hex":
|
||||
params, err = hex.DecodeString(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding hex value: %w", err)
|
||||
}
|
||||
default:
|
||||
return xerrors.Errorf("unrecognized encoding: %s", cctx.String("encoding"))
|
||||
}
|
||||
|
||||
ts, err := LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+85
-18
@@ -326,9 +326,9 @@ var clientDealCmd = &cli.Command{
|
||||
Value: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "verified-deal",
|
||||
Usage: "indicate that the deal counts towards verified client total",
|
||||
Value: false,
|
||||
Name: "verified-deal",
|
||||
Usage: "indicate that the deal counts towards verified client total",
|
||||
DefaultText: "true if client is verified, false otherwise",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "provider-collateral",
|
||||
@@ -655,19 +655,19 @@ uiLoop:
|
||||
state = "find"
|
||||
}
|
||||
case "find":
|
||||
asks, err := getAsks(ctx, api)
|
||||
asks, err := GetAsks(ctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ask := range asks {
|
||||
if ask.MinPieceSize > ds.PieceSize {
|
||||
if ask.Ask.MinPieceSize > ds.PieceSize {
|
||||
continue
|
||||
}
|
||||
if ask.MaxPieceSize < ds.PieceSize {
|
||||
if ask.Ask.MaxPieceSize < ds.PieceSize {
|
||||
continue
|
||||
}
|
||||
candidateAsks = append(candidateAsks, ask)
|
||||
candidateAsks = append(candidateAsks, ask.Ask)
|
||||
}
|
||||
|
||||
afmt.Printf("Found %d candidate asks\n", len(candidateAsks))
|
||||
@@ -1191,6 +1191,11 @@ var clientDealStatsCmd = &cli.Command{
|
||||
var clientListAsksCmd = &cli.Command{
|
||||
Name: "list-asks",
|
||||
Usage: "List asks for top miners",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "by-ping",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
@@ -1199,17 +1204,26 @@ var clientListAsksCmd = &cli.Command{
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
asks, err := getAsks(ctx, api)
|
||||
asks, err := GetAsks(ctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ask := range asks {
|
||||
fmt.Printf("%s: min:%s max:%s price:%s/GiB/Epoch verifiedPrice:%s/GiB/Epoch\n", ask.Miner,
|
||||
if cctx.Bool("by-ping") {
|
||||
sort.Slice(asks, func(i, j int) bool {
|
||||
return asks[i].Ping < asks[j].Ping
|
||||
})
|
||||
}
|
||||
|
||||
for _, a := range asks {
|
||||
ask := a.Ask
|
||||
|
||||
fmt.Printf("%s: min:%s max:%s price:%s/GiB/Epoch verifiedPrice:%s/GiB/Epoch ping:%s\n", ask.Miner,
|
||||
types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))),
|
||||
types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))),
|
||||
types.FIL(ask.Price),
|
||||
types.FIL(ask.VerifiedPrice),
|
||||
a.Ping,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1217,7 +1231,12 @@ var clientListAsksCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func getAsks(ctx context.Context, api lapi.FullNode) ([]*storagemarket.StorageAsk, error) {
|
||||
type QueriedAsk struct {
|
||||
Ask *storagemarket.StorageAsk
|
||||
Ping time.Duration
|
||||
}
|
||||
|
||||
func GetAsks(ctx context.Context, api lapi.FullNode) ([]QueriedAsk, error) {
|
||||
color.Blue(".. getting miner list")
|
||||
miners, err := api.StateListMiners(ctx, types.EmptyTSK)
|
||||
if err != nil {
|
||||
@@ -1272,7 +1291,7 @@ loop:
|
||||
|
||||
color.Blue(".. querying asks")
|
||||
|
||||
var asks []*storagemarket.StorageAsk
|
||||
var asks []QueriedAsk
|
||||
var queried, got int64
|
||||
|
||||
done = make(chan struct{})
|
||||
@@ -1308,9 +1327,19 @@ loop:
|
||||
return
|
||||
}
|
||||
|
||||
rt := time.Now()
|
||||
|
||||
_, err = api.ClientQueryAsk(ctx, *mi.PeerId, miner)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
atomic.AddInt64(&got, 1)
|
||||
lk.Lock()
|
||||
asks = append(asks, ask)
|
||||
asks = append(asks, QueriedAsk{
|
||||
Ask: ask,
|
||||
Ping: time.Now().Sub(rt),
|
||||
})
|
||||
lk.Unlock()
|
||||
}(miner)
|
||||
}
|
||||
@@ -1328,7 +1357,7 @@ loop2:
|
||||
fmt.Printf("\r* Queried %d asks, got %d responses\n", atomic.LoadInt64(&queried), atomic.LoadInt64(&got))
|
||||
|
||||
sort.Slice(asks, func(i, j int) bool {
|
||||
return asks[i].Price.LessThan(asks[j].Price)
|
||||
return asks[i].Ask.Price.LessThan(asks[j].Ask.Price)
|
||||
})
|
||||
|
||||
return asks, nil
|
||||
@@ -1400,6 +1429,7 @@ var clientQueryAskCmd = &cli.Command{
|
||||
afmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price))
|
||||
afmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.VerifiedPrice))
|
||||
afmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))))
|
||||
afmt.Printf("Min Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))))
|
||||
|
||||
size := cctx.Int64("size")
|
||||
if size == 0 {
|
||||
@@ -1495,7 +1525,7 @@ var clientListDeals = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, cctx.Bool("verbose"), cctx.Bool("color"), showFailed)
|
||||
return outputStorageDeals(ctx, cctx.App.Writer, api, localDeals, verbose, color, showFailed)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1537,7 +1567,7 @@ func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode,
|
||||
|
||||
if verbose {
|
||||
w := tabwriter.NewWriter(out, 2, 4, 2, ' ', 0)
|
||||
fmt.Fprintf(w, "Created\tDealCid\tDealId\tProvider\tState\tOn Chain?\tSlashed?\tPieceCID\tSize\tPrice\tDuration\tVerified\tMessage\n")
|
||||
fmt.Fprintf(w, "Created\tDealCid\tDealId\tProvider\tState\tOn Chain?\tSlashed?\tPieceCID\tSize\tPrice\tDuration\tTransferChannelID\tTransferStatus\tVerified\tMessage\n")
|
||||
for _, d := range deals {
|
||||
onChain := "N"
|
||||
if d.OnChainDealState.SectorStartEpoch != -1 {
|
||||
@@ -1550,7 +1580,37 @@ func outputStorageDeals(ctx context.Context, out io.Writer, full lapi.FullNode,
|
||||
}
|
||||
|
||||
price := types.FIL(types.BigMul(d.LocalDeal.PricePerEpoch, types.NewInt(d.LocalDeal.Duration)))
|
||||
fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%v\t%s\n", d.LocalDeal.CreationTime.Format(time.Stamp), d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, dealStateString(color, d.LocalDeal.State), onChain, slashed, d.LocalDeal.PieceCID, types.SizeStr(types.NewInt(d.LocalDeal.Size)), price, d.LocalDeal.Duration, d.LocalDeal.Verified, d.LocalDeal.Message)
|
||||
transferChannelID := ""
|
||||
if d.LocalDeal.TransferChannelID != nil {
|
||||
transferChannelID = d.LocalDeal.TransferChannelID.String()
|
||||
}
|
||||
transferStatus := ""
|
||||
if d.LocalDeal.DataTransfer != nil {
|
||||
transferStatus = datatransfer.Statuses[d.LocalDeal.DataTransfer.Status]
|
||||
// TODO: Include the transferred percentage once this bug is fixed:
|
||||
// https://github.com/ipfs/go-graphsync/issues/126
|
||||
//fmt.Printf("transferred: %d / size: %d\n", d.LocalDeal.DataTransfer.Transferred, d.LocalDeal.Size)
|
||||
//if d.LocalDeal.Size > 0 {
|
||||
// pct := (100 * d.LocalDeal.DataTransfer.Transferred) / d.LocalDeal.Size
|
||||
// transferPct = fmt.Sprintf("%d%%", pct)
|
||||
//}
|
||||
}
|
||||
fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t%v\t%s\n",
|
||||
d.LocalDeal.CreationTime.Format(time.Stamp),
|
||||
d.LocalDeal.ProposalCid,
|
||||
d.LocalDeal.DealID,
|
||||
d.LocalDeal.Provider,
|
||||
dealStateString(color, d.LocalDeal.State),
|
||||
onChain,
|
||||
slashed,
|
||||
d.LocalDeal.PieceCID,
|
||||
types.SizeStr(types.NewInt(d.LocalDeal.Size)),
|
||||
price,
|
||||
d.LocalDeal.Duration,
|
||||
transferChannelID,
|
||||
transferStatus,
|
||||
d.LocalDeal.Verified,
|
||||
d.LocalDeal.Message)
|
||||
}
|
||||
return w.Flush()
|
||||
}
|
||||
@@ -1825,6 +1885,11 @@ var clientCancelTransfer = &cli.Command{
|
||||
Usage: "specify only transfers where peer is/is not initiator",
|
||||
Value: true,
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "cancel-timeout",
|
||||
Usage: "time to wait for cancel to be sent to storage provider",
|
||||
Value: 5 * time.Second,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
@@ -1868,7 +1933,9 @@ var clientCancelTransfer = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
return api.ClientCancelDataTransfer(ctx, transferID, other, initiator)
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, cctx.Duration("cancel-timeout"))
|
||||
defer cancel()
|
||||
return api.ClientCancelDataTransfer(timeoutCtx, transferID, other, initiator)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+44
-4
@@ -49,6 +49,14 @@ var mpoolPending = &cli.Command{
|
||||
Name: "cids",
|
||||
Usage: "only print cids of messages in output",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "to",
|
||||
Usage: "return messages to a given address",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "from",
|
||||
Usage: "return messages from a given address",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
@@ -59,6 +67,23 @@ var mpoolPending = &cli.Command{
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var toa, froma address.Address
|
||||
if tos := cctx.String("to"); tos != "" {
|
||||
a, err := address.NewFromString(tos)
|
||||
if err != nil {
|
||||
return fmt.Errorf("given 'to' address %q was invalid: %w", tos, err)
|
||||
}
|
||||
toa = a
|
||||
}
|
||||
|
||||
if froms := cctx.String("from"); froms != "" {
|
||||
a, err := address.NewFromString(froms)
|
||||
if err != nil {
|
||||
return fmt.Errorf("given 'from' address %q was invalid: %w", froms, err)
|
||||
}
|
||||
froma = a
|
||||
}
|
||||
|
||||
var filter map[address.Address]struct{}
|
||||
if cctx.Bool("local") {
|
||||
filter = map[address.Address]struct{}{}
|
||||
@@ -85,6 +110,13 @@ var mpoolPending = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
if toa != address.Undef && msg.Message.To != toa {
|
||||
continue
|
||||
}
|
||||
if froma != address.Undef && msg.Message.From != froma {
|
||||
continue
|
||||
}
|
||||
|
||||
if cctx.Bool("cids") {
|
||||
fmt.Println(msg.Cid())
|
||||
} else {
|
||||
@@ -233,6 +265,7 @@ var mpoolStat = &cli.Command{
|
||||
addr string
|
||||
past, cur, future uint64
|
||||
belowCurr, belowPast uint64
|
||||
gasLimit big.Int
|
||||
}
|
||||
|
||||
buckets := map[address.Address]*statBucket{}
|
||||
@@ -274,6 +307,7 @@ var mpoolStat = &cli.Command{
|
||||
|
||||
var s mpStat
|
||||
s.addr = a.String()
|
||||
s.gasLimit = big.Zero()
|
||||
|
||||
for _, m := range bkt.msgs {
|
||||
if m.Message.Nonce < act.Nonce {
|
||||
@@ -290,6 +324,8 @@ var mpoolStat = &cli.Command{
|
||||
if m.Message.GasFeeCap.LessThan(minBF) {
|
||||
s.belowPast++
|
||||
}
|
||||
|
||||
s.gasLimit = big.Add(s.gasLimit, types.NewInt(uint64(m.Message.GasLimit)))
|
||||
}
|
||||
|
||||
out = append(out, s)
|
||||
@@ -300,6 +336,7 @@ var mpoolStat = &cli.Command{
|
||||
})
|
||||
|
||||
var total mpStat
|
||||
total.gasLimit = big.Zero()
|
||||
|
||||
for _, stat := range out {
|
||||
total.past += stat.past
|
||||
@@ -307,12 +344,13 @@ var mpoolStat = &cli.Command{
|
||||
total.future += stat.future
|
||||
total.belowCurr += stat.belowCurr
|
||||
total.belowPast += stat.belowPast
|
||||
total.gasLimit = big.Add(total.gasLimit, stat.gasLimit)
|
||||
|
||||
fmt.Printf("%s: Nonce past: %d, cur: %d, future: %d; FeeCap cur: %d, min-%d: %d \n", stat.addr, stat.past, stat.cur, stat.future, stat.belowCurr, cctx.Int("basefee-lookback"), stat.belowPast)
|
||||
fmt.Printf("%s: Nonce past: %d, cur: %d, future: %d; FeeCap cur: %d, min-%d: %d, gasLimit: %s\n", stat.addr, stat.past, stat.cur, stat.future, stat.belowCurr, cctx.Int("basefee-lookback"), stat.belowPast, stat.gasLimit)
|
||||
}
|
||||
|
||||
fmt.Println("-----")
|
||||
fmt.Printf("total: Nonce past: %d, cur: %d, future: %d; FeeCap cur: %d, min-%d: %d \n", total.past, total.cur, total.future, total.belowCurr, cctx.Int("basefee-lookback"), total.belowPast)
|
||||
fmt.Printf("total: Nonce past: %d, cur: %d, future: %d; FeeCap cur: %d, min-%d: %d, gasLimit: %s\n", total.past, total.cur, total.future, total.belowCurr, cctx.Int("basefee-lookback"), total.belowPast, total.gasLimit)
|
||||
|
||||
return nil
|
||||
},
|
||||
@@ -440,9 +478,11 @@ var mpoolReplaceCmd = &cli.Command{
|
||||
return abi.TokenAmount(config.DefaultDefaultMaxFee), nil
|
||||
}
|
||||
|
||||
messagepool.CapGasFee(mff, &msg, mss.Get().MaxFee)
|
||||
messagepool.CapGasFee(mff, &msg, mss)
|
||||
} else {
|
||||
msg.GasLimit = cctx.Int64("gas-limit")
|
||||
if cctx.IsSet("gas-limit") {
|
||||
msg.GasLimit = cctx.Int64("gas-limit")
|
||||
}
|
||||
msg.GasPremium, err = types.BigFromString(cctx.String("gas-premium"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing gas-premium: %w", err)
|
||||
|
||||
+1
-1
@@ -1178,7 +1178,7 @@ var msigLockProposeCmd = &cli.Command{
|
||||
params, actErr := actors.SerializeParams(&msig2.LockBalanceParams{
|
||||
StartEpoch: abi.ChainEpoch(start),
|
||||
UnlockDuration: abi.ChainEpoch(duration),
|
||||
Amount: abi.NewTokenAmount(amount.Int64()),
|
||||
Amount: big.Int(amount),
|
||||
})
|
||||
|
||||
if actErr != nil {
|
||||
|
||||
+201
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
atypes "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
)
|
||||
@@ -34,6 +35,7 @@ var netCmd = &cli.Command{
|
||||
netScores,
|
||||
NetReachability,
|
||||
NetBandwidthCmd,
|
||||
NetBlockCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -375,3 +377,202 @@ var NetBandwidthCmd = &cli.Command{
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockCmd = &cli.Command{
|
||||
Name: "block",
|
||||
Usage: "Manage network connection gating rules",
|
||||
Subcommands: []*cli.Command{
|
||||
NetBlockAddCmd,
|
||||
NetBlockRemoveCmd,
|
||||
NetBlockListCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockAddCmd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "Add connection gating rules",
|
||||
Subcommands: []*cli.Command{
|
||||
NetBlockAddPeer,
|
||||
NetBlockAddIP,
|
||||
NetBlockAddSubnet,
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockAddPeer = &cli.Command{
|
||||
Name: "peer",
|
||||
Usage: "Block a peer",
|
||||
ArgsUsage: "<Peer> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var peers []peer.ID
|
||||
for _, s := range cctx.Args().Slice() {
|
||||
p, err := peer.Decode(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
peers = append(peers, p)
|
||||
}
|
||||
|
||||
return api.NetBlockAdd(ctx, atypes.NetBlockList{Peers: peers})
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockAddIP = &cli.Command{
|
||||
Name: "ip",
|
||||
Usage: "Block an IP address",
|
||||
ArgsUsage: "<IP> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
return api.NetBlockAdd(ctx, atypes.NetBlockList{IPAddrs: cctx.Args().Slice()})
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockAddSubnet = &cli.Command{
|
||||
Name: "subnet",
|
||||
Usage: "Block an IP subnet",
|
||||
ArgsUsage: "<CIDR> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
return api.NetBlockAdd(ctx, atypes.NetBlockList{IPSubnets: cctx.Args().Slice()})
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockRemoveCmd = &cli.Command{
|
||||
Name: "remove",
|
||||
Usage: "Remove connection gating rules",
|
||||
Subcommands: []*cli.Command{
|
||||
NetBlockRemovePeer,
|
||||
NetBlockRemoveIP,
|
||||
NetBlockRemoveSubnet,
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockRemovePeer = &cli.Command{
|
||||
Name: "peer",
|
||||
Usage: "Unblock a peer",
|
||||
ArgsUsage: "<Peer> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var peers []peer.ID
|
||||
for _, s := range cctx.Args().Slice() {
|
||||
p, err := peer.Decode(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
peers = append(peers, p)
|
||||
}
|
||||
|
||||
return api.NetBlockRemove(ctx, atypes.NetBlockList{Peers: peers})
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockRemoveIP = &cli.Command{
|
||||
Name: "ip",
|
||||
Usage: "Unblock an IP address",
|
||||
ArgsUsage: "<IP> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
return api.NetBlockRemove(ctx, atypes.NetBlockList{IPAddrs: cctx.Args().Slice()})
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockRemoveSubnet = &cli.Command{
|
||||
Name: "subnet",
|
||||
Usage: "Unblock an IP subnet",
|
||||
ArgsUsage: "<CIDR> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
return api.NetBlockRemove(ctx, atypes.NetBlockList{IPSubnets: cctx.Args().Slice()})
|
||||
},
|
||||
}
|
||||
|
||||
var NetBlockListCmd = &cli.Command{
|
||||
Name: "list",
|
||||
Usage: "list connection gating rules",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
acl, err := api.NetBlockList(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(acl.Peers) != 0 {
|
||||
sort.Slice(acl.Peers, func(i, j int) bool {
|
||||
return strings.Compare(string(acl.Peers[i]), string(acl.Peers[j])) > 0
|
||||
})
|
||||
|
||||
fmt.Println("Blocked Peers:")
|
||||
for _, p := range acl.Peers {
|
||||
fmt.Printf("\t%s\n", p)
|
||||
}
|
||||
}
|
||||
|
||||
if len(acl.IPAddrs) != 0 {
|
||||
sort.Slice(acl.IPAddrs, func(i, j int) bool {
|
||||
return strings.Compare(acl.IPAddrs[i], acl.IPAddrs[j]) < 0
|
||||
})
|
||||
|
||||
fmt.Println("Blocked IPs:")
|
||||
for _, a := range acl.IPAddrs {
|
||||
fmt.Printf("\t%s\n", a)
|
||||
}
|
||||
}
|
||||
|
||||
if len(acl.IPSubnets) != 0 {
|
||||
sort.Slice(acl.IPSubnets, func(i, j int) bool {
|
||||
return strings.Compare(acl.IPSubnets[i], acl.IPSubnets[j]) < 0
|
||||
})
|
||||
|
||||
fmt.Println("Blocked Subnets:")
|
||||
for _, n := range acl.IPSubnets {
|
||||
fmt.Printf("\t%s\n", n)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+4
-4
@@ -43,10 +43,10 @@ var sendCmd = &cli.Command{
|
||||
Usage: "specify gas limit",
|
||||
Value: 0,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
&cli.Uint64Flag{
|
||||
Name: "nonce",
|
||||
Usage: "specify the nonce to use",
|
||||
Value: -1,
|
||||
Value: 0,
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "method",
|
||||
@@ -143,8 +143,8 @@ var sendCmd = &cli.Command{
|
||||
Params: params,
|
||||
}
|
||||
|
||||
if cctx.Int64("nonce") > 0 {
|
||||
msg.Nonce = uint64(cctx.Int64("nonce"))
|
||||
if cctx.IsSet("nonce") {
|
||||
msg.Nonce = cctx.Uint64("nonce")
|
||||
sm, err := api.WalletSignMessage(ctx, fromAddr, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+39
-1
@@ -72,6 +72,7 @@ var stateCmd = &cli.Command{
|
||||
stateMinerInfo,
|
||||
stateMarketCmd,
|
||||
stateExecTraceCmd,
|
||||
stateNtwkVersionCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ var stateMinerInfo = &cli.Command{
|
||||
}
|
||||
|
||||
fmt.Printf("PeerID:\t%s\n", mi.PeerId)
|
||||
fmt.Printf("Multiaddrs: \t")
|
||||
fmt.Printf("Multiaddrs:\t")
|
||||
for _, addr := range mi.Multiaddrs {
|
||||
a, err := multiaddr.NewMultiaddrBytes(addr)
|
||||
if err != nil {
|
||||
@@ -127,6 +128,8 @@ var stateMinerInfo = &cli.Command{
|
||||
}
|
||||
fmt.Printf("%s ", a)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Printf("Consensus Fault End:\t%d\n", mi.ConsensusFaultElapsed)
|
||||
|
||||
fmt.Printf("SectorSize:\t%s (%d)\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))), mi.SectorSize)
|
||||
pow, err := api.StateMinerPower(ctx, addr, ts.Key())
|
||||
@@ -1757,6 +1760,9 @@ var stateSectorCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if si == nil {
|
||||
return xerrors.Errorf("sector %d for miner %s not found", sid, maddr)
|
||||
}
|
||||
|
||||
fmt.Println("SectorNumber: ", si.SectorNumber)
|
||||
fmt.Println("SealProof: ", si.SealProof)
|
||||
@@ -1830,3 +1836,35 @@ var stateMarketBalanceCmd = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var stateNtwkVersionCmd = &cli.Command{
|
||||
Name: "network-version",
|
||||
Usage: "Returns the network version",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Present() {
|
||||
return ShowHelp(cctx, fmt.Errorf("doesn't expect any arguments"))
|
||||
}
|
||||
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
ts, err := LoadTipSet(ctx, cctx, api)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nv, err := api.StateNetworkVersion(ctx, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Network Version: %d\n", nv)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+5
-4
@@ -43,13 +43,14 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
|
||||
require.Regexp(t, regexp.MustCompile("Ask:"), out)
|
||||
|
||||
// Create a deal (non-interactive)
|
||||
// client deal <cid> <miner addr> 1000000attofil <duration>
|
||||
// client deal --start-epoch=<start epoch> <cid> <miner addr> 1000000attofil <duration>
|
||||
res, _, err := test.CreateClientFile(ctx, clientNode, 1)
|
||||
require.NoError(t, err)
|
||||
startEpoch := fmt.Sprintf("--start-epoch=%d", 2<<12)
|
||||
dataCid := res.Root
|
||||
price := "1000000attofil"
|
||||
duration := fmt.Sprintf("%d", build.MinDealDuration)
|
||||
out = clientCLI.RunCmd("client", "deal", dataCid.String(), minerAddr.String(), price, duration)
|
||||
out = clientCLI.RunCmd("client", "deal", startEpoch, dataCid.String(), minerAddr.String(), price, duration)
|
||||
fmt.Println("client deal", out)
|
||||
|
||||
// Create a deal (interactive)
|
||||
@@ -82,7 +83,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
|
||||
fmt.Println("list-deals:\n", out)
|
||||
|
||||
lines := strings.Split(out, "\n")
|
||||
require.Len(t, lines, 2)
|
||||
require.GreaterOrEqual(t, len(lines), 2)
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
parts := re.Split(lines[1], -1)
|
||||
if len(parts) < 4 {
|
||||
@@ -111,7 +112,7 @@ func dealComplete(t *testing.T, dealStatus string) bool {
|
||||
switch dealStatus {
|
||||
case "StorageDealFailing", "StorageDealError":
|
||||
t.Fatal(xerrors.Errorf("Storage deal failed with status: " + dealStatus))
|
||||
case "StorageDealStaged", "StorageDealSealing", "StorageDealActive", "StorageDealExpired", "StorageDealSlashed":
|
||||
case "StorageDealStaged", "StorageDealAwaitingPreCommit", "StorageDealSealing", "StorageDealActive", "StorageDealExpired", "StorageDealSlashed":
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Dura
|
||||
// Start mining blocks
|
||||
bm := test.NewBlockMiner(ctx, t, miner, blocktime)
|
||||
bm.MineBlocks()
|
||||
t.Cleanup(bm.Stop)
|
||||
|
||||
// Get the full node's wallet address
|
||||
fullAddr, err := full.WalletDefaultAddress(ctx)
|
||||
@@ -67,6 +68,7 @@ func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Dur
|
||||
// Start mining blocks
|
||||
bm := test.NewBlockMiner(ctx, t, miner, blocktime)
|
||||
bm.MineBlocks()
|
||||
t.Cleanup(bm.Stop)
|
||||
|
||||
// Send some funds to register the second node
|
||||
fullNodeAddr2, err := fullNode2.WalletNew(ctx, types.KTSecp256k1)
|
||||
|
||||
+4
-21
@@ -16,11 +16,8 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
types "github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/tablewriter"
|
||||
)
|
||||
|
||||
@@ -585,27 +582,13 @@ var walletMarketWithdraw = &cli.Command{
|
||||
return xerrors.Errorf("zero unlocked funds available to withdraw")
|
||||
}
|
||||
|
||||
params, err := actors.SerializeParams(&market.WithdrawBalanceParams{
|
||||
ProviderOrClientAddress: addr,
|
||||
Amount: amt,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("serializing params: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Submitting WithdrawBalance message for amount %s for address %s\n", types.FIL(amt), from.String())
|
||||
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||
To: builtin.StorageMarketActorAddr,
|
||||
From: from,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin.MethodsMarket.WithdrawBalance,
|
||||
Params: params,
|
||||
}, nil)
|
||||
smsg, err := api.MarketWithdraw(ctx, from, addr, amt)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("submitting WithdrawBalance message: %w", err)
|
||||
return xerrors.Errorf("fund manager withdraw error: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("WithdrawBalance message cid: %s\n", smsg.Cid())
|
||||
fmt.Printf("WithdrawBalance message cid: %s\n", smsg)
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
@@ -60,7 +60,7 @@ type TipSetExec struct {
|
||||
|
||||
var importBenchCmd = &cli.Command{
|
||||
Name: "import",
|
||||
Usage: "benchmark chain import and validation",
|
||||
Usage: "Benchmark chain import and validation",
|
||||
Subcommands: []*cli.Command{
|
||||
importAnalyzeCmd,
|
||||
},
|
||||
@@ -263,6 +263,8 @@ var importBenchCmd = &cli.Command{
|
||||
|
||||
metadataDs := datastore.NewMapDatastore()
|
||||
cs := store.NewChainStore(bs, bs, metadataDs, vm.Syscalls(verifier), nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
stm := stmgr.NewStateManager(cs)
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
+117
-76
@@ -31,6 +31,7 @@ import (
|
||||
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
@@ -39,8 +40,10 @@ import (
|
||||
var log = logging.Logger("lotus-bench")
|
||||
|
||||
type BenchResults struct {
|
||||
SectorSize abi.SectorSize
|
||||
SectorSize abi.SectorSize
|
||||
SectorNumber int
|
||||
|
||||
SealingSum SealingResult
|
||||
SealingResults []SealingResult
|
||||
|
||||
PostGenerateCandidates time.Duration
|
||||
@@ -55,6 +58,26 @@ type BenchResults struct {
|
||||
VerifyWindowPostHot time.Duration
|
||||
}
|
||||
|
||||
func (bo *BenchResults) SumSealingTime() error {
|
||||
if len(bo.SealingResults) <= 0 {
|
||||
return xerrors.Errorf("BenchResults SealingResults len <= 0")
|
||||
}
|
||||
if len(bo.SealingResults) != bo.SectorNumber {
|
||||
return xerrors.Errorf("BenchResults SealingResults len(%d) != bo.SectorNumber(%d)", len(bo.SealingResults), bo.SectorNumber)
|
||||
}
|
||||
|
||||
for _, sealing := range bo.SealingResults {
|
||||
bo.SealingSum.AddPiece += sealing.AddPiece
|
||||
bo.SealingSum.PreCommit1 += sealing.PreCommit1
|
||||
bo.SealingSum.PreCommit2 += sealing.PreCommit2
|
||||
bo.SealingSum.Commit1 += sealing.Commit1
|
||||
bo.SealingSum.Commit2 += sealing.Commit2
|
||||
bo.SealingSum.Verify += sealing.Verify
|
||||
bo.SealingSum.Unseal += sealing.Unseal
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SealingResult struct {
|
||||
AddPiece time.Duration
|
||||
PreCommit1 time.Duration
|
||||
@@ -94,12 +117,13 @@ func main() {
|
||||
}
|
||||
|
||||
var sealBenchCmd = &cli.Command{
|
||||
Name: "sealing",
|
||||
Name: "sealing",
|
||||
Usage: "Benchmark seal and winning post and window post",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "storage-dir",
|
||||
Value: "~/.lotus-bench",
|
||||
Usage: "Path to the storage directory that will store sectors long term",
|
||||
Usage: "path to the storage directory that will store sectors long term",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "sector-size",
|
||||
@@ -131,16 +155,22 @@ var sealBenchCmd = &cli.Command{
|
||||
Name: "skip-unseal",
|
||||
Usage: "skip the unseal portion of the benchmark",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ticket-preimage",
|
||||
Usage: "ticket random",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "save-commit2-input",
|
||||
Usage: "Save commit2 input to a file",
|
||||
Usage: "save commit2 input to a file",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "num-sectors",
|
||||
Usage: "select number of sectors to seal",
|
||||
Value: 1,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "parallel",
|
||||
Usage: "num run in parallel",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
@@ -211,17 +241,9 @@ var sealBenchCmd = &cli.Command{
|
||||
}
|
||||
sectorSize := abi.SectorSize(sectorSizeInt)
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(sectorSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := &ffiwrapper.Config{
|
||||
SealProofType: spt,
|
||||
}
|
||||
|
||||
// Only fetch parameters if actually needed
|
||||
if !c.Bool("skip-commit2") {
|
||||
skipc2 := c.Bool("skip-commit2")
|
||||
if !skipc2 {
|
||||
if err := paramfetch.GetParams(lcli.ReqContext(c), build.ParametersJSON(), uint64(sectorSize)); err != nil {
|
||||
return xerrors.Errorf("getting params: %w", err)
|
||||
}
|
||||
@@ -231,11 +253,13 @@ var sealBenchCmd = &cli.Command{
|
||||
Root: sbdir,
|
||||
}
|
||||
|
||||
sb, err := ffiwrapper.New(sbfs, cfg)
|
||||
sb, err := ffiwrapper.New(sbfs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sectorNumber := c.Int("num-sectors")
|
||||
|
||||
var sealTimings []SealingResult
|
||||
var sealedSectors []saproof2.SectorInfo
|
||||
|
||||
@@ -246,18 +270,11 @@ var sealBenchCmd = &cli.Command{
|
||||
PreCommit2: 1,
|
||||
Commit: 1,
|
||||
}
|
||||
sealTimings, sealedSectors, err = runSeals(sb, sbfs, c.Int("num-sectors"), parCfg, mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), c.Bool("skip-commit2"), c.Bool("skip-unseal"))
|
||||
sealTimings, sealedSectors, err = runSeals(sb, sbfs, sectorNumber, parCfg, mid, sectorSize, []byte(c.String("ticket-preimage")), c.String("save-commit2-input"), skipc2, c.Bool("skip-unseal"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to run seals: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
beforePost := time.Now()
|
||||
|
||||
var challenge [32]byte
|
||||
rand.Read(challenge[:])
|
||||
|
||||
if robench != "" {
|
||||
} else {
|
||||
// TODO: implement sbfs.List() and use that for all cases (preexisting sectorbuilder or not)
|
||||
|
||||
// TODO: this assumes we only ever benchmark a preseal
|
||||
@@ -290,12 +307,21 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
bo := BenchResults{
|
||||
SectorSize: sectorSize,
|
||||
SectorNumber: sectorNumber,
|
||||
SealingResults: sealTimings,
|
||||
}
|
||||
if err := bo.SumSealingTime(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.Bool("skip-commit2") {
|
||||
var challenge [32]byte
|
||||
rand.Read(challenge[:])
|
||||
|
||||
beforePost := time.Now()
|
||||
|
||||
if !skipc2 {
|
||||
log.Info("generating winning post candidates")
|
||||
wipt, err := spt.RegisteredWinningPoStProof()
|
||||
wipt, err := spt(sectorSize).RegisteredWinningPoStProof()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -428,21 +454,21 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
fmt.Println(string(data))
|
||||
} else {
|
||||
fmt.Printf("----\nresults (v27) (%d)\n", sectorSize)
|
||||
fmt.Printf("----\nresults (v28) SectorSize:(%d), SectorNumber:(%d)\n", sectorSize, sectorNumber)
|
||||
if robench == "" {
|
||||
fmt.Printf("seal: addPiece: %s (%s)\n", bo.SealingResults[0].AddPiece, bps(bo.SectorSize, bo.SealingResults[0].AddPiece)) // TODO: average across multiple sealings
|
||||
fmt.Printf("seal: preCommit phase 1: %s (%s)\n", bo.SealingResults[0].PreCommit1, bps(bo.SectorSize, bo.SealingResults[0].PreCommit1))
|
||||
fmt.Printf("seal: preCommit phase 2: %s (%s)\n", bo.SealingResults[0].PreCommit2, bps(bo.SectorSize, bo.SealingResults[0].PreCommit2))
|
||||
fmt.Printf("seal: commit phase 1: %s (%s)\n", bo.SealingResults[0].Commit1, bps(bo.SectorSize, bo.SealingResults[0].Commit1))
|
||||
fmt.Printf("seal: commit phase 2: %s (%s)\n", bo.SealingResults[0].Commit2, bps(bo.SectorSize, bo.SealingResults[0].Commit2))
|
||||
fmt.Printf("seal: verify: %s\n", bo.SealingResults[0].Verify)
|
||||
fmt.Printf("seal: addPiece: %s (%s)\n", bo.SealingSum.AddPiece, bps(bo.SectorSize, bo.SectorNumber, bo.SealingSum.AddPiece))
|
||||
fmt.Printf("seal: preCommit phase 1: %s (%s)\n", bo.SealingSum.PreCommit1, bps(bo.SectorSize, bo.SectorNumber, bo.SealingSum.PreCommit1))
|
||||
fmt.Printf("seal: preCommit phase 2: %s (%s)\n", bo.SealingSum.PreCommit2, bps(bo.SectorSize, bo.SectorNumber, bo.SealingSum.PreCommit2))
|
||||
fmt.Printf("seal: commit phase 1: %s (%s)\n", bo.SealingSum.Commit1, bps(bo.SectorSize, bo.SectorNumber, bo.SealingSum.Commit1))
|
||||
fmt.Printf("seal: commit phase 2: %s (%s)\n", bo.SealingSum.Commit2, bps(bo.SectorSize, bo.SectorNumber, bo.SealingSum.Commit2))
|
||||
fmt.Printf("seal: verify: %s\n", bo.SealingSum.Verify)
|
||||
if !c.Bool("skip-unseal") {
|
||||
fmt.Printf("unseal: %s (%s)\n", bo.SealingResults[0].Unseal, bps(bo.SectorSize, bo.SealingResults[0].Unseal))
|
||||
fmt.Printf("unseal: %s (%s)\n", bo.SealingSum.Unseal, bps(bo.SectorSize, bo.SectorNumber, bo.SealingSum.Unseal))
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
if !c.Bool("skip-commit2") {
|
||||
fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize*abi.SectorSize(len(bo.SealingResults)), bo.PostGenerateCandidates))
|
||||
if !skipc2 {
|
||||
fmt.Printf("generate candidates: %s (%s)\n", bo.PostGenerateCandidates, bps(bo.SectorSize, len(bo.SealingResults), bo.PostGenerateCandidates))
|
||||
fmt.Printf("compute winning post proof (cold): %s\n", bo.PostWinningProofCold)
|
||||
fmt.Printf("compute winning post proof (hot): %s\n", bo.PostWinningProofHot)
|
||||
fmt.Printf("verify winning post proof (cold): %s\n", bo.VerifyWinningPostCold)
|
||||
@@ -475,11 +501,13 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
if numSectors%par.PreCommit1 != 0 {
|
||||
return nil, nil, fmt.Errorf("parallelism factor must cleanly divide numSectors")
|
||||
}
|
||||
|
||||
for i := abi.SectorNumber(1); i <= abi.SectorNumber(numSectors); i++ {
|
||||
sid := abi.SectorID{
|
||||
Miner: mid,
|
||||
Number: i,
|
||||
for i := abi.SectorNumber(0); i < abi.SectorNumber(numSectors); i++ {
|
||||
sid := storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: mid,
|
||||
Number: i,
|
||||
},
|
||||
ProofType: spt(sectorSize),
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
@@ -494,7 +522,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
|
||||
pieces = append(pieces, pi)
|
||||
|
||||
sealTimings[i-1].AddPiece = time.Since(start)
|
||||
sealTimings[i].AddPiece = time.Since(start)
|
||||
}
|
||||
|
||||
sectorsPerWorker := numSectors / par.PreCommit1
|
||||
@@ -503,13 +531,15 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
for wid := 0; wid < par.PreCommit1; wid++ {
|
||||
go func(worker int) {
|
||||
sealerr := func() error {
|
||||
start := 1 + (worker * sectorsPerWorker)
|
||||
start := worker * sectorsPerWorker
|
||||
end := start + sectorsPerWorker
|
||||
for i := abi.SectorNumber(start); i < abi.SectorNumber(end); i++ {
|
||||
ix := int(i - 1)
|
||||
sid := abi.SectorID{
|
||||
Miner: mid,
|
||||
Number: i,
|
||||
sid := storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: mid,
|
||||
Number: i,
|
||||
},
|
||||
ProofType: spt(sectorSize),
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
@@ -518,8 +548,8 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
ticket := abi.SealRandomness(trand[:])
|
||||
|
||||
log.Infof("[%d] Running replication(1)...", i)
|
||||
pieces := []abi.PieceInfo{pieces[ix]}
|
||||
pc1o, err := sb.SealPreCommit1(context.TODO(), sid, ticket, pieces)
|
||||
piece := []abi.PieceInfo{pieces[i]}
|
||||
pc1o, err := sb.SealPreCommit1(context.TODO(), sid, ticket, piece)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("commit: %w", err)
|
||||
}
|
||||
@@ -537,8 +567,8 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
precommit2 := time.Now()
|
||||
<-preCommit2Sema
|
||||
|
||||
sealedSectors[ix] = saproof2.SectorInfo{
|
||||
SealProof: sb.SealProofType(),
|
||||
sealedSectors[i] = saproof2.SectorInfo{
|
||||
SealProof: sid.ProofType,
|
||||
SectorNumber: i,
|
||||
SealedCID: cids.Sealed,
|
||||
}
|
||||
@@ -551,7 +581,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
commitSema <- struct{}{}
|
||||
commitStart := time.Now()
|
||||
log.Infof("[%d] Generating PoRep for sector (1)", i)
|
||||
c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, pieces, cids)
|
||||
c1o, err := sb.SealCommit1(context.TODO(), sid, ticket, seed.Value, piece, cids)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -592,7 +622,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
svi := saproof2.SealVerifyInfo{
|
||||
SectorID: abi.SectorID{Miner: mid, Number: i},
|
||||
SealedCID: cids.Sealed,
|
||||
SealProof: sb.SealProofType(),
|
||||
SealProof: sid.ProofType,
|
||||
Proof: proof,
|
||||
DealIDs: nil,
|
||||
Randomness: ticket,
|
||||
@@ -614,7 +644,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
if !skipunseal {
|
||||
log.Infof("[%d] Unsealing sector", i)
|
||||
{
|
||||
p, done, err := sbfs.AcquireSector(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, storiface.FTUnsealed, storiface.FTNone, storiface.PathSealing)
|
||||
p, done, err := sbfs.AcquireSector(context.TODO(), sid, storiface.FTUnsealed, storiface.FTNone, storiface.PathSealing)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("acquire unsealed sector for removing: %w", err)
|
||||
}
|
||||
@@ -625,19 +655,19 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
}
|
||||
}
|
||||
|
||||
err := sb.UnsealPiece(context.TODO(), abi.SectorID{Miner: mid, Number: 1}, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed)
|
||||
err := sb.UnsealPiece(context.TODO(), sid, 0, abi.PaddedPieceSize(sectorSize).Unpadded(), ticket, cids.Unsealed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
unseal := time.Now()
|
||||
|
||||
sealTimings[ix].PreCommit1 = precommit1.Sub(start)
|
||||
sealTimings[ix].PreCommit2 = precommit2.Sub(pc2Start)
|
||||
sealTimings[ix].Commit1 = sealcommit1.Sub(commitStart)
|
||||
sealTimings[ix].Commit2 = sealcommit2.Sub(sealcommit1)
|
||||
sealTimings[ix].Verify = verifySeal.Sub(sealcommit2)
|
||||
sealTimings[ix].Unseal = unseal.Sub(verifySeal)
|
||||
sealTimings[i].PreCommit1 = precommit1.Sub(start)
|
||||
sealTimings[i].PreCommit2 = precommit2.Sub(pc2Start)
|
||||
sealTimings[i].Commit1 = sealcommit1.Sub(commitStart)
|
||||
sealTimings[i].Commit2 = sealcommit2.Sub(sealcommit1)
|
||||
sealTimings[i].Verify = verifySeal.Sub(sealcommit2)
|
||||
sealTimings[i].Unseal = unseal.Sub(verifySeal)
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
@@ -660,8 +690,9 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
|
||||
}
|
||||
|
||||
var proveCmd = &cli.Command{
|
||||
Name: "prove",
|
||||
Usage: "Benchmark a proof computation",
|
||||
Name: "prove",
|
||||
Usage: "Benchmark a proof computation",
|
||||
ArgsUsage: "[input.json]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "no-gpu",
|
||||
@@ -708,23 +739,23 @@ var proveCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(abi.SectorSize(c2in.SectorSize))
|
||||
sb, err := ffiwrapper.New(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := &ffiwrapper.Config{
|
||||
SealProofType: spt,
|
||||
}
|
||||
|
||||
sb, err := ffiwrapper.New(nil, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
ref := storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(c2in.SectorNum),
|
||||
},
|
||||
ProofType: spt(abi.SectorSize(c2in.SectorSize)),
|
||||
}
|
||||
|
||||
fmt.Printf("----\nstart proof computation\n")
|
||||
start := time.Now()
|
||||
|
||||
proof, err := sb.SealCommit2(context.TODO(), abi.SectorID{Miner: abi.ActorID(mid), Number: abi.SectorNumber(c2in.SectorNum)}, c2in.Phase1Out)
|
||||
proof, err := sb.SealCommit2(context.TODO(), ref, c2in.Phase1Out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -733,17 +764,27 @@ var proveCmd = &cli.Command{
|
||||
|
||||
fmt.Printf("proof: %x\n", proof)
|
||||
|
||||
fmt.Printf("----\nresults (v27) (%d)\n", c2in.SectorSize)
|
||||
fmt.Printf("----\nresults (v28) (%d)\n", c2in.SectorSize)
|
||||
dur := sealCommit2.Sub(start)
|
||||
|
||||
fmt.Printf("seal: commit phase 2: %s (%s)\n", dur, bps(abi.SectorSize(c2in.SectorSize), dur))
|
||||
fmt.Printf("seal: commit phase 2: %s (%s)\n", dur, bps(abi.SectorSize(c2in.SectorSize), 1, dur))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func bps(data abi.SectorSize, d time.Duration) string {
|
||||
bdata := new(big.Int).SetUint64(uint64(data))
|
||||
func bps(sectorSize abi.SectorSize, sectorNum int, d time.Duration) string {
|
||||
bdata := new(big.Int).SetUint64(uint64(sectorSize))
|
||||
bdata = bdata.Mul(bdata, big.NewInt(int64(sectorNum)))
|
||||
bdata = bdata.Mul(bdata, big.NewInt(time.Second.Nanoseconds()))
|
||||
bps := bdata.Div(bdata, big.NewInt(d.Nanoseconds()))
|
||||
return types.SizeStr(types.BigInt{Int: bps}) + "/s"
|
||||
}
|
||||
|
||||
func spt(ssize abi.SectorSize) abi.RegisteredSealProof {
|
||||
spt, err := miner.SealProofTypeFromSectorSize(ssize, build.NewestNetworkVersion)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return spt
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ var runCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("Remote version: %s", v.Version)
|
||||
log.Infof("Remote version: %s", v.Version)
|
||||
|
||||
from, err := address.NewFromString(cctx.String("from"))
|
||||
if err != nil {
|
||||
|
||||
@@ -67,6 +67,7 @@ type gatewayDepsAPI interface {
|
||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
|
||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error)
|
||||
}
|
||||
@@ -362,7 +363,13 @@ func (a *GatewayAPI) StateCirculatingSupply(ctx context.Context, tsk types.TipSe
|
||||
return types.BigInt{}, err
|
||||
}
|
||||
return a.api.StateCirculatingSupply(ctx, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) {
|
||||
if err := a.checkTipsetKey(ctx, tsk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.api.StateSectorGetInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
|
||||
|
||||
@@ -171,7 +171,11 @@ func TestDealFlow(t *testing.T) {
|
||||
nodes := startNodesWithFunds(ctx, t, blocktime, maxLookbackCap, maxStateWaitLookbackLimit)
|
||||
defer nodes.closer()
|
||||
|
||||
test.MakeDeal(t, ctx, 6, nodes.lite, nodes.miner, false, false)
|
||||
// For these tests where the block time is artificially short, just use
|
||||
// a deal start epoch that is guaranteed to be far enough in the future
|
||||
// so that the deal starts sealing in time
|
||||
dealStartEpoch := abi.ChainEpoch(2 << 12)
|
||||
test.MakeDeal(t, ctx, 6, nodes.lite, nodes.miner, false, false, dealStartEpoch)
|
||||
}
|
||||
|
||||
func TestCLIDealFlow(t *testing.T) {
|
||||
@@ -278,6 +282,7 @@ func startNodes(
|
||||
// Start mining blocks
|
||||
bm := test.NewBlockMiner(ctx, t, miner, blocktime)
|
||||
bm.MineBlocks()
|
||||
t.Cleanup(bm.Stop)
|
||||
|
||||
return &testNodes{lite: lite, full: full, miner: miner, closer: closer}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,10 @@ var runCmd = &cli.Command{
|
||||
Usage: "host address and port the api server will listen on",
|
||||
Value: "0.0.0.0:2346",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "api-max-req-size",
|
||||
Usage: "maximum API request size accepted by the JSON RPC server",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
log.Info("Starting lotus gateway")
|
||||
@@ -87,7 +91,11 @@ var runCmd = &cli.Command{
|
||||
|
||||
log.Info("Setting up API endpoint at " + address)
|
||||
|
||||
rpcServer := jsonrpc.NewServer()
|
||||
serverOptions := make([]jsonrpc.ServerOption, 0)
|
||||
if maxRequestSize := cctx.Int("api-max-req-size"); maxRequestSize != 0 {
|
||||
serverOptions = append(serverOptions, jsonrpc.WithMaxRequestSize(int64(maxRequestSize)))
|
||||
}
|
||||
rpcServer := jsonrpc.NewServer(serverOptions...)
|
||||
rpcServer.Register("Filecoin", metrics.MetricedGatewayAPI(NewGatewayAPI(api)))
|
||||
|
||||
mux.Handle("/rpc/v0", rpcServer)
|
||||
|
||||
@@ -22,6 +22,11 @@ func main() {
|
||||
Value: "bls",
|
||||
Usage: "specify key type to generate (bls or secp256k1)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "out",
|
||||
Aliases: []string{"o"},
|
||||
Usage: "specify key file name to generate",
|
||||
},
|
||||
}
|
||||
app.Action = func(cctx *cli.Context) error {
|
||||
memks := wallet.NewMemKeyStore()
|
||||
@@ -50,7 +55,11 @@ func main() {
|
||||
return err
|
||||
}
|
||||
|
||||
fi, err := os.Create(fmt.Sprintf("%s.key", kaddr))
|
||||
outFile := fmt.Sprintf("%s.key", kaddr)
|
||||
if cctx.IsSet("out") {
|
||||
outFile = fmt.Sprintf("%s.key", cctx.String("out"))
|
||||
}
|
||||
fi, err := os.Create(outFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
)
|
||||
|
||||
var infoCmd = &cli.Command{
|
||||
@@ -49,10 +51,22 @@ var infoCmd = &cli.Command{
|
||||
return xerrors.Errorf("getting info: %w", err)
|
||||
}
|
||||
|
||||
tt, err := api.TaskTypes(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting task types: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Hostname: %s\n", info.Hostname)
|
||||
fmt.Printf("CPUs: %d; GPUs: %v\n", info.Resources.CPUs, info.Resources.GPUs)
|
||||
fmt.Printf("RAM: %s; Swap: %s\n", types.SizeStr(types.NewInt(info.Resources.MemPhysical)), types.SizeStr(types.NewInt(info.Resources.MemSwap)))
|
||||
fmt.Printf("Reserved memory: %s\n", types.SizeStr(types.NewInt(info.Resources.MemReserved)))
|
||||
|
||||
fmt.Printf("Task types: ")
|
||||
for _, t := range ttList(tt) {
|
||||
fmt.Printf("%s ", t.Short())
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println()
|
||||
|
||||
paths, err := api.Paths(ctx)
|
||||
@@ -64,7 +78,6 @@ var infoCmd = &cli.Command{
|
||||
fmt.Printf("%s:\n", path.ID)
|
||||
fmt.Printf("\tWeight: %d; Use: ", path.Weight)
|
||||
if path.CanSeal || path.CanStore {
|
||||
fmt.Printf("Weight: %d; Use: ", path.Weight)
|
||||
if path.CanSeal {
|
||||
fmt.Print("Seal ")
|
||||
}
|
||||
@@ -81,3 +94,14 @@ var infoCmd = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func ttList(tt map[sealtasks.TaskType]struct{}) []sealtasks.TaskType {
|
||||
tasks := make([]sealtasks.TaskType, 0, len(tt))
|
||||
for taskType := range tt {
|
||||
tasks = append(tasks, taskType)
|
||||
}
|
||||
sort.Slice(tasks, func(i, j int) bool {
|
||||
return tasks[i].Less(tasks[j])
|
||||
})
|
||||
return tasks
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/lib/lotuslog"
|
||||
@@ -60,6 +59,7 @@ func main() {
|
||||
storageCmd,
|
||||
setCmd,
|
||||
waitQuietCmd,
|
||||
tasksCmd,
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
@@ -356,11 +356,6 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
|
||||
// Setup remote sector store
|
||||
spt, err := ffiwrapper.SealProofTypeFromSectorSize(ssize)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting proof type: %w", err)
|
||||
}
|
||||
|
||||
sminfo, err := lcli.GetAPIInfo(cctx, repo.StorageMiner)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("could not get api info: %w", err)
|
||||
@@ -368,13 +363,23 @@ var runCmd = &cli.Command{
|
||||
|
||||
remote := stores.NewRemote(localStore, nodeApi, sminfo.AuthHeader(), cctx.Int("parallel-fetch-limit"))
|
||||
|
||||
fh := &stores.FetchHandler{Local: localStore}
|
||||
remoteHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) {
|
||||
w.WriteHeader(401)
|
||||
_ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing admin permission"})
|
||||
return
|
||||
}
|
||||
|
||||
fh.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Create / expose the worker
|
||||
|
||||
wsts := statestore.New(namespace.Wrap(ds, modules.WorkerCallsPrefix))
|
||||
|
||||
workerApi := &worker{
|
||||
LocalWorker: sectorstorage.NewLocalWorker(sectorstorage.WorkerConfig{
|
||||
SealProof: spt,
|
||||
TaskTypes: taskTypes,
|
||||
NoSwap: cctx.Bool("no-swap"),
|
||||
}, remote, localStore, nodeApi, nodeApi, wsts),
|
||||
@@ -392,7 +397,7 @@ var runCmd = &cli.Command{
|
||||
|
||||
mux.Handle("/rpc/v0", rpcServer)
|
||||
mux.Handle("/rpc/streams/v0/push/{uuid}", readerHandler)
|
||||
mux.PathPrefix("/remote").HandlerFunc((&stores.FetchHandler{Local: localStore}).ServeHTTP)
|
||||
mux.PathPrefix("/remote").HandlerFunc(remoteHandler)
|
||||
mux.PathPrefix("/").Handler(http.DefaultServeMux) // pprof
|
||||
|
||||
ah := &auth.Handler{
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
)
|
||||
|
||||
var tasksCmd = &cli.Command{
|
||||
Name: "tasks",
|
||||
Usage: "Manage task processing",
|
||||
Subcommands: []*cli.Command{
|
||||
tasksEnableCmd,
|
||||
tasksDisableCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var allowSetting = map[sealtasks.TaskType]struct{}{
|
||||
sealtasks.TTAddPiece: {},
|
||||
sealtasks.TTPreCommit1: {},
|
||||
sealtasks.TTPreCommit2: {},
|
||||
sealtasks.TTCommit2: {},
|
||||
sealtasks.TTUnseal: {},
|
||||
}
|
||||
|
||||
var settableStr = func() string {
|
||||
var s []string
|
||||
for _, tt := range ttList(allowSetting) {
|
||||
s = append(s, tt.Short())
|
||||
}
|
||||
return strings.Join(s, "|")
|
||||
}()
|
||||
|
||||
var tasksEnableCmd = &cli.Command{
|
||||
Name: "enable",
|
||||
Usage: "Enable a task type",
|
||||
ArgsUsage: "[" + settableStr + "]",
|
||||
Action: taskAction(api.WorkerAPI.TaskEnable),
|
||||
}
|
||||
|
||||
var tasksDisableCmd = &cli.Command{
|
||||
Name: "disable",
|
||||
Usage: "Disable a task type",
|
||||
ArgsUsage: "[" + settableStr + "]",
|
||||
Action: taskAction(api.WorkerAPI.TaskDisable),
|
||||
}
|
||||
|
||||
func taskAction(tf func(a api.WorkerAPI, ctx context.Context, tt sealtasks.TaskType) error) func(cctx *cli.Context) error {
|
||||
return func(cctx *cli.Context) error {
|
||||
if cctx.NArg() != 1 {
|
||||
return xerrors.Errorf("expected 1 argument")
|
||||
}
|
||||
|
||||
var tt sealtasks.TaskType
|
||||
for taskType := range allowSetting {
|
||||
if taskType.Short() == cctx.Args().First() {
|
||||
tt = taskType
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if tt == "" {
|
||||
return xerrors.Errorf("unknown task type '%s'", cctx.Args().First())
|
||||
}
|
||||
|
||||
api, closer, err := lcli.GetWorkerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
return tf(api, ctx, tt)
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/urfave/cli/v2"
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
@@ -128,12 +129,12 @@ var preSealCmd = &cli.Command{
|
||||
}
|
||||
sectorSize := abi.SectorSize(sectorSizeInt)
|
||||
|
||||
rp, err := ffiwrapper.SealProofTypeFromSectorSize(sectorSize)
|
||||
spt, err := miner.SealProofTypeFromSectorSize(sectorSize, network.Version0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gm, key, err := seed.PreSeal(maddr, rp, abi.SectorNumber(c.Uint64("sector-offset")), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage")), k, c.Bool("fake-sectors"))
|
||||
gm, key, err := seed.PreSeal(maddr, spt, abi.SectorNumber(c.Uint64("sector-offset")), c.Int("num-sectors"), sbroot, []byte(c.String("ticket-preimage")), k, c.Bool("fake-sectors"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+15
-17
@@ -19,9 +19,10 @@ import (
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-commp-utils/zerocomm"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/zerocomm"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
|
||||
@@ -42,10 +43,6 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cfg := &ffiwrapper.Config{
|
||||
SealProofType: spt,
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(sbroot, 0775); err != nil { //nolint:gosec
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -56,7 +53,7 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
Root: sbroot,
|
||||
}
|
||||
|
||||
sb, err := ffiwrapper.New(sbfs, cfg)
|
||||
sb, err := ffiwrapper.New(sbfs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -69,16 +66,17 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
var sealedSectors []*genesis.PreSeal
|
||||
for i := 0; i < sectors; i++ {
|
||||
sid := abi.SectorID{Miner: abi.ActorID(mid), Number: next}
|
||||
ref := storage.SectorRef{ID: sid, ProofType: spt}
|
||||
next++
|
||||
|
||||
var preseal *genesis.PreSeal
|
||||
if !fakeSectors {
|
||||
preseal, err = presealSector(sb, sbfs, sid, spt, ssize, preimage)
|
||||
preseal, err = presealSector(sb, sbfs, ref, ssize, preimage)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
preseal, err = presealSectorFake(sbfs, sid, spt, ssize)
|
||||
preseal, err = presealSectorFake(sbfs, ref, ssize)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -148,7 +146,7 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect
|
||||
return miner, &minerAddr.KeyInfo, nil
|
||||
}
|
||||
|
||||
func presealSector(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, sid abi.SectorID, spt abi.RegisteredSealProof, ssize abi.SectorSize, preimage []byte) (*genesis.PreSeal, error) {
|
||||
func presealSector(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, sid storage.SectorRef, ssize abi.SectorSize, preimage []byte) (*genesis.PreSeal, error) {
|
||||
pi, err := sb.AddPiece(context.TODO(), sid, nil, abi.PaddedPieceSize(ssize).Unpadded(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -182,12 +180,12 @@ func presealSector(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, sid abi.Sector
|
||||
return &genesis.PreSeal{
|
||||
CommR: cids.Sealed,
|
||||
CommD: cids.Unsealed,
|
||||
SectorID: sid.Number,
|
||||
ProofType: spt,
|
||||
SectorID: sid.ID.Number,
|
||||
ProofType: sid.ProofType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func presealSectorFake(sbfs *basicfs.Provider, sid abi.SectorID, spt abi.RegisteredSealProof, ssize abi.SectorSize) (*genesis.PreSeal, error) {
|
||||
func presealSectorFake(sbfs *basicfs.Provider, sid storage.SectorRef, ssize abi.SectorSize) (*genesis.PreSeal, error) {
|
||||
paths, done, err := sbfs.AcquireSector(context.TODO(), sid, 0, storiface.FTSealed|storiface.FTCache, storiface.PathSealing)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("acquire unsealed sector: %w", err)
|
||||
@@ -198,7 +196,7 @@ func presealSectorFake(sbfs *basicfs.Provider, sid abi.SectorID, spt abi.Registe
|
||||
return nil, xerrors.Errorf("mkdir cache: %w", err)
|
||||
}
|
||||
|
||||
commr, err := ffi.FauxRep(spt, paths.Cache, paths.Sealed)
|
||||
commr, err := ffi.FauxRep(sid.ProofType, paths.Cache, paths.Sealed)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("fauxrep: %w", err)
|
||||
}
|
||||
@@ -206,13 +204,13 @@ func presealSectorFake(sbfs *basicfs.Provider, sid abi.SectorID, spt abi.Registe
|
||||
return &genesis.PreSeal{
|
||||
CommR: commr,
|
||||
CommD: zerocomm.ZeroPieceCommitment(abi.PaddedPieceSize(ssize).Unpadded()),
|
||||
SectorID: sid.Number,
|
||||
ProofType: spt,
|
||||
SectorID: sid.ID.Number,
|
||||
ProofType: sid.ProofType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func cleanupUnsealed(sbfs *basicfs.Provider, sid abi.SectorID) error {
|
||||
paths, done, err := sbfs.AcquireSector(context.TODO(), sid, storiface.FTUnsealed, storiface.FTNone, storiface.PathSealing)
|
||||
func cleanupUnsealed(sbfs *basicfs.Provider, ref storage.SectorRef) error {
|
||||
paths, done, err := sbfs.AcquireSector(context.TODO(), ref, storiface.FTUnsealed, storiface.FTNone, storiface.PathSealing)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,9 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/gen/genesis"
|
||||
|
||||
@@ -62,6 +66,7 @@ var auditsCmd = &cli.Command{
|
||||
chainBalanceCmd,
|
||||
chainBalanceStateCmd,
|
||||
chainPledgeCmd,
|
||||
fillBalancesCmd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -189,6 +194,7 @@ var chainBalanceStateCmd = &cli.Command{
|
||||
}
|
||||
|
||||
cs := store.NewChainStore(bs, bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier), nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
cst := cbor.NewCborStore(bs)
|
||||
store := adt.WrapStore(ctx, cst)
|
||||
@@ -409,6 +415,7 @@ var chainPledgeCmd = &cli.Command{
|
||||
}
|
||||
|
||||
cs := store.NewChainStore(bs, bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier), nil)
|
||||
defer cs.Close() //nolint:errcheck
|
||||
|
||||
cst := cbor.NewCborStore(bs)
|
||||
store := adt.WrapStore(ctx, cst)
|
||||
@@ -485,3 +492,119 @@ var chainPledgeCmd = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
const dateFmt = "1/02/06"
|
||||
|
||||
func parseCsv(inp string) ([]time.Time, []address.Address, error) {
|
||||
fi, err := os.Open(inp)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := csv.NewReader(fi)
|
||||
recs, err := r.ReadAll()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var addrs []address.Address
|
||||
for _, rec := range recs[1:] {
|
||||
a, err := address.NewFromString(rec[0])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
addrs = append(addrs, a)
|
||||
}
|
||||
|
||||
var dates []time.Time
|
||||
for _, d := range recs[0][1:] {
|
||||
if len(d) == 0 {
|
||||
continue
|
||||
}
|
||||
p := strings.Split(d, " ")
|
||||
t, err := time.Parse(dateFmt, p[len(p)-1])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
dates = append(dates, t)
|
||||
}
|
||||
|
||||
return dates, addrs, nil
|
||||
}
|
||||
|
||||
func heightForDate(d time.Time, ts *types.TipSet) abi.ChainEpoch {
|
||||
secs := d.Unix()
|
||||
gents := ts.Blocks()[0].Timestamp
|
||||
gents -= uint64(30 * ts.Height())
|
||||
return abi.ChainEpoch((secs - int64(gents)) / 30)
|
||||
}
|
||||
|
||||
var fillBalancesCmd = &cli.Command{
|
||||
Name: "fill-balances",
|
||||
Description: "fill out balances for addresses on dates in given spreadsheet",
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
dates, addrs, err := parseCsv(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ts, err := api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var tipsets []*types.TipSet
|
||||
for _, d := range dates {
|
||||
h := heightForDate(d, ts)
|
||||
hts, err := api.ChainGetTipSetByHeight(ctx, h, ts.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tipsets = append(tipsets, hts)
|
||||
}
|
||||
|
||||
var balances [][]abi.TokenAmount
|
||||
for _, a := range addrs {
|
||||
var b []abi.TokenAmount
|
||||
for _, hts := range tipsets {
|
||||
act, err := api.StateGetActor(ctx, a, hts.Key())
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "actor not found") {
|
||||
return fmt.Errorf("error for %s at %s: %w", a, hts.Key(), err)
|
||||
}
|
||||
b = append(b, types.NewInt(0))
|
||||
continue
|
||||
}
|
||||
b = append(b, act.Balance)
|
||||
}
|
||||
balances = append(balances, b)
|
||||
}
|
||||
|
||||
var datestrs []string
|
||||
for _, d := range dates {
|
||||
datestrs = append(datestrs, "Balance at "+d.Format(dateFmt))
|
||||
}
|
||||
|
||||
w := csv.NewWriter(os.Stdout)
|
||||
w.Write(append([]string{"Wallet Address"}, datestrs...)) // nolint:errcheck
|
||||
for i := 0; i < len(addrs); i++ {
|
||||
row := []string{addrs[i].String()}
|
||||
for _, b := range balances[i] {
|
||||
row = append(row, types.FIL(b).String())
|
||||
}
|
||||
w.Write(row) // nolint:errcheck
|
||||
}
|
||||
w.Flush()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
blake2b "github.com/minio/blake2b-simd"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
)
|
||||
|
||||
var blockmsgidCmd = &cli.Command{
|
||||
Name: "blockmsgid",
|
||||
Usage: "Print a block's pubsub message ID",
|
||||
ArgsUsage: "<blockCid> ...",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
for _, arg := range cctx.Args().Slice() {
|
||||
blkcid, err := cid.Decode(arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error decoding block cid: %w", err)
|
||||
}
|
||||
|
||||
blkhdr, err := api.ChainGetBlock(ctx, blkcid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving block header: %w", err)
|
||||
}
|
||||
|
||||
blkmsgs, err := api.ChainGetBlockMessages(ctx, blkcid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving block messages: %w", err)
|
||||
}
|
||||
|
||||
blkmsg := &types.BlockMsg{
|
||||
Header: blkhdr,
|
||||
}
|
||||
|
||||
for _, m := range blkmsgs.BlsMessages {
|
||||
blkmsg.BlsMessages = append(blkmsg.BlsMessages, m.Cid())
|
||||
}
|
||||
|
||||
for _, m := range blkmsgs.SecpkMessages {
|
||||
blkmsg.SecpkMessages = append(blkmsg.SecpkMessages, m.Cid())
|
||||
}
|
||||
|
||||
bytes, err := blkmsg.Serialize()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error serializing BlockMsg: %w", err)
|
||||
}
|
||||
|
||||
msgId := blake2b.Sum256(bytes)
|
||||
msgId64 := base64.StdEncoding.EncodeToString(msgId[:])
|
||||
|
||||
fmt.Println(msgId64)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
+50
-16
@@ -5,44 +5,78 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cidCmd = &cli.Command{
|
||||
Name: "cid",
|
||||
Name: "cid",
|
||||
Usage: "Cid command",
|
||||
Subcommands: cli.Commands{
|
||||
cidIdCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var cidIdCmd = &cli.Command{
|
||||
Name: "id",
|
||||
Usage: "create identity CID from hex or base64 data",
|
||||
Name: "id",
|
||||
Usage: "Create identity CID from hex or base64 data",
|
||||
ArgsUsage: "[data]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "encoding",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "codec",
|
||||
Value: "id",
|
||||
Usage: "multicodec-packed content types: abi or id",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify data")
|
||||
}
|
||||
|
||||
dec, err := hex.DecodeString(cctx.Args().First())
|
||||
if err != nil {
|
||||
dec, err = base64.StdEncoding.DecodeString(cctx.Args().First())
|
||||
var dec []byte
|
||||
switch cctx.String("encoding") {
|
||||
case "base64":
|
||||
data, err := base64.StdEncoding.DecodeString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("decoding base64 value: %w", err)
|
||||
}
|
||||
|
||||
dec = data
|
||||
case "hex":
|
||||
data, err := hex.DecodeString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding hex value: %w", err)
|
||||
}
|
||||
dec = data
|
||||
default:
|
||||
return xerrors.Errorf("unrecognized encoding: %s", cctx.String("encoding"))
|
||||
}
|
||||
|
||||
builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}
|
||||
|
||||
c, err := builder.Sum(dec)
|
||||
if err != nil {
|
||||
return err
|
||||
switch cctx.String("codec") {
|
||||
case "abi":
|
||||
aCid, err := abi.CidBuilder.Sum(dec)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cidBuilder abi: %w", err)
|
||||
}
|
||||
fmt.Println(aCid)
|
||||
case "id":
|
||||
builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}
|
||||
rCid, err := builder.Sum(dec)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("cidBuilder raw: %w", err)
|
||||
}
|
||||
fmt.Println(rCid)
|
||||
default:
|
||||
return xerrors.Errorf("unrecognized codec: %s", cctx.String("codec"))
|
||||
}
|
||||
|
||||
fmt.Println(c)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+32
-4
@@ -1,27 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
commcid "github.com/filecoin-project/go-fil-commcid"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var commpToCidCmd = &cli.Command{
|
||||
Name: "commp-to-cid",
|
||||
Usage: "Convert commP to Cid",
|
||||
Description: "Convert a raw commP to a piece-Cid",
|
||||
ArgsUsage: "[data]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "encoding",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must specify commP to convert")
|
||||
}
|
||||
|
||||
dec, err := hex.DecodeString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decode input as hex string: %w", err)
|
||||
var dec []byte
|
||||
switch cctx.String("encoding") {
|
||||
case "base64":
|
||||
data, err := base64.StdEncoding.DecodeString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding base64 value: %w", err)
|
||||
}
|
||||
dec = data
|
||||
case "hex":
|
||||
data, err := hex.DecodeString(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("decoding hex value: %w", err)
|
||||
}
|
||||
dec = data
|
||||
default:
|
||||
return xerrors.Errorf("unrecognized encoding: %s", cctx.String("encoding"))
|
||||
}
|
||||
|
||||
fmt.Println(commcid.PieceCommitmentV1ToCID(dec))
|
||||
cid, err := commcid.PieceCommitmentV1ToCID(dec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(cid)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type dealStatsServer struct {
|
||||
api api.FullNode
|
||||
}
|
||||
|
||||
// Requested by @jbenet
|
||||
// How many epochs back to look at for dealstats
|
||||
var epochLookback = abi.ChainEpoch(10)
|
||||
|
||||
// these lists grow continuously with the network
|
||||
// TODO: need to switch this to an LRU of sorts, to ensure refreshes
|
||||
var knownFiltered = new(sync.Map)
|
||||
var resolvedWallets = new(sync.Map)
|
||||
|
||||
func init() {
|
||||
for _, a := range []string{
|
||||
"t0100", // client for genesis miner
|
||||
"t0101", // client for genesis miner
|
||||
"t0102", // client for genesis miner
|
||||
"t0112", // client for genesis miner
|
||||
"t0113", // client for genesis miner
|
||||
"t0114", // client for genesis miner
|
||||
"t1nslxql4pck5pq7hddlzym3orxlx35wkepzjkm3i", // SR1 dealbot wallet
|
||||
"t1stghxhdp2w53dym2nz2jtbpk6ccd4l2lxgmezlq", // SR1 dealbot wallet
|
||||
"t1mcr5xkgv4jdl3rnz77outn6xbmygb55vdejgbfi", // SR1 dealbot wallet
|
||||
"t1qiqdbbmrdalbntnuapriirduvxu5ltsc5mhy7si", // SR1 dealbot wallet
|
||||
} {
|
||||
a, err := address.NewFromString(a)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
knownFiltered.Store(a, true)
|
||||
}
|
||||
}
|
||||
|
||||
type dealCountResp struct {
|
||||
Epoch int64 `json:"epoch"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Payload int64 `json:"payload"`
|
||||
}
|
||||
|
||||
func (dss *dealStatsServer) handleStorageDealCount(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
epoch, deals := dss.filteredDealList()
|
||||
if epoch == 0 {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(&dealCountResp{
|
||||
Endpoint: "COUNT_DEALS",
|
||||
Payload: int64(len(deals)),
|
||||
Epoch: epoch,
|
||||
}); err != nil {
|
||||
log.Warnf("failed to write back deal count response: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type dealAverageResp struct {
|
||||
Epoch int64 `json:"epoch"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Payload int64 `json:"payload"`
|
||||
}
|
||||
|
||||
func (dss *dealStatsServer) handleStorageDealAverageSize(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
epoch, deals := dss.filteredDealList()
|
||||
if epoch == 0 {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
var totalBytes int64
|
||||
for _, d := range deals {
|
||||
totalBytes += int64(d.deal.Proposal.PieceSize.Unpadded())
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(&dealAverageResp{
|
||||
Endpoint: "AVERAGE_DEAL_SIZE",
|
||||
Payload: totalBytes / int64(len(deals)),
|
||||
Epoch: epoch,
|
||||
}); err != nil {
|
||||
log.Warnf("failed to write back deal average response: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type dealTotalResp struct {
|
||||
Epoch int64 `json:"epoch"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Payload int64 `json:"payload"`
|
||||
}
|
||||
|
||||
func (dss *dealStatsServer) handleStorageDealTotalReal(w http.ResponseWriter, r *http.Request) {
|
||||
epoch, deals := dss.filteredDealList()
|
||||
if epoch == 0 {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
var totalBytes int64
|
||||
for _, d := range deals {
|
||||
totalBytes += int64(d.deal.Proposal.PieceSize.Unpadded())
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(&dealTotalResp{
|
||||
Endpoint: "DEAL_BYTES",
|
||||
Payload: totalBytes,
|
||||
Epoch: epoch,
|
||||
}); err != nil {
|
||||
log.Warnf("failed to write back deal average response: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type clientStatsOutput struct {
|
||||
Epoch int64 `json:"epoch"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Payload []*clientStats `json:"payload"`
|
||||
}
|
||||
|
||||
type clientStats struct {
|
||||
Client address.Address `json:"client"`
|
||||
DataSize int64 `json:"data_size"`
|
||||
NumCids int `json:"num_cids"`
|
||||
NumDeals int `json:"num_deals"`
|
||||
NumMiners int `json:"num_miners"`
|
||||
|
||||
cids map[cid.Cid]bool
|
||||
providers map[address.Address]bool
|
||||
}
|
||||
|
||||
func (dss *dealStatsServer) handleStorageClientStats(w http.ResponseWriter, r *http.Request) {
|
||||
epoch, deals := dss.filteredDealList()
|
||||
if epoch == 0 {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
|
||||
stats := make(map[address.Address]*clientStats)
|
||||
|
||||
for _, d := range deals {
|
||||
|
||||
st, ok := stats[d.deal.Proposal.Client]
|
||||
if !ok {
|
||||
st = &clientStats{
|
||||
Client: d.resolvedWallet,
|
||||
cids: make(map[cid.Cid]bool),
|
||||
providers: make(map[address.Address]bool),
|
||||
}
|
||||
stats[d.deal.Proposal.Client] = st
|
||||
}
|
||||
|
||||
st.DataSize += int64(d.deal.Proposal.PieceSize.Unpadded())
|
||||
st.cids[d.deal.Proposal.PieceCID] = true
|
||||
st.providers[d.deal.Proposal.Provider] = true
|
||||
st.NumDeals++
|
||||
}
|
||||
|
||||
out := clientStatsOutput{
|
||||
Epoch: epoch,
|
||||
Endpoint: "CLIENT_DEAL_STATS",
|
||||
Payload: make([]*clientStats, 0, len(stats)),
|
||||
}
|
||||
for _, cs := range stats {
|
||||
cs.NumCids = len(cs.cids)
|
||||
cs.NumMiners = len(cs.providers)
|
||||
out.Payload = append(out.Payload, cs)
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(out); err != nil {
|
||||
log.Warnf("failed to write back client stats response: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type dealInfo struct {
|
||||
deal api.MarketDeal
|
||||
resolvedWallet address.Address
|
||||
}
|
||||
|
||||
// filteredDealList returns the current epoch and a list of filtered deals
|
||||
// on error returns an epoch of 0
|
||||
func (dss *dealStatsServer) filteredDealList() (int64, map[string]dealInfo) {
|
||||
ctx := context.Background()
|
||||
|
||||
head, err := dss.api.ChainHead(ctx)
|
||||
if err != nil {
|
||||
log.Warnf("failed to get chain head: %s", err)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
head, err = dss.api.ChainGetTipSetByHeight(ctx, head.Height()-epochLookback, head.Key())
|
||||
if err != nil {
|
||||
log.Warnf("failed to walk back %s epochs: %s", epochLookback, err)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Disabled as per @pooja's request
|
||||
//
|
||||
// // Exclude any address associated with a miner
|
||||
// miners, err := dss.api.StateListMiners(ctx, head.Key())
|
||||
// if err != nil {
|
||||
// log.Warnf("failed to get miner list: %s", err)
|
||||
// return 0, nil
|
||||
// }
|
||||
// for _, m := range miners {
|
||||
// info, err := dss.api.StateMinerInfo(ctx, m, head.Key())
|
||||
// if err != nil {
|
||||
// log.Warnf("failed to get info for known miner '%s': %s", m, err)
|
||||
// continue
|
||||
// }
|
||||
|
||||
// knownFiltered.Store(info.Owner, true)
|
||||
// knownFiltered.Store(info.Worker, true)
|
||||
// for _, a := range info.ControlAddresses {
|
||||
// knownFiltered.Store(a, true)
|
||||
// }
|
||||
// }
|
||||
|
||||
deals, err := dss.api.StateMarketDeals(ctx, head.Key())
|
||||
if err != nil {
|
||||
log.Warnf("failed to get market deals: %s", err)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
ret := make(map[string]dealInfo, len(deals))
|
||||
for dealKey, d := range deals {
|
||||
|
||||
// Counting no-longer-active deals as per Pooja's request
|
||||
// // https://github.com/filecoin-project/specs-actors/blob/v0.9.9/actors/builtin/market/deal.go#L81-L85
|
||||
// if d.State.SectorStartEpoch < 0 {
|
||||
// continue
|
||||
// }
|
||||
|
||||
if _, isFiltered := knownFiltered.Load(d.Proposal.Client); isFiltered {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, wasSeen := resolvedWallets.Load(d.Proposal.Client); !wasSeen {
|
||||
w, err := dss.api.StateAccountKey(ctx, d.Proposal.Client, head.Key())
|
||||
if err != nil {
|
||||
log.Warnf("failed to resolve id '%s' to wallet address: %s", d.Proposal.Client, err)
|
||||
continue
|
||||
} else {
|
||||
resolvedWallets.Store(d.Proposal.Client, w)
|
||||
}
|
||||
}
|
||||
|
||||
w, _ := resolvedWallets.Load(d.Proposal.Client)
|
||||
if _, isFiltered := knownFiltered.Load(w); isFiltered {
|
||||
continue
|
||||
}
|
||||
|
||||
ret[dealKey] = dealInfo{
|
||||
deal: d,
|
||||
resolvedWallet: w.(address.Address),
|
||||
}
|
||||
}
|
||||
|
||||
return int64(head.Height()), ret
|
||||
}
|
||||
|
||||
var serveDealStatsCmd = &cli.Command{
|
||||
Name: "serve-deal-stats",
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
_ = ctx
|
||||
|
||||
dss := &dealStatsServer{api}
|
||||
|
||||
mux := &http.ServeMux{}
|
||||
mux.HandleFunc("/api/storagedeal/count", dss.handleStorageDealCount)
|
||||
mux.HandleFunc("/api/storagedeal/averagesize", dss.handleStorageDealAverageSize)
|
||||
mux.HandleFunc("/api/storagedeal/totalreal", dss.handleStorageDealTotalReal)
|
||||
mux.HandleFunc("/api/storagedeal/clientstats", dss.handleStorageClientStats)
|
||||
|
||||
s := &http.Server{
|
||||
Addr: ":7272",
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if err := s.Shutdown(context.TODO()); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}()
|
||||
|
||||
list, err := net.Listen("tcp", ":7272") // nolint
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.Warnf("deal-stat server listening on %s\n== NOTE: QUERIES ARE EXPENSIVE - YOU MUST FRONT-CACHE THIS SERVICE\n", list.Addr().String())
|
||||
|
||||
return s.Serve(list)
|
||||
},
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user