Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebaa721e44 | ||
|
|
685a0fdc9c | ||
|
|
48c6c55f68 | ||
|
|
0a85dc6232 | ||
|
|
560a127ce6 | ||
|
|
834a6148b0 | ||
|
|
16d07d3f18 | ||
|
|
0579aecac4 | ||
|
|
388c53e637 | ||
|
|
db45a848f5 | ||
|
|
6bccdcc177 | ||
|
|
901079e880 | ||
|
|
827a473391 | ||
|
|
29bdd94b12 | ||
|
|
41e9345da0 | ||
|
|
2b3d66da3b | ||
|
|
69eb2163d2 | ||
|
|
eeadfedbe6 | ||
|
|
0eaa6d9983 | ||
|
|
38f9559080 | ||
|
|
10b2ec55b5 | ||
|
|
7747bcd859 | ||
|
|
476df99179 | ||
|
|
80b8d4b9d7 | ||
|
|
1e53ed6a82 | ||
|
|
32885e1129 | ||
|
|
9632a3836a | ||
|
|
4a114150f0 | ||
|
|
4015ddbb4f | ||
|
|
49abdd7d7d | ||
|
|
5453e70cab | ||
|
|
18d38ca42f | ||
|
|
7ddf1d1feb | ||
|
|
f01f1d377b | ||
|
|
785b660724 | ||
|
|
144b5a1350 | ||
|
|
7d2adc383f | ||
|
|
3224c84fb1 | ||
|
|
1cfb73cc3b | ||
|
|
1564db1fce | ||
|
|
3522c8d45a | ||
|
|
db977a2f91 | ||
|
|
174c595acc | ||
|
|
c3d94f8aa9 | ||
|
|
20c715d507 | ||
|
|
52cc2cd3eb | ||
|
|
96cb321eb5 | ||
|
|
fc59294154 | ||
|
|
951fc4e89d | ||
|
|
efd86876b4 | ||
|
|
bef53fa263 | ||
|
|
457ecad302 | ||
|
|
64ebcb1b31 | ||
|
|
1a61c028bc | ||
|
|
62e76bbcab | ||
|
|
b0bb36909b | ||
|
|
56277756a6 | ||
|
|
50d1fae85f | ||
|
|
5462ecf6da | ||
|
|
9e74c3c4e8 | ||
|
|
7d0296c409 | ||
|
|
3ce296489b | ||
|
|
9a0e552131 | ||
|
|
994934a42b | ||
|
|
6328f9c879 | ||
|
|
3fb605a743 | ||
|
|
299e72458e | ||
|
|
ab9b3b6851 | ||
|
|
93c21a6d2d | ||
|
|
c5a2cac06a | ||
|
|
32dcfb4842 | ||
|
|
afb9e5f672 | ||
|
|
108afe08fb | ||
|
|
c6440677aa | ||
|
|
92fb48d951 | ||
|
|
c58086ee27 | ||
|
|
6da09235dc | ||
|
|
9584c72026 | ||
|
|
fef5d65c0f | ||
|
|
835b84b12a | ||
|
|
858994a630 | ||
|
|
72871597cd | ||
|
|
8ac71f6d0a | ||
|
|
cbbe01eeb5 | ||
|
|
cf299b39b0 | ||
|
|
c6820ec059 | ||
|
|
e8e4b559e9 | ||
|
|
fdc46ad5df | ||
|
|
dbe580de10 | ||
|
|
25f3384939 | ||
|
|
a15080b563 | ||
|
|
cfcfd5d8fa | ||
|
|
ab529f4641 | ||
|
|
9b70fdbe9d | ||
|
|
dba2df80da | ||
|
|
2c9f4ad5ad | ||
|
|
4f9fcd2b01 | ||
|
|
f806822440 | ||
|
|
44a56c7e33 | ||
|
|
61b7b86af5 | ||
|
|
3287c621ad | ||
|
|
11d1e3cd5f | ||
|
|
1bd2ae034f | ||
|
|
4afef16ee6 | ||
|
|
72c1fa81db | ||
|
|
7583c4399a | ||
|
|
a7a6f24ceb | ||
|
|
cd032d5418 | ||
|
|
8613454d1d | ||
|
|
f9aca39caf | ||
|
|
6b9daa4d14 | ||
|
|
df973da748 | ||
|
|
e9cc697ee8 | ||
|
|
bb5a92e2f4 | ||
|
|
461a3cdebc | ||
|
|
d806fafee8 | ||
|
|
e9989d0e46 | ||
|
|
c01d9f05df | ||
|
|
bdd6cea13f | ||
|
|
e777b879a1 | ||
|
|
c7e3e9fa7f | ||
|
|
420888aeae | ||
|
|
594737ff6c | ||
|
|
c1aafb7b71 | ||
|
|
a3b325db5d | ||
|
|
24dd6e01d7 | ||
|
|
22884f18f1 | ||
|
|
984e4e9963 | ||
|
|
f24d401b61 | ||
|
|
19d457ae5b | ||
|
|
fda3b152bd | ||
|
|
b8bba15ed2 | ||
|
|
c11803ad55 | ||
|
|
5324440f7d | ||
|
|
f6cf27c781 | ||
|
|
d04c01939d | ||
|
|
f2aea11971 | ||
|
|
1f754bdb78 | ||
|
|
46e5cc9317 | ||
|
|
6c6711e638 | ||
|
|
3d52c087cc | ||
|
|
0d72d742b4 | ||
|
|
884e20f637 | ||
|
|
210216a94f | ||
|
|
2af1283c65 | ||
|
|
d2b7e7b2ab | ||
|
|
3fa51f08e1 | ||
|
|
446b1cc883 | ||
|
|
3c7f5f7629 | ||
|
|
dc8ff27b36 | ||
|
|
7db5e8061d | ||
|
|
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 | ||
|
|
5d9c79811f | ||
|
|
29817b6617 | ||
|
|
7be7a9b5e3 | ||
|
|
3a3270b37c | ||
|
|
72a3b41315 | ||
|
|
8c8396af59 | ||
|
|
7b8158b1af | ||
|
|
bf500711b3 | ||
|
|
f7f5a27ebf | ||
|
|
1f678c17d3 | ||
|
|
d98e989417 | ||
|
|
7f47bf452a | ||
|
|
dab20efc99 | ||
|
|
0e40a04975 | ||
|
|
c6cd699f0d | ||
|
|
3306bdec29 | ||
|
|
32b7797394 | ||
|
|
cde0e58e39 | ||
|
|
3e7efad0fd | ||
|
|
3c2cd506ec | ||
|
|
cdfa869ea6 | ||
|
|
fe40a53e8f | ||
|
|
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 | ||
|
|
7e3339820f | ||
|
|
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 |
+45
-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:
|
||||
@@ -200,6 +200,8 @@ jobs:
|
||||
<<: *test
|
||||
test-window-post:
|
||||
<<: *test
|
||||
test-terminate:
|
||||
<<: *test
|
||||
test-conformance:
|
||||
description: |
|
||||
Run tests using a corpus of interoperable test vectors for Filecoin
|
||||
@@ -264,22 +266,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 +318,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
|
||||
@@ -454,9 +478,15 @@ workflows:
|
||||
test-suite-name: cli
|
||||
packages: "./cli/... ./cmd/... ./api/..."
|
||||
- test-window-post:
|
||||
codecov-upload: true
|
||||
go-test-flags: "-run=TestWindowedPost"
|
||||
winpost-test: "1"
|
||||
test-suite-name: window-post
|
||||
- test-terminate:
|
||||
codecov-upload: true
|
||||
go-test-flags: "-run=TestTerminate"
|
||||
winpost-test: "1"
|
||||
test-suite-name: terminate
|
||||
- test-short:
|
||||
go-test-flags: "--timeout 10m --short"
|
||||
test-suite-name: short
|
||||
@@ -473,6 +503,11 @@ workflows:
|
||||
packages: "./conformance"
|
||||
vectors-branch: master
|
||||
- build-lotus-soup
|
||||
- trigger-testplans:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- build-debug
|
||||
- build-all:
|
||||
requires:
|
||||
|
||||
@@ -5,5 +5,15 @@ ignore:
|
||||
- "api/test/*"
|
||||
- "gen/**/*"
|
||||
- "gen/*"
|
||||
- "cmd/lotus-shed/*"
|
||||
- "cmd/tvx/*"
|
||||
- "cmd/lotus-pcr/*"
|
||||
- "cmd/tvx/*"
|
||||
- "cmd/lotus-chainwatch/*"
|
||||
- "cmd/lotus-health/*"
|
||||
- "cmd/lotus-fountain/*"
|
||||
- "cmd/lotus-townhall/*"
|
||||
- "cmd/lotus-stats/*"
|
||||
- "cmd/lotus-pcr/*"
|
||||
github_checks:
|
||||
annotations: false
|
||||
|
||||
@@ -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
|
||||
|
||||
+245
@@ -1,5 +1,250 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 1.4.1 / 2021-01-20
|
||||
|
||||
This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes. In particular, [#5341](https://github.com/filecoin-project/lotus/pull/5341) introduces the ability for Lotus miners to terminate sectors.
|
||||
|
||||
## Changes
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- fix(sync): enforce ForkLengthThreshold for synced chain (https://github.com/filecoin-project/lotus/pull/5182)
|
||||
- introduce memory watchdog; LOTUS_MAX_HEAP (https://github.com/filecoin-project/lotus/pull/5101)
|
||||
- Skip bootstrapping if no peers specified (https://github.com/filecoin-project/lotus/pull/5301)
|
||||
- Chainxchg write response timeout (https://github.com/filecoin-project/lotus/pull/5254)
|
||||
- update NewestNetworkVersion (https://github.com/filecoin-project/lotus/pull/5277)
|
||||
- fix(sync): remove checks bypass when we submit the block (https://github.com/filecoin-project/lotus/pull/4192)
|
||||
- chore: export vm.ShouldBurn (https://github.com/filecoin-project/lotus/pull/5355)
|
||||
- fix(sync): enforce fork len when changing head (https://github.com/filecoin-project/lotus/pull/5244)
|
||||
- Use 55th percentile instead of median for gas-price (https://github.com/filecoin-project/lotus/pull/5369)
|
||||
- update go-libp2p-pubsub to v0.4.1 (https://github.com/filecoin-project/lotus/pull/5329)
|
||||
|
||||
#### Sealing
|
||||
|
||||
- Sector termination support (https://github.com/filecoin-project/lotus/pull/5341)
|
||||
- update weight canSeal and canStore when attach (https://github.com/filecoin-project/lotus/pull/5242/files)
|
||||
- sector-storage/mock: improve mocked readpiece (https://github.com/filecoin-project/lotus/pull/5208)
|
||||
- Fix deadlock in runWorker in sched_worker.go (https://github.com/filecoin-project/lotus/pull/5251)
|
||||
- Skip checking terminated sectors provable (https://github.com/filecoin-project/lotus/pull/5217)
|
||||
- storagefsm: Fix unsealedInfoMap.lk init race (https://github.com/filecoin-project/lotus/pull/5319)
|
||||
- Multicore AddPiece CommP (https://github.com/filecoin-project/lotus/pull/5320)
|
||||
- storagefsm: Send correct event on ErrExpiredTicket in CommitFailed (https://github.com/filecoin-project/lotus/pull/5366)
|
||||
- expose StateSearchMessage on gateway (https://github.com/filecoin-project/lotus/pull/5382)
|
||||
- fix FileSize to return correct disk usage recursively (https://github.com/filecoin-project/lotus/pull/5384)
|
||||
|
||||
#### Dealmaking
|
||||
|
||||
- Better error message when withdrawing funds (https://github.com/filecoin-project/lotus/pull/5293)
|
||||
- add verbose for list transfers (https://github.com/filecoin-project/lotus/pull/5259)
|
||||
- cli - rename `client info` to `client balances` (https://github.com/filecoin-project/lotus/pull/5304)
|
||||
- Better CLI for wallet market withdraw and client info (https://github.com/filecoin-project/lotus/pull/5303)
|
||||
|
||||
#### UX
|
||||
|
||||
- correct flag usages for replace cmd (https://github.com/filecoin-project/lotus/pull/5255)
|
||||
- lotus state call will panic (https://github.com/filecoin-project/lotus/pull/5275)
|
||||
- fix get sector bug (https://github.com/filecoin-project/lotus/pull/4976)
|
||||
- feat: lotus wallet market add (adds funds to storage market actor) (https://github.com/filecoin-project/lotus/pull/5300)
|
||||
- Fix client flag parsing in client balances cli (https://github.com/filecoin-project/lotus/pull/5312)
|
||||
- delete slash-consensus miner (https://github.com/filecoin-project/lotus/pull/4577)
|
||||
- add fund sufficient check in send (https://github.com/filecoin-project/lotus/pull/5252)
|
||||
- enable parse and shorten negative FIL values (https://github.com/filecoin-project/lotus/pull/5315)
|
||||
- add limit and rate for chain noise (https://github.com/filecoin-project/lotus/pull/5223)
|
||||
- add bench env print (https://github.com/filecoin-project/lotus/pull/5222)
|
||||
- Implement full-node restore option (https://github.com/filecoin-project/lotus/pull/5362)
|
||||
- add color for token amount (https://github.com/filecoin-project/lotus/pull/5352)
|
||||
- correct log in maybeUseAddress (https://github.com/filecoin-project/lotus/pull/5359)
|
||||
- add slash-consensus from flag (https://github.com/filecoin-project/lotus/pull/5378)
|
||||
|
||||
#### Testing
|
||||
|
||||
- tvx extract: more tipset extraction goodness (https://github.com/filecoin-project/lotus/pull/5258)
|
||||
- Fix race in blockstore test suite (https://github.com/filecoin-project/lotus/pull/5297)
|
||||
|
||||
|
||||
#### Build & Networks
|
||||
|
||||
- Remove LOTUS_DISABLE_V2_ACTOR_MIGRATION envvar (https://github.com/filecoin-project/lotus/pull/5289)
|
||||
- Create a calibnet build option (https://github.com/filecoin-project/lotus/pull/5288)
|
||||
- Calibnet: Set Orange epoch (https://github.com/filecoin-project/lotus/pull/5325)
|
||||
|
||||
#### Management
|
||||
|
||||
- Update SECURITY.md (https://github.com/filecoin-project/lotus/pull/5246)
|
||||
- README: Contribute section (https://github.com/filecoin-project/lotus/pull/5330)
|
||||
- README: refine Contribute section (https://github.com/filecoin-project/lotus/pull/5331)
|
||||
- Add misc tooling to codecov ignore list (https://github.com/filecoin-project/lotus/pull/5347)
|
||||
|
||||
# 1.4.0 / 2020-12-19
|
||||
|
||||
This is a MANDATORY hotfix release of Lotus that resolves a chain halt at height 336,459 caused by nondeterminism in specs-actors. The fix is to update actors to 2.3.3 in order to incorporate this fix https://github.com/filecoin-project/specs-actors/pull/1334.
|
||||
|
||||
# 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.
|
||||
|
||||
@@ -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
|
||||
@@ -63,6 +63,9 @@ debug: lotus lotus-miner lotus-worker lotus-seed
|
||||
2k: GOFLAGS+=-tags=2k
|
||||
2k: lotus lotus-miner lotus-worker lotus-seed
|
||||
|
||||
calibnet: GOFLAGS+=-tags=calibnet
|
||||
calibnet: lotus lotus-miner lotus-worker lotus-seed
|
||||
|
||||
lotus: $(BUILD_DEPS)
|
||||
rm -f lotus
|
||||
go build $(GOFLAGS) -o lotus ./cmd/lotus
|
||||
@@ -204,6 +207,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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -24,24 +24,31 @@ For instructions on how to build, install and setup lotus, please visit [https:/
|
||||
|
||||
Please send an email to security@filecoin.org. See our [security policy](SECURITY.md) for more details.
|
||||
|
||||
## Development
|
||||
## Related packages
|
||||
|
||||
The main branches under development at the moment are:
|
||||
* [`master`](https://github.com/filecoin-project/lotus): current testnet.
|
||||
* [`next`](https://github.com/filecoin-project/lotus/tree/next): working branch with chain-breaking changes.
|
||||
* [`ntwk-calibration`](https://github.com/filecoin-project/lotus/tree/ntwk-calibration): devnet running one of `next` commits.
|
||||
These repos are independent and reusable modules, but are tightly integrated into Lotus to make up a fully featured Filecoin implementation:
|
||||
|
||||
### Tracker
|
||||
|
||||
All work is tracked via issues. An attempt at keeping an up-to-date view on remaining work towards Mainnet launch can be seen at the [lotus github project board](https://github.com/orgs/filecoin-project/projects/8). The issues labeled with `incentives` are there to identify the issues needed for Space Race launch.
|
||||
|
||||
### Packages
|
||||
|
||||
The lotus Filecoin implementation unfolds into the following packages:
|
||||
|
||||
- [This repo](https://github.com/filecoin-project/lotus)
|
||||
- [go-fil-markets](https://github.com/filecoin-project/go-fil-markets) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/markets-shared-components-5daa144a7046a60001c6e253/board)
|
||||
- [spec-actors](https://github.com/filecoin-project/specs-actors) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/actors-5ee6f3aa87591f0016c05685/board)
|
||||
- [specs-actors](https://github.com/filecoin-project/specs-actors) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/actors-5ee6f3aa87591f0016c05685/board)
|
||||
|
||||
## Contribute
|
||||
|
||||
Lotus is a universally open project and welcomes contributions of all kinds: code, docs, and more. However, before making a contribution, we ask you to heed these recommendations:
|
||||
|
||||
1. If the proposal entails a protocol change, please first submit a [Filecoin Improvement Proposal](https://github.com/filecoin-project/FIPs).
|
||||
2. If the change is complex and requires prior discussion, [open an issue](github.com/filecoin-project/lotus/issues) or a [discussion](https://github.com/filecoin-project/lotus/discussions) to request feedback before you start working on a pull request. This is to avoid disappointment and sunk costs, in case the change is not actually needed or accepted.
|
||||
3. Please refrain from submitting PRs to adapt existing code to subjective preferences. The changeset should contain functional or technical improvements/enhancements, bug fixes, new features, or some other clear material contribution. Simple stylistic changes are likely to be rejected in order to reduce code churn.
|
||||
|
||||
When implementing a change:
|
||||
|
||||
1. Adhere to the standard Go formatting guidelines, e.g. [Effective Go](https://golang.org/doc/effective_go.html). Run `go fmt`.
|
||||
2. Stick to the idioms and patterns used in the codebase. Familiar-looking code has a higher chance of being accepted than eerie code. Pay attention to commonly used variable and parameter names, avoidance of naked returns, error handling patterns, etc.
|
||||
3. Comments: follow the advice on the [Commentary](https://golang.org/doc/effective_go.html#commentary) section of Effective Go.
|
||||
4. Minimize code churn. Modify only what is strictly necessary. Well-encapsulated changesets will get a quicker response from maintainers.
|
||||
5. Lint your code with [`golangci-lint`](https://golangci-lint.run) (CI will reject your PR if unlinted).
|
||||
6. Add tests.
|
||||
7. Title the PR in a meaningful way and describe the rationale and the thought process in the PR description.
|
||||
8. Write clean, thoughtful, and detailed [commit messages](https://chris.beams.io/posts/git-commit/). This is even more important than the PR description, because commit messages are stored _inside_ the Git history. One good rule is: if you are happy posting the commit message as the PR description, then it's a good commit message.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+4
-4
@@ -2,11 +2,11 @@
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
For *critical* bugs, please consult our Security Policy and Responsible Disclosure Program information at https://github.com/filecoin-project/community/blob/master/SECURITY.md
|
||||
For reporting security vulnerabilities/bugs, please consult our Security Policy and Responsible Disclosure Program information at https://github.com/filecoin-project/community/blob/master/SECURITY.md. Security vulnerabilities should be reported via our [Vulnerability Reporting channels](https://github.com/filecoin-project/community/blob/master/SECURITY.md#vulnerability-reporting) and will be eligible for a [Bug Bounty](https://security.filecoin.io/bug-bounty/).
|
||||
|
||||
Please try to provide a clear description of any bugs reported, along with how to reproduce the bug if possible. More detailed bug reports (especially those with a PoC included) will help us move forward much faster. Additionally, please avoid reporting bugs that already have open issues. Take a moment to search the issue list of the related GitHub repositories before writing up a new report.
|
||||
|
||||
Here are some examples of bugs we would consider 'critical':
|
||||
Here are some examples of bugs we would consider to be security vulnerabilities:
|
||||
|
||||
* If you can spend from a `multisig` wallet you do not control the keys for.
|
||||
* If you can cause a miner to be slashed without them actually misbehaving.
|
||||
@@ -16,8 +16,8 @@ Here are some examples of bugs we would consider 'critical':
|
||||
* If you can craft a message that causes a persistent fork in the network.
|
||||
* If you can cause the total amount of Filecoin in the network to no longer be 2 billion.
|
||||
|
||||
This is not an exhaustive list, but should provide some idea of what we consider 'critical'.
|
||||
This is not an exhaustive list, but should provide some idea of what we consider as a security vulnerability, .
|
||||
|
||||
## Reporting a non security bug
|
||||
|
||||
For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
|
||||
For non-security bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -390,6 +391,8 @@ type FullNode interface {
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
|
||||
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
|
||||
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
|
||||
// StateSearchMsgLimited looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed
|
||||
StateSearchMsgLimited(ctx context.Context, msg cid.Cid, limit abi.ChainEpoch) (*MsgLookup, error)
|
||||
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
|
||||
// message arrives on chain, and gets to the indicated confidence depth.
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
@@ -514,10 +517,16 @@ type FullNode interface {
|
||||
// along with the address removal.
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error)
|
||||
|
||||
// MarketAddBalance adds funds to the market actor
|
||||
MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error)
|
||||
// MarketGetReserved gets the amount of funds that are currently reserved for the address
|
||||
MarketGetReserved(ctx context.Context, addr address.Address) (types.BigInt, error)
|
||||
// MarketReserveFunds reserves funds for a deal
|
||||
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 +600,9 @@ type DealInfo struct {
|
||||
|
||||
CreationTime time.Time
|
||||
Verified bool
|
||||
|
||||
TransferChannelID *datatransfer.ChannelID
|
||||
DataTransfer *DataTransferChannel
|
||||
}
|
||||
|
||||
type MsgLookup struct {
|
||||
@@ -785,6 +797,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,8 @@ 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)
|
||||
StateSearchMsg(ctx context.Context, msg cid.Cid) (*MsgLookup, 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)
|
||||
}
|
||||
|
||||
+42
-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
|
||||
@@ -56,7 +65,17 @@ type StorageMiner interface {
|
||||
// SectorGetExpectedSealDuration gets the expected time for a sector to seal
|
||||
SectorGetExpectedSealDuration(context.Context) (time.Duration, error)
|
||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
||||
// SectorRemove removes the sector from storage. It doesn't terminate it on-chain, which can
|
||||
// be done with SectorTerminate. Removing and not terminating live sectors will cause additional penalties.
|
||||
SectorRemove(context.Context, abi.SectorNumber) error
|
||||
// SectorTerminate terminates the sector on-chain (adding it to a termination batch first), then
|
||||
// automatically removes it from storage
|
||||
SectorTerminate(context.Context, abi.SectorNumber) error
|
||||
// SectorTerminateFlush immediately sends a terminate message with sectors batched for termination.
|
||||
// Returns null if message wasn't sent
|
||||
SectorTerminateFlush(ctx context.Context) (*cid.Cid, error)
|
||||
// SectorTerminatePending returns a list of pending sector terminations to be sent in the next batch message
|
||||
SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error)
|
||||
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber) error
|
||||
|
||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error)
|
||||
@@ -103,6 +122,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 +139,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 +220,19 @@ func (st *SealSeed) Equals(ost *SealSeed) bool {
|
||||
}
|
||||
|
||||
type SectorState string
|
||||
|
||||
type AddrUse int
|
||||
|
||||
const (
|
||||
PreCommitAddr AddrUse = iota
|
||||
CommitAddr
|
||||
PoStAddr
|
||||
|
||||
TerminateSectorsAddr
|
||||
)
|
||||
|
||||
type AddressConfig struct {
|
||||
PreCommitControl []address.Address
|
||||
CommitControl []address.Address
|
||||
TerminateControl []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
|
||||
|
||||
|
||||
+170
-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"`
|
||||
@@ -203,6 +206,7 @@ type FullNodeStruct struct {
|
||||
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateWaitMsgLimited func(context.Context, cid.Cid, uint64, abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateSearchMsgLimited func(context.Context, cid.Cid, abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateMarketBalance func(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) `perm:"read"`
|
||||
@@ -241,8 +245,11 @@ type FullNodeStruct struct {
|
||||
MsigSwapCancel func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigRemoveSigner func(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MarketAddBalance func(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MarketGetReserved func(ctx context.Context, addr address.Address) (types.BigInt, error) `perm:"sign"`
|
||||
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 +281,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 +305,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"`
|
||||
@@ -305,23 +315,26 @@ type StorageMinerStruct struct {
|
||||
SectorGetExpectedSealDuration func(context.Context) (time.Duration, error) `perm:"read"`
|
||||
SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"admin"`
|
||||
SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"`
|
||||
SectorTerminate func(context.Context, abi.SectorNumber) error `perm:"admin"`
|
||||
SectorTerminateFlush func(ctx context.Context) (*cid.Cid, error) `perm:"admin"`
|
||||
SectorTerminatePending func(ctx context.Context) ([]abi.SectorID, error) `perm:"admin"`
|
||||
SectorMarkForUpgrade func(ctx context.Context, id abi.SectorNumber) error `perm:"admin"`
|
||||
|
||||
WorkerConnect func(context.Context, string) error `perm:"admin" retry:"true"` // TODO: worker perm
|
||||
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 +352,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 +377,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 +392,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"`
|
||||
@@ -422,8 +444,10 @@ type GatewayStruct struct {
|
||||
StateMinerProvingDeadline func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
||||
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
|
||||
StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
|
||||
StateSearchMsg func(ctx context.Context, msg cid.Cid) (*api.MsgLookup, 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 +519,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)
|
||||
}
|
||||
@@ -979,6 +1015,10 @@ func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api
|
||||
return c.Internal.StateSearchMsg(ctx, msgc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSearchMsgLimited(ctx context.Context, msgc cid.Cid, limit abi.ChainEpoch) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateSearchMsgLimited(ctx, msgc, limit)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
|
||||
return c.Internal.StateListMiners(ctx, tsk)
|
||||
}
|
||||
@@ -1119,6 +1159,14 @@ func (c *FullNodeStruct) MsigRemoveSigner(ctx context.Context, msig address.Addr
|
||||
return c.Internal.MsigRemoveSigner(ctx, msig, proposer, toRemove, decrease)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketAddBalance(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) {
|
||||
return c.Internal.MarketAddBalance(ctx, wallet, addr, amt)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketGetReserved(ctx context.Context, addr address.Address) (types.BigInt, error) {
|
||||
return c.Internal.MarketGetReserved(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) {
|
||||
return c.Internal.MarketReserveFunds(ctx, wallet, addr, amt)
|
||||
}
|
||||
@@ -1127,6 +1175,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 +1261,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 +1279,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)
|
||||
}
|
||||
@@ -1255,6 +1319,18 @@ func (c *StorageMinerStruct) SectorRemove(ctx context.Context, number abi.Sector
|
||||
return c.Internal.SectorRemove(ctx, number)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorTerminate(ctx context.Context, number abi.SectorNumber) error {
|
||||
return c.Internal.SectorTerminate(ctx, number)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorTerminateFlush(ctx context.Context) (*cid.Cid, error) {
|
||||
return c.Internal.SectorTerminateFlush(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error) {
|
||||
return c.Internal.SectorTerminatePending(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorMarkForUpgrade(ctx context.Context, number abi.SectorNumber) error {
|
||||
return c.Internal.SectorMarkForUpgrade(ctx, number)
|
||||
}
|
||||
@@ -1271,47 +1347,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 +1547,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 +1587,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 +1609,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 +1785,14 @@ func (g GatewayStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSet
|
||||
return g.Internal.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) {
|
||||
return g.Internal.StateSearchMsg(ctx, msg)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
+10
-1
@@ -90,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)
|
||||
@@ -233,6 +233,14 @@ func init() {
|
||||
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)
|
||||
@@ -240,6 +248,7 @@ func init() {
|
||||
addExample(map[sealtasks.TaskType]struct{}{
|
||||
sealtasks.TTPreCommit2: {},
|
||||
})
|
||||
addExample(sealtasks.TTCommit2)
|
||||
}
|
||||
|
||||
func exampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
|
||||
@@ -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) {},
|
||||
|
||||
+278
-10
@@ -3,18 +3,23 @@ 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-bitfield"
|
||||
"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 +28,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 +152,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 {
|
||||
@@ -121,12 +212,13 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int,
|
||||
upgradeHeight abi.ChainEpoch) {
|
||||
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 +301,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 +332,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)
|
||||
@@ -334,3 +430,175 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
||||
require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged
|
||||
}
|
||||
|
||||
func TestTerminate(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
nSectors := uint64(2)
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(1)}, []StorageMiner{{Full: 0, Preseal: int(nSectors)}})
|
||||
|
||||
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)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for ctx.Err() == nil {
|
||||
build.Clock.Sleep(blocktime)
|
||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
||||
if ctx.Err() != nil {
|
||||
// context was canceled, ignore the error.
|
||||
return
|
||||
}
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
cancel()
|
||||
<-done
|
||||
}()
|
||||
|
||||
maddr, err := miner.ActorAddress(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
ssz, err := miner.ActorSectorSize(ctx, maddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
p, err := client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors))
|
||||
|
||||
fmt.Printf("Seal a sector\n")
|
||||
|
||||
pledgeSectors(t, ctx, miner, 1, 0, nil)
|
||||
|
||||
fmt.Printf("wait for power\n")
|
||||
|
||||
{
|
||||
// Wait until proven.
|
||||
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2
|
||||
fmt.Printf("End for head.Height > %d\n", waitUntil)
|
||||
|
||||
for {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > waitUntil {
|
||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nSectors++
|
||||
|
||||
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*nSectors))
|
||||
|
||||
fmt.Println("Terminate a sector")
|
||||
|
||||
toTerminate := abi.SectorNumber(3)
|
||||
|
||||
err = miner.SectorTerminate(ctx, toTerminate)
|
||||
require.NoError(t, err)
|
||||
|
||||
msgTriggerred := false
|
||||
loop:
|
||||
for {
|
||||
si, err := miner.SectorsStatus(ctx, toTerminate, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Println("state: ", si.State, msgTriggerred)
|
||||
|
||||
switch sealing.SectorState(si.State) {
|
||||
case sealing.Terminating:
|
||||
if !msgTriggerred {
|
||||
{
|
||||
p, err := miner.SectorTerminatePending(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, p, 1)
|
||||
require.Equal(t, abi.SectorNumber(3), p[0].Number)
|
||||
}
|
||||
|
||||
c, err := miner.SectorTerminateFlush(ctx)
|
||||
require.NoError(t, err)
|
||||
if c != nil {
|
||||
msgTriggerred = true
|
||||
fmt.Println("terminate message:", c)
|
||||
|
||||
{
|
||||
p, err := miner.SectorTerminatePending(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, p, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
case sealing.TerminateWait, sealing.TerminateFinality, sealing.Removed:
|
||||
break loop
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
// check power decreased
|
||||
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1)))
|
||||
|
||||
// check in terminated set
|
||||
{
|
||||
parts, err := client.StateMinerPartitions(ctx, maddr, 1, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(parts), 0)
|
||||
|
||||
bflen := func(b bitfield.BitField) uint64 {
|
||||
l, err := b.Count()
|
||||
require.NoError(t, err)
|
||||
return l
|
||||
}
|
||||
|
||||
require.Equal(t, uint64(1), bflen(parts[0].AllSectors))
|
||||
require.Equal(t, uint64(0), bflen(parts[0].LiveSectors))
|
||||
}
|
||||
|
||||
di, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
for {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||
break
|
||||
}
|
||||
build.Clock.Sleep(blocktime)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
||||
|
||||
p, err = client.StateMinerPower(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, p.MinerPower, p.TotalPower)
|
||||
require.Equal(t, p.MinerPower.RawBytePower, types.NewInt(uint64(ssz)*(nSectors-1)))
|
||||
}
|
||||
|
||||
+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
|
||||
}
|
||||
|
||||
+9
-19
@@ -2,11 +2,9 @@ package build
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -17,24 +15,16 @@ func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var out []peer.AddrInfo
|
||||
|
||||
b := rice.MustFindBox("bootstrap")
|
||||
err := b.Walk("", func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to walk box: %w", err)
|
||||
|
||||
if BootstrappersFile != "" {
|
||||
spi := b.MustString(BootstrappersFile)
|
||||
if spi == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(path, ".pi") {
|
||||
return nil
|
||||
}
|
||||
spi := b.MustString(path)
|
||||
if spi == "" {
|
||||
return nil
|
||||
}
|
||||
pi, err := addrutil.ParseAddresses(context.TODO(), strings.Split(strings.TrimSpace(spi), "\n"))
|
||||
out = append(out, pi...)
|
||||
return err
|
||||
})
|
||||
return out, err
|
||||
return addrutil.ParseAddresses(context.TODO(), strings.Split(strings.TrimSpace(spi), "\n"))
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWK1QYsm6iqyhgH7vqsbeoNoKHbT368h1JLHS1qYN36oyc
|
||||
/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWKDyJZoPsNak1iYNN1GGmvGnvhyVbWBL6iusYfP3RpgYs
|
||||
/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWJRSTnzABB6MYYEBbSTT52phQntVD1PpRTMh1xt9mh6yH
|
||||
/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWQLi3kY6HnMYLUtwCe26zWMdNhniFgHVNn1DioQc7NiWv
|
||||
+1
-1
@@ -14,7 +14,7 @@ func MaybeGenesis() []byte {
|
||||
log.Warnf("loading built-in genesis: %s", err)
|
||||
return nil
|
||||
}
|
||||
genBytes, err := builtinGen.Bytes("devnet.car")
|
||||
genBytes, err := builtinGen.Bytes(GenesisFile)
|
||||
if err != nil {
|
||||
log.Warnf("loading built-in genesis: %s", err)
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
)
|
||||
|
||||
func IsNearUpgrade(epoch, upgradeEpoch abi.ChainEpoch) bool {
|
||||
return epoch > upgradeEpoch-Finality && epoch < upgradeEpoch+Finality
|
||||
}
|
||||
+9
-10
@@ -3,13 +3,13 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
const BootstrappersFile = ""
|
||||
const GenesisFile = ""
|
||||
|
||||
const UpgradeBreezeHeight = -1
|
||||
const BreezeGasTampingDuration = 0
|
||||
|
||||
@@ -18,10 +18,14 @@ const UpgradeIgnitionHeight = -2
|
||||
const UpgradeRefuelHeight = -3
|
||||
const UpgradeTapeHeight = -4
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
||||
const UpgradeActorsV2Height = 10
|
||||
const UpgradeLiftoffHeight = -5
|
||||
|
||||
const UpgradeKumquatHeight = 15
|
||||
const UpgradeCalicoHeight = 20
|
||||
const UpgradePersianHeight = 25
|
||||
const UpgradeOrangeHeight = 27
|
||||
const UpgradeClausHeight = 30
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
@@ -32,11 +36,6 @@ func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV2Height = math.MaxInt64
|
||||
UpgradeLiftoffHeight = 11
|
||||
}
|
||||
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// +build calibnet
|
||||
|
||||
package build
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
const BootstrappersFile = "calibnet.pi"
|
||||
const GenesisFile = "calibnet.car"
|
||||
|
||||
const UpgradeBreezeHeight = -1
|
||||
const BreezeGasTampingDuration = 120
|
||||
|
||||
const UpgradeSmokeHeight = -2
|
||||
|
||||
const UpgradeIgnitionHeight = -3
|
||||
const UpgradeRefuelHeight = -4
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(30)
|
||||
|
||||
const UpgradeTapeHeight = 60
|
||||
|
||||
// This signals our tentative epoch for mainnet launch. Can make it later, but not earlier.
|
||||
// Miners, clients, developers, custodians all need time to prepare.
|
||||
// We still have upgrades and state changes to do, but can happen after signaling timing here.
|
||||
const UpgradeLiftoffHeight = -5
|
||||
|
||||
const UpgradeKumquatHeight = 90
|
||||
|
||||
const UpgradeCalicoHeight = 92000
|
||||
const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
|
||||
|
||||
// 2020-12-17T19:00:00Z
|
||||
const UpgradeClausHeight = 161386
|
||||
|
||||
// 2021-01-17T19:00:00Z
|
||||
const UpgradeOrangeHeight = 250666
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 30))
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
)
|
||||
|
||||
SetAddressNetwork(address.Testnet)
|
||||
|
||||
Devnet = true
|
||||
}
|
||||
|
||||
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
|
||||
+15
-10
@@ -1,11 +1,11 @@
|
||||
// +build !debug
|
||||
// +build !2k
|
||||
// +build !testground
|
||||
// +build !calibnet
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -19,7 +19,11 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
UpgradeSmokeHeight: DrandMainnet,
|
||||
}
|
||||
|
||||
const BootstrappersFile = "mainnet.pi"
|
||||
const GenesisFile = "mainnet.car"
|
||||
|
||||
const UpgradeBreezeHeight = 41280
|
||||
|
||||
const BreezeGasTampingDuration = 120
|
||||
|
||||
const UpgradeSmokeHeight = 51000
|
||||
@@ -27,7 +31,7 @@ const UpgradeSmokeHeight = 51000
|
||||
const UpgradeIgnitionHeight = 94000
|
||||
const UpgradeRefuelHeight = 130800
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(138720)
|
||||
const UpgradeActorsV2Height = 138720
|
||||
|
||||
const UpgradeTapeHeight = 140760
|
||||
|
||||
@@ -38,21 +42,21 @@ const UpgradeLiftoffHeight = 148888
|
||||
|
||||
const UpgradeKumquatHeight = 170000
|
||||
|
||||
const UpgradeCalicoHeight = 265200
|
||||
const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
|
||||
|
||||
const UpgradeOrangeHeight = 336458
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV2Height = math.MaxInt64
|
||||
}
|
||||
|
||||
Devnet = false
|
||||
}
|
||||
|
||||
@@ -60,4 +64,5 @@ 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.Version9
|
||||
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,15 +88,23 @@ 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
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -10
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
NewestNetworkVersion = network.Version5
|
||||
NewestNetworkVersion = network.Version9
|
||||
ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
Devnet = true
|
||||
Devnet = true
|
||||
ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||
|
||||
BootstrappersFile = ""
|
||||
GenesisFile = ""
|
||||
)
|
||||
|
||||
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.3"
|
||||
const BuildVersion = "1.4.1"
|
||||
|
||||
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, 1)
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -42,6 +43,10 @@ var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
|
||||
|
||||
const MinSectorExpiration = miner0.MinSectorExpiration
|
||||
|
||||
// Not used / checked in v0
|
||||
var DeclarationsMax = miner2.DeclarationsMax
|
||||
var AddressedSectorsMax = miner2.AddressedSectorsMax
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StorageMinerActorCodeID:
|
||||
|
||||
@@ -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, network.Version9:
|
||||
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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -56,7 +56,11 @@ func (s *server) HandleStream(stream inet.Stream) {
|
||||
}
|
||||
|
||||
_ = stream.SetDeadline(time.Now().Add(WriteResDeadline))
|
||||
if err := cborutil.WriteCborRPC(stream, resp); err != nil {
|
||||
buffered := bufio.NewWriter(stream)
|
||||
if err = cborutil.WriteCborRPC(buffered, resp); err == nil {
|
||||
err = buffered.Flush()
|
||||
}
|
||||
if err != nil {
|
||||
_ = stream.SetDeadline(time.Time{})
|
||||
log.Warnw("failed to write back response for handle stream",
|
||||
"err", err, "peer", stream.Conn().RemotePeer())
|
||||
|
||||
+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
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package slashfilter
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -26,6 +28,10 @@ func New(dstore ds.Batching) *SlashFilter {
|
||||
}
|
||||
|
||||
func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpoch) error {
|
||||
if build.IsNearUpgrade(bh.Height, build.UpgradeOrangeHeight) {
|
||||
return nil
|
||||
}
|
||||
|
||||
epochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, bh.Height))
|
||||
{
|
||||
// double-fork mining (2 blocks at one epoch)
|
||||
|
||||
@@ -2,6 +2,7 @@ package market
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -129,6 +130,11 @@ func (fm *FundManager) Withdraw(ctx context.Context, wallet, addr address.Addres
|
||||
return fm.getFundedAddress(addr).withdraw(ctx, wallet, amt)
|
||||
}
|
||||
|
||||
// GetReserved returns the amount that is currently reserved for the address
|
||||
func (fm *FundManager) GetReserved(addr address.Address) abi.TokenAmount {
|
||||
return fm.getFundedAddress(addr).getReserved()
|
||||
}
|
||||
|
||||
// FundedAddressState keeps track of the state of an address with funds in the
|
||||
// datastore
|
||||
type FundedAddressState struct {
|
||||
@@ -147,7 +153,7 @@ type fundedAddress struct {
|
||||
env *fundManagerEnvironment
|
||||
str *Store
|
||||
|
||||
lk sync.Mutex
|
||||
lk sync.RWMutex
|
||||
state *FundedAddressState
|
||||
|
||||
// Note: These request queues are ephemeral, they are not saved to store
|
||||
@@ -183,6 +189,13 @@ func (a *fundedAddress) start() {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *fundedAddress) getReserved() abi.TokenAmount {
|
||||
a.lk.RLock()
|
||||
defer a.lk.RUnlock()
|
||||
|
||||
return a.state.AmtReserved
|
||||
}
|
||||
|
||||
func (a *fundedAddress) reserve(ctx context.Context, wallet address.Address, amt abi.TokenAmount) (cid.Cid, error) {
|
||||
return a.requestAndWait(ctx, wallet, amt, &a.reservations)
|
||||
}
|
||||
@@ -501,7 +514,13 @@ func (a *fundedAddress) processWithdrawals(withdrawals []*fundRequest) (msgCid c
|
||||
// request with an error
|
||||
newWithdrawalAmt := types.BigAdd(withdrawalAmt, amt)
|
||||
if newWithdrawalAmt.GreaterThan(netAvail) {
|
||||
err := xerrors.Errorf("insufficient funds for withdrawal of %d", amt)
|
||||
msg := fmt.Sprintf("insufficient funds for withdrawal of %s: ", types.FIL(amt))
|
||||
msg += fmt.Sprintf("net available (%s) = available (%s) - reserved (%s)",
|
||||
types.FIL(types.BigSub(netAvail, withdrawalAmt)), types.FIL(avail), types.FIL(a.state.AmtReserved))
|
||||
if !withdrawalAmt.IsZero() {
|
||||
msg += fmt.Sprintf(" - queued withdrawals (%s)", types.FIL(withdrawalAmt))
|
||||
}
|
||||
err := xerrors.Errorf(msg)
|
||||
a.debugf("%s", err)
|
||||
req.Complete(cid.Undef, err)
|
||||
continue
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+70
-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,18 @@ 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,
|
||||
}, {
|
||||
Height: build.UpgradeOrangeHeight,
|
||||
Network: network.Version9,
|
||||
Migration: nil,
|
||||
}}
|
||||
|
||||
if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade
|
||||
@@ -601,7 +611,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 +662,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 {
|
||||
|
||||
+95
-207
@@ -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 {
|
||||
@@ -635,7 +639,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) {
|
||||
func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid, lookbackLimit abi.ChainEpoch) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) {
|
||||
msg, err := sm.cs.GetCMessage(mcid)
|
||||
if err != nil {
|
||||
return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err)
|
||||
@@ -652,7 +656,7 @@ func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid) (*ty
|
||||
return head, r, foundMsg, nil
|
||||
}
|
||||
|
||||
fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg, LookbackNoLimit)
|
||||
fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg, lookbackLimit)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf("failed to look back through chain for message %s", mcid)
|
||||
@@ -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 {
|
||||
|
||||
+154
-19
@@ -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 {
|
||||
@@ -349,7 +363,7 @@ func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error {
|
||||
|
||||
// MaybeTakeHeavierTipSet evaluates the incoming tipset and locks it in our
|
||||
// internal state as our new head, if and only if it is heavier than the current
|
||||
// head.
|
||||
// head and does not exceed the maximum fork length.
|
||||
func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipSet) error {
|
||||
cs.heaviestLk.Lock()
|
||||
defer cs.heaviestLk.Unlock()
|
||||
@@ -366,6 +380,15 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
|
||||
// TODO: don't do this for initial sync. Now that we don't have a
|
||||
// difference between 'bootstrap sync' and 'caught up' sync, we need
|
||||
// some other heuristic.
|
||||
|
||||
exceeds, err := cs.exceedsForkLength(cs.heaviest, ts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exceeds {
|
||||
return nil
|
||||
}
|
||||
|
||||
return cs.takeHeaviestTipSet(ctx, ts)
|
||||
} else if w.Equals(heaviestW) && !ts.Equals(cs.heaviest) {
|
||||
log.Errorw("weight draw", "currTs", cs.heaviest, "ts", ts)
|
||||
@@ -373,6 +396,67 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if the two tipsets have a fork length above `ForkLengthThreshold`.
|
||||
// `synced` is the head of the chain we are currently synced to and `external`
|
||||
// is the incoming tipset potentially belonging to a forked chain. It assumes
|
||||
// the external chain has already been validated and available in the ChainStore.
|
||||
// The "fast forward" case is covered in this logic as a valid fork of length 0.
|
||||
//
|
||||
// FIXME: We may want to replace some of the logic in `syncFork()` with this.
|
||||
// `syncFork()` counts the length on both sides of the fork at the moment (we
|
||||
// need to settle on that) but here we just enforce it on the `synced` side.
|
||||
func (cs *ChainStore) exceedsForkLength(synced, external *types.TipSet) (bool, error) {
|
||||
if synced == nil || external == nil {
|
||||
// FIXME: If `cs.heaviest` is nil we should just bypass the entire
|
||||
// `MaybeTakeHeavierTipSet` logic (instead of each of the called
|
||||
// functions having to handle the nil case on their own).
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
// `forkLength`: number of tipsets we need to walk back from the our `synced`
|
||||
// chain to the common ancestor with the new `external` head in order to
|
||||
// adopt the fork.
|
||||
for forkLength := 0; forkLength < int(build.ForkLengthThreshold); forkLength++ {
|
||||
// First walk back as many tipsets in the external chain to match the
|
||||
// `synced` height to compare them. If we go past the `synced` height
|
||||
// the subsequent match will fail but it will still be useful to get
|
||||
// closer to the `synced` head parent's height in the next loop.
|
||||
for external.Height() > synced.Height() {
|
||||
if external.Height() == 0 {
|
||||
// We reached the genesis of the external chain without a match;
|
||||
// this is considered a fork outside the allowed limit (of "infinite"
|
||||
// length).
|
||||
return true, nil
|
||||
}
|
||||
external, err = cs.LoadTipSet(external.Parents())
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("failed to load parent tipset in external chain: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Now check if we arrived at the common ancestor.
|
||||
if synced.Equals(external) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// If we didn't, go back *one* tipset on the `synced` side (incrementing
|
||||
// the `forkLength`).
|
||||
if synced.Height() == 0 {
|
||||
// Same check as the `external` side, if we reach the start (genesis)
|
||||
// there is no common ancestor.
|
||||
return true, nil
|
||||
}
|
||||
synced, err = cs.LoadTipSet(synced.Parents())
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("failed to load parent tipset in synced chain: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// We traversed the fork length allowed without finding a common ancestor.
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// ForceHeadSilent forces a chain head tipset without triggering a reorg
|
||||
// operation.
|
||||
//
|
||||
@@ -380,7 +464,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 +487,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 +521,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
|
||||
}
|
||||
@@ -483,9 +594,13 @@ func (cs *ChainStore) takeHeaviestTipSet(ctx context.Context, ts *types.TipSet)
|
||||
// FlushValidationCache removes all results of block validation from the
|
||||
// chain metadata store. Usually the first step after a new chain import.
|
||||
func (cs *ChainStore) FlushValidationCache() error {
|
||||
return FlushValidationCache(cs.ds)
|
||||
}
|
||||
|
||||
func FlushValidationCache(ds datastore.Batching) error {
|
||||
log.Infof("clearing block validation cache...")
|
||||
|
||||
dsWalk, err := cs.ds.Query(query.Query{
|
||||
dsWalk, err := ds.Query(query.Query{
|
||||
// Potential TODO: the validation cache is not a namespace on its own
|
||||
// but is rather constructed as prefixed-key `foo:bar` via .Instance(), which
|
||||
// in turn does not work with the filter, which can match only on `foo/bar`
|
||||
@@ -505,7 +620,7 @@ func (cs *ChainStore) FlushValidationCache() error {
|
||||
return xerrors.Errorf("failed to run key listing query: %w", err)
|
||||
}
|
||||
|
||||
batch, err := cs.ds.Batch()
|
||||
batch, err := ds.Batch()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to open a DS batch: %w", err)
|
||||
}
|
||||
@@ -685,12 +800,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 +891,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 +902,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)
|
||||
|
||||
+23
-17
@@ -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")
|
||||
@@ -100,6 +97,10 @@ func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *cha
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -340,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
|
||||
}
|
||||
|
||||
|
||||
+20
-18
@@ -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"
|
||||
|
||||
@@ -249,18 +250,6 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
|
||||
|
||||
syncer.incoming.Pub(fts.TipSet().Blocks(), LocalIncoming)
|
||||
|
||||
if from == syncer.self {
|
||||
// TODO: this is kindof a hack...
|
||||
log.Debug("got block from ourselves")
|
||||
|
||||
if err := syncer.Sync(ctx, fts.TipSet()); err != nil {
|
||||
log.Errorf("failed to sync our own block %s: %+v", fts.TipSet().Cids(), err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO: IMPORTANT(GARBAGE) this needs to be put in the 'temporary' side of
|
||||
// the blockstore
|
||||
if err := syncer.store.PersistBlockHeaders(fts.TipSet().Blocks()...); err != nil {
|
||||
@@ -731,6 +720,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 +915,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 +967,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 +999,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 +1063,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 +1319,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
|
||||
@@ -1446,7 +1437,7 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know
|
||||
return nil, ErrForkCheckpoint
|
||||
}
|
||||
|
||||
// TODO: Does this mean we always ask for ForkLengthThreshold blocks from the network, even if we just need, like, 2?
|
||||
// TODO: Does this mean we always ask for ForkLengthThreshold blocks from the network, even if we just need, like, 2? Yes.
|
||||
// Would it not be better to ask in smaller chunks, given that an ~ForkLengthThreshold is very rare?
|
||||
tips, err := syncer.Exchange.GetBlocks(ctx, incoming.Parents(), int(build.ForkLengthThreshold))
|
||||
if err != nil {
|
||||
@@ -1457,6 +1448,10 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load next local tipset: %w", err)
|
||||
}
|
||||
// Track the fork length on our side of the synced chain to enforce
|
||||
// `ForkLengthThreshold`. Initialized to 1 because we already walked back
|
||||
// one tipset from `known` (our synced head).
|
||||
forkLengthInHead := 1
|
||||
|
||||
for cur := 0; cur < len(tips); {
|
||||
if nts.Height() == 0 {
|
||||
@@ -1473,6 +1468,13 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know
|
||||
if nts.Height() < tips[cur].Height() {
|
||||
cur++
|
||||
} else {
|
||||
// Walk back one block in our synced chain to try to meet the fork's
|
||||
// height.
|
||||
forkLengthInHead++
|
||||
if forkLengthInHead > int(build.ForkLengthThreshold) {
|
||||
return nil, ErrForkTooLong
|
||||
}
|
||||
|
||||
// We will be forking away from nts, check that it isn't checkpointed
|
||||
if nts.Key() == chkpt {
|
||||
return nil, ErrForkCheckpoint
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+24
-1
@@ -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).Abs()
|
||||
|
||||
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':
|
||||
@@ -47,7 +70,7 @@ func (f FIL) UnmarshalText(text []byte) error {
|
||||
}
|
||||
|
||||
func ParseFIL(s string) (FIL, error) {
|
||||
suffix := strings.TrimLeft(s, ".1234567890")
|
||||
suffix := strings.TrimLeft(s, "-.1234567890")
|
||||
s = s[:len(s)-len(suffix)]
|
||||
var attofil bool
|
||||
if suffix != "" {
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
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"},
|
||||
|
||||
{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
|
||||
|
||||
+28
-11
@@ -7,25 +7,27 @@ 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/build"
|
||||
"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 +42,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 +59,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) {
|
||||
@@ -102,11 +108,18 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime2.Conse
|
||||
return nil, xerrors.Errorf("cannot decode second block header: %f", decodeErr)
|
||||
}
|
||||
|
||||
// workaround chain halt
|
||||
if build.IsNearUpgrade(blockA.Height, build.UpgradeOrangeHeight) {
|
||||
return nil, xerrors.Errorf("consensus reporting disabled around Upgrade Orange")
|
||||
}
|
||||
if build.IsNearUpgrade(blockB.Height, build.UpgradeOrangeHeight) {
|
||||
return nil, xerrors.Errorf("consensus reporting disabled around Upgrade Orange")
|
||||
}
|
||||
|
||||
// are blocks the same?
|
||||
if blockA.Cid().Equals(blockB.Cid()) {
|
||||
return nil, fmt.Errorf("no consensus fault: submitted blocks are the same")
|
||||
}
|
||||
|
||||
// (1) check conditions necessary to any consensus fault
|
||||
|
||||
// were blocks mined by same miner?
|
||||
@@ -202,6 +215,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 +311,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
|
||||
|
||||
+96
-19
@@ -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"
|
||||
@@ -40,9 +43,11 @@ import (
|
||||
|
||||
const MaxCallDepth = 4096
|
||||
|
||||
var log = logging.Logger("vm")
|
||||
var actorLog = logging.Logger("actors")
|
||||
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
|
||||
var (
|
||||
log = logging.Logger("vm")
|
||||
actorLog = logging.Logger("actors")
|
||||
gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
|
||||
)
|
||||
|
||||
// stat counters
|
||||
var (
|
||||
@@ -69,8 +74,10 @@ func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Ad
|
||||
return aast.PubkeyAddress()
|
||||
}
|
||||
|
||||
var _ cbor.IpldBlockstore = (*gasChargingBlocks)(nil)
|
||||
var _ blockstore.Viewer = (*gasChargingBlocks)(nil)
|
||||
var (
|
||||
_ cbor.IpldBlockstore = (*gasChargingBlocks)(nil)
|
||||
_ blockstore.Viewer = (*gasChargingBlocks)(nil)
|
||||
)
|
||||
|
||||
type gasChargingBlocks struct {
|
||||
chargeGas func(GasCharge)
|
||||
@@ -138,6 +145,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
|
||||
@@ -187,9 +198,11 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtim
|
||||
return vm.VM.makeRuntime(ctx, msg, nil)
|
||||
}
|
||||
|
||||
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
|
||||
type NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
|
||||
type LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error)
|
||||
type (
|
||||
CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
|
||||
NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
|
||||
LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error)
|
||||
)
|
||||
|
||||
type VM struct {
|
||||
cstate *state.StateTree
|
||||
@@ -258,7 +271,6 @@ type ApplyRet struct {
|
||||
|
||||
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
|
||||
gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) {
|
||||
|
||||
defer atomic.AddUint64(&StatSends, 1)
|
||||
|
||||
st := vm.cstate
|
||||
@@ -555,7 +567,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 +611,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 +643,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 +657,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 +714,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)
|
||||
}()
|
||||
|
||||
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 +765,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
|
||||
}
|
||||
|
||||
|
||||
+49
-23
@@ -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
|
||||
}
|
||||
|
||||
@@ -1102,8 +1106,8 @@ var slashConsensusFault = &cli.Command{
|
||||
ArgsUsage: "[blockCid1 blockCid2]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "miner",
|
||||
Usage: "Miner address",
|
||||
Name: "from",
|
||||
Usage: "optionally specify the account to report consensus from",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "extra",
|
||||
@@ -1138,9 +1142,25 @@ var slashConsensusFault = &cli.Command{
|
||||
return xerrors.Errorf("getting block 2: %w", err)
|
||||
}
|
||||
|
||||
def, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
if b1.Miner != b2.Miner {
|
||||
return xerrors.Errorf("block1.miner:%s block2.miner:%s", b1.Miner, b2.Miner)
|
||||
}
|
||||
|
||||
var fromAddr address.Address
|
||||
if from := cctx.String("from"); from == "" {
|
||||
defaddr, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fromAddr = defaddr
|
||||
} else {
|
||||
addr, err := address.NewFromString(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fromAddr = addr
|
||||
}
|
||||
|
||||
bh1, err := cborutil.Dump(b1)
|
||||
@@ -1182,18 +1202,9 @@ var slashConsensusFault = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if cctx.String("miner") == "" {
|
||||
return xerrors.Errorf("--miner flag is required")
|
||||
}
|
||||
|
||||
maddr, err := address.NewFromString(cctx.String("miner"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
To: maddr,
|
||||
From: def,
|
||||
To: b2.Miner,
|
||||
From: fromAddr,
|
||||
Value: types.NewInt(0),
|
||||
Method: builtin.MethodsMiner.ReportConsensusFault,
|
||||
Params: enc,
|
||||
@@ -1246,14 +1257,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 +1292,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
|
||||
|
||||
+124
-35
@@ -91,7 +91,7 @@ var clientCmd = &cli.Command{
|
||||
WithCategory("retrieval", clientRetrieveCmd),
|
||||
WithCategory("util", clientCommPCmd),
|
||||
WithCategory("util", clientCarGenCmd),
|
||||
WithCategory("util", clientInfoCmd),
|
||||
WithCategory("util", clientBalancesCmd),
|
||||
WithCategory("util", clientListTransfers),
|
||||
WithCategory("util", clientRestartTransfer),
|
||||
WithCategory("util", clientCancelTransfer),
|
||||
@@ -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()
|
||||
}
|
||||
@@ -1672,9 +1732,9 @@ var clientGetDealCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var clientInfoCmd = &cli.Command{
|
||||
Name: "info",
|
||||
Usage: "Print storage market client information",
|
||||
var clientBalancesCmd = &cli.Command{
|
||||
Name: "balances",
|
||||
Usage: "Print storage market client balances",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "client",
|
||||
@@ -1691,7 +1751,7 @@ var clientInfoCmd = &cli.Command{
|
||||
|
||||
var addr address.Address
|
||||
if clientFlag := cctx.String("client"); clientFlag != "" {
|
||||
ca, err := address.NewFromString("client")
|
||||
ca, err := address.NewFromString(clientFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1710,10 +1770,22 @@ var clientInfoCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Client Market Info:\n")
|
||||
reserved, err := api.MarketGetReserved(ctx, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Locked Funds:\t%s\n", types.FIL(balance.Locked))
|
||||
fmt.Printf("Escrowed Funds:\t%s\n", types.FIL(balance.Escrow))
|
||||
avail := big.Sub(big.Sub(balance.Escrow, balance.Locked), reserved)
|
||||
if avail.LessThan(big.Zero()) {
|
||||
avail = big.Zero()
|
||||
}
|
||||
|
||||
fmt.Printf("Client Market Balance for address %s:\n", addr)
|
||||
|
||||
fmt.Printf(" Escrowed Funds: %s\n", types.FIL(balance.Escrow))
|
||||
fmt.Printf(" Locked Funds: %s\n", types.FIL(balance.Locked))
|
||||
fmt.Printf(" Reserved Funds: %s\n", types.FIL(reserved))
|
||||
fmt.Printf(" Available to Withdraw: %s\n", types.FIL(avail))
|
||||
|
||||
return nil
|
||||
},
|
||||
@@ -1825,6 +1897,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 +1945,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)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1876,6 +1955,11 @@ var clientListTransfers = &cli.Command{
|
||||
Name: "list-transfers",
|
||||
Usage: "List ongoing data transfers for deals",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "print verbose transfer details",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "color",
|
||||
Usage: "use color in display output",
|
||||
@@ -1907,6 +1991,7 @@ var clientListTransfers = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
verbose := cctx.Bool("verbose")
|
||||
completed := cctx.Bool("completed")
|
||||
color := cctx.Bool("color")
|
||||
watch := cctx.Bool("watch")
|
||||
@@ -1922,7 +2007,7 @@ var clientListTransfers = &cli.Command{
|
||||
|
||||
tm.MoveCursor(1, 1)
|
||||
|
||||
OutputDataTransferChannels(tm.Screen, channels, completed, color, showFailed)
|
||||
OutputDataTransferChannels(tm.Screen, channels, verbose, completed, color, showFailed)
|
||||
|
||||
tm.Flush()
|
||||
|
||||
@@ -1947,13 +2032,13 @@ var clientListTransfers = &cli.Command{
|
||||
}
|
||||
}
|
||||
}
|
||||
OutputDataTransferChannels(os.Stdout, channels, completed, color, showFailed)
|
||||
OutputDataTransferChannels(os.Stdout, channels, verbose, completed, color, showFailed)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// OutputDataTransferChannels generates table output for a list of channels
|
||||
func OutputDataTransferChannels(out io.Writer, channels []lapi.DataTransferChannel, completed bool, color bool, showFailed bool) {
|
||||
func OutputDataTransferChannels(out io.Writer, channels []lapi.DataTransferChannel, verbose, completed, color, showFailed bool) {
|
||||
sort.Slice(channels, func(i, j int) bool {
|
||||
return channels[i].TransferID < channels[j].TransferID
|
||||
})
|
||||
@@ -1983,7 +2068,7 @@ func OutputDataTransferChannels(out io.Writer, channels []lapi.DataTransferChann
|
||||
tablewriter.Col("Voucher"),
|
||||
tablewriter.NewLineCol("Message"))
|
||||
for _, channel := range sendingChannels {
|
||||
w.Write(toChannelOutput(color, "Sending To", channel))
|
||||
w.Write(toChannelOutput(color, "Sending To", channel, verbose))
|
||||
}
|
||||
w.Flush(out) //nolint:errcheck
|
||||
|
||||
@@ -1997,7 +2082,7 @@ func OutputDataTransferChannels(out io.Writer, channels []lapi.DataTransferChann
|
||||
tablewriter.Col("Voucher"),
|
||||
tablewriter.NewLineCol("Message"))
|
||||
for _, channel := range receivingChannels {
|
||||
w.Write(toChannelOutput(color, "Receiving From", channel))
|
||||
w.Write(toChannelOutput(color, "Receiving From", channel, verbose))
|
||||
}
|
||||
w.Flush(out) //nolint:errcheck
|
||||
}
|
||||
@@ -2018,9 +2103,13 @@ func channelStatusString(useColor bool, status datatransfer.Status) string {
|
||||
}
|
||||
}
|
||||
|
||||
func toChannelOutput(useColor bool, otherPartyColumn string, channel lapi.DataTransferChannel) map[string]interface{} {
|
||||
rootCid := ellipsis(channel.BaseCID.String(), 8)
|
||||
otherParty := ellipsis(channel.OtherPeer.String(), 8)
|
||||
func toChannelOutput(useColor bool, otherPartyColumn string, channel lapi.DataTransferChannel, verbose bool) map[string]interface{} {
|
||||
rootCid := channel.BaseCID.String()
|
||||
otherParty := channel.OtherPeer.String()
|
||||
if !verbose {
|
||||
rootCid = ellipsis(rootCid, 8)
|
||||
otherParty = ellipsis(otherParty, 8)
|
||||
}
|
||||
|
||||
initiated := "N"
|
||||
if channel.IsInitiator {
|
||||
@@ -2028,7 +2117,7 @@ func toChannelOutput(useColor bool, otherPartyColumn string, channel lapi.DataTr
|
||||
}
|
||||
|
||||
voucher := channel.Voucher
|
||||
if len(voucher) > 40 {
|
||||
if len(voucher) > 40 && !verbose {
|
||||
voucher = ellipsis(voucher, 37)
|
||||
}
|
||||
|
||||
|
||||
+48
-8
@@ -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
|
||||
},
|
||||
@@ -324,15 +362,15 @@ var mpoolReplaceCmd = &cli.Command{
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "gas-feecap",
|
||||
Usage: "gas feecap for new message",
|
||||
Usage: "gas feecap for new message (burn and pay to miner, attoFIL/GasUnit)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "gas-premium",
|
||||
Usage: "gas price for new message",
|
||||
Usage: "gas price for new message (pay to miner, attoFIL/GasUnit)",
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
Name: "gas-limit",
|
||||
Usage: "gas price for new message",
|
||||
Usage: "gas limit for new message (GasUnit)",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "auto",
|
||||
@@ -340,7 +378,7 @@ var mpoolReplaceCmd = &cli.Command{
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "max-fee",
|
||||
Usage: "Spend up to X FIL for this message (applicable for auto mode)",
|
||||
Usage: "Spend up to X attoFIL for this message (applicable for auto mode)",
|
||||
},
|
||||
},
|
||||
ArgsUsage: "<from nonce> | <message-cid>",
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
|
||||
+24
-5
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
@@ -43,15 +44,15 @@ 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",
|
||||
Usage: "specify method to invoke",
|
||||
Value: 0,
|
||||
Value: uint64(builtin.MethodSend),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "params-json",
|
||||
@@ -61,6 +62,10 @@ var sendCmd = &cli.Command{
|
||||
Name: "params-hex",
|
||||
Usage: "specify invocation parameters in hex",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "force",
|
||||
Usage: "must be specified for the action to take effect if maybe SysErrInsufficientFunds etc",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() != 2 {
|
||||
@@ -143,8 +148,22 @@ var sendCmd = &cli.Command{
|
||||
Params: params,
|
||||
}
|
||||
|
||||
if cctx.Int64("nonce") > 0 {
|
||||
msg.Nonce = uint64(cctx.Int64("nonce"))
|
||||
if !cctx.Bool("force") {
|
||||
// Funds insufficient check
|
||||
fromBalance, err := api.WalletBalance(ctx, msg.From)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
totalCost := types.BigAdd(types.BigMul(msg.GasFeeCap, types.NewInt(uint64(msg.GasLimit))), msg.Value)
|
||||
|
||||
if fromBalance.LessThan(totalCost) {
|
||||
fmt.Printf("WARNING: From balance %s less than total cost %s\n", types.FIL(fromBalance), types.FIL(totalCost))
|
||||
return fmt.Errorf("--force must be specified for this action to have an effect; you have been warned")
|
||||
}
|
||||
}
|
||||
|
||||
if cctx.IsSet("nonce") {
|
||||
msg.Nonce = cctx.Uint64("nonce")
|
||||
sm, err := api.WalletSignMessage(ctx, fromAddr, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+40
-2
@@ -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())
|
||||
@@ -1614,7 +1617,7 @@ func parseParamsForMethod(act cid.Cid, method uint64, args []string) ([]byte, er
|
||||
return nil, fmt.Errorf("unknown method %d for actor %s", method, act)
|
||||
}
|
||||
|
||||
paramObj := methodMeta.Params
|
||||
paramObj := methodMeta.Params.Elem()
|
||||
if paramObj.NumField() != len(args) {
|
||||
return nil, fmt.Errorf("not enough arguments given to call that method (expecting %d)", paramObj.NumField())
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+129
-51
@@ -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"
|
||||
)
|
||||
|
||||
@@ -512,6 +509,7 @@ var walletMarket = &cli.Command{
|
||||
Usage: "Interact with market balances",
|
||||
Subcommands: []*cli.Command{
|
||||
walletMarketWithdraw,
|
||||
walletMarketAdd,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -521,13 +519,13 @@ var walletMarketWithdraw = &cli.Command{
|
||||
ArgsUsage: "[amount (FIL) optional, otherwise will withdraw max available]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "from",
|
||||
Usage: "Specify address to withdraw funds from, otherwise it will use the default wallet address",
|
||||
Aliases: []string{"f"},
|
||||
Name: "wallet",
|
||||
Usage: "Specify address to withdraw funds to, otherwise it will use the default wallet address",
|
||||
Aliases: []string{"w"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Usage: "Market address to withdraw from (account or miner actor address, defaults to --from address)",
|
||||
Usage: "Market address to withdraw from (account or miner actor address, defaults to --wallet address)",
|
||||
Aliases: []string{"a"},
|
||||
},
|
||||
},
|
||||
@@ -539,6 +537,123 @@ var walletMarketWithdraw = &cli.Command{
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var wallet address.Address
|
||||
if cctx.String("wallet") != "" {
|
||||
wallet, err = address.NewFromString(cctx.String("wallet"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing from address: %w", err)
|
||||
}
|
||||
} else {
|
||||
wallet, err = api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting default wallet address: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
addr := wallet
|
||||
if cctx.String("address") != "" {
|
||||
addr, err = address.NewFromString(cctx.String("address"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing market address: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Work out if there are enough unreserved, unlocked funds to withdraw
|
||||
bal, err := api.StateMarketBalance(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting market balance for address %s: %w", addr.String(), err)
|
||||
}
|
||||
|
||||
reserved, err := api.MarketGetReserved(ctx, addr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting market reserved amount for address %s: %w", addr.String(), err)
|
||||
}
|
||||
|
||||
avail := big.Subtract(big.Subtract(bal.Escrow, bal.Locked), reserved)
|
||||
|
||||
notEnoughErr := func(msg string) error {
|
||||
return xerrors.Errorf("%s; "+
|
||||
"available (%s) = escrow (%s) - locked (%s) - reserved (%s)",
|
||||
msg, types.FIL(avail), types.FIL(bal.Escrow), types.FIL(bal.Locked), types.FIL(reserved))
|
||||
}
|
||||
|
||||
if avail.IsZero() || avail.LessThan(big.Zero()) {
|
||||
avail = big.Zero()
|
||||
return notEnoughErr("no funds available to withdraw")
|
||||
}
|
||||
|
||||
// Default to withdrawing all available funds
|
||||
amt := avail
|
||||
|
||||
// If there was an amount argument, only withdraw that amount
|
||||
if cctx.Args().Present() {
|
||||
f, err := types.ParseFIL(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing 'amount' argument: %w", err)
|
||||
}
|
||||
|
||||
amt = abi.TokenAmount(f)
|
||||
}
|
||||
|
||||
// Check the amount is positive
|
||||
if amt.IsZero() || amt.LessThan(big.Zero()) {
|
||||
return xerrors.Errorf("amount must be > 0")
|
||||
}
|
||||
|
||||
// Check there are enough available funds
|
||||
if amt.GreaterThan(avail) {
|
||||
msg := fmt.Sprintf("can't withdraw more funds than available; requested: %s", types.FIL(amt))
|
||||
return notEnoughErr(msg)
|
||||
}
|
||||
|
||||
fmt.Printf("Submitting WithdrawBalance message for amount %s for address %s\n", types.FIL(amt), wallet.String())
|
||||
smsg, err := api.MarketWithdraw(ctx, wallet, addr, amt)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fund manager withdraw error: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("WithdrawBalance message cid: %s\n", smsg)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var walletMarketAdd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "Add funds to the Storage Market Actor",
|
||||
ArgsUsage: "<amount>",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "from",
|
||||
Usage: "Specify address to move funds from, otherwise it will use the default wallet address",
|
||||
Aliases: []string{"f"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Usage: "Market address to move funds to (account or miner actor address, defaults to --from address)",
|
||||
Aliases: []string{"a"},
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting node API: %w", err)
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
// Get amount param
|
||||
if !cctx.Args().Present() {
|
||||
return fmt.Errorf("must pass amount to add")
|
||||
}
|
||||
f, err := types.ParseFIL(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing 'amount' argument: %w", err)
|
||||
}
|
||||
|
||||
amt := abi.TokenAmount(f)
|
||||
|
||||
// Get from param
|
||||
var from address.Address
|
||||
if cctx.String("from") != "" {
|
||||
from, err = address.NewFromString(cctx.String("from"))
|
||||
@@ -552,6 +667,7 @@ var walletMarketWithdraw = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
// Get address param
|
||||
addr := from
|
||||
if cctx.String("address") != "" {
|
||||
addr, err = address.NewFromString(cctx.String("address"))
|
||||
@@ -560,52 +676,14 @@ var walletMarketWithdraw = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
bal, err := api.StateMarketBalance(ctx, addr, types.EmptyTSK)
|
||||
// Add balance to market actor
|
||||
fmt.Printf("Submitting Add Balance message for amount %s for address %s\n", types.FIL(amt), addr)
|
||||
smsg, err := api.MarketAddBalance(ctx, from, addr, amt)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting market balance for address %s: %w", addr.String(), err)
|
||||
return xerrors.Errorf("add balance error: %w", err)
|
||||
}
|
||||
|
||||
avail := big.Subtract(bal.Escrow, bal.Locked)
|
||||
amt := avail
|
||||
|
||||
if cctx.Args().Present() {
|
||||
f, err := types.ParseFIL(cctx.Args().First())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parsing 'amount' argument: %w", err)
|
||||
}
|
||||
|
||||
amt = abi.TokenAmount(f)
|
||||
}
|
||||
|
||||
if amt.GreaterThan(avail) {
|
||||
return xerrors.Errorf("can't withdraw more funds than available; requested: %s; available: %s", types.FIL(amt), types.FIL(avail))
|
||||
}
|
||||
|
||||
if avail.IsZero() {
|
||||
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)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("submitting WithdrawBalance message: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("WithdrawBalance message cid: %s\n", smsg.Cid())
|
||||
fmt.Printf("AddBalance message cid: %s\n", smsg)
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
+24
-2
@@ -27,6 +27,16 @@ func main() {
|
||||
Hidden: true,
|
||||
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "limit",
|
||||
Usage: "spam transaction count limit, <= 0 is no limit",
|
||||
Value: 0,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "rate",
|
||||
Usage: "spam transaction rate, count per second",
|
||||
Value: 5,
|
||||
},
|
||||
},
|
||||
Commands: []*cli.Command{runCmd},
|
||||
}
|
||||
@@ -52,11 +62,17 @@ var runCmd = &cli.Command{
|
||||
defer closer()
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
return sendSmallFundsTxs(ctx, api, addr, 5)
|
||||
rate := cctx.Int("rate")
|
||||
if rate <= 0 {
|
||||
rate = 5
|
||||
}
|
||||
limit := cctx.Int("limit")
|
||||
|
||||
return sendSmallFundsTxs(ctx, api, addr, rate, limit)
|
||||
},
|
||||
}
|
||||
|
||||
func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate int) error {
|
||||
func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate, limit int) error {
|
||||
var sendSet []address.Address
|
||||
for i := 0; i < 20; i++ {
|
||||
naddr, err := api.WalletNew(ctx, types.KTSecp256k1)
|
||||
@@ -66,9 +82,14 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
|
||||
|
||||
sendSet = append(sendSet, naddr)
|
||||
}
|
||||
count := limit
|
||||
|
||||
tick := build.Clock.Ticker(time.Second / time.Duration(rate))
|
||||
for {
|
||||
if count <= 0 && limit > 0 {
|
||||
fmt.Printf("%d messages sent.\n", limit)
|
||||
return nil
|
||||
}
|
||||
select {
|
||||
case <-tick.C:
|
||||
msg := &types.Message{
|
||||
@@ -81,6 +102,7 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count--
|
||||
fmt.Println("Message sent: ", smsg.Cid())
|
||||
case <-ctx.Done():
|
||||
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()
|
||||
|
||||
+132
-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,12 @@ import (
|
||||
var log = logging.Logger("lotus-bench")
|
||||
|
||||
type BenchResults struct {
|
||||
SectorSize abi.SectorSize
|
||||
EnvVar map[string]string
|
||||
|
||||
SectorSize abi.SectorSize
|
||||
SectorNumber int
|
||||
|
||||
SealingSum SealingResult
|
||||
SealingResults []SealingResult
|
||||
|
||||
PostGenerateCandidates time.Duration
|
||||
@@ -55,6 +60,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 +119,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 +157,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 +243,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 +255,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 +272,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 +309,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
|
||||
}
|
||||
@@ -420,6 +448,15 @@ var sealBenchCmd = &cli.Command{
|
||||
bo.VerifyWindowPostHot = verifyWindowpost2.Sub(verifyWindowpost1)
|
||||
}
|
||||
|
||||
bo.EnvVar = make(map[string]string)
|
||||
for _, envKey := range []string{"BELLMAN_NO_GPU", "FIL_PROOFS_MAXIMIZE_CACHING", "FIL_PROOFS_USE_GPU_COLUMN_BUILDER",
|
||||
"FIL_PROOFS_USE_GPU_TREE_BUILDER", "FIL_PROOFS_USE_MULTICORE_SDR", "BELLMAN_CUSTOM_GPU"} {
|
||||
envValue, found := os.LookupEnv(envKey)
|
||||
if found {
|
||||
bo.EnvVar[envKey] = envValue
|
||||
}
|
||||
}
|
||||
|
||||
if c.Bool("json-out") {
|
||||
data, err := json.MarshalIndent(bo, "", " ")
|
||||
if err != nil {
|
||||
@@ -428,21 +465,25 @@ var sealBenchCmd = &cli.Command{
|
||||
|
||||
fmt.Println(string(data))
|
||||
} else {
|
||||
fmt.Printf("----\nresults (v27) (%d)\n", sectorSize)
|
||||
fmt.Println("environment variable list:")
|
||||
for envKey, envValue := range bo.EnvVar {
|
||||
fmt.Printf("%s=%s\n", envKey, envValue)
|
||||
}
|
||||
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 +516,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 +537,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 +546,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 +563,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 +582,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 +596,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 +637,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 +659,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 +670,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 +705,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 +754,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 +779,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 {
|
||||
|
||||
@@ -57,6 +57,7 @@ type gatewayDepsAPI interface {
|
||||
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
|
||||
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
StateSearchMsgLimited(ctx context.Context, msg cid.Cid, lookbackLimit abi.ChainEpoch) (*api.MsgLookup, error)
|
||||
StateWaitMsgLimited(ctx context.Context, msg cid.Cid, confidence uint64, h abi.ChainEpoch) (*api.MsgLookup, error)
|
||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*api.ActorState, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
|
||||
@@ -67,6 +68,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)
|
||||
}
|
||||
@@ -298,6 +300,10 @@ func (a *GatewayAPI) StateNetworkVersion(ctx context.Context, tsk types.TipSetKe
|
||||
return a.api.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) {
|
||||
return a.api.StateSearchMsgLimited(ctx, msg, a.stateWaitLookbackLimit)
|
||||
}
|
||||
|
||||
func (a *GatewayAPI) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
return a.api.StateWaitMsgLimited(ctx, msg, confidence, a.stateWaitLookbackLimit)
|
||||
}
|
||||
@@ -362,7 +368,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) {
|
||||
|
||||
@@ -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)
|
||||
@@ -80,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
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user