Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5324440f7d | ||
|
|
d04c01939d | ||
|
|
f2aea11971 | ||
|
|
1f754bdb78 | ||
|
|
46e5cc9317 | ||
|
|
6c6711e638 | ||
|
|
3d52c087cc | ||
|
|
0d72d742b4 | ||
|
|
884e20f637 | ||
|
|
210216a94f | ||
|
|
2af1283c65 | ||
|
|
d2b7e7b2ab | ||
|
|
3fa51f08e1 | ||
|
|
446b1cc883 | ||
|
|
3c7f5f7629 | ||
|
|
dc8ff27b36 | ||
|
|
65b921c62c | ||
|
|
c61f341b22 | ||
|
|
e33f873df8 | ||
|
|
46a5013dc1 | ||
|
|
53a6c4eac6 | ||
|
|
2e154ef6d0 | ||
|
|
47346907dd | ||
|
|
0cb2f51549 | ||
|
|
564b88af52 | ||
|
|
d347e7ab8f | ||
|
|
46c7f047d4 | ||
|
|
58729b7fd6 | ||
|
|
4767773d1b | ||
|
|
c9b489437d | ||
|
|
e07059e73d | ||
|
|
0570306bb6 | ||
|
|
0f08da3272 | ||
|
|
d4582fb32e | ||
|
|
3c50baaf5b | ||
|
|
e1be89b442 | ||
|
|
2ce5a29004 | ||
|
|
39e73e1cb4 | ||
|
|
bc9b5cb5fc | ||
|
|
9990d440e9 | ||
|
|
c6f5214657 | ||
|
|
696469aae7 | ||
|
|
d3fa728894 | ||
|
|
6ca5caef31 | ||
|
|
689b93dc0e | ||
|
|
72cb130e17 | ||
|
|
a999e41677 | ||
|
|
6b1c54162a | ||
|
|
5c37c9d8e9 | ||
|
|
b7975dcd9a | ||
|
|
3beebe5dc8 | ||
|
|
d56170d70e | ||
|
|
d9e3cc0374 | ||
|
|
a5a72a41eb | ||
|
|
2514c96cff | ||
|
|
88bd757024 | ||
|
|
1e6aa4b129 | ||
|
|
daca99687c | ||
|
|
65abeb066d | ||
|
|
13c8a235b6 | ||
|
|
b13226bc2f | ||
|
|
07afd93443 | ||
|
|
dc06d30f52 | ||
|
|
90a31fde9f | ||
|
|
f9cbf6d526 | ||
|
|
b190c3492a | ||
|
|
da5e1b319f | ||
|
|
ba7854d645 | ||
|
|
d844938a92 | ||
|
|
58695dc1bc | ||
|
|
1502ca6460 | ||
|
|
178691e37f | ||
|
|
93d26195f1 | ||
|
|
a584fcb935 | ||
|
|
bf93dfbc3b | ||
|
|
d033f8aab1 | ||
|
|
e34a759889 | ||
|
|
2ef8acdfc8 | ||
|
|
562f5839b7 | ||
|
|
c3a0feef96 | ||
|
|
2fd93a55ac | ||
|
|
783971d2c8 | ||
|
|
f74a1b70ab | ||
|
|
7246ef273f | ||
|
|
e8a5e0d2fe | ||
|
|
a415e49fdb | ||
|
|
655aea1018 | ||
|
|
9707c82285 | ||
|
|
370817eb60 | ||
|
|
97dd082585 | ||
|
|
3196b2cfd5 | ||
|
|
289ef910a0 | ||
|
|
95eaf13b5a | ||
|
|
c6f85886bf | ||
|
|
b6046924b3 | ||
|
|
bc14d0820f | ||
|
|
64e30808f8 | ||
|
|
28420b9eb0 | ||
|
|
b28ed5887c | ||
|
|
827ec75f5f | ||
|
|
c31774b08e | ||
|
|
be9f7b88b2 | ||
|
|
15c4793fe0 | ||
|
|
42cecbd879 | ||
|
|
00e5ace818 | ||
|
|
82b5cb89cd | ||
|
|
b7436cd300 | ||
|
|
715c32ff77 | ||
|
|
44d929c084 | ||
|
|
4b1d6bfcca | ||
|
|
614f45dcfb | ||
|
|
354b5af55a | ||
|
|
fc5120621b | ||
|
|
c4a6b94b9c | ||
|
|
054327b72a | ||
|
|
cb044f83a7 | ||
|
|
f1291f137c | ||
|
|
6bbb8ecafc | ||
|
|
ec08e27af2 | ||
|
|
c5a8b7076c | ||
|
|
4d019f16e4 | ||
|
|
ceea03cd40 | ||
|
|
32065f551e | ||
|
|
7bab281449 | ||
|
|
a8cdb8adc7 | ||
|
|
2be9836196 | ||
|
|
0439e95aa3 | ||
|
|
2e5843a0ee | ||
|
|
751568a4dd | ||
|
|
6dea0a6281 | ||
|
|
a4f3758f4c | ||
|
|
3e143cac4b | ||
|
|
0386cc5d48 | ||
|
|
e02a366419 | ||
|
|
d15ef9ac9b | ||
|
|
70732ac423 | ||
|
|
b18bc90dbc | ||
|
|
8382977e21 | ||
|
|
f4913c19b1 | ||
|
|
660ac26dd9 | ||
|
|
65d50c76d6 | ||
|
|
e8d2560581 | ||
|
|
dc7c7608df | ||
|
|
13a5b7f539 | ||
|
|
0c1592f2d3 | ||
|
|
61485beb22 | ||
|
|
01ad4c0514 | ||
|
|
09b9dfc3ce | ||
|
|
c66e594046 | ||
|
|
9ade05b33b | ||
|
|
13ff98416f | ||
|
|
4f675b76ad | ||
|
|
a6658a858f | ||
|
|
bfb5bad124 | ||
|
|
3672053ae9 | ||
|
|
4dfec7b232 | ||
|
|
23c7728edb | ||
|
|
aa278443d3 | ||
|
|
42173e29d6 | ||
|
|
32c159fa3a | ||
|
|
fad250058d | ||
|
|
2304ea0077 | ||
|
|
6df0340136 | ||
|
|
41d370557f | ||
|
|
dfb769c505 | ||
|
|
b916ac83cb | ||
|
|
74f040f9d5 | ||
|
|
fcec665267 | ||
|
|
506624f509 | ||
|
|
1f9ca1958e | ||
|
|
91259c29d4 | ||
|
|
e2278ebe6a | ||
|
|
eeb38fa649 | ||
|
|
ba87cb4fa9 | ||
|
|
65653a1747 | ||
|
|
663b3f4f21 | ||
|
|
d15d9b0fb9 | ||
|
|
86e25e7969 | ||
|
|
2e544e3e6a | ||
|
|
7904f135ff | ||
|
|
89493fe2b8 | ||
|
|
23bf3349d7 | ||
|
|
6166204bac | ||
|
|
97a76a4b9a | ||
|
|
f1948d54f0 | ||
|
|
cd7580e6d8 | ||
|
|
15aa8e5253 | ||
|
|
0c7962ce5f | ||
|
|
694834e8d5 | ||
|
|
47a4128311 | ||
|
|
239e180683 | ||
|
|
25070314ce | ||
|
|
214f46bc88 | ||
|
|
a63ef1dcd5 | ||
|
|
5ed79fa73e | ||
|
|
2e85b42665 | ||
|
|
eb2be69ace | ||
|
|
9cef300535 | ||
|
|
5f28c12f2e | ||
|
|
f850d77f1e | ||
|
|
7c831101f3 | ||
|
|
8b8449faee | ||
|
|
fe92a6e2d4 | ||
|
|
1f9c0f8040 | ||
|
|
7c0b6f41d8 | ||
|
|
bb25eb980d | ||
|
|
afec58f780 | ||
|
|
52da5acc96 | ||
|
|
fd640864cb | ||
|
|
3f151351aa | ||
|
|
844c0a3527 | ||
|
|
83b1009837 | ||
|
|
85e592bbe2 | ||
|
|
e2a6b99144 | ||
|
|
be2a5942fb | ||
|
|
ffa96389bc | ||
|
|
a145819004 | ||
|
|
0e39e760e5 | ||
|
|
721120fc60 | ||
|
|
3634ca50ca | ||
|
|
c965696586 | ||
|
|
53c39b1176 | ||
|
|
7e2d05cfd7 | ||
|
|
f601d1bf6b | ||
|
|
6ce14132cc | ||
|
|
c13ade3fbf | ||
|
|
7d540905ac | ||
|
|
4a8df0c3fa | ||
|
|
2d2ebdcc4b | ||
|
|
f3838a47c7 | ||
|
|
e7f3554c62 | ||
|
|
2609342356 | ||
|
|
9fe3649dd2 | ||
|
|
9b199f0476 | ||
|
|
b6893b0a3f | ||
|
|
69bfe7b7a8 | ||
|
|
218f7c2c5d | ||
|
|
375b7a1c4c | ||
|
|
3113b15217 | ||
|
|
34bca28416 | ||
|
|
99972c9e34 | ||
|
|
91a3d1d34a | ||
|
|
71dfc2e338 | ||
|
|
e9fae0425f | ||
|
|
17597fdd8f | ||
|
|
9613acd46b | ||
|
|
4b507f5be1 | ||
|
|
8508cdc00b | ||
|
|
4483d94db3 | ||
|
|
94763c2aaa | ||
|
|
d033042d6b | ||
|
|
54637d5093 | ||
|
|
7d4bc90d42 | ||
|
|
a13690dcf1 | ||
|
|
f0eac01a3c | ||
|
|
ef444676c2 | ||
|
|
853f9da457 | ||
|
|
bb9d2b5af4 | ||
|
|
7aec500384 | ||
|
|
b10b6fdd11 | ||
|
|
2d9123a618 | ||
|
|
96f004032b | ||
|
|
463a647118 | ||
|
|
df66f48f64 | ||
|
|
89ffd368b8 | ||
|
|
44040f0f3f | ||
|
|
1999156d06 | ||
|
|
b4fa099257 | ||
|
|
b7a282decc | ||
|
|
9f807f4aeb | ||
|
|
16dbbadddf | ||
|
|
648f02cbd6 | ||
|
|
880204045b | ||
|
|
9d2208e0e8 | ||
|
|
55061ae6fb | ||
|
|
2b611b3a99 | ||
|
|
de9cef62f7 | ||
|
|
ba56d02a1c | ||
|
|
e7b8511622 | ||
|
|
b1afa2022b | ||
|
|
3737a8f3cc | ||
|
|
7b39c3a907 | ||
|
|
62d20f2191 | ||
|
|
e9664a997e | ||
|
|
6d1bac7f70 | ||
|
|
dc3d17c9ea | ||
|
|
e061a8d163 | ||
|
|
9f34f98368 | ||
|
|
226efe28e5 | ||
|
|
452c85de98 | ||
|
|
09c996d572 | ||
|
|
adee4b2a5e | ||
|
|
322f34c6c6 | ||
|
|
49f8590578 | ||
|
|
016f5e44c0 | ||
|
|
9305947547 | ||
|
|
b92ce76a78 | ||
|
|
379100b470 | ||
|
|
8575f5518c | ||
|
|
707f9e31df | ||
|
|
52d34c8a5e | ||
|
|
68a16afeda | ||
|
|
50146fb9b9 | ||
|
|
c5470ee17e | ||
|
|
00335878ab | ||
|
|
4982de89b2 | ||
|
|
9328d98f84 | ||
|
|
3536ec9f85 | ||
|
|
8191654089 | ||
|
|
e23170d194 | ||
|
|
e7549dbf2c | ||
|
|
65202668af | ||
|
|
51e93feb9a | ||
|
|
c8d985b5c7 | ||
|
|
7ce4e5342b | ||
|
|
f580892e9e | ||
|
|
080a1165ee | ||
|
|
1413d6d4b7 | ||
|
|
9b64dba4a1 | ||
|
|
f9771c67fb | ||
|
|
238174cfca | ||
|
|
f130cd6fca | ||
|
|
336aa95ab5 | ||
|
|
c40c513508 | ||
|
|
bfbdbc04ba | ||
|
|
b242d69805 | ||
|
|
b8853aa4d5 | ||
|
|
fe448e706d | ||
|
|
193630f7b6 | ||
|
|
c597c43724 | ||
|
|
425ad9c5fa | ||
|
|
693bbee953 | ||
|
|
92b765bd21 | ||
|
|
7838752352 | ||
|
|
596b31fb9e | ||
|
|
2219bff1c9 | ||
|
|
5c791cd93b | ||
|
|
ce9146916a | ||
|
|
dff88b63b2 | ||
|
|
a2abeef727 | ||
|
|
dd9682f2be | ||
|
|
a152d98af8 | ||
|
|
27c0ce4a3a | ||
|
|
0c6072a1a0 | ||
|
|
d25e5d1c08 | ||
|
|
e0ade92b29 | ||
|
|
8db9c19e1c | ||
|
|
bc05618fd1 | ||
|
|
444239a643 | ||
|
|
bead8ac38e | ||
|
|
638900f97f | ||
|
|
d8afd71f4c | ||
|
|
869867e92e | ||
|
|
508375a55c | ||
|
|
1f91e7267d | ||
|
|
c8ff58aae1 | ||
|
|
4f33c91f81 | ||
|
|
423ff0631d | ||
|
|
948ee53080 | ||
|
|
4d8327c29a | ||
|
|
cd0cb1407d | ||
|
|
915c5e0fdd | ||
|
|
2a7e4af5ee | ||
|
|
931979809f | ||
|
|
584907269a | ||
|
|
05db5ce426 | ||
|
|
219c695967 | ||
|
|
4544d2118e | ||
|
|
d7c2c073a3 | ||
|
|
6bea9dd178 | ||
|
|
0a169357f7 | ||
|
|
b13a41a44d | ||
|
|
470538b082 | ||
|
|
bac51dd4e3 | ||
|
|
d7b4f92f1f | ||
|
|
87d6daf745 | ||
|
|
49d3bb9497 | ||
|
|
d4f6e1ddb4 | ||
|
|
b63687795d | ||
|
|
96d56ec096 | ||
|
|
6d0b3978b9 | ||
|
|
afe6c51016 | ||
|
|
09be3f0a01 | ||
|
|
6667220a27 | ||
|
|
1af1ceb1e0 | ||
|
|
ae76711ab4 | ||
|
|
fe339d46eb | ||
|
|
91e2530e11 | ||
|
|
f9fc601567 | ||
|
|
2b68ba5f1d | ||
|
|
4b187b85eb | ||
|
|
b8884adaf1 | ||
|
|
b71f069854 | ||
|
|
5a0b9f4197 | ||
|
|
4b1d1b6540 | ||
|
|
15fe726e65 | ||
|
|
17c2c0d1c8 | ||
|
|
2971dd4317 | ||
|
|
6742a74260 | ||
|
|
41af94f1b7 | ||
|
|
6bb67f2fe9 | ||
|
|
961a25298b | ||
|
|
5f1737379a | ||
|
|
c5c0185943 | ||
|
|
8fdb9148e4 | ||
|
|
d3d5f8d7f0 | ||
|
|
99031bae17 | ||
|
|
56373b0d46 | ||
|
|
7921f8d713 | ||
|
|
6d3e59e047 | ||
|
|
63f13977ce | ||
|
|
408183c7a6 | ||
|
|
11b041224e | ||
|
|
36b78b1891 | ||
|
|
a6d061d0f6 | ||
|
|
bf547112de | ||
|
|
5d9c79811f | ||
|
|
28ffa8ca06 | ||
|
|
55240b3e07 | ||
|
|
697a0a3b95 | ||
|
|
26e12e6f6a | ||
|
|
0e3e449bf8 | ||
|
|
f3922e7485 | ||
|
|
fb05bb7f07 | ||
|
|
8246149544 | ||
|
|
d525acdeda | ||
|
|
2f0075752d | ||
|
|
8409e155d4 | ||
|
|
3a3986320c | ||
|
|
498477da04 | ||
|
|
29817b6617 | ||
|
|
7be7a9b5e3 | ||
|
|
a389622ac6 | ||
|
|
72547f9ec3 | ||
|
|
04a866121e | ||
|
|
f4df58ed0f | ||
|
|
bc7eaee6d3 | ||
|
|
ff7bdb5140 | ||
|
|
6184d228c1 | ||
|
|
8ac495723e | ||
|
|
09f9f871a3 | ||
|
|
2a3d930933 | ||
|
|
bd71bf2379 | ||
|
|
6f593d53d0 | ||
|
|
d1e4211f4b | ||
|
|
9745f676ed | ||
|
|
90dd39d581 | ||
|
|
9011e88f9f | ||
|
|
0e20a65a0b | ||
|
|
28c4a2d8fa | ||
|
|
ea810ac806 | ||
|
|
11ed015dca | ||
|
|
029c516cbc | ||
|
|
c6b9e4951f | ||
|
|
ebd6b0da49 | ||
|
|
cceb74a66e | ||
|
|
9f7204ee26 | ||
|
|
0d243bb824 | ||
|
|
e53b0ef068 | ||
|
|
1301fd6ddb | ||
|
|
0101436933 | ||
|
|
0e0ffc9c10 | ||
|
|
a51a62cb42 | ||
|
|
86c204d8a8 | ||
|
|
1182927fe5 | ||
|
|
4d3cd7dcb8 | ||
|
|
8b889139e9 | ||
|
|
1323dbddfe | ||
|
|
c02341c85f | ||
|
|
735c04f999 | ||
|
|
bc6965c86f | ||
|
|
075297d8ad | ||
|
|
8f5847b8e3 | ||
|
|
ab7ee2f8a9 | ||
|
|
18aa97f962 | ||
|
|
2ae0edc4df | ||
|
|
89632416ba | ||
|
|
61fa94617d | ||
|
|
659ceaabdd | ||
|
|
d79ff24014 | ||
|
|
1df7318450 | ||
|
|
60debfb0a6 | ||
|
|
379dd02fb6 | ||
|
|
339391ecfb | ||
|
|
38c404e04e | ||
|
|
f8c3756ac0 | ||
|
|
360194b29b | ||
|
|
af7236f7e7 | ||
|
|
6d78de95a1 | ||
|
|
577476b8fe | ||
|
|
54bf7c99d7 | ||
|
|
e340996919 | ||
|
|
f5401317c9 | ||
|
|
de2637b4fa | ||
|
|
ea726c9f17 | ||
|
|
314dda08e8 | ||
|
|
b010ac21d3 | ||
|
|
7519bdde42 | ||
|
|
09a0d6e607 | ||
|
|
a3e93554e5 | ||
|
|
d2acc78787 | ||
|
|
3ec25cbece | ||
|
|
5caa277261 | ||
|
|
f819e71d12 | ||
|
|
27a9dd3bbb | ||
|
|
5b8f555221 | ||
|
|
fbc05fa5a8 | ||
|
|
95d9084899 | ||
|
|
f31383516e | ||
|
|
82e88a3239 | ||
|
|
3a3270b37c | ||
|
|
290414e935 | ||
|
|
e1122404d1 | ||
|
|
185653f85a | ||
|
|
72a3b41315 | ||
|
|
5bcc6339b4 | ||
|
|
8c8396af59 | ||
|
|
7b8158b1af | ||
|
|
3665f90795 | ||
|
|
f225b7b928 | ||
|
|
4a3ff8ff9e | ||
|
|
378d7a1ad9 | ||
|
|
9a76c648f1 | ||
|
|
6660f81363 | ||
|
|
84c9d1dbb7 | ||
|
|
08aab1c48a | ||
|
|
9149ae2164 | ||
|
|
ec13c5f80d | ||
|
|
4058f5642f | ||
|
|
48bdf79b5b | ||
|
|
bf500711b3 | ||
|
|
f7f5a27ebf | ||
|
|
1f678c17d3 | ||
|
|
5a34e5b2bf | ||
|
|
3577300aee | ||
|
|
258cc0067b | ||
|
|
0b2a02c8ea | ||
|
|
7c442e1a98 | ||
|
|
85e37e4b70 | ||
|
|
de4a0725f3 | ||
|
|
426c2e8c2b | ||
|
|
db1159414f | ||
|
|
6bb8521a55 | ||
|
|
3c9e438a68 | ||
|
|
2f9d19c42c | ||
|
|
ee9df63221 | ||
|
|
2076abf0c1 | ||
|
|
273da38bdd | ||
|
|
d98e989417 | ||
|
|
7f47bf452a | ||
|
|
a3f5d0f590 | ||
|
|
94438bf3cd | ||
|
|
df7f13d069 | ||
|
|
8befc0c1f5 | ||
|
|
dab20efc99 | ||
|
|
0e40a04975 | ||
|
|
c6cd699f0d | ||
|
|
3306bdec29 | ||
|
|
32b7797394 | ||
|
|
b1aa43741a | ||
|
|
c966054bf6 | ||
|
|
105f0fd49a | ||
|
|
fe95d19e29 | ||
|
|
2a294f048a | ||
|
|
bd4322f56f | ||
|
|
a411342f0c | ||
|
|
370ef93db6 | ||
|
|
7d540fc0d8 | ||
|
|
fd1439f284 | ||
|
|
a1e1b03ca4 | ||
|
|
87ce2f774d | ||
|
|
9deda06ec6 | ||
|
|
b0824ada15 | ||
|
|
5487356370 | ||
|
|
97a06444f2 | ||
|
|
809111336a | ||
|
|
18418128c3 | ||
|
|
581ac5b019 | ||
|
|
cde0e58e39 | ||
|
|
842c8ca056 | ||
|
|
fe4298674f | ||
|
|
3e7efad0fd | ||
|
|
9270ac6358 | ||
|
|
d421274dcd | ||
|
|
3c2cd506ec | ||
|
|
1df02d5a93 | ||
|
|
fdd90e036f | ||
|
|
761c9ee2b6 | ||
|
|
c215615da3 | ||
|
|
b7b6252048 | ||
|
|
6d27531663 | ||
|
|
3c44407c57 | ||
|
|
bfa04da572 | ||
|
|
e547710c6d | ||
|
|
5c3055219c | ||
|
|
46619fbb8d | ||
|
|
4d9c90ed4a | ||
|
|
af1743f9f3 | ||
|
|
b5d2f01993 | ||
|
|
af8cc3d29f | ||
|
|
e68f69b63b | ||
|
|
a4cf6fa715 | ||
|
|
656ece06e5 | ||
|
|
1d17d61dbc | ||
|
|
d457b7a5e3 | ||
|
|
398a831701 | ||
|
|
61fa03b1ad | ||
|
|
56980ffc1f | ||
|
|
d1ebf3c769 | ||
|
|
7facdf63c9 | ||
|
|
f4e13ffd80 | ||
|
|
44e34d9606 | ||
|
|
35ccd73a86 | ||
|
|
aece624d1c | ||
|
|
c2355b18f9 | ||
|
|
634467d24b | ||
|
|
0b8a21ee16 | ||
|
|
72e573d98d | ||
|
|
5a98660d1b | ||
|
|
d8d85373f5 | ||
|
|
a16d7f221e | ||
|
|
95f512aa69 | ||
|
|
099c4b5e1d | ||
|
|
9437136f84 | ||
|
|
d2e2322fd2 | ||
|
|
ce27b13076 | ||
|
|
a5c05f87f1 | ||
|
|
7cba0b25fd | ||
|
|
978192233d | ||
|
|
c6a8efff7d | ||
|
|
0f8dadadf5 | ||
|
|
862c5b61a4 | ||
|
|
6fcdf3c7ed | ||
|
|
8eae921cbf | ||
|
|
5a7863d21a | ||
|
|
077bc83f7f | ||
|
|
22742a9ba0 | ||
|
|
3b16faddad | ||
|
|
094ea3fe97 | ||
|
|
6985af5e88 | ||
|
|
6cdbf5216e | ||
|
|
f380d6be43 | ||
|
|
fb492d9acb | ||
|
|
a7ff906e17 | ||
|
|
696a6867dd | ||
|
|
12f6119739 | ||
|
|
885c6c94d3 | ||
|
|
8afceee7a9 | ||
|
|
d6e2c80608 | ||
|
|
2f4582147a | ||
|
|
69e44ebf07 | ||
|
|
f90a387f96 | ||
|
|
5dcf339840 | ||
|
|
774e2ecebf | ||
|
|
af1d45d969 | ||
|
|
79a8ff04fd | ||
|
|
7fbb868513 | ||
|
|
f6ecff0e26 | ||
|
|
5ff42505e8 | ||
|
|
c3d00b0ac6 | ||
|
|
ae7889f830 | ||
|
|
d8d9291402 | ||
|
|
7d02cd6679 | ||
|
|
7d0f279353 | ||
|
|
ad9a5acb7f | ||
|
|
8d25fd39cf | ||
|
|
ee814fb48e | ||
|
|
57234d8ef3 | ||
|
|
47830efbf5 | ||
|
|
dc5d6316c9 | ||
|
|
a650641813 | ||
|
|
8702ff8b7e | ||
|
|
c6b03ce62b | ||
|
|
ea5bb5cdab | ||
|
|
e168f7a917 | ||
|
|
33459f1b36 | ||
|
|
f0f75e2d2c | ||
|
|
a26420f6e8 | ||
|
|
ae905bd056 | ||
|
|
7b8dae92d9 | ||
|
|
c80e8cb7d3 | ||
|
|
a2c66dd102 | ||
|
|
0297be4b9a | ||
|
|
ecc1d94b3a | ||
|
|
553408d573 | ||
|
|
e33cc5ee12 | ||
|
|
32ea060e99 | ||
|
|
ad905fc310 | ||
|
|
5f657b4333 | ||
|
|
704bef5dfc | ||
|
|
f79652c28c | ||
|
|
e575b5fe8a | ||
|
|
da7ecc1527 | ||
|
|
86f9abda0d | ||
|
|
4475b9ac05 | ||
|
|
4100f6eead | ||
|
|
ed2f81da2f | ||
|
|
4cf00b8b42 | ||
|
|
96c5ff7e7f | ||
|
|
8731fe9112 | ||
|
|
84b567c790 | ||
|
|
ba2512655e | ||
|
|
6266bae1d3 | ||
|
|
188d1649d3 | ||
|
|
9ddf7bbd15 | ||
|
|
469666de82 | ||
|
|
fc1ac3e752 | ||
|
|
ab7a66b90d | ||
|
|
2b82e5a118 | ||
|
|
16d2cb6309 | ||
|
|
413643a712 | ||
|
|
843c0719e0 | ||
|
|
3d02dba5dc | ||
|
|
efc8d90bc1 | ||
|
|
1db69acbc0 | ||
|
|
c0f6f834b7 | ||
|
|
8c60069bb8 | ||
|
|
e1da874258 | ||
|
|
616e0e8eb5 | ||
|
|
89f6da14bc | ||
|
|
832c0998e4 | ||
|
|
0d06f8fa2b | ||
|
|
2b6bc7d59a | ||
|
|
0d384050fa | ||
|
|
8141f7b6a6 | ||
|
|
cced3bf9ee | ||
|
|
ea6afe84db | ||
|
|
382dcf9a37 | ||
|
|
8923524f6a | ||
|
|
31a474a1ca | ||
|
|
1afd3a41cb | ||
|
|
5a6195feb6 | ||
|
|
2fd0d430c8 | ||
|
|
f055681972 | ||
|
|
1fefcc2b46 | ||
|
|
c0a039ee11 | ||
|
|
09f1d00733 | ||
|
|
f26385d0c6 | ||
|
|
b097a5fb0c | ||
|
|
af53b72eb8 | ||
|
|
a37c372d06 | ||
|
|
8fe7db107a | ||
|
|
5d34b7d618 | ||
|
|
43b492204c | ||
|
|
ce9cce921d | ||
|
|
5ed57d34f0 | ||
|
|
e65aa4cf17 | ||
|
|
bfbf6a2711 | ||
|
|
6b76371d64 | ||
|
|
cdfa869ea6 | ||
|
|
d4cdc6d334 | ||
|
|
7b3f1c2b85 | ||
|
|
9972f19240 | ||
|
|
f23034305f | ||
|
|
2663d6c3cb | ||
|
|
8b8d81e767 | ||
|
|
d43bc79050 | ||
|
|
06af2fb52b | ||
|
|
8bb69f1e9c | ||
|
|
b98b2d4310 | ||
|
|
f05b03f02c | ||
|
|
4d87473053 | ||
|
|
660236b224 | ||
|
|
194f56377e | ||
|
|
2023615f55 | ||
|
|
de2cbfa8a9 | ||
|
|
067de4508b | ||
|
|
74bf4c5e71 | ||
|
|
099bb2cbaa | ||
|
|
e395559f75 | ||
|
|
b7b6ab779a | ||
|
|
109b326ae2 | ||
|
|
c7e6c8eacc | ||
|
|
9fbd2a50ff | ||
|
|
ea69386519 | ||
|
|
8124fe98c7 | ||
|
|
16a911bc39 | ||
|
|
c81db5a21c | ||
|
|
dbcba6477e | ||
|
|
36816fb4f3 | ||
|
|
1ec8252412 | ||
|
|
91fae36b86 | ||
|
|
623ffebe62 | ||
|
|
906286fdbe | ||
|
|
92942d44d1 | ||
|
|
9caa6ae69c | ||
|
|
39d9150175 | ||
|
|
5301c416bc | ||
|
|
92395745d3 | ||
|
|
7d9e8f9d92 | ||
|
|
6842c03399 | ||
|
|
2c3d80494f | ||
|
|
2cf770cc91 | ||
|
|
bfdb74bfee | ||
|
|
580a2f4dc6 | ||
|
|
c8fe21c1ef | ||
|
|
59cfabf8a4 | ||
|
|
810feee5a1 | ||
|
|
24fc7d4cbd | ||
|
|
5edfc527b0 | ||
|
|
febc28f83f | ||
|
|
98297cef4d | ||
|
|
0289c39850 | ||
|
|
29e334de54 | ||
|
|
f9723ca3c1 | ||
|
|
c17e8e778d | ||
|
|
b2510e5fc5 | ||
|
|
6c800bd0e3 | ||
|
|
88ac85b6ae | ||
|
|
6bdf9935bf | ||
|
|
29cda82eac | ||
|
|
b05613445e | ||
|
|
defeba5576 | ||
|
|
4a550d12d4 | ||
|
|
70c39fe78c | ||
|
|
6fc8550c19 | ||
|
|
6b9a4c4a34 | ||
|
|
041762a34f | ||
|
|
25c4a1bd8d | ||
|
|
05b459e4c5 | ||
|
|
1665d61c89 | ||
|
|
9a58763a4e | ||
|
|
f9707ba344 | ||
|
|
ae04f3029b | ||
|
|
40872e9d90 | ||
|
|
ee8d8bf5e5 | ||
|
|
b85bf82d00 | ||
|
|
6fb3dafa95 | ||
|
|
f5960df544 | ||
|
|
93227bfd4d | ||
|
|
0832d5a7d5 | ||
|
|
602d2b8ad5 | ||
|
|
0341944350 | ||
|
|
00d1e6b549 | ||
|
|
9c17ac5bde | ||
|
|
90ce1c018e | ||
|
|
618fed75fe | ||
|
|
ef9eea470c | ||
|
|
9d9da1a3e8 | ||
|
|
7c16f2182c | ||
|
|
9dc9bf5eb0 | ||
|
|
035a762358 | ||
|
|
7f98be2920 | ||
|
|
7bdc7aa527 | ||
|
|
5c9c08ef85 | ||
|
|
5e23933757 | ||
|
|
9d15a08d27 | ||
|
|
0c2ec04c09 | ||
|
|
30bda0b4c4 | ||
|
|
710ac9d544 | ||
|
|
bcabe7b3b5 | ||
|
|
4e730b5ec8 | ||
|
|
f0d966a595 | ||
|
|
8cad245f80 | ||
|
|
7cbd4d49c3 | ||
|
|
7a33d5bb34 | ||
|
|
3e767ca5c8 | ||
|
|
c767399fc6 | ||
|
|
3a46c15c4a | ||
|
|
00dcb1bce9 | ||
|
|
420ec18c5b | ||
|
|
d78dd42ed4 | ||
|
|
547c01f5ff | ||
|
|
75eb644108 | ||
|
|
ee5dcbc1d8 | ||
|
|
7f46ad19ac | ||
|
|
6530431995 | ||
|
|
ed1645109a | ||
|
|
277d3e9ab4 | ||
|
|
556f92a823 | ||
|
|
ef32449309 | ||
|
|
e08032da93 | ||
|
|
dc40469cb3 | ||
|
|
abc3e783ff | ||
|
|
6bc56c549a | ||
|
|
580980d149 | ||
|
|
c779e4e8ee | ||
|
|
ee0078f7c1 | ||
|
|
da044d8b00 | ||
|
|
09e92f98ff | ||
|
|
0dbf10ce69 | ||
|
|
e7a68dba58 | ||
|
|
608010c35d | ||
|
|
1c6ea75f4b | ||
|
|
1ee9fb44e2 | ||
|
|
473afc41e7 | ||
|
|
a055540c25 | ||
|
|
cb0513f4c1 | ||
|
|
be42dd824b | ||
|
|
06c0444d45 | ||
|
|
bae735447d | ||
|
|
1974490ab0 | ||
|
|
d24d3e420d | ||
|
|
869d71446d | ||
|
|
268d29222a | ||
|
|
1a10f95973 | ||
|
|
8c86ea6b75 | ||
|
|
dbb421c4f7 | ||
|
|
879aa9512d | ||
|
|
cf4dfa3a05 | ||
|
|
f933e1d2b7 | ||
|
|
8d06cca073 | ||
|
|
7ac5dc55d0 | ||
|
|
0f5aa9ba5c | ||
|
|
68be28ca6d | ||
|
|
70e2170e3e | ||
|
|
4de8f50642 | ||
|
|
4a057d84b8 | ||
|
|
a8430088b2 | ||
|
|
111942b50b | ||
|
|
40e34b334a | ||
|
|
1a049a4f8e | ||
|
|
d0e4150cea | ||
|
|
0775c6c9d5 | ||
|
|
2fd4a97698 | ||
|
|
89f46cb5cc | ||
|
|
6f86b95f62 | ||
|
|
a71fbee2d1 | ||
|
|
99c07703f8 | ||
|
|
af1a422ddd | ||
|
|
8351420404 | ||
|
|
7826cc0bab | ||
|
|
cb801d47c7 | ||
|
|
726eacbe03 | ||
|
|
17fcf30edd | ||
|
|
eae7d62a2b | ||
|
|
5bee85d57a | ||
|
|
0b7dc6971d | ||
|
|
8c7d2efe72 | ||
|
|
a931ff94e9 | ||
|
|
c56ef260d5 | ||
|
|
955d7f9c54 | ||
|
|
1fb9ed1c9a | ||
|
|
7e6ede7563 | ||
|
|
4e659e30c5 | ||
|
|
f5d48b0e86 | ||
|
|
f74852bd73 | ||
|
|
9c99171cb8 | ||
|
|
925606ff26 | ||
|
|
90d2a92a2d | ||
|
|
2818353418 | ||
|
|
ccc780f35a | ||
|
|
fdb115e369 | ||
|
|
3bd2e2f777 | ||
|
|
6d771d29c7 | ||
|
|
b29e3b5242 | ||
|
|
8340124786 | ||
|
|
8f98c7d960 | ||
|
|
3fb5334959 | ||
|
|
a40fc98e56 | ||
|
|
8bb84acbc5 | ||
|
|
22f49f8946 | ||
|
|
1350079503 | ||
|
|
251374eca7 | ||
|
|
a50a5366b2 | ||
|
|
52800f5dca | ||
|
|
958f169267 | ||
|
|
df6f4a572c | ||
|
|
698b49b7ef | ||
|
|
7e5b1ac272 | ||
|
|
86e30729bf | ||
|
|
7ccb2aabf0 | ||
|
|
811f1304e6 | ||
|
|
6de82364e9 | ||
|
|
d02d4bc275 | ||
|
|
39670df6af | ||
|
|
28823fb8e9 | ||
|
|
ddade32bd3 | ||
|
|
15fe998c68 | ||
|
|
4b38809c0b | ||
|
|
e2fbbdcb15 | ||
|
|
bbc6de94fc | ||
|
|
ea1349205b | ||
|
|
470a565c34 | ||
|
|
04bbeface6 | ||
|
|
8df58064e3 | ||
|
|
01de4cb2ec | ||
|
|
b060569fe9 | ||
|
|
dfd6fbfaa4 | ||
|
|
d3d304bfd7 | ||
|
|
ab4f051b83 | ||
|
|
881e37ec02 | ||
|
|
12f36c5bda | ||
|
|
194c9d6e07 | ||
|
|
45cd510da1 | ||
|
|
00a5083146 | ||
|
|
c6ed6a0d65 | ||
|
|
4ad8d85b13 | ||
|
|
465703b618 | ||
|
|
30dd5d9644 | ||
|
|
2613e837a9 | ||
|
|
41bfeb56e2 | ||
|
|
2e7cd024df | ||
|
|
bf619862c3 | ||
|
|
29e54c40be | ||
|
|
308144ee6a | ||
|
|
ce54110228 | ||
|
|
458ea277fc | ||
|
|
58662b79b3 | ||
|
|
7dbc8965be | ||
|
|
2426700821 | ||
|
|
51aca86e98 | ||
|
|
9c6ee802cc | ||
|
|
b61281ba4b | ||
|
|
3d80c38064 | ||
|
|
98c1aa7988 | ||
|
|
d5cea9f402 | ||
|
|
b74a3229f8 | ||
|
|
71b3b9075d | ||
|
|
20c57fcd0e | ||
|
|
ce548c8f95 | ||
|
|
8987defb9d | ||
|
|
fbe76d0fa1 | ||
|
|
1a70dbe37d | ||
|
|
87cd8c6725 | ||
|
|
1eb2d0ae50 | ||
|
|
5fd0bf11ba | ||
|
|
4edebcec2b | ||
|
|
619ee1e6f9 | ||
|
|
0e88f32d66 | ||
|
|
546614455f | ||
|
|
0b9499a00f | ||
|
|
448ca6e43c | ||
|
|
c9955c0635 | ||
|
|
768d2db114 | ||
|
|
79d94c4771 | ||
|
|
a3e26233b2 | ||
|
|
07d0b67628 | ||
|
|
9b4cac9612 | ||
|
|
8232cc8415 | ||
|
|
be74a13736 | ||
|
|
195d96ccc0 | ||
|
|
49155ace62 | ||
|
|
83624a8858 | ||
|
|
96e1dfd8d7 | ||
|
|
61661fb1f0 | ||
|
|
6c08120628 | ||
|
|
8d769f0c07 | ||
|
|
79c5d2c6d2 | ||
|
|
224a96431f | ||
|
|
8001ed3030 | ||
|
|
2855c2bc49 | ||
|
|
65883cbb6b | ||
|
|
b7726c4ca8 | ||
|
|
443131b214 | ||
|
|
8b648cf77c | ||
|
|
c0961fb63d | ||
|
|
dc4e73c737 | ||
|
|
a6b2180756 | ||
|
|
160f209f6a | ||
|
|
a9d8bc7c45 | ||
|
|
92177b5738 | ||
|
|
4ac2bee81c | ||
|
|
a2e0832a12 | ||
|
|
8fd9b5f235 | ||
|
|
a95e343dee | ||
|
|
c296e1bbca | ||
|
|
ae366972a9 | ||
|
|
b4215e5f46 | ||
|
|
df7ee610cd | ||
|
|
fda8b932ba | ||
|
|
bae3b7d594 | ||
|
|
7b4a5fc7ca | ||
|
|
d6c8276c7a | ||
|
|
2b21fdef33 | ||
|
|
6a232e7214 | ||
|
|
7ee6bafd23 | ||
|
|
753d7b71a9 | ||
|
|
bb6a354b62 | ||
|
|
8ae66d6c6a | ||
|
|
2c92157233 | ||
|
|
66d6113340 | ||
|
|
99791a6953 | ||
|
|
b35f9b56b4 | ||
|
|
23470bc38f | ||
|
|
a36ec27230 | ||
|
|
40b2e2d0c1 | ||
|
|
85be11fb75 | ||
|
|
bc1f18b73a | ||
|
|
cc8a0f8022 | ||
|
|
c3a405eac7 | ||
|
|
e4209d86f6 | ||
|
|
fcb9dea501 | ||
|
|
c810b157cf | ||
|
|
c458f6e826 | ||
|
|
c99e223cb1 | ||
|
|
5c27d6aeee | ||
|
|
00620aac57 | ||
|
|
32d95fc97a | ||
|
|
a491fc97b9 | ||
|
|
151577f04e | ||
|
|
c463582528 | ||
|
|
7245ac2b69 | ||
|
|
58f13a7d5a | ||
|
|
e7d3b2503e | ||
|
|
ee8b8b8174 | ||
|
|
4fa6afad13 | ||
|
|
a80e98dc05 | ||
|
|
23f5a99117 | ||
|
|
651522cbaa | ||
|
|
388c9afce0 | ||
|
|
9a26896c69 | ||
|
|
2db8b7efa7 | ||
|
|
18e58467f8 | ||
|
|
1401efb115 | ||
|
|
f417d39a08 | ||
|
|
11e35cf911 | ||
|
|
10d464a1eb | ||
|
|
d84f5dabab | ||
|
|
f3abd1ae82 | ||
|
|
85abca4b16 | ||
|
|
6610a247cf | ||
|
|
a6d9b302fa | ||
|
|
f32b3bf99b | ||
|
|
114a1aaffd | ||
|
|
83ba7ec8cc | ||
|
|
83dfc460d4 | ||
|
|
283fd054e8 | ||
|
|
09bff14d85 | ||
|
|
3cb1abba4f | ||
|
|
e0dcb0ec49 | ||
|
|
d4c92942e7 | ||
|
|
f773ab4b28 | ||
|
|
c0182f8301 | ||
|
|
c06f394b81 | ||
|
|
748d2e82a7 | ||
|
|
a5c78371fd | ||
|
|
d80e7eda93 | ||
|
|
9f9d5cb2a5 | ||
|
|
fdaa9c14ad | ||
|
|
9d8932d395 | ||
|
|
105aa40007 | ||
|
|
110f033c83 | ||
|
|
f87d325b6f | ||
|
|
ab8286fa38 | ||
|
|
4cca3f19a3 | ||
|
|
feb4b3c8b4 | ||
|
|
7f7c9e978f | ||
|
|
200a95f824 | ||
|
|
d69e4c7cf2 | ||
|
|
b2834baa4b | ||
|
|
e9e27cbbb0 | ||
|
|
ef73b964fb | ||
|
|
7b1bec91ed | ||
|
|
b32d25c562 | ||
|
|
767611247c | ||
|
|
be09a8a00a | ||
|
|
2719adc1b1 | ||
|
|
f1b1d8cec6 | ||
|
|
8fa4c0a970 | ||
|
|
00a14de094 | ||
|
|
eec13ff8dc | ||
|
|
1ffdd7d5b3 | ||
|
|
e19cd9ed01 | ||
|
|
bacac245c7 | ||
|
|
e1792ffe4d | ||
|
|
9c35762966 | ||
|
|
4832cad1f1 | ||
|
|
5930bf6d93 | ||
|
|
d37389162e | ||
|
|
356137439f | ||
|
|
6cc7559b04 | ||
|
|
3cd53ad9d9 | ||
|
|
6c54d2445d | ||
|
|
6a10af626c | ||
|
|
597d065e05 | ||
|
|
791aa5c6c8 | ||
|
|
82b15d2637 | ||
|
|
7d2f06cfbd | ||
|
|
6e8efb9d2c | ||
|
|
f3dc730b05 | ||
|
|
114776f2c5 | ||
|
|
4835109470 | ||
|
|
8783c7434e | ||
|
|
2d3b61675b | ||
|
|
a23ab123d7 | ||
|
|
26ed6af040 | ||
|
|
82bd7bd2ec | ||
|
|
cd0a43b7f4 | ||
|
|
b14632b750 | ||
|
|
ebcf77e830 | ||
|
|
344d30e960 | ||
|
|
efb13a0d9b | ||
|
|
0223582d41 | ||
|
|
973f61bc10 | ||
|
|
60768f4863 | ||
|
|
c60d13ee56 | ||
|
|
0f8fc119f3 | ||
|
|
e4d2e6e01d | ||
|
|
d55f10bed6 | ||
|
|
21de538d09 | ||
|
|
fe5b32026a | ||
|
|
91c10c2df5 | ||
|
|
c3420c0ceb | ||
|
|
7933cf094f | ||
|
|
1a64caaa4d | ||
|
|
4cd73f1560 | ||
|
|
8a175a7465 | ||
|
|
f7f229ae54 | ||
|
|
1323e07a2c | ||
|
|
2ad671649c | ||
|
|
d26ece10b8 | ||
|
|
4c8084dcb0 | ||
|
|
98d702fb5a | ||
|
|
17f61ac212 | ||
|
|
df67576b89 | ||
|
|
cdc2f86f5a | ||
|
|
67b3a55e30 | ||
|
|
3201e0eb8f | ||
|
|
8d2d74438b | ||
|
|
1f9446f91f | ||
|
|
4937ca1a96 | ||
|
|
264fe4edb9 | ||
|
|
cb7d99fcc7 | ||
|
|
7332a39f00 | ||
|
|
0de3051821 | ||
|
|
0f53eca883 | ||
|
|
cd9af278b4 | ||
|
|
4cc1fcb37b | ||
|
|
8f4911ac0d | ||
|
|
12cd478e11 | ||
|
|
e55b00f358 | ||
|
|
6f4a762664 | ||
|
|
c02daca9e9 | ||
|
|
5bd6a3cdad | ||
|
|
44af7e43b6 | ||
|
|
673de6aeb6 | ||
|
|
bf959e45fb | ||
|
|
ce247bcab3 | ||
|
|
2a6e05b776 | ||
|
|
fe1ef154cf | ||
|
|
6b3ffdbd3d | ||
|
|
0017ea8fd0 | ||
|
|
a5b57068d4 | ||
|
|
921d78f820 | ||
|
|
ef3987e2ab | ||
|
|
6b5f8a6b1d | ||
|
|
5932f28519 | ||
|
|
79d2ddf24f | ||
|
|
2cfe22d4e5 | ||
|
|
e3ee4e4718 | ||
|
|
2d16af6ee6 | ||
|
|
4f97d9637e | ||
|
|
c228598098 | ||
|
|
a783bf9b8b | ||
|
|
54fdd6ba5a | ||
|
|
6ddea62d09 | ||
|
|
6855284d88 | ||
|
|
46a5beafe4 | ||
|
|
0f2dcf28b1 | ||
|
|
bc7f20e179 | ||
|
|
1e6a69f8aa | ||
|
|
9bd2537971 | ||
|
|
bf554d0e43 | ||
|
|
810c767200 | ||
|
|
4ba7af6061 | ||
|
|
86cf3c835e | ||
|
|
9e7d6823b1 | ||
|
|
aa7090df49 | ||
|
|
a9d1ca4d83 | ||
|
|
400af0d2fa | ||
|
|
41ab87e904 | ||
|
|
cf71f034dc | ||
|
|
1a7aea1906 | ||
|
|
3207bc4704 | ||
|
|
60e950015c | ||
|
|
08fc0b7aec | ||
|
|
a8fcb86c10 | ||
|
|
48b7945714 | ||
|
|
c507f409a5 | ||
|
|
72537b6614 | ||
|
|
c839c5721c | ||
|
|
04ee53e061 | ||
|
|
f57652524c | ||
|
|
d817dceb05 | ||
|
|
c17f0d7e61 | ||
|
|
3003789288 | ||
|
|
86c222ab58 | ||
|
|
f21ca8591c | ||
|
|
ce6b92484f | ||
|
|
80619fa8a0 | ||
|
|
9a0d5cd739 | ||
|
|
6185e157e9 | ||
|
|
04ad1791b0 | ||
|
|
bb5cc06677 | ||
|
|
706f4f2ef5 | ||
|
|
36b8a017bd | ||
|
|
b8865fb182 | ||
|
|
03c3d8bdb3 | ||
|
|
aa5bd7bc17 | ||
|
|
1c9257d537 | ||
|
|
ea56e56ec1 | ||
|
|
17680fff55 | ||
|
|
d9d644b27f | ||
|
|
5e09581256 | ||
|
|
ed7423b2b5 | ||
|
|
77a956cda4 | ||
|
|
a9253837ac | ||
|
|
63f903a3fb | ||
|
|
f702ce331a | ||
|
|
b1361aaf8b | ||
|
|
8b7e7d438c | ||
|
|
097d82535d | ||
|
|
03cf6cca40 | ||
|
|
20a0f7ac68 | ||
|
|
6cff57ab43 | ||
|
|
e9d25e5919 | ||
|
|
381a6cdfac | ||
|
|
1ebca8f732 | ||
|
|
172204c933 | ||
|
|
77000db747 | ||
|
|
6563a68ae2 | ||
|
|
d9bcdfe61b | ||
|
|
5f08fe7ead | ||
|
|
d3f6657032 | ||
|
|
554570f884 | ||
|
|
231a9e4051 | ||
|
|
9e6f974f3c | ||
|
|
06e3852cef | ||
|
|
5d73943929 | ||
|
|
159ce13f5e | ||
|
|
780f6dba34 | ||
|
|
f90cfda2e6 | ||
|
|
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 |
+63
-11
@@ -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:
|
||||
@@ -34,7 +34,7 @@ commands:
|
||||
condition: << parameters.linux >>
|
||||
steps:
|
||||
- run: sudo apt-get update
|
||||
- run: sudo apt-get install ocl-icd-opencl-dev
|
||||
- run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev
|
||||
- run: git submodule sync
|
||||
- run: git submodule update --init
|
||||
download-params:
|
||||
@@ -188,6 +188,14 @@ jobs:
|
||||
command: |
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
test-chain:
|
||||
<<: *test
|
||||
test-node:
|
||||
<<: *test
|
||||
test-storage:
|
||||
<<: *test
|
||||
test-cli:
|
||||
<<: *test
|
||||
test-short:
|
||||
<<: *test
|
||||
test-window-post:
|
||||
@@ -256,22 +264,44 @@ jobs:
|
||||
path: /tmp/test-artifacts/conformance-coverage.html
|
||||
build-lotus-soup:
|
||||
description: |
|
||||
Compile `lotus-soup` Testground test plan using the current version of Lotus.
|
||||
Compile `lotus-soup` Testground test plan
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: cd extern/oni && git submodule sync
|
||||
- run: cd extern/oni && git submodule update --init
|
||||
- run: cd extern/filecoin-ffi && make
|
||||
- run:
|
||||
name: "replace lotus, filecoin-ffi, blst and fil-blst deps"
|
||||
command: cd extern/oni/lotus-soup && go mod edit -replace github.com/filecoin-project/lotus=../../../ && go mod edit -replace github.com/filecoin-project/filecoin-ffi=../../filecoin-ffi && go mod edit -replace github.com/supranational/blst=../../fil-blst/blst && go mod edit -replace github.com/filecoin-project/fil-blst=../../fil-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:
|
||||
@@ -286,8 +316,8 @@ jobs:
|
||||
- run:
|
||||
name: Install go
|
||||
command: |
|
||||
curl -O https://dl.google.com/go/go1.14.2.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.14.2.darwin-amd64.pkg -target /
|
||||
curl -O https://dl.google.com/go/go1.15.5.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.15.5.darwin-amd64.pkg -target /
|
||||
- run:
|
||||
name: Install pkg-config
|
||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config
|
||||
@@ -351,6 +381,7 @@ jobs:
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: make deps
|
||||
- run: make docsgen
|
||||
- run: git --no-pager diff
|
||||
- run: git --no-pager diff --quiet
|
||||
@@ -428,6 +459,22 @@ workflows:
|
||||
- test:
|
||||
codecov-upload: true
|
||||
test-suite-name: full
|
||||
- test-chain:
|
||||
codecov-upload: true
|
||||
test-suite-name: chain
|
||||
packages: "./chain/..."
|
||||
- test-node:
|
||||
codecov-upload: true
|
||||
test-suite-name: node
|
||||
packages: "./node/..."
|
||||
- test-storage:
|
||||
codecov-upload: true
|
||||
test-suite-name: storage
|
||||
packages: "./storage/... ./extern/..."
|
||||
- test-cli:
|
||||
codecov-upload: true
|
||||
test-suite-name: cli
|
||||
packages: "./cli/... ./cmd/... ./api/..."
|
||||
- test-window-post:
|
||||
go-test-flags: "-run=TestWindowedPost"
|
||||
winpost-test: "1"
|
||||
@@ -448,6 +495,11 @@ workflows:
|
||||
packages: "./conformance"
|
||||
vectors-branch: master
|
||||
- build-lotus-soup
|
||||
- trigger-testplans:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- build-debug
|
||||
- build-all:
|
||||
requires:
|
||||
|
||||
+5
-1
@@ -1,5 +1,9 @@
|
||||
comment: off
|
||||
ignore:
|
||||
- "cbor_gen.go"
|
||||
- "**/cbor_gen.go"
|
||||
- "api/test/**/*"
|
||||
- "api/test/*"
|
||||
- "gen/**/*"
|
||||
- "gen/*"
|
||||
github_checks:
|
||||
annotations: false
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
/lotus-bench
|
||||
/lotus-gateway
|
||||
/lotus-pcr
|
||||
/lotus-wallet
|
||||
/lotus-keygen
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
|
||||
+4
-8
@@ -1,16 +1,12 @@
|
||||
[submodule "extern/filecoin-ffi"]
|
||||
path = extern/filecoin-ffi
|
||||
url = https://github.com/filecoin-project/filecoin-ffi.git
|
||||
branch = master
|
||||
[submodule "extern/serialization-vectors"]
|
||||
path = extern/serialization-vectors
|
||||
url = https://github.com/filecoin-project/serialization-vectors
|
||||
url = https://github.com/filecoin-project/serialization-vectors.git
|
||||
[submodule "extern/test-vectors"]
|
||||
path = extern/test-vectors
|
||||
url = https://github.com/filecoin-project/test-vectors.git
|
||||
[submodule "extern/fil-blst"]
|
||||
path = extern/fil-blst
|
||||
url = https://github.com/filecoin-project/fil-blst.git
|
||||
[submodule "extern/oni"]
|
||||
path = extern/oni
|
||||
url = https://github.com/filecoin-project/oni
|
||||
[submodule "extern/blst"]
|
||||
path = extern/blst
|
||||
url = https://github.com/supranational/blst.git
|
||||
|
||||
+470
@@ -1,5 +1,475 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 1.3.0 / 2020-12-16
|
||||
|
||||
This is a mandatory release of Lotus that introduces the third post-liftoff upgrade to the Filecoin network. The network upgrade occurs at height 343200, before which time all nodes must have updated to this release (or later). The change that breaks consensus is an implementation of FIP-0009(https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0009.md).
|
||||
|
||||
## Changes
|
||||
|
||||
- Disable gas burning for window post messages (https://github.com/filecoin-project/lotus/pull/5200)
|
||||
- fix lock propose (https://github.com/filecoin-project/lotus/pull/5197)
|
||||
|
||||
# 1.2.3 / 2020-12-15
|
||||
|
||||
This is an optional Lotus release that introduces many performance improvements, bugfixes, and UX improvements.
|
||||
|
||||
## Changes
|
||||
|
||||
- When waiting for deal commit messages, ignore unsuccessful messages (https://github.com/filecoin-project/lotus/pull/5189)
|
||||
- Bigger copy buffer size for stores (https://github.com/filecoin-project/lotus/pull/5177)
|
||||
- Print MinPieceSize when querying ask (https://github.com/filecoin-project/lotus/pull/5178)
|
||||
- Optimize miner info & sectors list loading (https://github.com/filecoin-project/lotus/pull/5176)
|
||||
- Allow miners to filter (un)verified deals (https://github.com/filecoin-project/lotus/pull/5094)
|
||||
- Fix curSealing out of MaxSealingSectors limit (https://github.com/filecoin-project/lotus/pull/5166)
|
||||
- Add mpool pending from / to filter (https://github.com/filecoin-project/lotus/pull/5169)
|
||||
- Add metrics for delayed blocks (https://github.com/filecoin-project/lotus/pull/5171)
|
||||
- Fix PushUntrusted publishing -- the message is local (https://github.com/filecoin-project/lotus/pull/5173)
|
||||
- Avoid potential hang in events API when starting event listener (https://github.com/filecoin-project/lotus/pull/5159)
|
||||
- Show data transfer ID in list-deals (https://github.com/filecoin-project/lotus/pull/5150)
|
||||
- Fix events API mutex locking (https://github.com/filecoin-project/lotus/pull/5160)
|
||||
- Message pool refactors (https://github.com/filecoin-project/lotus/pull/5162)
|
||||
- Fix lotus-shed cid output (https://github.com/filecoin-project/lotus/pull/5072)
|
||||
- Use FundManager to withdraw funds, add MarketWithdraw API (https://github.com/filecoin-project/lotus/pull/5112)
|
||||
- Add keygen outfile (https://github.com/filecoin-project/lotus/pull/5118)
|
||||
- Update sr2 stat aggregation (https://github.com/filecoin-project/lotus/pull/5114)
|
||||
- Fix miner control address lookup (https://github.com/filecoin-project/lotus/pull/5119)
|
||||
- Fix send with declared nonce 0 (https://github.com/filecoin-project/lotus/pull/5111)
|
||||
- Introduce memory watchdog; LOTUS_MAX_HEAP (https://github.com/filecoin-project/lotus/pull/5101)
|
||||
- Miner control address config for (pre)commits (https://github.com/filecoin-project/lotus/pull/5103)
|
||||
- Delete repeated call func (https://github.com/filecoin-project/lotus/pull/5099)
|
||||
- lotus-shed ledger show command (https://github.com/filecoin-project/lotus/pull/5098)
|
||||
- Log a message when there aren't enough peers for sync (https://github.com/filecoin-project/lotus/pull/5105)
|
||||
- Miner code cleanup (https://github.com/filecoin-project/lotus/pull/5107)
|
||||
|
||||
# 1.2.2 / 2020-12-03
|
||||
|
||||
This is an optional Lotus release that introduces various improvements to the mining logic and deal-making workflow, as well as several new UX features.
|
||||
|
||||
## Changes
|
||||
|
||||
- Set lower feecap on PoSt messages with low balance (https://github.com/filecoin-project/lotus/pull/4217)
|
||||
- Add options to set BlockProfileRate and MutexProfileFraction (https://github.com/filecoin-project/lotus/pull/4140)
|
||||
- Shed/post find (https://github.com/filecoin-project/lotus/pull/4355)
|
||||
- tvx extract: make it work with secp messages.(https://github.com/filecoin-project/lotus/pull/4583)
|
||||
- update go from 1.14 to 1.15 (https://github.com/filecoin-project/lotus/pull/4909)
|
||||
- print multiple blocks from miner cid (https://github.com/filecoin-project/lotus/pull/4767)
|
||||
- Connection Gater support (https://github.com/filecoin-project/lotus/pull/4849)
|
||||
- just return storedask.NewStoredAsk to reduce unuseful code (https://github.com/filecoin-project/lotus/pull/4902)
|
||||
- add go main version (https://github.com/filecoin-project/lotus/pull/4910)
|
||||
- Use version0 when pre-sealing (https://github.com/filecoin-project/lotus/pull/4911)
|
||||
- optimize code UpgradeTapeHeight and go fmt (https://github.com/filecoin-project/lotus/pull/4913)
|
||||
- CLI to get network version (https://github.com/filecoin-project/lotus/pull/4914)
|
||||
- Improve error for ActorsVersionPredicate (https://github.com/filecoin-project/lotus/pull/4915)
|
||||
- upgrade to go-fil-markets 1.0.5 (https://github.com/filecoin-project/lotus/pull/4916)
|
||||
- bug:replace with func recordFailure (https://github.com/filecoin-project/lotus/pull/4919)
|
||||
- Remove unused key (https://github.com/filecoin-project/lotus/pull/4924)
|
||||
- change typeV7 make len (https://github.com/filecoin-project/lotus/pull/4943)
|
||||
- emit events for peer disconnections and act upon them in the blocksync tracker (https://github.com/filecoin-project/lotus/pull/4754)
|
||||
- Fix lotus bench error (https://github.com/filecoin-project/lotus/pull/4305)
|
||||
- Reduce badger ValueTreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
|
||||
- Downgrade duplicate nonce logs to debug (https://github.com/filecoin-project/lotus/pull/4933)
|
||||
- readme update golang version from 1.14.7 to 1.15.5 (https://github.com/filecoin-project/lotus/pull/4974)
|
||||
- add data transfer logging (https://github.com/filecoin-project/lotus/pull/4975)
|
||||
- Remove all temp file generation for deals (https://github.com/filecoin-project/lotus/pull/4929)
|
||||
- fix get sector bug (https://github.com/filecoin-project/lotus/pull/4976)
|
||||
- fix nil pointer in StateSectorPreCommitInfo (https://github.com/filecoin-project/lotus/pull/4082)
|
||||
- Add logging on data-transfer to miner (https://github.com/filecoin-project/lotus/pull/4980)
|
||||
- bugfix: fixup devnet script (https://github.com/filecoin-project/lotus/pull/4956)
|
||||
- modify for unsafe (https://github.com/filecoin-project/lotus/pull/4024)
|
||||
- move testground/lotus-soup testplan from oni to lotus (https://github.com/filecoin-project/lotus/pull/4727)
|
||||
- Setup remainder msig signers when parsing genesis template (https://github.com/filecoin-project/lotus/pull/4904)
|
||||
- Update JSON RPC server to enforce a maximum request size (https://github.com/filecoin-project/lotus/pull/4923)
|
||||
- New SR-specific lotus-shed cmd (https://github.com/filecoin-project/lotus/pull/4971)
|
||||
- update index to sectorNumber (https://github.com/filecoin-project/lotus/pull/4987)
|
||||
- storagefsm: Fix expired ticket retry loop (https://github.com/filecoin-project/lotus/pull/4876)
|
||||
- add .sec scale to measurements; humanize for metric tags (https://github.com/filecoin-project/lotus/pull/4989)
|
||||
- Support seal proof type switching (https://github.com/filecoin-project/lotus/pull/4873)
|
||||
- fix log format (https://github.com/filecoin-project/lotus/pull/4984)
|
||||
- Format workerID as string (https://github.com/filecoin-project/lotus/pull/4973)
|
||||
- miner: Winning PoSt Warmup (https://github.com/filecoin-project/lotus/pull/4824)
|
||||
- Default StartDealParams's fast retrieval field to true over JSON (https://github.com/filecoin-project/lotus/pull/4998)
|
||||
- Fix actor not found in chain inspect-usage (https://github.com/filecoin-project/lotus/pull/5010)
|
||||
- storagefsm: Improve new deal sector logic (https://github.com/filecoin-project/lotus/pull/5007)
|
||||
- Configure simultaneous requests (https://github.com/filecoin-project/lotus/pull/4996)
|
||||
- miner: log winningPoSt duration separately (https://github.com/filecoin-project/lotus/pull/5005)
|
||||
- fix wallet dead lock (https://github.com/filecoin-project/lotus/pull/5002)
|
||||
- Update go-jsonrpc to v0.1.2 (https://github.com/filecoin-project/lotus/pull/5015)
|
||||
- markets - separate watching for pre-commit from prove-commit (https://github.com/filecoin-project/lotus/pull/4945)
|
||||
- storagefsm: Add missing planners (https://github.com/filecoin-project/lotus/pull/5016)
|
||||
- fix wallet delete address where address is default (https://github.com/filecoin-project/lotus/pull/5019)
|
||||
- worker: More robust remote checks (https://github.com/filecoin-project/lotus/pull/5008)
|
||||
- Add new booststrappers (https://github.com/filecoin-project/lotus/pull/4007)
|
||||
- add a tooling to make filecoin accounting a little easier (https://github.com/filecoin-project/lotus/pull/5025)
|
||||
- fix: start a new line in print miner-info to avoid ambiguous display (https://github.com/filecoin-project/lotus/pull/5029)
|
||||
- Print gas limit sum in mpool stat (https://github.com/filecoin-project/lotus/pull/5035)
|
||||
- Fix chainstore tipset leak (https://github.com/filecoin-project/lotus/pull/5037)
|
||||
- shed rpc: Allow calling with args (https://github.com/filecoin-project/lotus/pull/5036)
|
||||
- Make --gas-limit optional in mpool replace cli (https://github.com/filecoin-project/lotus/pull/5059)
|
||||
- client list-asks --by-ping (https://github.com/filecoin-project/lotus/pull/5060)
|
||||
- Ledger signature verification (https://github.com/filecoin-project/lotus/pull/5068)
|
||||
- Fix helptext for verified-deal default in client deal (https://github.com/filecoin-project/lotus/pull/5074)
|
||||
- worker: Support setting task types at runtime (https://github.com/filecoin-project/lotus/pull/5023)
|
||||
- Enable Callers tracing when GasTracing is enabled (https://github.com/filecoin-project/lotus/pull/5080)
|
||||
- Cancel transfer cancels storage deal (https://github.com/filecoin-project/lotus/pull/5032)
|
||||
- Sector check command (https://github.com/filecoin-project/lotus/pull/5041)
|
||||
- add commp-to-cid base64 decode (https://github.com/filecoin-project/lotus/pull/5079)
|
||||
- miner info cli improvements (https://github.com/filecoin-project/lotus/pull/5083)
|
||||
- miner: Add slow mode to proving check (https://github.com/filecoin-project/lotus/pull/5086)
|
||||
- Error out deals that are not activated by proposed deal start epoch (https://github.com/filecoin-project/lotus/pull/5061)
|
||||
|
||||
# 1.2.1 / 2020-11-20
|
||||
|
||||
This is a very small release of Lotus that fixes an issue users are experiencing when importing snapshots. There is no need to upgrade unless you experience an issue with creating a new datastore directory in the Lotus repo.
|
||||
|
||||
## Changes
|
||||
|
||||
- fix blockstore directory not created automatically (https://github.com/filecoin-project/lotus/pull/4922)
|
||||
- WindowPoStScheduler.checkSectors() delete useless judgment (https://github.com/filecoin-project/lotus/pull/4918)
|
||||
|
||||
|
||||
# 1.2.0 / 2020-11-18
|
||||
|
||||
This is a mandatory release of Lotus that introduces the second post-liftoff upgrade to the Filecoin network. The network upgrade occurs at height 265200, before which time all nodes must have updated to this release (or later). This release also bumps the required version of Go to 1.15.
|
||||
|
||||
The changes that break consensus are:
|
||||
|
||||
- Upgrading to sepcs-actors 2.3.2 (https://github.com/filecoin-project/specs-actors/releases/tag/v2.3.2)
|
||||
- Introducing proofs v5.4.0 (https://github.com/filecoin-project/rust-fil-proofs/releases/tag/storage-proofs-v5.4.0), and switching between the proof types (https://github.com/filecoin-project/lotus/pull/4873)
|
||||
- Don't use terminated sectors for winning PoSt (https://github.com/filecoin-project/lotus/pull/4770)
|
||||
- Various small VM-level edge-case handling (https://github.com/filecoin-project/lotus/pull/4783)
|
||||
- Correction of the VM circulating supply calculation (https://github.com/filecoin-project/lotus/pull/4862)
|
||||
- Retuning gas costs (https://github.com/filecoin-project/lotus/pull/4830)
|
||||
- Avoid sending messages to the zero BLS address (https://github.com/filecoin-project/lotus/pull/4888)
|
||||
|
||||
## Other Changes
|
||||
|
||||
- delayed pubsub subscribe for messages topic (https://github.com/filecoin-project/lotus/pull/3646)
|
||||
- add chain base64 decode params (https://github.com/filecoin-project/lotus/pull/4748)
|
||||
- chore(dep): update bitswap to fix an initialization race that could panic (https://github.com/filecoin-project/lotus/pull/4855)
|
||||
- Chore/blockstore nits (https://github.com/filecoin-project/lotus/pull/4813)
|
||||
- Print Consensus Faults in miner info (https://github.com/filecoin-project/lotus/pull/4853)
|
||||
- Truncate genesis file before generating (https://github.com/filecoin-project/lotus/pull/4851)
|
||||
- miner: Winning PoSt Warmup (https://github.com/filecoin-project/lotus/pull/4824)
|
||||
- Fix init actor address map diffing (https://github.com/filecoin-project/lotus/pull/4875)
|
||||
- Bump API versions to 1.0.0 (https://github.com/filecoin-project/lotus/pull/4884)
|
||||
- Fix cid recording issue (https://github.com/filecoin-project/lotus/pull/4874)
|
||||
- Speed up worker key retrieval (https://github.com/filecoin-project/lotus/pull/4885)
|
||||
- Add error codes to worker return (https://github.com/filecoin-project/lotus/pull/4890)
|
||||
- Update go to 1.15.5 (https://github.com/filecoin-project/lotus/pull/4896)
|
||||
- Fix MaxSealingSectrosForDeals getting reset to 0 (https://github.com/filecoin-project/lotus/pull/4879)
|
||||
- add sanity check for maximum block size (https://github.com/filecoin-project/lotus/pull/3171)
|
||||
- Check (pre)commit receipt before other checks in failed states (https://github.com/filecoin-project/lotus/pull/4712)
|
||||
- fix badger double open on daemon --import-snapshot; chainstore lifecycle (https://github.com/filecoin-project/lotus/pull/4872)
|
||||
- Update to ipfs-blockstore 1.0.3 (https://github.com/filecoin-project/lotus/pull/4897)
|
||||
- break loop when found warm up sector (https://github.com/filecoin-project/lotus/pull/4869)
|
||||
- Tweak handling of bad beneficaries in DeleteActor (https://github.com/filecoin-project/lotus/pull/4903)
|
||||
- cap maximum number of messages per block in selection (https://github.com/filecoin-project/lotus/pull/4905)
|
||||
- Set Calico epoch (https://github.com/filecoin-project/lotus/pull/4889)
|
||||
|
||||
# 1.1.3 / 2020-11-13
|
||||
|
||||
This is an optional release of Lotus that upgrades Lotus dependencies, and includes many performance enhancements, bugfixes, and UX improvements.
|
||||
|
||||
## Highlights
|
||||
|
||||
- Refactored much of the miner code (https://github.com/filecoin-project/lotus/pull/3618), improving its recovery from restarts and overall sector success rate
|
||||
- Updated [proofs](https://github.com/filecoin-project/rust-fil-proofs) to v5.3.0, which brings significant performance improvements
|
||||
- Updated [markets](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.0.4) to v1.0.4, which reduces failures due to reorgs (https://github.com/filecoin-project/lotus/pull/4730) and uses the newly refactored fund manager (https://github.com/filecoin-project/lotus/pull/4736)
|
||||
|
||||
## Changes
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- polish: add Equals method to MinerInfo shim (https://github.com/filecoin-project/lotus/pull/4604)
|
||||
- Fix messagepool accounting (https://github.com/filecoin-project/lotus/pull/4668)
|
||||
- Prep for gas balancing (https://github.com/filecoin-project/lotus/pull/4651)
|
||||
- Reduce badger ValueThreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
|
||||
- Config for default max gas fee (https://github.com/filecoin-project/lotus/pull/4652)
|
||||
- bootstrap: don't return early when one drand resolution fails (https://github.com/filecoin-project/lotus/pull/4626)
|
||||
- polish: add ClaimsChanged and DiffClaims method to power shim (https://github.com/filecoin-project/lotus/pull/4628)
|
||||
- Simplify chain event Called API (https://github.com/filecoin-project/lotus/pull/4664)
|
||||
- Cache deal states for most recent old/new tipset (https://github.com/filecoin-project/lotus/pull/4623)
|
||||
- Add miner available balance and power info to state miner info (https://github.com/filecoin-project/lotus/pull/4618)
|
||||
- Call GetHeaviestTipSet() only once when syncing (https://github.com/filecoin-project/lotus/pull/4696)
|
||||
- modify runtime gasUsed printf (https://github.com/filecoin-project/lotus/pull/4704)
|
||||
- Rename builtin actor generators (https://github.com/filecoin-project/lotus/pull/4697)
|
||||
- Move gas multiplier as property of pricelist (https://github.com/filecoin-project/lotus/pull/4728)
|
||||
- polish: add msig pendingtxn diffing and comp (https://github.com/filecoin-project/lotus/pull/4719)
|
||||
- Optional chain Bitswap (https://github.com/filecoin-project/lotus/pull/4717)
|
||||
- rewrite sync manager (https://github.com/filecoin-project/lotus/pull/4599)
|
||||
- async connect to bootstrappers (https://github.com/filecoin-project/lotus/pull/4785)
|
||||
- head change coalescer (https://github.com/filecoin-project/lotus/pull/4688)
|
||||
- move to native badger blockstore; leverage zero-copy View() to deserialize in-place (https://github.com/filecoin-project/lotus/pull/4681)
|
||||
- badger blockstore: minor improvements (https://github.com/filecoin-project/lotus/pull/4811)
|
||||
- Do not fail wallet delete because of pre-existing trashed key (https://github.com/filecoin-project/lotus/pull/4589)
|
||||
- Correctly delete the default wallet address (https://github.com/filecoin-project/lotus/pull/4705)
|
||||
- Reduce badger ValueTreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
|
||||
- predicates: Fast StateGetActor wrapper (https://github.com/filecoin-project/lotus/pull/4835)
|
||||
|
||||
#### Mining
|
||||
|
||||
- worker key should change when set sender found key not equal with the value on chain (https://github.com/filecoin-project/lotus/pull/4595)
|
||||
- extern/sector-storage: fix GPU usage overwrite bug (https://github.com/filecoin-project/lotus/pull/4627)
|
||||
- sectorstorage: Fix manager restart edge-case (https://github.com/filecoin-project/lotus/pull/4645)
|
||||
- storagefsm: Fix GetTicket loop when the sector is already precommitted (https://github.com/filecoin-project/lotus/pull/4643)
|
||||
- Debug flag to force running sealing scheduler (https://github.com/filecoin-project/lotus/pull/4662)
|
||||
- Fix worker reenabling, handle multiple restarts in worker (https://github.com/filecoin-project/lotus/pull/4666)
|
||||
- keep retrying the proof until we run out of sectors to skip (https://github.com/filecoin-project/lotus/pull/4633)
|
||||
- worker: Commands to pause/resume task processing (https://github.com/filecoin-project/lotus/pull/4615)
|
||||
- struct name incorrect (https://github.com/filecoin-project/lotus/pull/4699)
|
||||
- optimize code replace strings with constants (https://github.com/filecoin-project/lotus/pull/4769)
|
||||
- optimize pledge sector (https://github.com/filecoin-project/lotus/pull/4765)
|
||||
- Track sealing processes across lotus-miner restarts (https://github.com/filecoin-project/lotus/pull/3618)
|
||||
- Fix scheduler lockups after storage is freed (https://github.com/filecoin-project/lotus/pull/4778)
|
||||
- storage: Track worker hostnames with work (https://github.com/filecoin-project/lotus/pull/4779)
|
||||
- Expand sched-diag; Command to abort sealing calls (https://github.com/filecoin-project/lotus/pull/4804)
|
||||
- miner: Winning PoSt Warmup (https://github.com/filecoin-project/lotus/pull/4824)
|
||||
- docsgen: Support miner/worker (https://github.com/filecoin-project/lotus/pull/4817)
|
||||
- miner: Basic storage cleanup command (https://github.com/filecoin-project/lotus/pull/4834)
|
||||
|
||||
#### Markets and Data Transfer
|
||||
|
||||
- Flesh out data transfer features (https://github.com/filecoin-project/lotus/pull/4572)
|
||||
- Fix memory leaks in data transfer (https://github.com/filecoin-project/lotus/pull/4619)
|
||||
- Handle deal id changes in OnDealSectorCommitted (https://github.com/filecoin-project/lotus/pull/4730)
|
||||
- Refactor FundManager (https://github.com/filecoin-project/lotus/pull/4736)
|
||||
- refactor: integrate new FundManager (https://github.com/filecoin-project/lotus/pull/4787)
|
||||
- Fix race in paych manager when req context is cancelled (https://github.com/filecoin-project/lotus/pull/4803)
|
||||
- fix race in paych manager add funds (https://github.com/filecoin-project/lotus/pull/4597)
|
||||
- Fix panic in FundManager (https://github.com/filecoin-project/lotus/pull/4808)
|
||||
- Fix: dont crash on startup if funds migration fails (https://github.com/filecoin-project/lotus/pull/4827)
|
||||
|
||||
#### UX
|
||||
|
||||
- Make EarlyExpiration in sectors list less scary (https://github.com/filecoin-project/lotus/pull/4600)
|
||||
- Add commands to change the worker key (https://github.com/filecoin-project/lotus/pull/4513)
|
||||
- Expose ClientDealSize via CLI (https://github.com/filecoin-project/lotus/pull/4569)
|
||||
- client deal: Cache CommD when creating multiple deals (https://github.com/filecoin-project/lotus/pull/4535)
|
||||
- miner sectors list: flags for events/seal time (https://github.com/filecoin-project/lotus/pull/4649)
|
||||
- make IPFS online mode configurable (https://github.com/filecoin-project/lotus/pull/4650)
|
||||
- Add sync status to miner info command (https://github.com/filecoin-project/lotus/pull/4669)
|
||||
- Add a StateDecodeParams method (https://github.com/filecoin-project/lotus/pull/4105)
|
||||
- sched: Interactive RPC Shell (https://github.com/filecoin-project/lotus/pull/4692)
|
||||
- Add api for getting status given a code (https://github.com/filecoin-project/lotus/pull/4210)
|
||||
- Update lotus-stats with a richer cli (https://github.com/filecoin-project/lotus/pull/4718)
|
||||
- Use TSK passed to GasEstimateGasLimit (https://github.com/filecoin-project/lotus/pull/4739)
|
||||
- match data type for reward state api (https://github.com/filecoin-project/lotus/pull/4745)
|
||||
- Add `termination-estimate` to get an estimation for how much a termination penalty will be (https://github.com/filecoin-project/lotus/pull/4617)
|
||||
- Restrict `ParseFIL` input length (https://github.com/filecoin-project/lotus/pull/4780)
|
||||
- cmd sectors commitIDs len debug (https://github.com/filecoin-project/lotus/pull/4786)
|
||||
- Add client deal-stats CLI (https://github.com/filecoin-project/lotus/pull/4788)
|
||||
- Modify printf format (https://github.com/filecoin-project/lotus/pull/4795)
|
||||
- Updated msig inspect (https://github.com/filecoin-project/lotus/pull/4533)
|
||||
- Delete the duplicate output (https://github.com/filecoin-project/lotus/pull/4819)
|
||||
- miner: Storage list sectors command (https://github.com/filecoin-project/lotus/pull/4831)
|
||||
- drop a few logs down to debug (https://github.com/filecoin-project/lotus/pull/4832)
|
||||
|
||||
#### Testing and Tooling
|
||||
|
||||
- refactor: share code between CLI tests (https://github.com/filecoin-project/lotus/pull/4598)
|
||||
- Fix flaky TestCLIDealFlow (https://github.com/filecoin-project/lotus/pull/4608)
|
||||
- Fix flaky testMiningReal (https://github.com/filecoin-project/lotus/pull/4609)
|
||||
- Add election run-dummy command (https://github.com/filecoin-project/lotus/pull/4498)
|
||||
- Fix .gitmodules (https://github.com/filecoin-project/lotus/pull/4713)
|
||||
- fix metrics wiring.(https://github.com/filecoin-project/lotus/pull/4691)
|
||||
- shed: Util for creating ID CIDs (https://github.com/filecoin-project/lotus/pull/4726)
|
||||
- Run kumquat upgrade on devnets (https://github.com/filecoin-project/lotus/pull/4734)
|
||||
- Make pond work again (https://github.com/filecoin-project/lotus/pull/4775)
|
||||
- lotus-stats: fix influx flags (https://github.com/filecoin-project/lotus/pull/4810)
|
||||
- 2k sync BootstrapPeerThreshold (https://github.com/filecoin-project/lotus/pull/4797)
|
||||
- test for FundManager panic to ensure it is fixed (https://github.com/filecoin-project/lotus/pull/4825)
|
||||
- Stop mining at the end of tests (https://github.com/filecoin-project/lotus/pull/4826)
|
||||
- Make some logs quieter (https://github.com/filecoin-project/lotus/pull/4709)
|
||||
|
||||
#### Dependencies
|
||||
|
||||
- update filecoin-ffi in go mod (https://github.com/filecoin-project/lotus/pull/4584)
|
||||
- Update FFI (https://github.com/filecoin-project/lotus/pull/4613)
|
||||
- feat: integrate new optional blst backend and verification optimizations from proofs (https://github.com/filecoin-project/lotus/pull/4630)
|
||||
- Use https for blst submodule (https://github.com/filecoin-project/lotus/pull/4710)
|
||||
- Update go-bitfield (https://github.com/filecoin-project/lotus/pull/4756)
|
||||
- Update Yamux (https://github.com/filecoin-project/lotus/pull/4758)
|
||||
- Update to latest go-bitfield (https://github.com/filecoin-project/lotus/pull/4793)
|
||||
- Update to latest go-address (https://github.com/filecoin-project/lotus/pull/4798)
|
||||
- update libp2p for stream interface changes (https://github.com/filecoin-project/lotus/pull/4814)
|
||||
|
||||
# 1.1.2 / 2020-10-24
|
||||
|
||||
This is a patch release of Lotus that builds on the fixes involving worker keys that was introduced in v1.1.1. Miners and node operators should update to this release as soon as possible in order to ensure their blocks are propagated and validated.
|
||||
|
||||
## Changes
|
||||
|
||||
- Handle worker key changes correctly in runtime (https://github.com/filecoin-project/lotus/pull/4579)
|
||||
|
||||
# 1.1.1 / 2020-10-24
|
||||
|
||||
This is a patch release of Lotus that addresses some issues caused by when miners change their worker keys. Miners and node operators should update to this release as soon as possible, especially any miner who has changed their worker key recently.
|
||||
|
||||
## Changes
|
||||
|
||||
- Miner finder for interactive client deal CLI (https://github.com/filecoin-project/lotus/pull/4504)
|
||||
- Disable blockstore bloom filter (https://github.com/filecoin-project/lotus/pull/4512)
|
||||
- Add api for getting status given a code (https://github.com/filecoin-project/lotus/pull/4210)
|
||||
- add batch api for push messages (https://github.com/filecoin-project/lotus/pull/4236)
|
||||
- add measure datastore wrapper around bench chain datastore (https://github.com/filecoin-project/lotus/pull/4302)
|
||||
- Look at block base fee for PCR (https://github.com/filecoin-project/lotus/pull/4313)
|
||||
- Add a shed util to determine % of power that has won a block (https://github.com/filecoin-project/lotus/pull/4318)
|
||||
- Shed/borked cmd (https://github.com/filecoin-project/lotus/pull/4339)
|
||||
- optimize mining code (https://github.com/filecoin-project/lotus/pull/4379)
|
||||
- heaviestTipSet reurning nil is a ok (https://github.com/filecoin-project/lotus/pull/4523)
|
||||
- Remove most v0 actor imports (https://github.com/filecoin-project/lotus/pull/4383)
|
||||
- Small chain export optimization (https://github.com/filecoin-project/lotus/pull/4536)
|
||||
- Add block list to pcr (https://github.com/filecoin-project/lotus/pull/4314)
|
||||
- Fix circ supply default in conformance (https://github.com/filecoin-project/lotus/pull/4449)
|
||||
- miner: fix init --create-worker-key (https://github.com/filecoin-project/lotus/pull/4475)
|
||||
- make push and addLocal atomic (https://github.com/filecoin-project/lotus/pull/4500)
|
||||
- add some methods that oni needs (https://github.com/filecoin-project/lotus/pull/4501)
|
||||
- MinerGetBaseInfo: if miner is not found in lookback, check current (https://github.com/filecoin-project/lotus/pull/4508)
|
||||
- Delete wallet from local wallet cache (https://github.com/filecoin-project/lotus/pull/4526)
|
||||
- Fix lotus-shed ledger list (https://github.com/filecoin-project/lotus/pull/4521)
|
||||
- Manage sectors by size instead of proof type (https://github.com/filecoin-project/lotus/pull/4511)
|
||||
- Feat/api request metrics wrapper (https://github.com/filecoin-project/lotus/pull/4516)
|
||||
- Fix chain sync stopping to sync (https://github.com/filecoin-project/lotus/pull/4541)
|
||||
- Use the correct lookback for the worker key when creating blocks (https://github.com/filecoin-project/lotus/pull/4539)
|
||||
- Cleanup test initialization and always validate VRFs in tests (https://github.com/filecoin-project/lotus/pull/4538)
|
||||
- Add a market WithdrawBalance CLI (https://github.com/filecoin-project/lotus/pull/4524)
|
||||
- wallet list: Add market balance and ID address flags (https://github.com/filecoin-project/lotus/pull/4555)
|
||||
- tvx simulate command; tvx extract --ignore-sanity-checks (https://github.com/filecoin-project/lotus/pull/4554)
|
||||
- lotus-lite: CLI tests for `lotus client` commands (https://github.com/filecoin-project/lotus/pull/4497)
|
||||
- lite-mode - market storage and retrieval clients (https://github.com/filecoin-project/lotus/pull/4263)
|
||||
- Chore: update drand to v1.2.0 (https://github.com/filecoin-project/lotus/pull/4420)
|
||||
- Fix random test failures (https://github.com/filecoin-project/lotus/pull/4559)
|
||||
- Fix flaky TestTimedBSSimple (https://github.com/filecoin-project/lotus/pull/4561)
|
||||
- Make wallet market withdraw usable with miner addresses (https://github.com/filecoin-project/lotus/pull/4556)
|
||||
- Fix flaky TestChainExportImportFull (https://github.com/filecoin-project/lotus/pull/4564)
|
||||
- Use older randomness for the PoSt commit on specs-actors version 2 (https://github.com/filecoin-project/lotus/pull/4563)
|
||||
- shed: Commad to decode messages (https://github.com/filecoin-project/lotus/pull/4565)
|
||||
- Fetch worker key from correct block on sync (https://github.com/filecoin-project/lotus/pull/4573)
|
||||
|
||||
# 1.1.0 / 2020-10-20
|
||||
|
||||
This is a mandatory release that introduces the first post-liftoff upgrade to the Filecoin network. The changes that break consensus are an upgrade to specs-actors v2.2.0 at epoch 170000.
|
||||
|
||||
## Changes
|
||||
|
||||
- Introduce Network version 6 (https://github.com/filecoin-project/lotus/pull/4506)
|
||||
- Update markets v1.0.0 (https://github.com/filecoin-project/lotus/pull/4505)
|
||||
- Add some extra logging to try and debug sync issues (https://github.com/filecoin-project/lotus/pull/4486)
|
||||
- Circle: Run tests for some subsystems separately (https://github.com/filecoin-project/lotus/pull/4496)
|
||||
- Add a terminate sectors command to lotus-shed (https://github.com/filecoin-project/lotus/pull/4507)
|
||||
- Add a comment to BlockMessages to address #4446 (https://github.com/filecoin-project/lotus/pull/4491)
|
||||
|
||||
# 1.0.0 / 2020-10-19
|
||||
|
||||
It's 1.0.0! This is an optional release of Lotus that introduces some UX improvements to the 0.10 series.
|
||||
|
||||
This very small release is largely cosmetic, and intended to flag the code that the Filecoin mainnet was launched with.
|
||||
|
||||
## API changes
|
||||
|
||||
- `StateMsgGasCost` has been removed. The equivalent information can be gained by calling `StateReplay`.
|
||||
- A `GasCost` field has been added to the `InvocResult` type, meaning detailed gas costs will be returned when calling `StateReplay`, `StateCompute`, and `StateCall`.
|
||||
- The behaviour of `StateReplay` in response to an empty tipset key has been changed. Instead of simply using the heaviest tipset (which is almost guaranteed to be an unsuccessful replay), we search now search the chain for the tipset that included the message, and replay the message in that tipset (we fail if no such tipset is found).
|
||||
|
||||
## Changes
|
||||
|
||||
- Increase code coverage! (https://github.com/filecoin-project/lotus/pull/4410)
|
||||
- Mpool: Don't block node startup loading messages (https://github.com/filecoin-project/lotus/pull/4411)
|
||||
- Improve the UX of multisig approves (https://github.com/filecoin-project/lotus/pull/4398)
|
||||
- Use build.BlockDelaySecs for deal start buffer (https://github.com/filecoin-project/lotus/pull/4415)
|
||||
- Conformance: support multiple protocol versions (https://github.com/filecoin-project/lotus/pull/4393)
|
||||
- Ensure msig inspect cli works with lotus-lite (https://github.com/filecoin-project/lotus/pull/4421)
|
||||
- Add command to (slowly) prune lotus chain datastore (https://github.com/filecoin-project/lotus/pull/3876)
|
||||
- Add WalletVerify to lotus-gateway (https://github.com/filecoin-project/lotus/pull/4373)
|
||||
- Improve StateMsg APIs (https://github.com/filecoin-project/lotus/pull/4429)
|
||||
- Add endpoints needed by spacegap (https://github.com/filecoin-project/lotus/pull/4426)
|
||||
- Make audit balances capable of printing robust addresses (https://github.com/filecoin-project/lotus/pull/4423)
|
||||
- Custom filters for retrieval deals (https://github.com/filecoin-project/lotus/pull/4424)
|
||||
- Fix message list api (https://github.com/filecoin-project/lotus/pull/4422)
|
||||
- Replace bootstrap peers (https://github.com/filecoin-project/lotus/pull/4447)
|
||||
- Don't overwrite previously-configured maxPieceSize for a persisted ask (https://github.com/filecoin-project/lotus/pull/4480)
|
||||
- State: optimize state snapshot address cache (https://github.com/filecoin-project/lotus/pull/4481)
|
||||
|
||||
# 0.10.2 / 2020-10-14
|
||||
|
||||
This is an optional release of Lotus that updates markets to 0.9.1, which fixes an issue affecting deals that were mid-transfer when the node was upgraded to 0.9.0. This release also includes some tweaks to default gas values and minor performance improvements.
|
||||
|
||||
## Changes
|
||||
|
||||
- Use updated stored ask API (https://github.com/filecoin-project/lotus/pull/4384)
|
||||
- tvx: trace puts to blockstore for inclusion in CAR. (https://github.com/filecoin-project/lotus/pull/4278)
|
||||
- Add propose remove (https://github.com/filecoin-project/lotus/pull/4311)
|
||||
- Update to 0.9.1 bugfix release (https://github.com/filecoin-project/lotus/pull/4402)
|
||||
- Update drand endpoints (https://github.com/filecoin-project/lotus/pull/4125)
|
||||
- fix: return true when deadlines changed (https://github.com/filecoin-project/lotus/pull/4403)
|
||||
- sync wait --watch (https://github.com/filecoin-project/lotus/pull/4396)
|
||||
- reduce garbage in blockstore (https://github.com/filecoin-project/lotus/pull/4406)
|
||||
- give the TimeCacheBS tests a bit more time (https://github.com/filecoin-project/lotus/pull/4407)
|
||||
- Improve gas defaults (https://github.com/filecoin-project/lotus/pull/4408)
|
||||
- Change default gas premium to for 10 block inclusion (https://github.com/filecoin-project/lotus/pull/4222)
|
||||
|
||||
# 0.10.1 / 2020-10-14
|
||||
|
||||
This is an optional release of Lotus that updates markets to 0.9.0, which adds the ability to restart data transfers. This release also introduces Ledger support, and various UX improvements.
|
||||
|
||||
## Changes
|
||||
|
||||
- Test the tape upgrade (https://github.com/filecoin-project/lotus/pull/4328)
|
||||
- Adding in Ledger support (https://github.com/filecoin-project/lotus/pull/4290)
|
||||
- Improve the UX for lotus-miner sealing workers (https://github.com/filecoin-project/lotus/pull/4329)
|
||||
- Add a CLI tool for miner's to repay debt (https://github.com/filecoin-project/lotus/pull/4319)
|
||||
- Rename params_testnet to params_mainnet (https://github.com/filecoin-project/lotus/pull/4336)
|
||||
- Use seal-duration in calculating the earliest StartEpoch (https://github.com/filecoin-project/lotus/pull/4337)
|
||||
- Reject deals that are > 7 days in the future in the BasicDealFilter (https://github.com/filecoin-project/lotus/pull/4173)
|
||||
- Add an API endpoint to calculate the exact circulating supply (https://github.com/filecoin-project/lotus/pull/4148)
|
||||
- lotus-pcr: ignore all other market messages (https://github.com/filecoin-project/lotus/pull/4341)
|
||||
- Add message CID to InvocResult (https://github.com/filecoin-project/lotus/pull/4382)
|
||||
- types: Add CID fields to messages in json marshalers (https://github.com/filecoin-project/lotus/pull/4338)
|
||||
- fix(sync state): set state height to actual tipset height (https://github.com/filecoin-project/lotus/pull/4347)
|
||||
- Fix off by one tipset in searchBackForMsg (https://github.com/filecoin-project/lotus/pull/4367)
|
||||
- fix a panic on startup when we fail to load the tipset (https://github.com/filecoin-project/lotus/pull/4376)
|
||||
- Avoid having the same message CID show up in execution traces (https://github.com/filecoin-project/lotus/pull/4350)
|
||||
- feat(markets): update markets 0.9.0 and add data transfer restart (https://github.com/filecoin-project/lotus/pull/4363)
|
||||
|
||||
# 0.10.0 / 2020-10-12
|
||||
|
||||
This is a consensus-breaking hotfix that addresses an issue in specs-actors v2.0.3 that made it impossible to pledge new 32GiB sectors. The change in Lotus is to update to actors v2.1.0, behind the new network version 5.
|
||||
|
||||
## Changes
|
||||
|
||||
- make pledge test pass with the race detector (https://github.com/filecoin-project/lotus/pull/4291)
|
||||
- fix a race in tipset cache usage (https://github.com/filecoin-project/lotus/pull/4282)
|
||||
- add an api for removing multisig signers (https://github.com/filecoin-project/lotus/pull/4274)
|
||||
- cli: Don't output errors to stdout (https://github.com/filecoin-project/lotus/pull/4298)
|
||||
- Fix panic in wallet export when key is not found (https://github.com/filecoin-project/lotus/pull/4299)
|
||||
- Dump the block validation cache whenever we perform an import (https://github.com/filecoin-project/lotus/pull/4287)
|
||||
- Fix two races (https://github.com/filecoin-project/lotus/pull/4301)
|
||||
- sync unmark-bad --all (https://github.com/filecoin-project/lotus/pull/4296)
|
||||
- decode parameters for multisig transactions in inspect (https://github.com/filecoin-project/lotus/pull/4312)
|
||||
- Chain is love (https://github.com/filecoin-project/lotus/pull/4321)
|
||||
- lotus-stats: optmize getting miner power (https://github.com/filecoin-project/lotus/pull/4315)
|
||||
- implement tape upgrade (https://github.com/filecoin-project/lotus/pull/4322)
|
||||
|
||||
# 0.9.1 / 2020-10-10
|
||||
|
||||
This release fixes an issue which may cause the actors v2 migration to compute the state incorrectly when more than one migration is running in parallel.
|
||||
|
||||
## Changes
|
||||
|
||||
- Make concurrent actor migrations safe (https://github.com/filecoin-project/lotus/pull/4293)
|
||||
- Remote wallet backends (https://github.com/filecoin-project/lotus/pull/3583)
|
||||
- Track funds in FundMgr correctly in case of AddFunds failing (https://github.com/filecoin-project/lotus/pull/4273)
|
||||
- Partial lite-node mode (https://github.com/filecoin-project/lotus/pull/4095)
|
||||
- Fix potential infinite loop in GetBestMiningCandidate (https://github.com/filecoin-project/lotus/pull/3444)
|
||||
- sync wait: Handle processed message offset (https://github.com/filecoin-project/lotus/pull/4253)
|
||||
- Add some new endpoints for querying Msig info (https://github.com/filecoin-project/lotus/pull/4250)
|
||||
- Update markets v0.7.1 (https://github.com/filecoin-project/lotus/pull/4254)
|
||||
- Optimize SearchForMessage and GetReceipt (https://github.com/filecoin-project/lotus/pull/4246)
|
||||
- Use FIL instead of attoFIL in CLI more consistently (https://github.com/filecoin-project/lotus/pull/4249)
|
||||
- fix: clash between daemon --api flag and cli tests (https://github.com/filecoin-project/lotus/pull/4241)
|
||||
- add more info to chain sync lookback failure (https://github.com/filecoin-project/lotus/pull/4245)
|
||||
- Add message counts to inspect chain output (https://github.com/filecoin-project/lotus/pull/4230)
|
||||
|
||||
# 0.9.0 / 2020-10-07
|
||||
|
||||
This consensus-breaking release of Lotus upgrades the actors version to v2.0.0. This requires migrating actor state from v0 to v2. The changes that break consensus are:
|
||||
|
||||
@@ -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
|
||||
@@ -133,18 +133,30 @@ benchmarks:
|
||||
|
||||
lotus-pond: 2k
|
||||
go build -o lotus-pond ./lotuspond
|
||||
(cd lotuspond/front && npm i && CI=false npm run build)
|
||||
.PHONY: lotus-pond
|
||||
BINS+=lotus-pond
|
||||
|
||||
lotus-pond-front:
|
||||
(cd lotuspond/front && npm i && CI=false npm run build)
|
||||
.PHONY: lotus-pond-front
|
||||
|
||||
lotus-pond-app: lotus-pond-front lotus-pond
|
||||
.PHONY: lotus-pond-app
|
||||
|
||||
lotus-townhall:
|
||||
rm -f lotus-townhall
|
||||
go build -o lotus-townhall ./cmd/lotus-townhall
|
||||
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build
|
||||
.PHONY: lotus-townhall
|
||||
BINS+=lotus-townhall
|
||||
|
||||
lotus-townhall-front:
|
||||
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
|
||||
.PHONY: lotus-townhall-front
|
||||
|
||||
lotus-townhall-app: lotus-touch lotus-townhall-front
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build
|
||||
.PHONY: lotus-townhall-app
|
||||
|
||||
lotus-fountain:
|
||||
rm -f lotus-fountain
|
||||
go build -o lotus-fountain ./cmd/lotus-fountain
|
||||
@@ -167,7 +179,7 @@ BINS+=lotus-bench
|
||||
|
||||
lotus-stats:
|
||||
rm -f lotus-stats
|
||||
go build -o lotus-stats ./cmd/lotus-stats
|
||||
go build $(GOFLAGS) -o lotus-stats ./cmd/lotus-stats
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-stats -i ./build
|
||||
.PHONY: lotus-stats
|
||||
BINS+=lotus-stats
|
||||
@@ -186,6 +198,18 @@ lotus-health:
|
||||
.PHONY: lotus-health
|
||||
BINS+=lotus-health
|
||||
|
||||
lotus-wallet:
|
||||
rm -f lotus-wallet
|
||||
go build -o lotus-wallet ./cmd/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
|
||||
@@ -286,7 +310,9 @@ method-gen:
|
||||
gen: type-gen method-gen
|
||||
|
||||
docsgen:
|
||||
go run ./api/docgen > documentation/en/api-methods.md
|
||||
go run ./api/docgen "api/api_full.go" "FullNode" > documentation/en/api-methods.md
|
||||
go run ./api/docgen "api/api_storage.go" "StorageMiner" > documentation/en/api-methods-miner.md
|
||||
go run ./api/docgen "api/api_worker.go" "WorkerAPI" > documentation/en/api-methods-worker.md
|
||||
|
||||
print-%:
|
||||
@echo $*=$($*)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<a href="https://circleci.com/gh/filecoin-project/lotus"><img src="https://circleci.com/gh/filecoin-project/lotus.svg?style=svg"></a>
|
||||
<a href="https://codecov.io/gh/filecoin-project/lotus"><img src="https://codecov.io/gh/filecoin-project/lotus/branch/master/graph/badge.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/filecoin-project/lotus"><img src="https://goreportcard.com/badge/github.com/filecoin-project/lotus" /></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.14.7-blue.svg" /></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.15.5-blue.svg" /></a>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
|
||||
+3
-9
@@ -2,9 +2,7 @@
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
For *critical* bugs, please send an email to security@filecoin.org.
|
||||
|
||||
The bug reporting process differs between bugs that are critical and may crash the network, and others that are unlikely to cause problems if malicious parties know about it. For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
|
||||
For *critical* bugs, please consult our Security Policy and Responsible Disclosure Program information at https://github.com/filecoin-project/community/blob/master/SECURITY.md
|
||||
|
||||
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.
|
||||
|
||||
@@ -20,10 +18,6 @@ Here are some examples of bugs we would consider 'critical':
|
||||
|
||||
This is not an exhaustive list, but should provide some idea of what we consider 'critical'.
|
||||
|
||||
## Supported Versions
|
||||
## Reporting a non security bug
|
||||
|
||||
* TODO: This should be defined and set up by Mainnet launch.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| Testnet | :white_check_mark: |
|
||||
For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
@@ -44,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
|
||||
@@ -58,6 +65,9 @@ type Common interface {
|
||||
// trigger graceful shutdown
|
||||
Shutdown(context.Context) error
|
||||
|
||||
// Session returns a random UUID of api provider session
|
||||
Session(context.Context) (uuid.UUID, error)
|
||||
|
||||
Closing(context.Context) (<-chan struct{}, error)
|
||||
}
|
||||
|
||||
|
||||
+119
-15
@@ -2,9 +2,11 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -172,6 +174,9 @@ type FullNode interface {
|
||||
// SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
||||
SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
|
||||
// SyncUnmarkAllBad purges bad block cache, making it possible to sync to chains previously marked as bad
|
||||
SyncUnmarkAllBad(ctx context.Context) error
|
||||
|
||||
// SyncCheckBad checks if a block was marked as bad, and if it was, returns
|
||||
// the reason.
|
||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||
@@ -203,6 +208,15 @@ type FullNode interface {
|
||||
// based on current chain conditions
|
||||
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
|
||||
|
||||
// MpoolBatchPush batch pushes a signed message to mempool.
|
||||
MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
|
||||
|
||||
// MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources.
|
||||
MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
|
||||
|
||||
// MpoolBatchPushMessage batch pushes a unsigned message to mempool.
|
||||
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error)
|
||||
|
||||
// MpoolGetNonce gets next nonce for the specified sender.
|
||||
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||
@@ -226,7 +240,9 @@ type FullNode interface {
|
||||
// MethodGroup: Wallet
|
||||
|
||||
// WalletNew creates a new address in the wallet with the given sigType.
|
||||
WalletNew(context.Context, crypto.SigType) (address.Address, error)
|
||||
// Available key types: bls, secp256k1, secp256k1-ledger
|
||||
// Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
// WalletHas indicates whether the given address is in the wallet.
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
// WalletList lists all the addresses in the wallet.
|
||||
@@ -271,6 +287,8 @@ type FullNode interface {
|
||||
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
||||
// ClientGetDealUpdates returns the status of updated deals
|
||||
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error)
|
||||
// ClientGetDealStatus returns status given a code
|
||||
ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error)
|
||||
// ClientHasLocal indicates whether a certain CID is locally stored.
|
||||
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
||||
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
|
||||
@@ -284,6 +302,8 @@ type FullNode interface {
|
||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
|
||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error)
|
||||
// ClientCalcCommP calculates the CommP and data size of the specified CID
|
||||
ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error)
|
||||
// ClientCalcCommP calculates the CommP for a specified file
|
||||
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
|
||||
// ClientGenCar generates a CAR file for the specified file.
|
||||
@@ -293,6 +313,10 @@ type FullNode interface {
|
||||
// ClientListTransfers returns the status of all ongoing transfers of data
|
||||
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
||||
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
||||
// ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
||||
ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
||||
ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
// ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel
|
||||
// which are stuck due to insufficient funds
|
||||
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
|
||||
@@ -307,19 +331,22 @@ type FullNode interface {
|
||||
|
||||
// MethodGroup: State
|
||||
// The State methods are used to query, inspect, and interact with chain state.
|
||||
// All methods take a TipSetKey as a parameter. The state looked up is the state at that tipset.
|
||||
// Most methods take a TipSetKey as a parameter. The state looked up is the state at that tipset.
|
||||
// A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used.
|
||||
|
||||
// StateCall runs the given message and returns its result without any persisted changes.
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
|
||||
// StateReplay returns the result of executing the indicated message, assuming it was executed in the indicated tipset.
|
||||
// StateReplay replays a given message, assuming it was included in a block in the specified tipset.
|
||||
// If no tipset key is provided, the appropriate tipset is looked up.
|
||||
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
||||
// StateGetActor returns the indicated actor's nonce and balance.
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||
// StateReadState returns the indicated actor's state.
|
||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
|
||||
// StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height.
|
||||
StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
StateListMessages(ctx context.Context, match *MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
|
||||
// StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number.
|
||||
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
|
||||
|
||||
// StateNetworkName returns the name of the network the node is synced to
|
||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||
@@ -350,6 +377,8 @@ type FullNode interface {
|
||||
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
|
||||
// StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent
|
||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
// StateMinerSectorAllocated checks if a sector is allocated
|
||||
StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error)
|
||||
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
|
||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
||||
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
|
||||
@@ -362,11 +391,13 @@ 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)
|
||||
// StateMsgGasCost searches for a message in the chain, and returns details of the messages gas costs, including the penalty and miner tip
|
||||
StateMsgGasCost(context.Context, cid.Cid, types.TipSetKey) (*MsgGasCost, 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)
|
||||
// StateWaitMsgLimited looks back up to limit epochs in the chain for a message.
|
||||
// If not found, it blocks until the message arrives on chain, and gets to the
|
||||
// indicated confidence depth.
|
||||
StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error)
|
||||
// StateListMiners returns the addresses of every miner that has claimed power in the Power Actor
|
||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
// StateListActors returns the addresses of every actor in the state
|
||||
@@ -407,8 +438,12 @@ type FullNode interface {
|
||||
// can issue. It takes the deal size and verified status as parameters.
|
||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
||||
|
||||
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
||||
// StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
|
||||
// This is not used anywhere in the protocol itself, and is only for external consumption.
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
|
||||
// StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset.
|
||||
// This is the value reported by the runtime interface to actors code.
|
||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
||||
// StateNetworkVersion returns the network version at the given tipset
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
|
||||
@@ -418,6 +453,8 @@ type FullNode interface {
|
||||
|
||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
// MsigGetVestingSchedule returns the vesting details of a given multisig.
|
||||
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error)
|
||||
// MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
||||
@@ -429,12 +466,21 @@ type FullNode interface {
|
||||
// It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the propose msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
// MsigApprove approves a previously-proposed multisig message
|
||||
|
||||
// MsigApprove approves a previously-proposed multisig message by transaction ID
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID> <signer address>
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error)
|
||||
|
||||
// MsigApproveTxnHash approves a previously-proposed multisig message, specified
|
||||
// using both transaction ID and a hash of the parameters used in the
|
||||
// proposal. This method of approval can be used to ensure you only approve
|
||||
// exactly the transaction you think you are.
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the approve msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
|
||||
// MsigCancel cancels a previously-proposed multisig message
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <recipient address>, <value to transfer>,
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error)
|
||||
// MsigAddPropose proposes adding a signer in the multisig
|
||||
@@ -462,8 +508,19 @@ type FullNode interface {
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
||||
|
||||
MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error)
|
||||
// MarketFreeBalance
|
||||
// MsigRemoveSigner proposes the removal of a signer from the multisig.
|
||||
// It accepts the multisig to make the change on, the proposer address to
|
||||
// send the message from, the address to be removed, and a boolean
|
||||
// indicating whether or not the signing threshold should be lowered by one
|
||||
// along with the address removal.
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, 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
|
||||
@@ -537,6 +594,9 @@ type DealInfo struct {
|
||||
|
||||
CreationTime time.Time
|
||||
Verified bool
|
||||
|
||||
TransferChannelID *datatransfer.ChannelID
|
||||
DataTransfer *DataTransferChannel
|
||||
}
|
||||
|
||||
type MsgLookup struct {
|
||||
@@ -558,6 +618,8 @@ type MsgGasCost struct {
|
||||
TotalCost abi.TokenAmount
|
||||
}
|
||||
|
||||
// BlsMessages[x].cid = Cids[x]
|
||||
// SecpkMessages[y].cid = Cids[BlsMessages.length + y]
|
||||
type BlockMessages struct {
|
||||
BlsMessages []*types.Message
|
||||
SecpkMessages []*types.SignedMessage
|
||||
@@ -703,8 +765,10 @@ type RetrievalOrder struct {
|
||||
}
|
||||
|
||||
type InvocResult struct {
|
||||
MsgCid cid.Cid
|
||||
Msg *types.Message
|
||||
MsgRct *types.MessageReceipt
|
||||
GasCost MsgGasCost
|
||||
ExecutionTrace types.ExecutionTrace
|
||||
Error string
|
||||
Duration time.Duration
|
||||
@@ -727,14 +791,31 @@ 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{}
|
||||
}
|
||||
|
||||
type ActiveSync struct {
|
||||
Base *types.TipSet
|
||||
Target *types.TipSet
|
||||
WorkerID uint64
|
||||
Base *types.TipSet
|
||||
Target *types.TipSet
|
||||
|
||||
Stage SyncStateStage
|
||||
Height abi.ChainEpoch
|
||||
@@ -839,6 +920,12 @@ type DataSize struct {
|
||||
PieceSize abi.PaddedPieceSize
|
||||
}
|
||||
|
||||
type DataCIDSize struct {
|
||||
PayloadSize int64
|
||||
PieceSize abi.PaddedPieceSize
|
||||
PieceCID cid.Cid
|
||||
}
|
||||
|
||||
type CommPRet struct {
|
||||
Root cid.Cid
|
||||
Size abi.UnpaddedPieceSize
|
||||
@@ -871,3 +958,20 @@ type Fault struct {
|
||||
Miner address.Address
|
||||
Epoch abi.ChainEpoch
|
||||
}
|
||||
|
||||
var EmptyVesting = MsigVesting{
|
||||
InitialBalance: types.EmptyInt,
|
||||
StartEpoch: -1,
|
||||
UnlockDuration: -1,
|
||||
}
|
||||
|
||||
type MsigVesting struct {
|
||||
InitialBalance abi.TokenAmount
|
||||
StartEpoch abi.ChainEpoch
|
||||
UnlockDuration abi.ChainEpoch
|
||||
}
|
||||
|
||||
type MessageMatch struct {
|
||||
To address.Address
|
||||
From address.Address
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type GatewayAPI interface {
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
|
||||
ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error)
|
||||
ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainNotify(context.Context) (<-chan []*HeadChange, error)
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
||||
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error)
|
||||
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*MarketDeal, error)
|
||||
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
|
||||
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
}
|
||||
+40
-3
@@ -5,13 +5,18 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
@@ -25,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)
|
||||
|
||||
@@ -37,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
|
||||
@@ -62,11 +74,13 @@ type StorageMiner interface {
|
||||
|
||||
// WorkerConnect tells the node to connect to workers RPC
|
||||
WorkerConnect(context.Context, string) error
|
||||
WorkerStats(context.Context) (map[uint64]storiface.WorkerStats, error)
|
||||
WorkerJobs(context.Context) (map[uint64][]storiface.WorkerJob, error)
|
||||
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error)
|
||||
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error)
|
||||
storiface.WorkerReturn
|
||||
|
||||
// SealingSchedDiag dumps internal sealing scheduler state
|
||||
SealingSchedDiag(context.Context) (interface{}, error)
|
||||
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error)
|
||||
SealingAbort(ctx context.Context, call storiface.CallID) error
|
||||
|
||||
stores.SectorIndex
|
||||
|
||||
@@ -81,6 +95,10 @@ type StorageMiner interface {
|
||||
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
|
||||
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
||||
// MinerRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
|
||||
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
|
||||
MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
|
||||
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||
DealsList(ctx context.Context) ([]MarketDeal, error)
|
||||
@@ -94,6 +112,10 @@ type StorageMiner interface {
|
||||
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error
|
||||
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOfflineRetrievalDeals(context.Context, bool) error
|
||||
DealsConsiderVerifiedStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderVerifiedStorageDeals(context.Context, bool) error
|
||||
DealsConsiderUnverifiedStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderUnverifiedStorageDeals(context.Context, bool) error
|
||||
|
||||
StorageAddLocal(ctx context.Context, path string) error
|
||||
|
||||
@@ -107,6 +129,8 @@ type StorageMiner interface {
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
// the path specified when calling CreateBackup is within the base path
|
||||
CreateBackup(ctx context.Context, fpath string) error
|
||||
|
||||
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error)
|
||||
}
|
||||
|
||||
type SealRes struct {
|
||||
@@ -186,3 +210,16 @@ func (st *SealSeed) Equals(ost *SealSeed) bool {
|
||||
}
|
||||
|
||||
type SectorState string
|
||||
|
||||
type AddrUse int
|
||||
|
||||
const (
|
||||
PreCommitAddr AddrUse = iota
|
||||
CommitAddr
|
||||
PoStAddr
|
||||
)
|
||||
|
||||
type AddressConfig struct {
|
||||
PreCommitControl []address.Address
|
||||
CommitControl []address.Address
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type MsgType string
|
||||
|
||||
const (
|
||||
MTUnknown = "unknown"
|
||||
|
||||
// Signing message CID. MsgMeta.Extra contains raw cbor message bytes
|
||||
MTChainMsg = "message"
|
||||
|
||||
// Signing a blockheader. signing raw cbor block bytes (MsgMeta.Extra is empty)
|
||||
MTBlock = "block"
|
||||
|
||||
// Signing a deal proposal. signing raw cbor proposal bytes (MsgMeta.Extra is empty)
|
||||
MTDealProposal = "dealproposal"
|
||||
|
||||
// TODO: Deals, Vouchers, VRF
|
||||
)
|
||||
|
||||
type MsgMeta struct {
|
||||
Type MsgType
|
||||
|
||||
// Additional data related to what is signed. Should be verifiable with the
|
||||
// signed bytes (e.g. CID(Extra).Bytes() == toSign)
|
||||
Extra []byte
|
||||
}
|
||||
|
||||
type WalletAPI interface {
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
WalletList(context.Context) ([]address.Address, error)
|
||||
|
||||
WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta MsgMeta) (*crypto.Signature, error)
|
||||
|
||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
||||
WalletDelete(context.Context, address.Address) error
|
||||
}
|
||||
+20
-11
@@ -2,15 +2,13 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
)
|
||||
@@ -23,18 +21,29 @@ type WorkerAPI interface {
|
||||
Paths(context.Context) ([]stores.StoragePath, error)
|
||||
Info(context.Context) (storiface.WorkerInfo, error)
|
||||
|
||||
AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error)
|
||||
storiface.WorkerCalls
|
||||
|
||||
storage.Sealer
|
||||
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error
|
||||
TaskEnable(ctx context.Context, tt sealtasks.TaskType) error
|
||||
|
||||
MoveStorage(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error
|
||||
|
||||
UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error
|
||||
ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (bool, error)
|
||||
// Storage / Other
|
||||
Remove(ctx context.Context, sector abi.SectorID) error
|
||||
|
||||
StorageAddLocal(ctx context.Context, path string) error
|
||||
|
||||
Fetch(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error
|
||||
// SetEnabled marks the worker as enabled/disabled. Not that this setting
|
||||
// may take a few seconds to propagate to task scheduler
|
||||
SetEnabled(ctx context.Context, enabled bool) error
|
||||
|
||||
Closing(context.Context) (<-chan struct{}, error)
|
||||
Enabled(ctx context.Context) (bool, error)
|
||||
|
||||
// WaitQuiet blocks until there are no tasks running
|
||||
WaitQuiet(ctx context.Context) error
|
||||
|
||||
// returns a random UUID of worker session, generated randomly when worker
|
||||
// process starts
|
||||
ProcessSession(context.Context) (uuid.UUID, error)
|
||||
|
||||
// Like ProcessSession, but returns an error when worker is disabled
|
||||
Session(context.Context) (uuid.UUID, error)
|
||||
}
|
||||
|
||||
@@ -36,3 +36,9 @@ func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI {
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
}
|
||||
|
||||
func PermissionedWalletAPI(a api.WalletAPI) api.WalletAPI {
|
||||
var out WalletStruct
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
}
|
||||
|
||||
+524
-95
@@ -5,8 +5,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
stnetwork "github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
@@ -15,6 +14,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
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"
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
stnetwork "github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
@@ -59,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"`
|
||||
@@ -67,6 +71,7 @@ type CommonStruct struct {
|
||||
LogSetLevel func(context.Context, string, string) error `perm:"write"`
|
||||
|
||||
Shutdown func(context.Context) error `perm:"admin"`
|
||||
Session func(context.Context) (uuid.UUID, error) `perm:"read"`
|
||||
Closing func(context.Context) (<-chan struct{}, error) `perm:"read"`
|
||||
}
|
||||
}
|
||||
@@ -111,6 +116,7 @@ type FullNodeStruct struct {
|
||||
SyncCheckpoint func(ctx context.Context, key types.TipSetKey) error `perm:"admin"`
|
||||
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncUnmarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncUnmarkAllBad func(ctx context.Context) error `perm:"admin"`
|
||||
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
|
||||
SyncValidateTipset func(ctx context.Context, tsk types.TipSetKey) (bool, error) `perm:"read"`
|
||||
|
||||
@@ -129,10 +135,14 @@ type FullNodeStruct struct {
|
||||
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
|
||||
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
|
||||
|
||||
MpoolBatchPush func(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
MpoolBatchPushUntrusted func(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
MpoolBatchPushMessage func(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"`
|
||||
|
||||
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
|
||||
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
|
||||
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletNew func(context.Context, types.KeyType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||
@@ -154,16 +164,20 @@ type FullNodeStruct struct {
|
||||
ClientMinerQueryOffer func(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) `perm:"read"`
|
||||
ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
|
||||
ClientGetDealStatus func(context.Context, uint64) (string, error) `perm:"read"`
|
||||
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"`
|
||||
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
|
||||
ClientRetrieveWithEvents func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
|
||||
ClientDealPieceCID func(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) `perm:"read"`
|
||||
ClientCalcCommP func(ctx context.Context, inpath string) (*api.CommPRet, error) `perm:"read"`
|
||||
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
|
||||
ClientDealSize func(ctx context.Context, root cid.Cid) (api.DataSize, error) `perm:"read"`
|
||||
ClientListDataTransfers func(ctx context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
|
||||
ClientDataTransferUpdates func(ctx context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
|
||||
ClientRestartDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"write"`
|
||||
ClientCancelDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"write"`
|
||||
ClientRetrieveTryRestartInsufficientFunds func(ctx context.Context, paymentChannel address.Address) error `perm:"write"`
|
||||
|
||||
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
@@ -180,6 +194,7 @@ type FullNodeStruct struct {
|
||||
StateMinerPreCommitDepositForPower func(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerInitialPledgeCollateral func(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerSectorAllocated func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) `perm:"read"`
|
||||
StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
|
||||
StateSectorGetInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
|
||||
@@ -188,8 +203,8 @@ type FullNodeStruct struct {
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StateMsgGasCost func(context.Context, cid.Cid, types.TipSetKey) (*api.MsgGasCost, error) `perm:"read"`
|
||||
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"`
|
||||
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
@@ -202,20 +217,24 @@ type FullNodeStruct struct {
|
||||
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
|
||||
StateGetReceipt func(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateDecodeParams func(context.Context, address.Address, abi.MethodNum, []byte, types.TipSetKey) (interface{}, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
|
||||
StateVerifierStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVerifiedRegistryRootKey func(ctx context.Context, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (abi.TokenAmount, error) `perm:"read"`
|
||||
StateVMCirculatingSupplyInternal func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"`
|
||||
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigGetVestingSchedule func(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error) `perm:"read"`
|
||||
MsigGetVested func(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigCreate func(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MsigPropose func(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApprove func(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApprove func(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApproveTxnHash func(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCancel func(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddPropose func(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) `perm:"sign"`
|
||||
@@ -223,8 +242,11 @@ type FullNodeStruct struct {
|
||||
MsigSwapPropose func(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapApprove func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
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"`
|
||||
|
||||
MarketEnsureAvailable func(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, 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"`
|
||||
@@ -256,8 +278,9 @@ type StorageMinerStruct struct {
|
||||
CommonStruct
|
||||
|
||||
Internal struct {
|
||||
ActorAddress func(context.Context) (address.Address, error) `perm:"read"`
|
||||
ActorSectorSize func(context.Context, address.Address) (abi.SectorSize, error) `perm:"read"`
|
||||
ActorAddress func(context.Context) (address.Address, error) `perm:"read"`
|
||||
ActorSectorSize func(context.Context, address.Address) (abi.SectorSize, error) `perm:"read"`
|
||||
ActorAddressConfig func(ctx context.Context) (api.AddressConfig, error) `perm:"read"`
|
||||
|
||||
MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
@@ -272,11 +295,15 @@ type StorageMinerStruct struct {
|
||||
MarketGetRetrievalAsk func(ctx context.Context) (*retrievalmarket.Ask, error) `perm:"read"`
|
||||
MarketListDataTransfers func(ctx context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
|
||||
MarketDataTransferUpdates func(ctx context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
|
||||
MarketRestartDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"read"`
|
||||
MarketCancelDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"read"`
|
||||
|
||||
PledgeSector func(context.Context) error `perm:"write"`
|
||||
|
||||
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"`
|
||||
@@ -287,37 +314,54 @@ type StorageMinerStruct struct {
|
||||
SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"`
|
||||
SectorMarkForUpgrade func(ctx context.Context, id abi.SectorNumber) error `perm:"admin"`
|
||||
|
||||
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
|
||||
WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"`
|
||||
WorkerJobs func(context.Context) (map[uint64][]storiface.WorkerJob, 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"`
|
||||
|
||||
SealingSchedDiag func(context.Context) (interface{}, error) `perm:"admin"`
|
||||
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"`
|
||||
|
||||
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
|
||||
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
|
||||
StorageStat func(context.Context, stores.ID) (fsutil.FsStat, error) `perm:"admin"`
|
||||
StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin"`
|
||||
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"`
|
||||
StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"`
|
||||
StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, abi.RegisteredSealProof, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
|
||||
StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
|
||||
StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"`
|
||||
StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"`
|
||||
SealingSchedDiag func(context.Context, bool) (interface{}, error) `perm:"admin"`
|
||||
SealingAbort func(ctx context.Context, call storiface.CallID) 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"`
|
||||
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
|
||||
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
|
||||
StorageStat func(context.Context, stores.ID) (fsutil.FsStat, error) `perm:"admin"`
|
||||
StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin"`
|
||||
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType, bool) error `perm:"admin"`
|
||||
StorageDropSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType) error `perm:"admin"`
|
||||
StorageFindSector func(context.Context, abi.SectorID, storiface.SectorFileType, abi.SectorSize, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
|
||||
StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageBestAlloc func(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, sealing storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
|
||||
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
|
||||
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"`
|
||||
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"`
|
||||
|
||||
@@ -327,6 +371,8 @@ type StorageMinerStruct struct {
|
||||
PiecesGetCIDInfo func(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"`
|
||||
|
||||
CreateBackup func(ctx context.Context, fpath string) error `perm:"admin"`
|
||||
|
||||
CheckProvable func(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) `perm:"admin"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,23 +386,75 @@ 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) (abi.PieceInfo, error) `perm:"admin"`
|
||||
SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"`
|
||||
SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"`
|
||||
SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"`
|
||||
SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"`
|
||||
FinalizeSector func(context.Context, abi.SectorID, []storage.Range) error `perm:"admin"`
|
||||
ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error `perm:"admin"`
|
||||
Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
|
||||
MoveStorage func(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error `perm:"admin"`
|
||||
StorageAddLocal func(ctx context.Context, path string) 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"`
|
||||
|
||||
UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"`
|
||||
ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (bool, 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"`
|
||||
|
||||
Fetch func(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error `perm:"admin"`
|
||||
Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
|
||||
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
|
||||
|
||||
Closing func(context.Context) (<-chan struct{}, error) `perm:"admin"`
|
||||
SetEnabled func(ctx context.Context, enabled bool) error `perm:"admin"`
|
||||
Enabled func(ctx context.Context) (bool, error) `perm:"admin"`
|
||||
|
||||
WaitQuiet func(ctx context.Context) error `perm:"admin"`
|
||||
|
||||
ProcessSession func(context.Context) (uuid.UUID, error) `perm:"admin"`
|
||||
Session func(context.Context) (uuid.UUID, error) `perm:"admin"`
|
||||
}
|
||||
}
|
||||
|
||||
type GatewayStruct struct {
|
||||
Internal struct {
|
||||
ChainGetBlockMessages func(ctx context.Context, c cid.Cid) (*api.BlockMessages, error)
|
||||
ChainGetMessage func(ctx context.Context, mc cid.Cid) (*types.Message, error)
|
||||
ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainHasObj func(context.Context, cid.Cid) (bool, error)
|
||||
ChainHead func(ctx context.Context) (*types.TipSet, error)
|
||||
ChainNotify func(ctx context.Context) (<-chan []*api.HeadChange, error)
|
||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error)
|
||||
GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||
MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||
MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||
StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateDealProviderCollateralBounds func(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
|
||||
StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
StateGetReceipt func(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateListMiners func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
||||
StateMinerInfo func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
|
||||
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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
type WalletStruct struct {
|
||||
Internal struct {
|
||||
WalletNew func(context.Context, types.KeyType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"`
|
||||
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
WalletDelete func(context.Context, address.Address) error `perm:"write"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,6 +512,18 @@ func (c *CommonStruct) NetBandwidthStatsByProtocol(ctx context.Context) (map[pro
|
||||
return c.Internal.NetBandwidthStatsByProtocol(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetBlockAdd(ctx context.Context, acl api.NetBlockList) error {
|
||||
return c.Internal.NetBlockAdd(ctx, acl)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetBlockRemove(ctx context.Context, acl api.NetBlockList) error {
|
||||
return c.Internal.NetBlockRemove(ctx, acl)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetBlockList(ctx context.Context) (api.NetBlockList, error) {
|
||||
return c.Internal.NetBlockList(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) NetAgentVersion(ctx context.Context, p peer.ID) (string, error) {
|
||||
return c.Internal.NetAgentVersion(ctx, p)
|
||||
}
|
||||
@@ -440,6 +550,10 @@ func (c *CommonStruct) Shutdown(ctx context.Context) error {
|
||||
return c.Internal.Shutdown(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) Session(ctx context.Context) (uuid.UUID, error) {
|
||||
return c.Internal.Session(ctx)
|
||||
}
|
||||
|
||||
func (c *CommonStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return c.Internal.Closing(ctx)
|
||||
}
|
||||
@@ -478,6 +592,10 @@ func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*
|
||||
return c.Internal.ClientGetDealInfo(ctx, deal)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) {
|
||||
return c.Internal.ClientGetDealStatus(ctx, statusCode)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
|
||||
return c.Internal.ClientListDeals(ctx)
|
||||
}
|
||||
@@ -497,6 +615,11 @@ func (c *FullNodeStruct) ClientRetrieveWithEvents(ctx context.Context, order api
|
||||
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) {
|
||||
return c.Internal.ClientQueryAsk(ctx, p, miner)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientDealPieceCID(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) {
|
||||
return c.Internal.ClientDealPieceCID(ctx, root)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) {
|
||||
return c.Internal.ClientCalcCommP(ctx, inpath)
|
||||
}
|
||||
@@ -517,6 +640,14 @@ func (c *FullNodeStruct) ClientDataTransferUpdates(ctx context.Context) (<-chan
|
||||
return c.Internal.ClientDataTransferUpdates(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
|
||||
return c.Internal.ClientRestartDataTransfer(ctx, transferID, otherPeer, isInitiator)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
|
||||
return c.Internal.ClientCancelDataTransfer(ctx, transferID, otherPeer, isInitiator)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error {
|
||||
return c.Internal.ClientRetrieveTryRestartInsufficientFunds(ctx, paymentChannel)
|
||||
}
|
||||
@@ -569,6 +700,18 @@ func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Messag
|
||||
return c.Internal.MpoolPushMessage(ctx, msg, spec)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolBatchPush(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) {
|
||||
return c.Internal.MpoolBatchPush(ctx, smsgs)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolBatchPushUntrusted(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) {
|
||||
return c.Internal.MpoolBatchPushUntrusted(ctx, smsgs)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) {
|
||||
return c.Internal.MpoolBatchPushMessage(ctx, msgs, spec)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) {
|
||||
return c.Internal.MpoolSub(ctx)
|
||||
}
|
||||
@@ -597,7 +740,7 @@ func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.Chain
|
||||
return c.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
|
||||
@@ -749,6 +892,10 @@ func (c *FullNodeStruct) SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error
|
||||
return c.Internal.SyncUnmarkBad(ctx, bcid)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncUnmarkAllBad(ctx context.Context) error {
|
||||
return c.Internal.SyncUnmarkAllBad(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
|
||||
return c.Internal.SyncCheckBad(ctx, bcid)
|
||||
}
|
||||
@@ -813,6 +960,10 @@ func (c *FullNodeStruct) StateMinerAvailableBalance(ctx context.Context, maddr a
|
||||
return c.Internal.StateMinerAvailableBalance(ctx, maddr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectorAllocated(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) {
|
||||
return c.Internal.StateMinerSectorAllocated(ctx, maddr, s, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) {
|
||||
return c.Internal.StateSectorPreCommitInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
@@ -845,14 +996,14 @@ func (c *FullNodeStruct) StateReadState(ctx context.Context, addr address.Addres
|
||||
return c.Internal.StateReadState(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMsgGasCost(ctx context.Context, msgc cid.Cid, tsk types.TipSetKey) (*api.MsgGasCost, error) {
|
||||
return c.Internal.StateMsgGasCost(ctx, msgc, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateWaitMsgLimited(ctx context.Context, msgc cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateWaitMsgLimited(ctx, msgc, confidence, limit)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateSearchMsg(ctx, msgc)
|
||||
}
|
||||
@@ -897,10 +1048,14 @@ func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk t
|
||||
return c.Internal.StateGetReceipt(ctx, msg, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
|
||||
return c.Internal.StateListMessages(ctx, match, tsk, toht)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) {
|
||||
return c.Internal.StateDecodeParams(ctx, toAddr, method, params, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (*api.ComputeStateOutput, error) {
|
||||
return c.Internal.StateCompute(ctx, height, msgs, tsk)
|
||||
}
|
||||
@@ -921,10 +1076,14 @@ func (c *FullNodeStruct) StateDealProviderCollateralBounds(ctx context.Context,
|
||||
return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
||||
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
|
||||
return c.Internal.StateCirculatingSupply(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
|
||||
return c.Internal.StateVMCirculatingSupplyInternal(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
|
||||
return c.Internal.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
@@ -933,6 +1092,10 @@ func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.
|
||||
return c.Internal.MsigGetAvailableBalance(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetVestingSchedule(ctx context.Context, a address.Address, tsk types.TipSetKey) (api.MsigVesting, error) {
|
||||
return c.Internal.MsigGetVestingSchedule(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetVested(ctx context.Context, a address.Address, sTsk types.TipSetKey, eTsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetVested(ctx, a, sTsk, eTsk)
|
||||
}
|
||||
@@ -945,8 +1108,12 @@ func (c *FullNodeStruct) MsigPropose(ctx context.Context, msig address.Address,
|
||||
return c.Internal.MsigPropose(ctx, msig, to, amt, src, method, params)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigApprove(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
return c.Internal.MsigApprove(ctx, msig, txID, proposer, to, amt, src, method, params)
|
||||
func (c *FullNodeStruct) MsigApprove(ctx context.Context, msig address.Address, txID uint64, signer address.Address) (cid.Cid, error) {
|
||||
return c.Internal.MsigApprove(ctx, msig, txID, signer)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
return c.Internal.MsigApproveTxnHash(ctx, msig, txID, proposer, to, amt, src, method, params)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
@@ -977,8 +1144,20 @@ func (c *FullNodeStruct) MsigSwapCancel(ctx context.Context, msig address.Addres
|
||||
return c.Internal.MsigSwapCancel(ctx, msig, src, txID, oldAdd, newAdd)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr, wallet address.Address, amt types.BigInt) (cid.Cid, error) {
|
||||
return c.Internal.MarketEnsureAvailable(ctx, addr, wallet, amt)
|
||||
func (c *FullNodeStruct) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) {
|
||||
return c.Internal.MsigRemoveSigner(ctx, msig, proposer, toRemove, decrease)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error {
|
||||
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) {
|
||||
@@ -1063,6 +1242,10 @@ func (c *StorageMinerStruct) ActorSectorSize(ctx context.Context, addr address.A
|
||||
return c.Internal.ActorSectorSize(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) ActorAddressConfig(ctx context.Context) (api.AddressConfig, error) {
|
||||
return c.Internal.ActorAddressConfig(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) PledgeSector(ctx context.Context) error {
|
||||
return c.Internal.PledgeSector(ctx)
|
||||
}
|
||||
@@ -1077,6 +1260,14 @@ func (c *StorageMinerStruct) SectorsList(ctx context.Context) ([]abi.SectorNumbe
|
||||
return c.Internal.SectorsList(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorsListInStates(ctx context.Context, states []api.SectorState) ([]abi.SectorNumber, error) {
|
||||
return c.Internal.SectorsListInStates(ctx, states)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) {
|
||||
return c.Internal.SectorsSummary(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]api.SealedRef, error) {
|
||||
return c.Internal.SectorsRefs(ctx)
|
||||
}
|
||||
@@ -1117,32 +1308,80 @@ func (c *StorageMinerStruct) WorkerConnect(ctx context.Context, url string) erro
|
||||
return c.Internal.WorkerConnect(ctx, url)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (map[uint64]storiface.WorkerStats, error) {
|
||||
func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (map[uuid.UUID]storiface.WorkerStats, error) {
|
||||
return c.Internal.WorkerStats(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) WorkerJobs(ctx context.Context) (map[uint64][]storiface.WorkerJob, error) {
|
||||
func (c *StorageMinerStruct) WorkerJobs(ctx context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) {
|
||||
return c.Internal.WorkerJobs(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SealingSchedDiag(ctx context.Context) (interface{}, error) {
|
||||
return c.Internal.SealingSchedDiag(ctx)
|
||||
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 *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 *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 *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 *storiface.CallError) error {
|
||||
return c.Internal.ReturnSealCommit2(ctx, callID, proof, err)
|
||||
}
|
||||
|
||||
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 *storiface.CallError) error {
|
||||
return c.Internal.ReturnReleaseUnsealed(ctx, callID, err)
|
||||
}
|
||||
|
||||
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 *storiface.CallError) error {
|
||||
return c.Internal.ReturnUnsealPiece(ctx, callID, err)
|
||||
}
|
||||
|
||||
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 *storiface.CallError) error {
|
||||
return c.Internal.ReturnFetch(ctx, callID, err)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) {
|
||||
return c.Internal.SealingSchedDiag(ctx, doSched)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) SealingAbort(ctx context.Context, call storiface.CallID) error {
|
||||
return c.Internal.SealingAbort(ctx, call)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageAttach(ctx context.Context, si stores.StorageInfo, st fsutil.FsStat) error {
|
||||
return c.Internal.StorageAttach(ctx, si, st)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType, primary bool) error {
|
||||
func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error {
|
||||
return c.Internal.StorageDeclareSector(ctx, storageId, s, ft, primary)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType) error {
|
||||
func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft storiface.SectorFileType) error {
|
||||
return c.Internal.StorageDropSector(ctx, storageId, s, ft)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, spt abi.RegisteredSealProof, allowFetch bool) ([]stores.SectorStorageInfo, error) {
|
||||
return c.Internal.StorageFindSector(ctx, si, types, spt, allowFetch)
|
||||
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) {
|
||||
return c.Internal.StorageFindSector(ctx, si, types, ssize, allowFetch)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) {
|
||||
@@ -1161,19 +1400,19 @@ func (c *StorageMinerStruct) StorageInfo(ctx context.Context, id stores.ID) (sto
|
||||
return c.Internal.StorageInfo(ctx, id)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, pt stores.PathType) ([]stores.StorageInfo, error) {
|
||||
return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt)
|
||||
func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pt storiface.PathType) ([]stores.StorageInfo, error) {
|
||||
return c.Internal.StorageBestAlloc(ctx, allocate, ssize, pt)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error {
|
||||
return c.Internal.StorageReportHealth(ctx, id, report)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error {
|
||||
func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error {
|
||||
return c.Internal.StorageLock(ctx, sector, read, write)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageTryLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) {
|
||||
func (c *StorageMinerStruct) StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) {
|
||||
return c.Internal.StorageTryLock(ctx, sector, read, write)
|
||||
}
|
||||
|
||||
@@ -1221,6 +1460,14 @@ func (c *StorageMinerStruct) MarketDataTransferUpdates(ctx context.Context) (<-c
|
||||
return c.Internal.MarketDataTransferUpdates(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
|
||||
return c.Internal.MarketRestartDataTransfer(ctx, transferID, otherPeer, isInitiator)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
|
||||
return c.Internal.MarketCancelDataTransfer(ctx, transferID, otherPeer, isInitiator)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error {
|
||||
return c.Internal.DealsImportData(ctx, dealPropCid, file)
|
||||
}
|
||||
@@ -1269,6 +1516,22 @@ func (c *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(ctx context.C
|
||||
return c.Internal.DealsSetConsiderOfflineRetrievalDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(ctx context.Context) (bool, error) {
|
||||
return c.Internal.DealsConsiderVerifiedStorageDeals(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(ctx context.Context, b bool) error {
|
||||
return c.Internal.DealsSetConsiderVerifiedStorageDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(ctx context.Context) (bool, error) {
|
||||
return c.Internal.DealsConsiderUnverifiedStorageDeals(ctx)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(ctx context.Context, b bool) error {
|
||||
return c.Internal.DealsSetConsiderUnverifiedStorageDeals(ctx, b)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) StorageAddLocal(ctx context.Context, path string) error {
|
||||
return c.Internal.StorageAddLocal(ctx, path)
|
||||
}
|
||||
@@ -1293,6 +1556,10 @@ func (c *StorageMinerStruct) CreateBackup(ctx context.Context, fpath string) err
|
||||
return c.Internal.CreateBackup(ctx, fpath)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storage.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) {
|
||||
return c.Internal.CheckProvable(ctx, pp, sectors, expensive)
|
||||
}
|
||||
|
||||
// WorkerStruct
|
||||
|
||||
func (w *WorkerStruct) Version(ctx context.Context) (build.Version, error) {
|
||||
@@ -1311,63 +1578,225 @@ 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) (abi.PieceInfo, 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) (storage.PreCommit1Out, 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, p1o storage.PreCommit1Out) (storage.SectorCids, error) {
|
||||
return w.Internal.SealPreCommit2(ctx, sector, p1o)
|
||||
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) (storage.Commit1Out, 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) (storage.Proof, 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) 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) 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 storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) {
|
||||
return w.Internal.MoveStorage(ctx, sector, types)
|
||||
}
|
||||
|
||||
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 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 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)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error {
|
||||
return w.Internal.MoveStorage(ctx, sector, types)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) StorageAddLocal(ctx context.Context, path string) error {
|
||||
return w.Internal.StorageAddLocal(ctx, path)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) UnsealPiece(ctx context.Context, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error {
|
||||
return w.Internal.UnsealPiece(ctx, id, index, size, randomness, c)
|
||||
func (w *WorkerStruct) SetEnabled(ctx context.Context, enabled bool) error {
|
||||
return w.Internal.SetEnabled(ctx, enabled)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) ReadPiece(ctx context.Context, writer io.Writer, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) {
|
||||
return w.Internal.ReadPiece(ctx, writer, id, index, size)
|
||||
func (w *WorkerStruct) Enabled(ctx context.Context) (bool, error) {
|
||||
return w.Internal.Enabled(ctx)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, ptype stores.PathType, am stores.AcquireMode) error {
|
||||
return w.Internal.Fetch(ctx, id, fileType, ptype, am)
|
||||
func (w *WorkerStruct) WaitQuiet(ctx context.Context) error {
|
||||
return w.Internal.WaitQuiet(ctx)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return w.Internal.Closing(ctx)
|
||||
func (w *WorkerStruct) ProcessSession(ctx context.Context) (uuid.UUID, error) {
|
||||
return w.Internal.ProcessSession(ctx)
|
||||
}
|
||||
|
||||
func (w *WorkerStruct) Session(ctx context.Context) (uuid.UUID, error) {
|
||||
return w.Internal.Session(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) {
|
||||
return g.Internal.ChainGetBlockMessages(ctx, c)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) {
|
||||
return g.Internal.ChainGetMessage(ctx, mc)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return g.Internal.ChainGetTipSet(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return g.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
|
||||
return g.Internal.ChainHasObj(ctx, c)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||
return g.Internal.ChainHead(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) {
|
||||
return g.Internal.ChainNotify(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
||||
return g.Internal.ChainReadObj(ctx, c)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
|
||||
return g.Internal.GasEstimateMessageGas(ctx, msg, spec, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) {
|
||||
return g.Internal.MpoolPush(ctx, sm)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return g.Internal.MsigGetAvailableBalance(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) {
|
||||
return g.Internal.MsigGetVested(ctx, addr, start, end)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return g.Internal.StateAccountKey(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) {
|
||||
return g.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
|
||||
return g.Internal.StateGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateGetReceipt(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) {
|
||||
return g.Internal.StateGetReceipt(ctx, c, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return g.Internal.StateLookupID(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
|
||||
return g.Internal.StateListMiners(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) {
|
||||
return g.Internal.StateMarketBalance(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) {
|
||||
return g.Internal.StateMarketStorageDeal(ctx, dealId, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
|
||||
return g.Internal.StateMinerInfo(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) {
|
||||
return g.Internal.StateMinerProvingDeadline(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
|
||||
return g.Internal.StateMinerPower(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
|
||||
return g.Internal.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) {
|
||||
return g.Internal.StateSectorGetInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
|
||||
return g.Internal.StateVerifiedClientStatus(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
return g.Internal.StateWaitMsg(ctx, msg, confidence)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletHas(ctx context.Context, addr address.Address) (bool, error) {
|
||||
return c.Internal.WalletHas(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletList(ctx context.Context) ([]address.Address, error) {
|
||||
return c.Internal.WalletList(ctx)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletSign(ctx context.Context, k address.Address, msg []byte, meta api.MsgMeta) (*crypto.Signature, error) {
|
||||
return c.Internal.WalletSign(ctx, k, msg, meta)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) {
|
||||
return c.Internal.WalletExport(ctx, a)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletImport(ctx context.Context, ki *types.KeyInfo) (address.Address, error) {
|
||||
return c.Internal.WalletImport(ctx, ki)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletDelete(ctx context.Context, addr address.Address) error {
|
||||
return c.Internal.WalletDelete(ctx, addr)
|
||||
}
|
||||
|
||||
var _ api.Common = &CommonStruct{}
|
||||
var _ api.FullNode = &FullNodeStruct{}
|
||||
var _ api.StorageMiner = &StorageMinerStruct{}
|
||||
var _ api.WorkerAPI = &WorkerStruct{}
|
||||
var _ api.GatewayAPI = &GatewayStruct{}
|
||||
var _ api.WalletAPI = &WalletStruct{}
|
||||
|
||||
@@ -82,3 +82,29 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
// NewGatewayRPC creates a new http jsonrpc client for a gateway node.
|
||||
func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.GatewayStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
opts...,
|
||||
)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WalletAPI, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.WalletStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
+131
-28
@@ -6,12 +6,14 @@ import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-filestore"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
@@ -24,6 +26,7 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
filestore2 "github.com/filecoin-project/go-fil-markets/filestore"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
@@ -36,6 +39,10 @@ import (
|
||||
"github.com/filecoin-project/lotus/api/apistruct"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
@@ -83,10 +90,11 @@ 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)
|
||||
addExample(types.KTBLS)
|
||||
addExample(int64(9))
|
||||
addExample(12.3)
|
||||
addExample(123)
|
||||
@@ -116,17 +124,17 @@ func init() {
|
||||
addExample(network.ReachabilityPublic)
|
||||
addExample(build.NewestNetworkVersion)
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
Msg: exampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
})
|
||||
addExample(map[string]types.Actor{
|
||||
"t01236": exampleValue(reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
"t01236": exampleValue("init", reflect.TypeOf(types.Actor{}), nil).(types.Actor),
|
||||
})
|
||||
addExample(map[string]api.MarketDeal{
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketDeal{}), nil).(api.MarketDeal),
|
||||
})
|
||||
addExample(map[string]api.MarketBalance{
|
||||
"t026363": exampleValue(reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
"t026363": exampleValue("init", reflect.TypeOf(api.MarketBalance{}), nil).(api.MarketBalance),
|
||||
})
|
||||
addExample(map[string]*pubsub.TopicScoreSnapshot{
|
||||
"/blocks": {
|
||||
@@ -161,9 +169,89 @@ func init() {
|
||||
// because reflect.TypeOf(maddr) returns the concrete type...
|
||||
ExampleValues[reflect.TypeOf(struct{ A multiaddr.Multiaddr }{}).Field(0).Type] = maddr
|
||||
|
||||
// miner specific
|
||||
addExample(filestore2.Path(".lotusminer/fstmp123"))
|
||||
si := multistore.StoreID(12)
|
||||
addExample(&si)
|
||||
addExample(retrievalmarket.DealID(5))
|
||||
addExample(abi.ActorID(1000))
|
||||
addExample(map[string][]api.SealedRef{
|
||||
"98000": {
|
||||
api.SealedRef{
|
||||
SectorID: 100,
|
||||
Offset: 10 << 20,
|
||||
Size: 1 << 20,
|
||||
},
|
||||
},
|
||||
})
|
||||
addExample(api.SectorState(sealing.Proving))
|
||||
addExample(stores.ID("76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8"))
|
||||
addExample(storiface.FTUnsealed)
|
||||
addExample(storiface.PathSealing)
|
||||
addExample(map[stores.ID][]stores.Decl{
|
||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": {
|
||||
{
|
||||
SectorID: abi.SectorID{Miner: 1000, Number: 100},
|
||||
SectorFileType: storiface.FTSealed,
|
||||
},
|
||||
},
|
||||
})
|
||||
addExample(map[stores.ID]string{
|
||||
"76f1988b-ef30-4d7e-b3ec-9a627f4ba5a8": "/data/path",
|
||||
})
|
||||
addExample(map[uuid.UUID][]storiface.WorkerJob{
|
||||
uuid.MustParse("ef8d99a2-6865-4189-8ffa-9fef0f806eee"): {
|
||||
{
|
||||
ID: storiface.CallID{
|
||||
Sector: abi.SectorID{Miner: 1000, Number: 100},
|
||||
ID: uuid.MustParse("76081ba0-61bd-45a5-bc08-af05f1c26e5d"),
|
||||
},
|
||||
Sector: abi.SectorID{Miner: 1000, Number: 100},
|
||||
Task: sealtasks.TTPreCommit2,
|
||||
RunWait: 0,
|
||||
Start: time.Unix(1605172927, 0).UTC(),
|
||||
Hostname: "host",
|
||||
},
|
||||
},
|
||||
})
|
||||
addExample(map[uuid.UUID]storiface.WorkerStats{
|
||||
uuid.MustParse("ef8d99a2-6865-4189-8ffa-9fef0f806eee"): {
|
||||
Info: storiface.WorkerInfo{
|
||||
Hostname: "host",
|
||||
Resources: storiface.WorkerResources{
|
||||
MemPhysical: 256 << 30,
|
||||
MemSwap: 120 << 30,
|
||||
MemReserved: 2 << 30,
|
||||
CPUs: 64,
|
||||
GPUs: []string{"aGPU 1337"},
|
||||
},
|
||||
},
|
||||
Enabled: true,
|
||||
MemUsedMin: 0,
|
||||
MemUsedMax: 0,
|
||||
GpuUsed: false,
|
||||
CpuUse: 0,
|
||||
},
|
||||
})
|
||||
addExample(storiface.ErrorCode(0))
|
||||
addExample(map[abi.SectorNumber]string{
|
||||
123: "can't acquire read lock",
|
||||
})
|
||||
addExample(map[api.SectorState]int{
|
||||
api.SectorState(sealing.Proving): 120,
|
||||
})
|
||||
addExample([]abi.SectorNumber{123, 124})
|
||||
|
||||
// worker specific
|
||||
addExample(storiface.AcquireMove)
|
||||
addExample(storiface.UnpaddedByteIndex(abi.PaddedPieceSize(1 << 20).Unpadded()))
|
||||
addExample(map[sealtasks.TaskType]struct{}{
|
||||
sealtasks.TTPreCommit2: {},
|
||||
})
|
||||
addExample(sealtasks.TTCommit2)
|
||||
}
|
||||
|
||||
func exampleValue(t, parent reflect.Type) interface{} {
|
||||
func exampleValue(method string, t, parent reflect.Type) interface{} {
|
||||
v, ok := ExampleValues[t]
|
||||
if ok {
|
||||
return v
|
||||
@@ -172,25 +260,25 @@ func exampleValue(t, parent reflect.Type) interface{} {
|
||||
switch t.Kind() {
|
||||
case reflect.Slice:
|
||||
out := reflect.New(t).Elem()
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem(), t)))
|
||||
reflect.Append(out, reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||
return out.Interface()
|
||||
case reflect.Chan:
|
||||
return exampleValue(t.Elem(), nil)
|
||||
return exampleValue(method, t.Elem(), nil)
|
||||
case reflect.Struct:
|
||||
es := exampleStruct(t, parent)
|
||||
es := exampleStruct(method, t, parent)
|
||||
v := reflect.ValueOf(es).Elem().Interface()
|
||||
ExampleValues[t] = v
|
||||
return v
|
||||
case reflect.Array:
|
||||
out := reflect.New(t).Elem()
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(t.Elem(), t)))
|
||||
out.Index(i).Set(reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||
}
|
||||
return out.Interface()
|
||||
|
||||
case reflect.Ptr:
|
||||
if t.Elem().Kind() == reflect.Struct {
|
||||
es := exampleStruct(t.Elem(), t)
|
||||
es := exampleStruct(method, t.Elem(), t)
|
||||
//ExampleValues[t] = es
|
||||
return es
|
||||
}
|
||||
@@ -198,10 +286,10 @@ func exampleValue(t, parent reflect.Type) interface{} {
|
||||
return struct{}{}
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("No example value for type: %s", t))
|
||||
panic(fmt.Sprintf("No example value for type: %s (method '%s')", t, method))
|
||||
}
|
||||
|
||||
func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
func exampleStruct(method string, t, parent reflect.Type) interface{} {
|
||||
ns := reflect.New(t)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
@@ -209,7 +297,7 @@ func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
continue
|
||||
}
|
||||
if strings.Title(f.Name) == f.Name {
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(f.Type, t)))
|
||||
ns.Elem().Field(i).Set(reflect.ValueOf(exampleValue(method, f.Type, t)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +305,7 @@ func exampleStruct(t, parent reflect.Type) interface{} {
|
||||
}
|
||||
|
||||
type Visitor struct {
|
||||
Root string
|
||||
Methods map[string]ast.Node
|
||||
}
|
||||
|
||||
@@ -226,7 +315,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
return v
|
||||
}
|
||||
|
||||
if st.Name.Name != "FullNode" {
|
||||
if st.Name.Name != v.Root {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -242,7 +331,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
||||
|
||||
const noComment = "There are not yet any comments for this method."
|
||||
|
||||
func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
||||
func parseApiASTInfo(apiFile, iface string) (map[string]string, map[string]string) { //nolint:golint
|
||||
fset := token.NewFileSet()
|
||||
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
||||
if err != nil {
|
||||
@@ -251,11 +340,11 @@ func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
||||
|
||||
ap := pkgs["api"]
|
||||
|
||||
f := ap.Files["api/api_full.go"]
|
||||
f := ap.Files[apiFile]
|
||||
|
||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
||||
|
||||
v := &Visitor{make(map[string]ast.Node)}
|
||||
v := &Visitor{iface, make(map[string]ast.Node)}
|
||||
ast.Walk(v, pkgs["api"])
|
||||
|
||||
groupDocs := make(map[string]string)
|
||||
@@ -311,13 +400,30 @@ func methodGroupFromName(mn string) string {
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
comments, groupComments := parseApiASTInfo()
|
||||
comments, groupComments := parseApiASTInfo(os.Args[1], os.Args[2])
|
||||
|
||||
groups := make(map[string]*MethodGroup)
|
||||
|
||||
var api struct{ api.FullNode }
|
||||
t := reflect.TypeOf(api)
|
||||
var t reflect.Type
|
||||
var permStruct, commonPermStruct reflect.Type
|
||||
|
||||
switch os.Args[2] {
|
||||
case "FullNode":
|
||||
t = reflect.TypeOf(new(struct{ api.FullNode })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "StorageMiner":
|
||||
t = reflect.TypeOf(new(struct{ api.StorageMiner })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.StorageMinerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
case "WorkerAPI":
|
||||
t = reflect.TypeOf(new(struct{ api.WorkerAPI })).Elem()
|
||||
permStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
commonPermStruct = reflect.TypeOf(apistruct.WorkerStruct{}.Internal)
|
||||
default:
|
||||
panic("unknown type")
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
m := t.Method(i)
|
||||
|
||||
@@ -335,7 +441,7 @@ func main() {
|
||||
ft := m.Func.Type()
|
||||
for j := 2; j < ft.NumIn(); j++ {
|
||||
inp := ft.In(j)
|
||||
args = append(args, exampleValue(inp, nil))
|
||||
args = append(args, exampleValue(m.Name, inp, nil))
|
||||
}
|
||||
|
||||
v, err := json.MarshalIndent(args, "", " ")
|
||||
@@ -343,7 +449,7 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
outv := exampleValue(ft.Out(0), nil)
|
||||
outv := exampleValue(m.Name, ft.Out(0), nil)
|
||||
|
||||
ov, err := json.MarshalIndent(outv, "", " ")
|
||||
if err != nil {
|
||||
@@ -376,9 +482,6 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
permStruct := reflect.TypeOf(apistruct.FullNodeStruct{}.Internal)
|
||||
commonPermStruct := reflect.TypeOf(apistruct.CommonStruct{}.Internal)
|
||||
|
||||
for _, g := range groupslice {
|
||||
g := g
|
||||
fmt.Printf("## %s\n", g.GroupName)
|
||||
|
||||
@@ -37,7 +37,12 @@ func (bm *BlockMiner) MineBlocks() {
|
||||
go func() {
|
||||
defer close(bm.done)
|
||||
for atomic.LoadInt64(&bm.mine) == 1 {
|
||||
time.Sleep(bm.blocktime)
|
||||
select {
|
||||
case <-bm.ctx.Done():
|
||||
return
|
||||
case <-time.After(bm.blocktime):
|
||||
}
|
||||
|
||||
nulls := atomic.SwapInt64(&bm.nulls, 0)
|
||||
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
|
||||
InjectNulls: abi.ChainEpoch(nulls),
|
||||
|
||||
+2
-12
@@ -3,7 +3,6 @@ package test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -12,16 +11,11 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
)
|
||||
|
||||
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
for _, height := range []abi.ChainEpoch{
|
||||
1, // before
|
||||
162, // while sealing
|
||||
@@ -37,11 +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, 1, OneMiner, node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
Network: build.ActorUpgradeNetworkVersion,
|
||||
Height: upgradeHeight,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}}))
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -99,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
|
||||
|
||||
|
||||
+48
-43
@@ -12,19 +12,18 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/ipld/go-car"
|
||||
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
dag "github.com/ipfs/go-merkledag"
|
||||
dstest "github.com/ipfs/go-merkledag/test"
|
||||
unixfile "github.com/ipfs/go-unixfs/file"
|
||||
@@ -34,21 +33,10 @@ import (
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
)
|
||||
|
||||
var MineNext = miner.MineReq{
|
||||
InjectNulls: 0,
|
||||
Done: func(bool, abi.ChainEpoch, error) {},
|
||||
}
|
||||
|
||||
func init() {
|
||||
logging.SetAllLoggers(logging.LevelInfo)
|
||||
build.InsecurePoStValidation = true
|
||||
}
|
||||
|
||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -74,18 +62,17 @@ 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) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -112,27 +99,24 @@ 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 *impl.FullNodeAPI, miner TestStorageNode, carExport, fastRet bool) {
|
||||
data := make([]byte, 1600)
|
||||
rand.New(rand.NewSource(int64(rseed))).Read(data)
|
||||
|
||||
r := bytes.NewReader(data)
|
||||
fcid, err := client.ClientImportLocal(ctx, r)
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -145,11 +129,32 @@ func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNod
|
||||
testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data)
|
||||
}
|
||||
|
||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api.ImportRes, []byte, error) {
|
||||
data := make([]byte, 1600)
|
||||
rand.New(rand.NewSource(int64(rseed))).Read(data)
|
||||
|
||||
dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, "sourcefile.dat")
|
||||
err = ioutil.WriteFile(path, data, 0644)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
res, err := client.ClientImport(ctx, api.FileRef{Path: path})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return res, data, nil
|
||||
}
|
||||
|
||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -186,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")
|
||||
@@ -200,11 +205,10 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
func TestSecondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -250,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)
|
||||
@@ -276,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 *impl.FullNodeAPI, 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)
|
||||
@@ -294,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,
|
||||
})
|
||||
@@ -303,7 +308,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
|
||||
return deal
|
||||
}
|
||||
|
||||
func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client *impl.FullNodeAPI, deal *cid.Cid, noseal bool) {
|
||||
func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal bool) {
|
||||
loop:
|
||||
for {
|
||||
di, err := client.ClientGetDealInfo(ctx, *deal)
|
||||
@@ -311,7 +316,7 @@ loop:
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch di.State {
|
||||
case storagemarket.StorageDealSealing:
|
||||
case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing:
|
||||
if noseal {
|
||||
return
|
||||
}
|
||||
@@ -351,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
|
||||
}
|
||||
@@ -376,7 +381,7 @@ func startSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNod
|
||||
}
|
||||
}
|
||||
|
||||
func testRetrieval(t *testing.T, ctx context.Context, client *impl.FullNodeAPI, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) {
|
||||
func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) {
|
||||
offers, err := client.ClientFindData(ctx, fcid, piece)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
+9
-15
@@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -25,7 +24,7 @@ var log = logging.Logger("apitest")
|
||||
|
||||
func (ts *testSuite) testMining(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, sn := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
newHeads, err := api.ChainNotify(ctx)
|
||||
@@ -54,19 +53,16 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
||||
}()
|
||||
|
||||
ctx := context.Background()
|
||||
apis, sn := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
newHeads, err := api.ChainNotify(ctx)
|
||||
require.NoError(t, err)
|
||||
initHead := (<-newHeads)[0]
|
||||
if initHead.Val.Height() != 2 {
|
||||
<-newHeads
|
||||
}
|
||||
at := (<-newHeads)[0].Val.Height()
|
||||
|
||||
h1, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, abi.ChainEpoch(2), h1.Height())
|
||||
require.Equal(t, int64(at), int64(h1.Height()))
|
||||
|
||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||
require.NoError(t, err)
|
||||
@@ -75,25 +71,23 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
||||
|
||||
h2, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, abi.ChainEpoch(3), h2.Height())
|
||||
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
|
||||
|
||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
<-newHeads
|
||||
|
||||
h2, err = api.ChainHead(ctx)
|
||||
h3, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, abi.ChainEpoch(4), h2.Height())
|
||||
require.Greater(t, int64(h3.Height()), int64(h2.Height()))
|
||||
}
|
||||
|
||||
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
// test making a deal with a fresh miner, and see if it starts to mine
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, []StorageMiner{
|
||||
n, sn := b(t, OneFull, []StorageMiner{
|
||||
{Full: 0, Preseal: PresealGenesis},
|
||||
{Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node
|
||||
})
|
||||
@@ -192,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)
|
||||
|
||||
+6
-11
@@ -3,14 +3,10 @@ package test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -22,18 +18,17 @@ import (
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
)
|
||||
|
||||
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 2, OneMiner)
|
||||
n, sn := b(t, TwoFull, OneMiner)
|
||||
|
||||
paymentCreator := n[0]
|
||||
paymentReceiver := n[1]
|
||||
@@ -58,7 +53,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
bm.MineBlocks()
|
||||
|
||||
// send some funds to register the receiver
|
||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
|
||||
receiverAddr, err := paymentReceiver.WalletNew(ctx, types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -228,7 +223,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
}
|
||||
|
||||
// wait for the settlement period to pass before collecting
|
||||
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych0.SettleDelay)
|
||||
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, policy.PaychSettleDelay)
|
||||
|
||||
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
||||
if err != nil {
|
||||
@@ -284,7 +279,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec
|
||||
|
||||
// Add a real block
|
||||
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
|
||||
To: builtin0.BurntFundsActorAddr,
|
||||
To: builtin.BurntFundsActorAddr,
|
||||
From: receiverAddr,
|
||||
Value: types.NewInt(0),
|
||||
}, nil)
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
t.Run("before", func(t *testing.T) { testTapeFix(t, b, blocktime, false) })
|
||||
t.Run("after", func(t *testing.T) { testTapeFix(t, b, blocktime, true) })
|
||||
}
|
||||
func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
upgradeSchedule := stmgr.UpgradeSchedule{{
|
||||
Network: build.ActorUpgradeNetworkVersion,
|
||||
Height: 1,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}}
|
||||
if after {
|
||||
upgradeSchedule = append(upgradeSchedule, stmgr.Upgrade{
|
||||
Network: network.Version5,
|
||||
Height: 2,
|
||||
})
|
||||
}
|
||||
|
||||
n, sn := b(t, []FullNodeOpts{{Opts: func(_ []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), upgradeSchedule)
|
||||
}}}, 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)
|
||||
|
||||
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
|
||||
}()
|
||||
|
||||
err = miner.PledgeSector(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Wait till done.
|
||||
var sectorNo abi.SectorNumber
|
||||
for {
|
||||
s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM
|
||||
require.NoError(t, err)
|
||||
fmt.Printf("Sectors: %d\n", len(s))
|
||||
if len(s) == 1 {
|
||||
sectorNo = s[0]
|
||||
break
|
||||
}
|
||||
|
||||
build.Clock.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
fmt.Printf("All sectors is fsm\n")
|
||||
|
||||
// If before, we expect the precommit to fail
|
||||
successState := api.SectorState(sealing.CommitFailed)
|
||||
failureState := api.SectorState(sealing.Proving)
|
||||
if after {
|
||||
// otherwise, it should succeed.
|
||||
successState, failureState = failureState, successState
|
||||
}
|
||||
|
||||
for {
|
||||
st, err := miner.SectorsStatus(ctx, sectorNo, false)
|
||||
require.NoError(t, err)
|
||||
if st.State == successState {
|
||||
break
|
||||
}
|
||||
require.NotEqual(t, failureState, st.State)
|
||||
build.Clock.Sleep(100 * time.Millisecond)
|
||||
fmt.Println("WaitSeal")
|
||||
}
|
||||
|
||||
}
|
||||
+128
-4
@@ -2,19 +2,38 @@ package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"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/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logging.SetAllLoggers(logging.LevelInfo)
|
||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
|
||||
}
|
||||
build.InsecurePoStValidation = true
|
||||
}
|
||||
|
||||
type TestNode struct {
|
||||
api.FullNode
|
||||
// ListenAddr is the address on which an API server is listening, if an
|
||||
@@ -35,17 +54,27 @@ var PresealGenesis = -1
|
||||
|
||||
const GenesisPreseals = 2
|
||||
|
||||
// Options for setting up a mock storage miner
|
||||
type StorageMiner struct {
|
||||
Full int
|
||||
Preseal int
|
||||
}
|
||||
|
||||
type OptionGenerator func([]TestNode) node.Option
|
||||
|
||||
// Options for setting up a mock full node
|
||||
type FullNodeOpts struct {
|
||||
Lite bool // run node in "lite" mode
|
||||
Opts OptionGenerator // generate dependency injection options
|
||||
}
|
||||
|
||||
// APIBuilder is a function which is invoked in test suite to provide
|
||||
// test nodes and networks
|
||||
//
|
||||
// fullOpts array defines options for each full node
|
||||
// storage array defines storage nodes, numbers in the array specify full node
|
||||
// index the storage node 'belongs' to
|
||||
type APIBuilder func(t *testing.T, nFull int, storage []StorageMiner, opts ...node.Option) ([]TestNode, []TestStorageNode)
|
||||
type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
||||
type testSuite struct {
|
||||
makeNodes APIBuilder
|
||||
}
|
||||
@@ -61,15 +90,67 @@ func TestApis(t *testing.T, b APIBuilder) {
|
||||
t.Run("testConnectTwo", ts.testConnectTwo)
|
||||
t.Run("testMining", ts.testMining)
|
||||
t.Run("testMiningReal", ts.testMiningReal)
|
||||
t.Run("testSearchMsg", ts.testSearchMsg)
|
||||
}
|
||||
|
||||
func DefaultFullOpts(nFull int) []FullNodeOpts {
|
||||
full := make([]FullNodeOpts, nFull)
|
||||
for i := range full {
|
||||
full[i] = FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Options()
|
||||
},
|
||||
}
|
||||
}
|
||||
return full
|
||||
}
|
||||
|
||||
var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
||||
var OneFull = DefaultFullOpts(1)
|
||||
var TwoFull = DefaultFullOpts(2)
|
||||
|
||||
var FullNodeWithActorsV2At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
return FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
// Skip directly to tape height so precommits work.
|
||||
Network: network.Version5,
|
||||
Height: upgradeHeight,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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) {},
|
||||
}
|
||||
|
||||
func (ts *testSuite) testVersion(t *testing.T) {
|
||||
build.RunningNodeType = build.NodeFull
|
||||
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
v, err := api.Version(ctx)
|
||||
@@ -79,9 +160,52 @@ func (ts *testSuite) testVersion(t *testing.T) {
|
||||
require.Equal(t, v.Version, build.BuildVersion)
|
||||
}
|
||||
|
||||
func (ts *testSuite) testSearchMsg(t *testing.T) {
|
||||
apis, miners := ts.makeNodes(t, OneFull, OneMiner)
|
||||
|
||||
api := apis[0]
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
senderAddr, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
From: senderAddr,
|
||||
To: senderAddr,
|
||||
Value: big.Zero(),
|
||||
}
|
||||
bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond)
|
||||
bm.MineBlocks()
|
||||
defer bm.Stop()
|
||||
|
||||
sm, err := api.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := api.StateWaitMsg(ctx, sm.Cid(), 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Receipt.ExitCode != 0 {
|
||||
t.Fatal("did not successfully send message")
|
||||
}
|
||||
|
||||
searchRes, err := api.StateSearchMsg(ctx, sm.Cid())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if searchRes.TipSet != res.TipSet {
|
||||
t.Fatalf("search ts: %s, different from wait ts: %s", searchRes.TipSet, res.TipSet)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (ts *testSuite) testID(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
id, err := api.ID(ctx)
|
||||
@@ -93,7 +217,7 @@ func (ts *testSuite) testID(t *testing.T) {
|
||||
|
||||
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 2, OneMiner)
|
||||
apis, _ := ts.makeNodes(t, TwoFull, OneMiner)
|
||||
|
||||
p, err := apis[0].NetPeers(ctx)
|
||||
if err != nil {
|
||||
|
||||
+112
-29
@@ -3,38 +3,35 @@ package test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
bminer "github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
|
||||
}
|
||||
}
|
||||
func TestSDRUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithSDRAt(500, 1000)}, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -48,11 +45,95 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
|
||||
}
|
||||
build.Clock.Sleep(time.Second)
|
||||
|
||||
mine := true
|
||||
pledge := make(chan struct{})
|
||||
mine := int64(1)
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for mine {
|
||||
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()
|
||||
|
||||
n, sn := b(t, OneFull, 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)
|
||||
|
||||
mine := int64(1)
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for atomic.LoadInt64(&mine) != 0 {
|
||||
build.Clock.Sleep(blocktime)
|
||||
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
|
||||
|
||||
@@ -64,17 +145,19 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
|
||||
|
||||
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
||||
|
||||
mine = false
|
||||
atomic.StoreInt64(&mine, 0)
|
||||
<-done
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -133,11 +216,7 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
n, sn := b(t, 1, OneMiner, node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
Network: build.ActorUpgradeNetworkVersion,
|
||||
Height: upgradeHeight,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}}))
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
@@ -220,15 +299,17 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
|
||||
// Drop the partition
|
||||
err = secs.ForEach(func(sid uint64) error {
|
||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sid),
|
||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sid),
|
||||
},
|
||||
}, true)
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
var s abi.SectorID
|
||||
var s storage.SectorRef
|
||||
|
||||
// Drop 1 sectors from deadline 3 partition 0
|
||||
{
|
||||
@@ -249,9 +330,11 @@ func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration,
|
||||
require.NoError(t, err)
|
||||
fmt.Println("the sectors", all)
|
||||
|
||||
s = abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sn),
|
||||
s = storage.SectorRef{
|
||||
ID: abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sn),
|
||||
},
|
||||
}
|
||||
|
||||
err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true)
|
||||
|
||||
+6
-14
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -51,19 +50,6 @@ type MessageSendSpec struct {
|
||||
MaxFee abi.TokenAmount
|
||||
}
|
||||
|
||||
var DefaultMessageSendSpec = MessageSendSpec{
|
||||
// MaxFee of 0.1FIL
|
||||
MaxFee: abi.NewTokenAmount(int64(build.FilecoinPrecision) / 10),
|
||||
}
|
||||
|
||||
func (ms *MessageSendSpec) Get() MessageSendSpec {
|
||||
if ms == nil {
|
||||
return DefaultMessageSendSpec
|
||||
}
|
||||
|
||||
return *ms
|
||||
}
|
||||
|
||||
type DataTransferChannel struct {
|
||||
TransferID datatransfer.TransferID
|
||||
Status datatransfer.Status
|
||||
@@ -107,3 +93,9 @@ func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelSta
|
||||
}
|
||||
return channel
|
||||
}
|
||||
|
||||
type NetBlockList struct {
|
||||
Peers []peer.ID
|
||||
IPAddrs []string
|
||||
IPSubnets []string
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/dns4/bootstrap-0.testnet.fildev.network/tcp/1347/p2p/12D3KooWJTUBUjtzWJGWU1XSiY21CwmHaCNLNYn2E7jqHEHyZaP7
|
||||
/dns4/bootstrap-1.testnet.fildev.network/tcp/1347/p2p/12D3KooW9yeKXha4hdrJKq74zEo99T8DhriQdWNoojWnnQbsgB3v
|
||||
/dns4/bootstrap-2.testnet.fildev.network/tcp/1347/p2p/12D3KooWCrx8yVG9U9Kf7w8KLN3Edkj5ZKDhgCaeMqQbcQUoB6CT
|
||||
/dns4/bootstrap-4.testnet.fildev.network/tcp/1347/p2p/12D3KooWPkL9LrKRQgHtq7kn9ecNhGU9QaziG8R5tX8v9v7t3h34
|
||||
/dns4/bootstrap-3.testnet.fildev.network/tcp/1347/p2p/12D3KooWKYSsbpgZ3HAjax5M1BXCwXLa6gVkUARciz7uN3FNtr7T
|
||||
/dns4/bootstrap-5.testnet.fildev.network/tcp/1347/p2p/12D3KooWQYzqnLASJAabyMpPb1GcWZvNSe7JDcRuhdRqonFoiK9W
|
||||
/dns4/bootstrap-0.mainnet.filops.net/tcp/1347/p2p/12D3KooWCVe8MmsEMes2FzgTpt9fXtmCY7wrq91GRiaC8PHSCCBj
|
||||
/dns4/bootstrap-1.mainnet.filops.net/tcp/1347/p2p/12D3KooWCwevHg1yLCvktf2nvLu7L9894mcrJR4MsBCcm4syShVc
|
||||
/dns4/bootstrap-2.mainnet.filops.net/tcp/1347/p2p/12D3KooWEWVwHGn2yR36gKLozmb4YjDJGerotAPGxmdWZx2nxMC4
|
||||
/dns4/bootstrap-3.mainnet.filops.net/tcp/1347/p2p/12D3KooWKhgq8c7NQ9iGjbyK7v7phXvG6492HQfiDaGHLHLQjk7R
|
||||
/dns4/bootstrap-4.mainnet.filops.net/tcp/1347/p2p/12D3KooWL6PsFNPhYftrJzGgF5U18hFoaVhfGk7xwzD8yVrHJ3Uc
|
||||
/dns4/bootstrap-5.mainnet.filops.net/tcp/1347/p2p/12D3KooWLFynvDQiUpXoHroV1YxKHhPJgysQGH2k3ZGwtWzR4dFH
|
||||
/dns4/bootstrap-6.mainnet.filops.net/tcp/1347/p2p/12D3KooWP5MwCiqdMETF9ub1P3MbCvQCcfconnYHbWg6sUJcDRQQ
|
||||
/dns4/bootstrap-7.mainnet.filops.net/tcp/1347/p2p/12D3KooWRs3aY1p3juFjPy8gPN95PEQChm2QKGUCAdcDCC4EBMKf
|
||||
/dns4/bootstrap-8.mainnet.filops.net/tcp/1347/p2p/12D3KooWScFR7385LTyR4zU1bYdzSiiAb5rnNABfVahPvVSzyTkR
|
||||
/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C
|
||||
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
|
||||
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
|
||||
|
||||
+1
-10
@@ -35,6 +35,7 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
|
||||
"https://api.drand.sh",
|
||||
"https://api2.drand.sh",
|
||||
"https://api3.drand.sh",
|
||||
"https://drand.cloudflare.com",
|
||||
},
|
||||
Relays: []string{
|
||||
"/dnsaddr/api.drand.sh/",
|
||||
@@ -68,16 +69,6 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
|
||||
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
|
||||
},
|
||||
DrandIncentinet: {
|
||||
Servers: []string{
|
||||
"https://pl-eu.incentinet.drand.sh",
|
||||
"https://pl-us.incentinet.drand.sh",
|
||||
"https://pl-sin.incentinet.drand.sh",
|
||||
},
|
||||
Relays: []string{
|
||||
"/dnsaddr/pl-eu.incentinet.drand.sh/",
|
||||
"/dnsaddr/pl-us.incentinet.drand.sh/",
|
||||
"/dnsaddr/pl-sin.incentinet.drand.sh/",
|
||||
},
|
||||
ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`,
|
||||
},
|
||||
}
|
||||
|
||||
+9
-2
@@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
@@ -17,9 +16,15 @@ const BreezeGasTampingDuration = 0
|
||||
const UpgradeSmokeHeight = -1
|
||||
const UpgradeIgnitionHeight = -2
|
||||
const UpgradeRefuelHeight = -3
|
||||
const UpgradeTapeHeight = -4
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-4)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
||||
|
||||
const UpgradeKumquatHeight = 15
|
||||
const UpgradeCalicoHeight = 20
|
||||
const UpgradePersianHeight = 25
|
||||
const UpgradeClausHeight = 30
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
@@ -50,3 +55,5 @@ const SlashablePowerDelay = 20
|
||||
|
||||
// Epochs
|
||||
const InteractivePoRepConfidence = 6
|
||||
|
||||
const BootstrapPeerThreshold = 1
|
||||
|
||||
@@ -11,8 +11,7 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
@@ -30,17 +29,23 @@ const UpgradeRefuelHeight = 130800
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(138720)
|
||||
|
||||
const UpgradeTapeHeight = 140760
|
||||
|
||||
// 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 = 148888
|
||||
|
||||
const UpgradeKumquatHeight = 170000
|
||||
|
||||
const UpgradeCalicoHeight = 265200
|
||||
const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
|
||||
|
||||
// 2020-12-22T02:00:00Z
|
||||
const UpgradeClausHeight = 343200
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
)
|
||||
|
||||
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
||||
SetAddressNetwork(address.Mainnet)
|
||||
@@ -53,6 +58,9 @@ func init() {
|
||||
Devnet = false
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds)
|
||||
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
|
||||
@@ -1,36 +1,13 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
func DefaultSectorSize() abi.SectorSize {
|
||||
szs := make([]abi.SectorSize, 0, len(miner0.SupportedProofTypes))
|
||||
for spt := range miner0.SupportedProofTypes {
|
||||
ss, err := spt.SectorSize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
szs = append(szs, ss)
|
||||
}
|
||||
|
||||
sort.Slice(szs, func(i, j int) bool {
|
||||
return szs[i] < szs[j]
|
||||
})
|
||||
|
||||
return szs[0]
|
||||
}
|
||||
|
||||
// Core network constants
|
||||
|
||||
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
||||
@@ -39,14 +16,15 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
||||
return protocol.ID("/fil/kad/" + string(netName))
|
||||
}
|
||||
|
||||
func UseNewestNetwork() bool {
|
||||
// TODO: Put these in a container we can iterate over
|
||||
if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2Height <= 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
// /////
|
||||
@@ -25,14 +25,14 @@ const UnixfsLinksPerLevel = 1024
|
||||
// Consensus / Network
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version4
|
||||
const NewestNetworkVersion = network.Version8
|
||||
const ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
// Epochs
|
||||
const ForkLengthThreshold = Finality
|
||||
|
||||
// Blocks (e)
|
||||
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
||||
var BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
|
||||
|
||||
// Epochs
|
||||
const Finality = policy.ChainFinality
|
||||
@@ -61,6 +61,9 @@ const TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||
|
||||
const AddressMainnetEnvVar = "_mainnet_"
|
||||
|
||||
// the 'f' prefix doesn't matter
|
||||
var ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||
|
||||
// /////
|
||||
// Devnet settings
|
||||
|
||||
@@ -116,4 +119,4 @@ const PackingEfficiencyDenom = 5
|
||||
|
||||
// Actor consts
|
||||
// TODO: Pull from actors when its made not private
|
||||
var MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
|
||||
var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
||||
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
@@ -21,14 +22,14 @@ var (
|
||||
UnixfsChunkSize = uint64(1 << 20)
|
||||
UnixfsLinksPerLevel = 1024
|
||||
|
||||
BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
||||
BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
|
||||
BlockMessageLimit = 512
|
||||
BlockGasLimit = int64(100_000_000_000)
|
||||
BlockGasTarget = int64(BlockGasLimit / 2)
|
||||
BaseFeeMaxChangeDenom = int64(8) // 12.5%
|
||||
InitialBaseFee = int64(100e6)
|
||||
MinimumBaseFee = int64(100)
|
||||
BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
|
||||
BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
||||
PropagationDelaySecs = uint64(6)
|
||||
|
||||
AllowableClockDriftSecs = uint64(1)
|
||||
@@ -72,7 +73,7 @@ var (
|
||||
|
||||
// Actor consts
|
||||
// TODO: Pull from actors when its made not private
|
||||
MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
|
||||
MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
||||
|
||||
PackingEfficiencyNum int64 = 4
|
||||
PackingEfficiencyDenom int64 = 5
|
||||
@@ -83,15 +84,23 @@ var (
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeActorsV2Height abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -4
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -7
|
||||
UpgradePersianHeight abi.ChainEpoch = -8
|
||||
UpgradeClausHeight abi.ChainEpoch = -9
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
NewestNetworkVersion = network.Version4
|
||||
NewestNetworkVersion = network.Version8
|
||||
ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
Devnet = true
|
||||
Devnet = true
|
||||
ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||
)
|
||||
|
||||
const BootstrapPeerThreshold = 1
|
||||
|
||||
+4
-4
@@ -29,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.9.0"
|
||||
const BuildVersion = "1.3.0"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
@@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
|
||||
|
||||
// semver versions of the rpc api exposed
|
||||
var (
|
||||
FullAPIVersion = newVer(0, 16, 0)
|
||||
MinerAPIVersion = newVer(0, 15, 0)
|
||||
WorkerAPIVersion = newVer(0, 15, 0)
|
||||
FullAPIVersion = newVer(1, 0, 0)
|
||||
MinerAPIVersion = newVer(1, 0, 0)
|
||||
WorkerAPIVersion = newVer(1, 0, 0)
|
||||
)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
|
||||
@@ -12,8 +12,9 @@ import (
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
)
|
||||
@@ -22,24 +23,24 @@ func TestDiffAdtArray(t *testing.T) {
|
||||
ctxstoreA := newContextStore()
|
||||
ctxstoreB := newContextStore()
|
||||
|
||||
arrA := adt0.MakeEmptyArray(ctxstoreA)
|
||||
arrB := adt0.MakeEmptyArray(ctxstoreB)
|
||||
arrA := adt2.MakeEmptyArray(ctxstoreA)
|
||||
arrB := adt2.MakeEmptyArray(ctxstoreB)
|
||||
|
||||
require.NoError(t, arrA.Set(0, runtime.CBORBytes([]byte{0}))) // delete
|
||||
require.NoError(t, arrA.Set(0, builtin2.CBORBytes([]byte{0}))) // delete
|
||||
|
||||
require.NoError(t, arrA.Set(1, runtime.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, arrB.Set(1, runtime.CBORBytes([]byte{1})))
|
||||
require.NoError(t, arrA.Set(1, builtin2.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, arrB.Set(1, builtin2.CBORBytes([]byte{1})))
|
||||
|
||||
require.NoError(t, arrA.Set(2, runtime.CBORBytes([]byte{1}))) // delete
|
||||
require.NoError(t, arrA.Set(2, builtin2.CBORBytes([]byte{1}))) // delete
|
||||
|
||||
require.NoError(t, arrA.Set(3, runtime.CBORBytes([]byte{0}))) // noop
|
||||
require.NoError(t, arrB.Set(3, runtime.CBORBytes([]byte{0})))
|
||||
require.NoError(t, arrA.Set(3, builtin2.CBORBytes([]byte{0}))) // noop
|
||||
require.NoError(t, arrB.Set(3, builtin2.CBORBytes([]byte{0})))
|
||||
|
||||
require.NoError(t, arrA.Set(4, runtime.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, arrB.Set(4, runtime.CBORBytes([]byte{6})))
|
||||
require.NoError(t, arrA.Set(4, builtin2.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, arrB.Set(4, builtin2.CBORBytes([]byte{6})))
|
||||
|
||||
require.NoError(t, arrB.Set(5, runtime.CBORBytes{8})) // add
|
||||
require.NoError(t, arrB.Set(6, runtime.CBORBytes{9})) // add
|
||||
require.NoError(t, arrB.Set(5, builtin2.CBORBytes{8})) // add
|
||||
require.NoError(t, arrB.Set(6, builtin2.CBORBytes{9})) // add
|
||||
|
||||
changes := new(TestDiffArray)
|
||||
|
||||
@@ -76,24 +77,24 @@ func TestDiffAdtMap(t *testing.T) {
|
||||
ctxstoreA := newContextStore()
|
||||
ctxstoreB := newContextStore()
|
||||
|
||||
mapA := adt0.MakeEmptyMap(ctxstoreA)
|
||||
mapB := adt0.MakeEmptyMap(ctxstoreB)
|
||||
mapA := adt2.MakeEmptyMap(ctxstoreA)
|
||||
mapB := adt2.MakeEmptyMap(ctxstoreB)
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(0), runtime.CBORBytes([]byte{0}))) // delete
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(0), builtin2.CBORBytes([]byte{0}))) // delete
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{1})))
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{1})))
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(2), runtime.CBORBytes([]byte{1}))) // delete
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(2), builtin2.CBORBytes([]byte{1}))) // delete
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0}))) // noop
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0})))
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) // noop
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0})))
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{6})))
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{0}))) // modify
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{6})))
|
||||
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(5), runtime.CBORBytes{8})) // add
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(6), runtime.CBORBytes{9})) // add
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(5), builtin2.CBORBytes{8})) // add
|
||||
require.NoError(t, mapB.Put(abi.UIntKey(6), builtin2.CBORBytes{9})) // add
|
||||
|
||||
changes := new(TestDiffMap)
|
||||
|
||||
@@ -144,7 +145,7 @@ func (t *TestDiffMap) AsKey(key string) (abi.Keyer, error) {
|
||||
}
|
||||
|
||||
func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error {
|
||||
v := new(runtime.CBORBytes)
|
||||
v := new(builtin2.CBORBytes)
|
||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -161,13 +162,13 @@ func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error {
|
||||
}
|
||||
|
||||
func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error {
|
||||
vFrom := new(runtime.CBORBytes)
|
||||
vFrom := new(builtin2.CBORBytes)
|
||||
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vTo := new(runtime.CBORBytes)
|
||||
vTo := new(builtin2.CBORBytes)
|
||||
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -194,7 +195,7 @@ func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error {
|
||||
}
|
||||
|
||||
func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
|
||||
v := new(runtime.CBORBytes)
|
||||
v := new(builtin2.CBORBytes)
|
||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -212,7 +213,7 @@ func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
|
||||
|
||||
type adtMapDiffResult struct {
|
||||
key uint64
|
||||
val runtime.CBORBytes
|
||||
val builtin2.CBORBytes
|
||||
}
|
||||
|
||||
type TestAdtMapDiffModified struct {
|
||||
@@ -222,7 +223,7 @@ type TestAdtMapDiffModified struct {
|
||||
|
||||
type adtArrayDiffResult struct {
|
||||
key uint64
|
||||
val runtime.CBORBytes
|
||||
val builtin2.CBORBytes
|
||||
}
|
||||
|
||||
type TestDiffArray struct {
|
||||
@@ -239,7 +240,7 @@ type TestAdtArrayDiffModified struct {
|
||||
}
|
||||
|
||||
func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
|
||||
v := new(runtime.CBORBytes)
|
||||
v := new(builtin2.CBORBytes)
|
||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -252,13 +253,13 @@ func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
|
||||
}
|
||||
|
||||
func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
vFrom := new(runtime.CBORBytes)
|
||||
vFrom := new(builtin2.CBORBytes)
|
||||
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vTo := new(runtime.CBORBytes)
|
||||
vTo := new(builtin2.CBORBytes)
|
||||
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -280,7 +281,7 @@ func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
}
|
||||
|
||||
func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error {
|
||||
v := new(runtime.CBORBytes)
|
||||
v := new(builtin2.CBORBytes)
|
||||
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -24,6 +24,8 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Methods = builtin2.MethodsAccount
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.AccountActorCodeID:
|
||||
|
||||
@@ -2,28 +2,46 @@ package builtin
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||
)
|
||||
|
||||
var SystemActorAddr = builtin0.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin0.CronActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
var (
|
||||
ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch
|
||||
)
|
||||
|
||||
const (
|
||||
EpochDurationSeconds = builtin0.EpochDurationSeconds
|
||||
EpochsInDay = builtin0.EpochsInDay
|
||||
SecondsInDay = builtin0.SecondsInDay
|
||||
)
|
||||
|
||||
const (
|
||||
MethodSend = builtin2.MethodSend
|
||||
MethodConstructor = builtin2.MethodConstructor
|
||||
)
|
||||
|
||||
// TODO: Why does actors have 2 different versions of this?
|
||||
type SectorInfo = proof0.SectorInfo
|
||||
type PoStProof = proof0.PoStProof
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
)
|
||||
|
||||
var (
|
||||
Address = builtin2.CronActorAddr
|
||||
Methods = builtin2.MethodsCron
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
@@ -26,7 +26,10 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Address = builtin0.InitActorAddr
|
||||
var (
|
||||
Address = builtin2.InitActorAddr
|
||||
Methods = builtin2.MethodsInit
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
@@ -54,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)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,10 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Address = builtin0.StorageMarketActorAddr
|
||||
var (
|
||||
Address = builtin2.StorageMarketActorAddr
|
||||
Methods = builtin2.MethodsMarket
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
@@ -78,6 +81,7 @@ type DealProposals interface {
|
||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
||||
|
||||
type ClientDealProposal = market0.ClientDealProposal
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
)
|
||||
|
||||
type DeadlinesDiff map[uint64]*DeadlineDiff
|
||||
type DeadlinesDiff map[uint64]DeadlineDiff
|
||||
|
||||
func DiffDeadlines(pre, cur State) (*DeadlinesDiff, error) {
|
||||
func DiffDeadlines(pre, cur State) (DeadlinesDiff, error) {
|
||||
changed, err := pre.DeadlinesChanged(cur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -18,11 +18,7 @@ func DiffDeadlines(pre, cur State) (*DeadlinesDiff, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
numDl, err := pre.NumDeadlines()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dlDiff := make(DeadlinesDiff, numDl)
|
||||
dlDiff := make(DeadlinesDiff)
|
||||
if err := pre.ForEachDeadline(func(idx uint64, preDl Deadline) error {
|
||||
curDl, err := cur.LoadDeadline(idx)
|
||||
if err != nil {
|
||||
@@ -39,12 +35,12 @@ func DiffDeadlines(pre, cur State) (*DeadlinesDiff, error) {
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dlDiff, nil
|
||||
return dlDiff, nil
|
||||
}
|
||||
|
||||
type DeadlineDiff map[uint64]*PartitionDiff
|
||||
|
||||
func DiffDeadline(pre, cur Deadline) (*DeadlineDiff, error) {
|
||||
func DiffDeadline(pre, cur Deadline) (DeadlineDiff, error) {
|
||||
changed, err := pre.PartitionsChanged(cur)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -104,7 +100,7 @@ func DiffDeadline(pre, cur Deadline) (*DeadlineDiff, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &partDiff, nil
|
||||
return partDiff, nil
|
||||
}
|
||||
|
||||
type PartitionDiff struct {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -30,6 +31,8 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Methods = builtin2.MethodsMiner
|
||||
|
||||
// Unchanged between v0 and v2 actors
|
||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
||||
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
||||
@@ -74,6 +77,7 @@ type State interface {
|
||||
DeadlinesChanged(State) (bool, error)
|
||||
|
||||
Info() (MinerInfo, error)
|
||||
MinerInfoChanged(State) (bool, error)
|
||||
|
||||
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
||||
|
||||
@@ -148,6 +152,20 @@ type MinerInfo struct {
|
||||
ConsensusFaultElapsed abi.ChainEpoch
|
||||
}
|
||||
|
||||
func (mi MinerInfo) IsController(addr address.Address) bool {
|
||||
if addr == mi.Owner || addr == mi.Worker {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, ca := range mi.ControlAddresses {
|
||||
if addr == ca {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
@@ -182,3 +200,7 @@ type LockedFunds struct {
|
||||
InitialPledgeRequirement abi.TokenAmount
|
||||
PreCommitDeposits abi.TokenAmount
|
||||
}
|
||||
|
||||
func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount {
|
||||
return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits))
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -47,8 +47,16 @@ type partition0 struct {
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return s.GetAvailableBalance(bal), nil
|
||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = xerrors.Errorf("failed to get available balance: %w", r)
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
available = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
@@ -266,7 +274,16 @@ func (s *state0) DeadlinesChanged(other State) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return s.State.Deadlines.Equals(other0.Deadlines), nil
|
||||
return !s.State.Deadlines.Equals(other0.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state0) MinerInfoChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Info.Equals(other0.State.Info), nil
|
||||
}
|
||||
|
||||
func (s *state0) Info() (MinerInfo, error) {
|
||||
@@ -362,7 +379,7 @@ func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
||||
return !d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
|
||||
|
||||
@@ -45,8 +45,16 @@ type partition2 struct {
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state2) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return s.GetAvailableBalance(bal)
|
||||
func (s *state2) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = xerrors.Errorf("failed to get available balance: %w", r)
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
@@ -265,7 +273,16 @@ func (s *state2) DeadlinesChanged(other State) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return s.State.Deadlines.Equals(other2.Deadlines), nil
|
||||
return !s.State.Deadlines.Equals(other2.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state2) MinerInfoChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state2)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Info.Equals(other0.State.Info), nil
|
||||
}
|
||||
|
||||
func (s *state2) Info() (MinerInfo, error) {
|
||||
@@ -361,7 +378,7 @@ func (d *deadline2) PartitionsChanged(other Deadline) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline2) PostSubmissions() (bitfield.BitField, error) {
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
)
|
||||
|
||||
type PendingTransactionChanges struct {
|
||||
Added []TransactionChange
|
||||
Modified []TransactionModification
|
||||
Removed []TransactionChange
|
||||
}
|
||||
|
||||
type TransactionChange struct {
|
||||
TxID int64
|
||||
Tx Transaction
|
||||
}
|
||||
|
||||
type TransactionModification struct {
|
||||
TxID int64
|
||||
From Transaction
|
||||
To Transaction
|
||||
}
|
||||
|
||||
func DiffPendingTransactions(pre, cur State) (*PendingTransactionChanges, error) {
|
||||
results := new(PendingTransactionChanges)
|
||||
if changed, err := pre.PendingTxnChanged(cur); err != nil {
|
||||
return nil, err
|
||||
} else if !changed { // if nothing has changed then return an empty result and bail.
|
||||
return results, nil
|
||||
}
|
||||
|
||||
pret, err := pre.transactions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curt, err := cur.transactions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := adt.DiffAdtMap(pret, curt, &transactionDiffer{results, pre, cur}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type transactionDiffer struct {
|
||||
Results *PendingTransactionChanges
|
||||
pre, after State
|
||||
}
|
||||
|
||||
func (t *transactionDiffer) AsKey(key string) (abi.Keyer, error) {
|
||||
txID, err := abi.ParseIntKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return abi.IntKey(txID), nil
|
||||
}
|
||||
|
||||
func (t *transactionDiffer) Add(key string, val *cbg.Deferred) error {
|
||||
txID, err := abi.ParseIntKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx, err := t.after.decodeTransaction(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Results.Added = append(t.Results.Added, TransactionChange{
|
||||
TxID: txID,
|
||||
Tx: tx,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *transactionDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
||||
txID, err := abi.ParseIntKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txFrom, err := t.pre.decodeTransaction(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txTo, err := t.after.decodeTransaction(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if approvalsChanged(txFrom.Approved, txTo.Approved) {
|
||||
t.Results.Modified = append(t.Results.Modified, TransactionModification{
|
||||
TxID: txID,
|
||||
From: txFrom,
|
||||
To: txTo,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func approvalsChanged(from, to []address.Address) bool {
|
||||
if len(from) != len(to) {
|
||||
return true
|
||||
}
|
||||
for idx := range from {
|
||||
if from[idx] != to[idx] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *transactionDiffer) Remove(key string, val *cbg.Deferred) error {
|
||||
txID, err := abi.ParseIntKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx, err := t.pre.decodeTransaction(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Results.Removed = append(t.Results.Removed, TransactionChange{
|
||||
TxID: txID,
|
||||
Tx: tx,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -9,12 +9,15 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
var Methods = builtin2.MethodsMultisig
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
@@ -45,6 +48,7 @@ type MessageBuilder interface {
|
||||
|
||||
// this type is the same between v0 and v2
|
||||
type ProposalHashData = multisig2.ProposalHashData
|
||||
type ProposeReturn = multisig2.ProposeReturn
|
||||
|
||||
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
|
||||
params := multisig2.TxnIDParams{ID: multisig2.TxnID(id)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -47,6 +48,10 @@ type State interface {
|
||||
Signers() ([]address.Address, error)
|
||||
|
||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||
PendingTxnChanged(State) (bool, error)
|
||||
|
||||
transactions() (adt.Map, error)
|
||||
decodeTransaction(val *cbg.Deferred) (Transaction, error)
|
||||
}
|
||||
|
||||
type Transaction = msig0.Transaction
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
multisig0 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||
)
|
||||
|
||||
var _ State = (*state0)(nil)
|
||||
@@ -68,3 +71,24 @@ func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
return cb(txid, (Transaction)(out))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state0) PendingTxnChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.PendingTxns.Equals(other0.PendingTxns), nil
|
||||
}
|
||||
|
||||
func (s *state0) transactions() (adt.Map, error) {
|
||||
return adt0.AsMap(s.store, s.PendingTxns)
|
||||
}
|
||||
|
||||
func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
||||
var tx multisig0.Transaction
|
||||
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Transaction{}, err
|
||||
}
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
@@ -68,3 +70,24 @@ func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
||||
return cb(txid, (Transaction)(out))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state2) PendingTxnChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state2)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
|
||||
}
|
||||
|
||||
func (s *state2) transactions() (adt.Map, error) {
|
||||
return adt2.AsMap(s.store, s.PendingTxns)
|
||||
}
|
||||
|
||||
func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
|
||||
var tx msig2.Transaction
|
||||
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Transaction{}, err
|
||||
}
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
@@ -7,8 +7,12 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
)
|
||||
|
||||
var Methods = builtin2.MethodsPaych
|
||||
|
||||
func Message(version actors.Version, from address.Address) MessageBuilder {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
)
|
||||
|
||||
type ClaimChanges struct {
|
||||
Added []ClaimInfo
|
||||
Modified []ClaimModification
|
||||
Removed []ClaimInfo
|
||||
}
|
||||
|
||||
type ClaimModification struct {
|
||||
Miner address.Address
|
||||
From Claim
|
||||
To Claim
|
||||
}
|
||||
|
||||
type ClaimInfo struct {
|
||||
Miner address.Address
|
||||
Claim Claim
|
||||
}
|
||||
|
||||
func DiffClaims(pre, cur State) (*ClaimChanges, error) {
|
||||
results := new(ClaimChanges)
|
||||
|
||||
prec, err := pre.claims()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curc, err := cur.claims()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := adt.DiffAdtMap(prec, curc, &claimDiffer{results, pre, cur}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type claimDiffer struct {
|
||||
Results *ClaimChanges
|
||||
pre, after State
|
||||
}
|
||||
|
||||
func (c *claimDiffer) AsKey(key string) (abi.Keyer, error) {
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return abi.AddrKey(addr), nil
|
||||
}
|
||||
|
||||
func (c *claimDiffer) Add(key string, val *cbg.Deferred) error {
|
||||
ci, err := c.after.decodeClaim(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Results.Added = append(c.Results.Added, ClaimInfo{
|
||||
Miner: addr,
|
||||
Claim: ci,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *claimDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
||||
ciFrom, err := c.pre.decodeClaim(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ciTo, err := c.after.decodeClaim(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ciFrom != ciTo {
|
||||
c.Results.Modified = append(c.Results.Modified, ClaimModification{
|
||||
Miner: addr,
|
||||
From: ciFrom,
|
||||
To: ciTo,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *claimDiffer) Remove(key string, val *cbg.Deferred) error {
|
||||
ci, err := c.after.decodeClaim(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addr, err := address.NewFromBytes([]byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Results.Removed = append(c.Results.Removed, ClaimInfo{
|
||||
Miner: addr,
|
||||
Claim: ci,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@@ -25,7 +27,10 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Address = builtin0.StoragePowerActorAddr
|
||||
var (
|
||||
Address = builtin2.StoragePowerActorAddr
|
||||
Methods = builtin2.MethodsPower
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
@@ -51,6 +56,12 @@ type State interface {
|
||||
MinerPower(address.Address) (Claim, bool, error)
|
||||
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
||||
ListAllMiners() ([]address.Address, error)
|
||||
ForEachClaim(func(miner address.Address, claim Claim) error) error
|
||||
ClaimsChanged(State) (bool, error)
|
||||
|
||||
// Diff helpers. Used by Diff* functions internally.
|
||||
claims() (adt.Map, error)
|
||||
decodeClaim(*cbg.Deferred) (Claim, error)
|
||||
}
|
||||
|
||||
type Claim struct {
|
||||
@@ -60,3 +71,10 @@ type Claim struct {
|
||||
// Sum of quality adjusted power for a miner's sectors.
|
||||
QualityAdjPower abi.StoragePower
|
||||
}
|
||||
|
||||
func AddClaims(a Claim, b Claim) Claim {
|
||||
return Claim{
|
||||
RawBytePower: big.Add(a.RawBytePower, b.RawBytePower),
|
||||
QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
@@ -96,3 +99,47 @@ func (s *state0) ListAllMiners() ([]address.Address, error) {
|
||||
|
||||
return miners, nil
|
||||
}
|
||||
|
||||
func (s *state0) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var claim power0.Claim
|
||||
return claims.ForEach(&claim, func(k string) error {
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(a, Claim{
|
||||
RawBytePower: claim.RawBytePower,
|
||||
QualityAdjPower: claim.QualityAdjPower,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state0) ClaimsChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Claims.Equals(other0.State.Claims), nil
|
||||
}
|
||||
|
||||
func (s *state0) claims() (adt.Map, error) {
|
||||
return adt0.AsMap(s.store, s.Claims)
|
||||
}
|
||||
|
||||
func (s *state0) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
||||
var ci power0.Claim
|
||||
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Claim{}, err
|
||||
}
|
||||
return fromV0Claim(ci), nil
|
||||
}
|
||||
|
||||
func fromV0Claim(v0 power0.Claim) Claim {
|
||||
return (Claim)(v0)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
@@ -96,3 +99,50 @@ func (s *state2) ListAllMiners() ([]address.Address, error) {
|
||||
|
||||
return miners, nil
|
||||
}
|
||||
|
||||
func (s *state2) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
|
||||
claims, err := adt2.AsMap(s.store, s.Claims)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var claim power2.Claim
|
||||
return claims.ForEach(&claim, func(k string) error {
|
||||
a, err := address.NewFromBytes([]byte(k))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cb(a, Claim{
|
||||
RawBytePower: claim.RawBytePower,
|
||||
QualityAdjPower: claim.QualityAdjPower,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state2) ClaimsChanged(other State) (bool, error) {
|
||||
other2, ok := other.(*state2)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
return !s.State.Claims.Equals(other2.State.Claims), nil
|
||||
}
|
||||
|
||||
func (s *state2) claims() (adt.Map, error) {
|
||||
return adt2.AsMap(s.store, s.Claims)
|
||||
}
|
||||
|
||||
func (s *state2) decodeClaim(val *cbg.Deferred) (Claim, error) {
|
||||
var ci power2.Claim
|
||||
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return Claim{}, err
|
||||
}
|
||||
return fromV2Claim(ci), nil
|
||||
}
|
||||
|
||||
func fromV2Claim(v2 power2.Claim) Claim {
|
||||
return Claim{
|
||||
RawBytePower: v2.RawBytePower,
|
||||
QualityAdjPower: v2.QualityAdjPower,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Address = builtin0.RewardActorAddr
|
||||
var (
|
||||
Address = builtin2.RewardActorAddr
|
||||
Methods = builtin2.MethodsReward
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
|
||||
@@ -57,7 +57,7 @@ func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
|
||||
}
|
||||
|
||||
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
return s.State.CumsumRealized, nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
|
||||
@@ -28,7 +28,7 @@ type state2 struct {
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state2) ThisEpochReward() (abi.StoragePower, error) {
|
||||
func (s *state2) ThisEpochReward() (abi.TokenAmount, error) {
|
||||
return s.State.ThisEpochReward, nil
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ func (s *state2) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||
return s.State.EffectiveNetworkTime, nil
|
||||
}
|
||||
|
||||
func (s *state2) CumsumBaseline() (abi.StoragePower, error) {
|
||||
func (s *state2) CumsumBaseline() (reward2.Spacetime, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state2) CumsumRealized() (abi.StoragePower, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
func (s *state2) CumsumRealized() (reward2.Spacetime, error) {
|
||||
return s.State.CumsumRealized, nil
|
||||
}
|
||||
|
||||
func (s *state2) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
|
||||
@@ -24,7 +24,10 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
var Address = builtin0.VerifiedRegistryActorAddr
|
||||
var (
|
||||
Address = builtin2.VerifiedRegistryActorAddr
|
||||
Methods = builtin2.MethodsVerifiedRegistry
|
||||
)
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
@@ -11,33 +13,42 @@ import (
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
||||
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
||||
)
|
||||
|
||||
const (
|
||||
ChainFinality = miner0.ChainFinality
|
||||
SealRandomnessLookback = ChainFinality
|
||||
PaychSettleDelay = paych2.SettleDelay
|
||||
)
|
||||
|
||||
// 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{}{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,3 +125,35 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
||||
|
||||
return ChainFinality
|
||||
}
|
||||
|
||||
func GetMaxSectorExpirationExtension() abi.ChainEpoch {
|
||||
return miner0.MaxSectorExpirationExtension
|
||||
}
|
||||
|
||||
// TODO: we'll probably need to abstract over this better in the future.
|
||||
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
|
||||
sectorsPerPart, err := builtin2.PoStProofWindowPoStPartitionSectors(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(miner2.AddressedSectorsMax / sectorsPerPart), nil
|
||||
}
|
||||
|
||||
func GetDefaultSectorSize() abi.SectorSize {
|
||||
// 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)
|
||||
}
|
||||
|
||||
szs = append(szs, ss)
|
||||
}
|
||||
|
||||
sort.Slice(szs, func(i, j int) bool {
|
||||
return szs[i] < szs[j]
|
||||
})
|
||||
|
||||
return szs[0]
|
||||
}
|
||||
|
||||
@@ -6,9 +6,13 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
||||
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
||||
)
|
||||
|
||||
@@ -40,11 +44,27 @@ 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)
|
||||
require.Equal(t, miner0.WPoStChallengeWindow, miner2.WPoStChallengeWindow)
|
||||
require.Equal(t, miner0.WPoStProvingPeriod, miner2.WPoStProvingPeriod)
|
||||
require.Equal(t, miner0.WPoStPeriodDeadlines, miner2.WPoStPeriodDeadlines)
|
||||
require.Equal(t, miner0.AddressedSectorsMax, miner2.AddressedSectorsMax)
|
||||
require.Equal(t, paych0.SettleDelay, paych2.SettleDelay)
|
||||
require.True(t, verifreg0.MinVerifiedDealSize.Equals(verifreg2.MinVerifiedDealSize))
|
||||
}
|
||||
|
||||
func TestPartitionSizes(t *testing.T) {
|
||||
for _, p := range abi.SealProofInfos {
|
||||
sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p.WindowPoStProof)
|
||||
require.NoError(t, err)
|
||||
sizeOld, err := builtin0.PoStProofWindowPoStPartitionSectors(p.WindowPoStProof)
|
||||
if err != nil {
|
||||
// new proof type.
|
||||
continue
|
||||
}
|
||||
require.Equal(t, sizeOld, sizeNew)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8:
|
||||
return Version2
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||
|
||||
@@ -60,6 +60,10 @@ func (bts *BadBlockCache) Remove(c cid.Cid) {
|
||||
bts.badBlocks.Remove(c)
|
||||
}
|
||||
|
||||
func (bts *BadBlockCache) Purge() {
|
||||
bts.badBlocks.Purge()
|
||||
}
|
||||
|
||||
func (bts *BadBlockCache) Has(c cid.Cid) (BadBlockReason, bool) {
|
||||
rval, ok := bts.badBlocks.Get(c)
|
||||
if !ok {
|
||||
|
||||
@@ -65,6 +65,11 @@ type DrandBeacon struct {
|
||||
localCache map[uint64]types.BeaconEntry
|
||||
}
|
||||
|
||||
// DrandHTTPClient interface overrides the user agent used by drand
|
||||
type DrandHTTPClient interface {
|
||||
SetUserAgent(string)
|
||||
}
|
||||
|
||||
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) {
|
||||
if genesisTs == 0 {
|
||||
panic("what are you doing this cant be zero")
|
||||
@@ -84,6 +89,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("could not create http drand client: %w", err)
|
||||
}
|
||||
hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.BuildVersion)
|
||||
clients = append(clients, hc)
|
||||
|
||||
}
|
||||
@@ -92,7 +98,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
|
||||
dclient.WithChainInfo(drandChain),
|
||||
dclient.WithCacheSize(1024),
|
||||
dclient.WithLogger(dlogger),
|
||||
dclient.WithAutoWatch(),
|
||||
}
|
||||
|
||||
if ps != nil {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestPrintGroupInfo(t *testing.T) {
|
||||
server := build.DrandConfigs[build.DrandIncentinet].Servers[0]
|
||||
server := build.DrandConfigs[build.DrandDevnet].Servers[0]
|
||||
c, err := hclient.New(server, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
cg := c.(interface {
|
||||
|
||||
+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 {
|
||||
|
||||
@@ -459,7 +459,7 @@ type messageEvents struct {
|
||||
hcAPI headChangeAPI
|
||||
|
||||
lk sync.RWMutex
|
||||
matchers map[triggerID][]MsgMatchFunc
|
||||
matchers map[triggerID]MsgMatchFunc
|
||||
}
|
||||
|
||||
func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) messageEvents {
|
||||
@@ -467,7 +467,7 @@ func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) mes
|
||||
ctx: ctx,
|
||||
cs: cs,
|
||||
hcAPI: hcAPI,
|
||||
matchers: map[triggerID][]MsgMatchFunc{},
|
||||
matchers: make(map[triggerID]MsgMatchFunc),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,32 +482,23 @@ func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventDat
|
||||
me.lk.RLock()
|
||||
defer me.lk.RUnlock()
|
||||
|
||||
// For each message in the tipset
|
||||
res := make(map[triggerID]eventData)
|
||||
me.messagesForTs(pts, func(msg *types.Message) {
|
||||
// TODO: provide receipts
|
||||
|
||||
for tid, matchFns := range me.matchers {
|
||||
var matched bool
|
||||
var once bool
|
||||
for _, matchFn := range matchFns {
|
||||
matchOne, ok, err := matchFn(msg)
|
||||
if err != nil {
|
||||
log.Errorf("event matcher failed: %s", err)
|
||||
continue
|
||||
}
|
||||
matched = ok
|
||||
once = matchOne
|
||||
|
||||
if matched {
|
||||
break
|
||||
}
|
||||
// Run each trigger's matcher against the message
|
||||
for tid, matchFn := range me.matchers {
|
||||
matched, err := matchFn(msg)
|
||||
if err != nil {
|
||||
log.Errorf("event matcher failed: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// If there was a match, include the message in the results for the
|
||||
// trigger
|
||||
if matched {
|
||||
res[tid] = msg
|
||||
if once {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -555,7 +546,7 @@ func (me *messageEvents) messagesForTs(ts *types.TipSet, consume func(*types.Mes
|
||||
// `curH`-`ts.Height` = `confidence`
|
||||
type MsgHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error)
|
||||
|
||||
type MsgMatchFunc func(msg *types.Message) (matchOnce bool, matched bool, err error)
|
||||
type MsgMatchFunc func(msg *types.Message) (matched bool, err error)
|
||||
|
||||
// Called registers a callback which is triggered when a specified method is
|
||||
// called on an actor, or a timeout is reached.
|
||||
@@ -607,7 +598,7 @@ func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHa
|
||||
|
||||
me.lk.Lock()
|
||||
defer me.lk.Unlock()
|
||||
me.matchers[id] = append(me.matchers[id], mf)
|
||||
me.matchers[id] = mf
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -572,9 +572,9 @@ func TestAtChainedConfidenceNull(t *testing.T) {
|
||||
require.Equal(t, false, reverted)
|
||||
}
|
||||
|
||||
func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (matchOnce bool, matched bool, err error) {
|
||||
return func(msg *types.Message) (matchOnce bool, matched bool, err error) {
|
||||
return true, to == msg.To && m == msg.Method, nil
|
||||
func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (matched bool, err error) {
|
||||
return func(msg *types.Message) (matched bool, err error) {
|
||||
return to == msg.To && m == msg.Method, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
type FastChainApiAPI interface {
|
||||
ChainAPI
|
||||
|
||||
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
|
||||
}
|
||||
|
||||
type fastAPI struct {
|
||||
FastChainApiAPI
|
||||
}
|
||||
|
||||
func WrapFastAPI(api FastChainApiAPI) ChainAPI {
|
||||
return &fastAPI{
|
||||
api,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *fastAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
ts, err := a.FastChainApiAPI.ChainGetTipSet(ctx, tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a.FastChainApiAPI.StateGetActor(ctx, actor, ts.Parents())
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type MockAPI struct {
|
||||
bs blockstore.Blockstore
|
||||
|
||||
lk sync.Mutex
|
||||
ts map[types.TipSetKey]*types.Actor
|
||||
stateGetActorCalled int
|
||||
}
|
||||
|
||||
func NewMockAPI(bs blockstore.Blockstore) *MockAPI {
|
||||
return &MockAPI{
|
||||
bs: bs,
|
||||
ts: make(map[types.TipSetKey]*types.Actor),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
|
||||
return m.bs.Has(c)
|
||||
}
|
||||
|
||||
func (m *MockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
||||
blk, err := m.bs.Get(c)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("blockstore get: %w", err)
|
||||
}
|
||||
|
||||
return blk.RawData(), nil
|
||||
}
|
||||
|
||||
func (m *MockAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
m.lk.Lock()
|
||||
defer m.lk.Unlock()
|
||||
|
||||
m.stateGetActorCalled++
|
||||
return m.ts[tsk], nil
|
||||
}
|
||||
|
||||
func (m *MockAPI) StateGetActorCallCount() int {
|
||||
m.lk.Lock()
|
||||
defer m.lk.Unlock()
|
||||
|
||||
return m.stateGetActorCalled
|
||||
}
|
||||
|
||||
func (m *MockAPI) ResetCallCounts() {
|
||||
m.lk.Lock()
|
||||
defer m.lk.Unlock()
|
||||
|
||||
m.stateGetActorCalled = 0
|
||||
}
|
||||
|
||||
func (m *MockAPI) SetActor(tsk types.TipSetKey, act *types.Actor) {
|
||||
m.lk.Lock()
|
||||
defer m.lk.Unlock()
|
||||
|
||||
m.ts[tsk] = act
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func CreateEmptyMarketState(t *testing.T, store adt.Store) *market.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
return market.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||
}
|
||||
|
||||
func CreateDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
for dealID, dealState := range deals {
|
||||
err := root.Set(uint64(dealID), dealState)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
rootCid, err := root.Root()
|
||||
require.NoError(t, err)
|
||||
return rootCid
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
var dummyCid cid.Cid
|
||||
|
||||
func init() {
|
||||
dummyCid, _ = cid.Parse("bafkqaaa")
|
||||
}
|
||||
|
||||
func MockTipset(minerAddr address.Address, timestamp uint64) (*types.TipSet, error) {
|
||||
return types.NewTipSet([]*types.BlockHeader{{
|
||||
Miner: minerAddr,
|
||||
Height: 5,
|
||||
ParentStateRoot: dummyCid,
|
||||
Messages: dummyCid,
|
||||
ParentMessageReceipts: dummyCid,
|
||||
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
|
||||
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
|
||||
Timestamp: timestamp,
|
||||
}})
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,28 +4,26 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
test "github.com/filecoin-project/lotus/chain/events/state/mock"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbornode "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
tutils "github.com/filecoin-project/specs-actors/v2/support/testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
tutils "github.com/filecoin-project/specs-actors/support/testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
)
|
||||
@@ -36,60 +34,27 @@ func init() {
|
||||
dummyCid, _ = cid.Parse("bafkqaaa")
|
||||
}
|
||||
|
||||
type mockAPI struct {
|
||||
ts map[types.TipSetKey]*types.Actor
|
||||
bs bstore.Blockstore
|
||||
}
|
||||
|
||||
func newMockAPI(bs bstore.Blockstore) *mockAPI {
|
||||
return &mockAPI{
|
||||
bs: bs,
|
||||
ts: make(map[types.TipSetKey]*types.Actor),
|
||||
}
|
||||
}
|
||||
|
||||
func (m mockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
|
||||
return m.bs.Has(c)
|
||||
}
|
||||
|
||||
func (m mockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
|
||||
blk, err := m.bs.Get(c)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("blockstore get: %w", err)
|
||||
}
|
||||
|
||||
return blk.RawData(), nil
|
||||
}
|
||||
|
||||
func (m mockAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
return m.ts[tsk], nil
|
||||
}
|
||||
|
||||
func (m mockAPI) setActor(tsk types.TipSetKey, act *types.Actor) {
|
||||
m.ts[tsk] = act
|
||||
}
|
||||
|
||||
func TestMarketPredicates(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
bs := bstore.NewTemporarySync()
|
||||
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||
|
||||
oldDeal1 := &market0.DealState{
|
||||
oldDeal1 := &market2.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 2,
|
||||
SlashEpoch: 0,
|
||||
}
|
||||
oldDeal2 := &market0.DealState{
|
||||
oldDeal2 := &market2.DealState{
|
||||
SectorStartEpoch: 4,
|
||||
LastUpdatedEpoch: 5,
|
||||
SlashEpoch: 0,
|
||||
}
|
||||
oldDeals := map[abi.DealID]*market0.DealState{
|
||||
oldDeals := map[abi.DealID]*market2.DealState{
|
||||
abi.DealID(1): oldDeal1,
|
||||
abi.DealID(2): oldDeal2,
|
||||
}
|
||||
|
||||
oldProp1 := &market0.DealProposal{
|
||||
oldProp1 := &market2.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@@ -101,7 +66,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
oldProp2 := &market0.DealProposal{
|
||||
oldProp2 := &market2.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@@ -113,7 +78,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
oldProps := map[abi.DealID]*market0.DealProposal{
|
||||
oldProps := map[abi.DealID]*market2.DealProposal{
|
||||
abi.DealID(1): oldProp1,
|
||||
abi.DealID(2): oldProp2,
|
||||
}
|
||||
@@ -127,7 +92,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
|
||||
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
|
||||
|
||||
newDeal1 := &market0.DealState{
|
||||
newDeal1 := &market2.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 3,
|
||||
SlashEpoch: 0,
|
||||
@@ -136,19 +101,19 @@ func TestMarketPredicates(t *testing.T) {
|
||||
// deal 2 removed
|
||||
|
||||
// added
|
||||
newDeal3 := &market0.DealState{
|
||||
newDeal3 := &market2.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 2,
|
||||
SlashEpoch: 3,
|
||||
}
|
||||
newDeals := map[abi.DealID]*market0.DealState{
|
||||
newDeals := map[abi.DealID]*market2.DealState{
|
||||
abi.DealID(1): newDeal1,
|
||||
// deal 2 was removed
|
||||
abi.DealID(3): newDeal3,
|
||||
}
|
||||
|
||||
// added
|
||||
newProp3 := &market0.DealProposal{
|
||||
newProp3 := &market2.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@@ -160,7 +125,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
newProps := map[abi.DealID]*market0.DealProposal{
|
||||
newProps := map[abi.DealID]*market2.DealProposal{
|
||||
abi.DealID(1): oldProp1, // 1 was persisted
|
||||
// prop 2 was removed
|
||||
abi.DealID(3): newProp3, // new
|
||||
@@ -177,14 +142,14 @@ func TestMarketPredicates(t *testing.T) {
|
||||
|
||||
minerAddr, err := address.NewFromString("t00")
|
||||
require.NoError(t, err)
|
||||
oldState, err := mockTipset(minerAddr, 1)
|
||||
oldState, err := test.MockTipset(minerAddr, 1)
|
||||
require.NoError(t, err)
|
||||
newState, err := mockTipset(minerAddr, 2)
|
||||
newState, err := test.MockTipset(minerAddr, 2)
|
||||
require.NoError(t, err)
|
||||
|
||||
api := newMockAPI(bs)
|
||||
api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC})
|
||||
api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC})
|
||||
api := test.NewMockAPI(bs)
|
||||
api.SetActor(oldState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: oldStateC})
|
||||
api.SetActor(newState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: newStateC})
|
||||
|
||||
t.Run("deal ID predicate", func(t *testing.T) {
|
||||
preds := NewStatePredicates(api)
|
||||
@@ -239,11 +204,11 @@ func TestMarketPredicates(t *testing.T) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
marketState0 := createEmptyMarketState(t, store)
|
||||
marketState0 := test.CreateEmptyMarketState(t, store)
|
||||
marketCid, err := store.Put(ctx, marketState0)
|
||||
require.NoError(t, err)
|
||||
marketState, err := market.Load(store, &types.Actor{
|
||||
Code: builtin0.StorageMarketActorCodeID,
|
||||
Code: builtin2.StorageMarketActorCodeID,
|
||||
Head: marketCid,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -352,11 +317,11 @@ func TestMarketPredicates(t *testing.T) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
marketState0 := createEmptyMarketState(t, store)
|
||||
marketState0 := test.CreateEmptyMarketState(t, store)
|
||||
marketCid, err := store.Put(ctx, marketState0)
|
||||
require.NoError(t, err)
|
||||
marketState, err := market.Load(store, &types.Actor{
|
||||
Code: builtin0.StorageMarketActorCodeID,
|
||||
Code: builtin2.StorageMarketActorCodeID,
|
||||
Head: marketCid,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -370,7 +335,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
func TestMinerSectorChange(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
bs := bstore.NewTemporarySync()
|
||||
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||
|
||||
nextID := uint64(0)
|
||||
nextIDAddrF := func() address.Address {
|
||||
@@ -379,12 +344,12 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
}
|
||||
|
||||
owner, worker := nextIDAddrF(), nextIDAddrF()
|
||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
||||
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner0.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
|
||||
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner0.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
|
||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner2.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
||||
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner2.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
|
||||
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner2.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
|
||||
oldMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si0, si1, si2})
|
||||
|
||||
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner0.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
|
||||
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner2.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
|
||||
// 0 delete
|
||||
// 1 extend
|
||||
// 2 same
|
||||
@@ -394,14 +359,14 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
newMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si1Ext, si2, si3})
|
||||
|
||||
minerAddr := nextIDAddrF()
|
||||
oldState, err := mockTipset(minerAddr, 1)
|
||||
oldState, err := test.MockTipset(minerAddr, 1)
|
||||
require.NoError(t, err)
|
||||
newState, err := mockTipset(minerAddr, 2)
|
||||
newState, err := test.MockTipset(minerAddr, 2)
|
||||
require.NoError(t, err)
|
||||
|
||||
api := newMockAPI(bs)
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID})
|
||||
api := test.NewMockAPI(bs)
|
||||
api.SetActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin2.StorageMinerActorCodeID})
|
||||
api.SetActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin2.StorageMinerActorCodeID})
|
||||
|
||||
preds := NewStatePredicates(api)
|
||||
|
||||
@@ -449,29 +414,16 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.Equal(t, si1Ext, sectorChanges.Extended[0].From)
|
||||
}
|
||||
|
||||
func mockTipset(minerAddr address.Address, timestamp uint64) (*types.TipSet, error) {
|
||||
return types.NewTipSet([]*types.BlockHeader{{
|
||||
Miner: minerAddr,
|
||||
Height: 5,
|
||||
ParentStateRoot: dummyCid,
|
||||
Messages: dummyCid,
|
||||
ParentMessageReceipts: dummyCid,
|
||||
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
|
||||
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
|
||||
Timestamp: timestamp,
|
||||
}})
|
||||
}
|
||||
|
||||
type balance struct {
|
||||
available abi.TokenAmount
|
||||
locked abi.TokenAmount
|
||||
}
|
||||
|
||||
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState, props map[abi.DealID]*market0.DealProposal, balances map[address.Address]balance) cid.Cid {
|
||||
dealRootCid := createDealAMT(ctx, t, store, deals)
|
||||
func createMarketState(ctx context.Context, t *testing.T, store adt2.Store, deals map[abi.DealID]*market2.DealState, props map[abi.DealID]*market2.DealProposal, balances map[address.Address]balance) cid.Cid {
|
||||
dealRootCid := test.CreateDealAMT(ctx, t, store, deals)
|
||||
propRootCid := createProposalAMT(ctx, t, store, props)
|
||||
balancesCids := createBalanceTable(ctx, t, store, balances)
|
||||
state := createEmptyMarketState(t, store)
|
||||
state := test.CreateEmptyMarketState(t, store)
|
||||
state.States = dealRootCid
|
||||
state.Proposals = propRootCid
|
||||
state.EscrowTable = balancesCids[0]
|
||||
@@ -482,27 +434,8 @@ func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals
|
||||
return stateC
|
||||
}
|
||||
|
||||
func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
return market0.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||
}
|
||||
|
||||
func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
for dealID, dealState := range deals {
|
||||
err := root.Set(uint64(dealID), dealState)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
rootCid, err := root.Root()
|
||||
require.NoError(t, err)
|
||||
return rootCid
|
||||
}
|
||||
|
||||
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market0.DealProposal) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, props map[abi.DealID]*market2.DealProposal) cid.Cid {
|
||||
root := adt2.MakeEmptyArray(store)
|
||||
for dealID, prop := range props {
|
||||
err := root.Set(uint64(dealID), prop)
|
||||
require.NoError(t, err)
|
||||
@@ -512,16 +445,16 @@ func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props
|
||||
return rootCid
|
||||
}
|
||||
|
||||
func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, balances map[address.Address]balance) [2]cid.Cid {
|
||||
escrowMapRoot := adt.MakeEmptyMap(store)
|
||||
func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, balances map[address.Address]balance) [2]cid.Cid {
|
||||
escrowMapRoot := adt2.MakeEmptyMap(store)
|
||||
escrowMapRootCid, err := escrowMapRoot.Root()
|
||||
require.NoError(t, err)
|
||||
escrowRoot, err := adt.AsBalanceTable(store, escrowMapRootCid)
|
||||
escrowRoot, err := adt2.AsBalanceTable(store, escrowMapRootCid)
|
||||
require.NoError(t, err)
|
||||
lockedMapRoot := adt.MakeEmptyMap(store)
|
||||
lockedMapRoot := adt2.MakeEmptyMap(store)
|
||||
lockedMapRootCid, err := lockedMapRoot.Root()
|
||||
require.NoError(t, err)
|
||||
lockedRoot, err := adt.AsBalanceTable(store, lockedMapRootCid)
|
||||
lockedRoot, err := adt2.AsBalanceTable(store, lockedMapRootCid)
|
||||
require.NoError(t, err)
|
||||
|
||||
for addr, balance := range balances {
|
||||
@@ -538,7 +471,7 @@ func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, bala
|
||||
return [2]cid.Cid{escrowRootCid, lockedRootCid}
|
||||
}
|
||||
|
||||
func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||
func createMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||
rootCid := createSectorsAMT(ctx, t, store, sectors)
|
||||
|
||||
state := createEmptyMinerState(ctx, t, store, owner, worker)
|
||||
@@ -549,20 +482,20 @@ func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner,
|
||||
return stateC
|
||||
}
|
||||
|
||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address) *miner2.State {
|
||||
emptyArrayCid, err := adt2.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
emptyMap, err := adt2.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyDeadline, err := store.Put(store.Context(), miner0.ConstructDeadline(emptyArrayCid))
|
||||
emptyDeadline, err := store.Put(store.Context(), miner2.ConstructDeadline(emptyArrayCid))
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyVestingFunds := miner0.ConstructVestingFunds()
|
||||
emptyVestingFunds := miner2.ConstructVestingFunds()
|
||||
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline)
|
||||
emptyDeadlines := miner2.ConstructDeadlines(emptyDeadline)
|
||||
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -572,16 +505,30 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
|
||||
emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, err := miner0.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
|
||||
state, err := miner2.ConstructState(minerInfo, 123, 4, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
|
||||
require.NoError(t, err)
|
||||
return state
|
||||
|
||||
}
|
||||
|
||||
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
func createSectorsAMT(ctx context.Context, t *testing.T, store adt2.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||
root := adt2.MakeEmptyArray(store)
|
||||
for _, sector := range sectors {
|
||||
sector := (miner0.SectorOnChainInfo)(sector)
|
||||
sector := miner2.SectorOnChainInfo{
|
||||
SectorNumber: sector.SectorNumber,
|
||||
SealProof: sector.SealProof,
|
||||
SealedCID: sector.SealedCID,
|
||||
DealIDs: sector.DealIDs,
|
||||
Activation: sector.Activation,
|
||||
Expiration: sector.Expiration,
|
||||
DealWeight: sector.DealWeight,
|
||||
VerifiedDealWeight: sector.VerifiedDealWeight,
|
||||
InitialPledge: sector.InitialPledge,
|
||||
ExpectedDayReward: sector.ExpectedDayReward,
|
||||
ExpectedStoragePledge: sector.ExpectedStoragePledge,
|
||||
ReplacedSectorAge: 0,
|
||||
ReplacedDayReward: big.NewInt(0),
|
||||
}
|
||||
err := root.Set(uint64(sector.SectorNumber), §or)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -614,8 +561,8 @@ const (
|
||||
)
|
||||
|
||||
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
|
||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner0.SectorPreCommitInfo {
|
||||
return &miner0.SectorPreCommitInfo{
|
||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner2.SectorPreCommitInfo {
|
||||
return &miner2.SectorPreCommitInfo{
|
||||
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
SectorNumber: sectorNo,
|
||||
SealedCID: sealed,
|
||||
@@ -625,7 +572,7 @@ func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiratio
|
||||
}
|
||||
}
|
||||
|
||||
func dealEquality(expected market0.DealState, actual market.DealState) bool {
|
||||
func dealEquality(expected market2.DealState, actual market.DealState) bool {
|
||||
return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
|
||||
expected.SectorStartEpoch == actual.SectorStartEpoch &&
|
||||
expected.SlashEpoch == actual.SlashEpoch
|
||||
|
||||
+24
-2
@@ -2,6 +2,7 @@ package events
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -17,6 +18,8 @@ type tsCacheAPI interface {
|
||||
// tipSetCache implements a simple ring-buffer cache to keep track of recent
|
||||
// tipsets
|
||||
type tipSetCache struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
cache []*types.TipSet
|
||||
start int
|
||||
len int
|
||||
@@ -35,6 +38,9 @@ func newTSCache(cap abi.ChainEpoch, storage tsCacheAPI) *tipSetCache {
|
||||
}
|
||||
|
||||
func (tsc *tipSetCache) add(ts *types.TipSet) error {
|
||||
tsc.mu.Lock()
|
||||
defer tsc.mu.Unlock()
|
||||
|
||||
if tsc.len > 0 {
|
||||
if tsc.cache[tsc.start].Height() >= ts.Height() {
|
||||
return xerrors.Errorf("tipSetCache.add: expected new tipset height to be at least %d, was %d", tsc.cache[tsc.start].Height()+1, ts.Height())
|
||||
@@ -65,6 +71,13 @@ func (tsc *tipSetCache) add(ts *types.TipSet) error {
|
||||
}
|
||||
|
||||
func (tsc *tipSetCache) revert(ts *types.TipSet) error {
|
||||
tsc.mu.Lock()
|
||||
defer tsc.mu.Unlock()
|
||||
|
||||
return tsc.revertUnlocked(ts)
|
||||
}
|
||||
|
||||
func (tsc *tipSetCache) revertUnlocked(ts *types.TipSet) error {
|
||||
if tsc.len == 0 {
|
||||
return nil // this can happen, and it's fine
|
||||
}
|
||||
@@ -77,7 +90,7 @@ func (tsc *tipSetCache) revert(ts *types.TipSet) error {
|
||||
tsc.start = normalModulo(tsc.start-1, len(tsc.cache))
|
||||
tsc.len--
|
||||
|
||||
_ = tsc.revert(nil) // revert null block gap
|
||||
_ = tsc.revertUnlocked(nil) // revert null block gap
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -95,7 +108,10 @@ func (tsc *tipSetCache) getNonNull(height abi.ChainEpoch) (*types.TipSet, error)
|
||||
}
|
||||
|
||||
func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
|
||||
tsc.mu.RLock()
|
||||
|
||||
if tsc.len == 0 {
|
||||
tsc.mu.RUnlock()
|
||||
log.Warnf("tipSetCache.get: cache is empty, requesting from storage (h=%d)", height)
|
||||
return tsc.storage.ChainGetTipSetByHeight(context.TODO(), height, types.EmptyTSK)
|
||||
}
|
||||
@@ -103,6 +119,7 @@ func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
|
||||
headH := tsc.cache[tsc.start].Height()
|
||||
|
||||
if height > headH {
|
||||
tsc.mu.RUnlock()
|
||||
return nil, xerrors.Errorf("tipSetCache.get: requested tipset not in cache (req: %d, cache head: %d)", height, headH)
|
||||
}
|
||||
|
||||
@@ -116,15 +133,20 @@ func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
|
||||
}
|
||||
|
||||
if height < tail.Height() {
|
||||
tsc.mu.RUnlock()
|
||||
log.Warnf("tipSetCache.get: requested tipset not in cache, requesting from storage (h=%d; tail=%d)", height, tail.Height())
|
||||
return tsc.storage.ChainGetTipSetByHeight(context.TODO(), height, tail.Key())
|
||||
}
|
||||
|
||||
return tsc.cache[normalModulo(tsc.start-int(headH-height), clen)], nil
|
||||
ts := tsc.cache[normalModulo(tsc.start-int(headH-height), clen)]
|
||||
tsc.mu.RUnlock()
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
func (tsc *tipSetCache) best() (*types.TipSet, error) {
|
||||
tsc.mu.RLock()
|
||||
best := tsc.cache[tsc.start]
|
||||
tsc.mu.RUnlock()
|
||||
if best == nil {
|
||||
return tsc.storage.ChainHead(context.TODO())
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ func (me *messageEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd
|
||||
}
|
||||
|
||||
func (me *messageEvents) MatchMsg(inmsg *types.Message) MsgMatchFunc {
|
||||
return func(msg *types.Message) (matchOnce bool, matched bool, err error) {
|
||||
return func(msg *types.Message) (matched bool, err error) {
|
||||
if msg.From == inmsg.From && msg.Nonce == inmsg.Nonce && !inmsg.Equals(msg) {
|
||||
return true, false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
|
||||
return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
|
||||
}
|
||||
|
||||
return true, inmsg.Equals(msg), nil
|
||||
return inmsg.Equals(msg), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -412,11 +411,7 @@ func (c *client) sendRequestToPeer(ctx context.Context, peer peer.ID, req *Reque
|
||||
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
go helpers.FullClose(stream) //nolint:errcheck
|
||||
}()
|
||||
defer stream.Close() //nolint:errcheck
|
||||
|
||||
// Write request.
|
||||
_ = stream.SetWriteDeadline(time.Now().Add(WriteReqDeadline))
|
||||
|
||||
@@ -38,20 +38,26 @@ func newPeerTracker(lc fx.Lifecycle, h host.Host, pmgr *peermgr.PeerMgr) *bsPeer
|
||||
pmgr: pmgr,
|
||||
}
|
||||
|
||||
sub, err := h.EventBus().Subscribe(new(peermgr.NewFilPeer))
|
||||
evtSub, err := h.EventBus().Subscribe(new(peermgr.FilPeerEvt))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for newPeer := range sub.Out() {
|
||||
bsPt.addPeer(newPeer.(peermgr.NewFilPeer).Id)
|
||||
for evt := range evtSub.Out() {
|
||||
pEvt := evt.(peermgr.FilPeerEvt)
|
||||
switch pEvt.Type {
|
||||
case peermgr.AddFilPeerEvt:
|
||||
bsPt.addPeer(pEvt.ID)
|
||||
case peermgr.RemoveFilPeerEvt:
|
||||
bsPt.removePeer(pEvt.ID)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return sub.Close()
|
||||
return evtSub.Close()
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
)
|
||||
|
||||
@@ -40,16 +39,14 @@ func (s *server) HandleStream(stream inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "chainxchg.HandleStream")
|
||||
defer span.End()
|
||||
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
defer helpers.FullClose(stream) //nolint:errcheck
|
||||
defer stream.Close() //nolint:errcheck
|
||||
|
||||
var req Request
|
||||
if err := cborutil.ReadCborRPC(bufio.NewReader(stream), &req); err != nil {
|
||||
log.Warnf("failed to read block sync request: %s", err)
|
||||
return
|
||||
}
|
||||
log.Infow("block sync request",
|
||||
log.Debugw("block sync request",
|
||||
"start", req.Head, "len", req.Length)
|
||||
|
||||
resp, err := s.processRequest(ctx, &req)
|
||||
|
||||
+48
-33
@@ -4,17 +4,16 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"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/crypto"
|
||||
"github.com/google/uuid"
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -26,6 +25,8 @@ import (
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
@@ -39,6 +40,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
@@ -49,7 +51,7 @@ const msgsPerBlock = 20
|
||||
//nolint:deadcode,varcheck
|
||||
var log = logging.Logger("gen")
|
||||
|
||||
var ValidWpostForTesting = []proof.PoStProof{{
|
||||
var ValidWpostForTesting = []proof2.PoStProof{{
|
||||
ProofBytes: []byte("valid proof"),
|
||||
}}
|
||||
|
||||
@@ -71,7 +73,7 @@ type ChainGen struct {
|
||||
|
||||
GetMessages func(*ChainGen) ([]*types.SignedMessage, error)
|
||||
|
||||
w *wallet.Wallet
|
||||
w *wallet.LocalWallet
|
||||
|
||||
eppProvs map[address.Address]WinningPoStProver
|
||||
Miners []address.Address
|
||||
@@ -122,6 +124,7 @@ var DefaultRemainderAccountActor = genesis.Actor{
|
||||
}
|
||||
|
||||
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
j := journal.NilJournal()
|
||||
// TODO: we really shouldn't modify a global variable here.
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
|
||||
@@ -136,12 +139,20 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, xerrors.Errorf("failed to get metadata datastore: %w", err)
|
||||
}
|
||||
|
||||
bds, err := lr.Datastore("/chain")
|
||||
bs, err := lr.Blockstore(repo.BlockstoreChain)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get blocks datastore: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bs := mybs{blockstore.NewBlockstore(bds)}
|
||||
defer func() {
|
||||
if c, ok := bs.(io.Closer); ok {
|
||||
if err := c.Close(); err != nil {
|
||||
log.Warnf("failed to close blockstore: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
bs = mybs{bs}
|
||||
|
||||
ks, err := lr.KeyStore()
|
||||
if err != nil {
|
||||
@@ -153,14 +164,14 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
|
||||
}
|
||||
|
||||
banker, err := w.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
banker, err := w.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate banker key: %w", err)
|
||||
}
|
||||
|
||||
receievers := make([]address.Address, msgsPerBlock)
|
||||
for r := range receievers {
|
||||
receievers[r], err = w.GenerateKey(crypto.SigTypeBLS)
|
||||
receievers[r], err = w.WalletNew(context.Background(), types.KTBLS)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate receiver key: %w", err)
|
||||
}
|
||||
@@ -190,11 +201,11 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mk1, err := w.Import(k1)
|
||||
mk1, err := w.WalletImport(context.Background(), k1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mk2, err := w.Import(k2)
|
||||
mk2, err := w.WalletImport(context.Background(), k2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -229,12 +240,12 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
Timestamp: uint64(build.Clock.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()),
|
||||
}
|
||||
|
||||
genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl)
|
||||
genb, err := genesis2.MakeGenesisBlock(context.TODO(), j, bs, sys, tpl)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("make genesis block failed: %w", err)
|
||||
}
|
||||
|
||||
cs := store.NewChainStore(bs, ds, sys)
|
||||
cs := store.NewChainStore(bs, bs, ds, sys, j)
|
||||
|
||||
genfb := &types.FullBlock{Header: genb.Genesis}
|
||||
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
|
||||
@@ -336,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]
|
||||
}
|
||||
@@ -374,7 +379,13 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
return nil, nil, nil, xerrors.Errorf("get miner worker: %w", err)
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, ticketRand)
|
||||
sf := func(ctx context.Context, a address.Address, i []byte) (*crypto.Signature, error) {
|
||||
return cg.w.WalletSign(ctx, a, i, api.MsgMeta{
|
||||
Type: api.MTUnknown,
|
||||
})
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, sf, worker, ticketRand)
|
||||
if err != nil {
|
||||
return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err)
|
||||
}
|
||||
@@ -459,7 +470,7 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners
|
||||
|
||||
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
|
||||
eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch,
|
||||
wpost []proof.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
|
||||
wpost []proof2.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
|
||||
|
||||
var ts uint64
|
||||
if cg.Timestamper != nil {
|
||||
@@ -506,7 +517,7 @@ func (cg *ChainGen) Banker() address.Address {
|
||||
return cg.banker
|
||||
}
|
||||
|
||||
func (cg *ChainGen) Wallet() *wallet.Wallet {
|
||||
func (cg *ChainGen) Wallet() *wallet.LocalWallet {
|
||||
return cg.w
|
||||
}
|
||||
|
||||
@@ -528,7 +539,9 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) {
|
||||
GasPremium: types.NewInt(0),
|
||||
}
|
||||
|
||||
sig, err := cg.w.Sign(context.TODO(), cg.banker, msg.Cid().Bytes())
|
||||
sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes(), api.MsgMeta{
|
||||
Type: api.MTUnknown, // testing
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -559,7 +572,7 @@ type MiningCheckAPI interface {
|
||||
}
|
||||
|
||||
type mca struct {
|
||||
w *wallet.Wallet
|
||||
w *wallet.LocalWallet
|
||||
sm *stmgr.StateManager
|
||||
pv ffiwrapper.Verifier
|
||||
bcn beacon.Schedule
|
||||
@@ -588,12 +601,14 @@ func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoc
|
||||
}
|
||||
|
||||
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) {
|
||||
return mca.w.Sign(ctx, a, v)
|
||||
return mca.w.WalletSign(ctx, a, v, api.MsgMeta{
|
||||
Type: api.MTUnknown,
|
||||
})
|
||||
}
|
||||
|
||||
type WinningPoStProver interface {
|
||||
GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error)
|
||||
ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error)
|
||||
ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error)
|
||||
}
|
||||
|
||||
type wppProvider struct{}
|
||||
@@ -602,7 +617,7 @@ func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandom
|
||||
return []uint64{0}, nil
|
||||
}
|
||||
|
||||
func (wpp *wppProvider) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) {
|
||||
func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) {
|
||||
return ValidWpostForTesting, nil
|
||||
}
|
||||
|
||||
@@ -669,15 +684,15 @@ type genFakeVerifier struct{}
|
||||
|
||||
var _ ffiwrapper.Verifier = (*genFakeVerifier)(nil)
|
||||
|
||||
func (m genFakeVerifier) VerifySeal(svi proof.SealVerifyInfo) (bool, error) {
|
||||
func (m genFakeVerifier) VerifySeal(svi proof2.SealVerifyInfo) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) {
|
||||
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) {
|
||||
panic("not supported")
|
||||
}
|
||||
|
||||
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) {
|
||||
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) {
|
||||
panic("not supported")
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
@@ -133,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)
|
||||
}
|
||||
@@ -466,7 +467,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallBuilder, template genesis.Template) (*GenesisBootstrap, error) {
|
||||
func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blockstore, sys vm.SyscallBuilder, template genesis.Template) (*GenesisBootstrap, error) {
|
||||
if j == nil {
|
||||
j = journal.NilJournal()
|
||||
}
|
||||
st, keyIDs, err := MakeInitialStateTree(ctx, bs, template)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("make initial state tree failed: %w", err)
|
||||
@@ -478,7 +482,7 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
||||
}
|
||||
|
||||
// temp chainstore
|
||||
cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys)
|
||||
cs := store.NewChainStore(bs, bs, datastore.NewMapDatastore(), sys, j)
|
||||
|
||||
// Verify PreSealed Data
|
||||
stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs)
|
||||
|
||||
+16
-17
@@ -23,12 +23,11 @@ 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"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
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"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
@@ -47,7 +46,7 @@ func MinerAddress(genesisIndex uint64) address.Address {
|
||||
}
|
||||
|
||||
type fakedSigSyscalls struct {
|
||||
runtime.Syscalls
|
||||
runtime2.Syscalls
|
||||
}
|
||||
|
||||
func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) error {
|
||||
@@ -55,9 +54,9 @@ func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer
|
||||
}
|
||||
|
||||
func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
|
||||
return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
|
||||
return func(ctx context.Context, rt *vm.Runtime) runtime2.Syscalls {
|
||||
return &fakedSigSyscalls{
|
||||
base(ctx, cstate, cst),
|
||||
base(ctx, rt),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,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
|
||||
}
|
||||
@@ -114,7 +113,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
params := mustEnc(constructorParams)
|
||||
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
|
||||
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin0.MethodsPower.CreateMiner, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
||||
}
|
||||
@@ -146,7 +145,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
|
||||
if m.MarketBalance.GreaterThan(big.Zero()) {
|
||||
params := mustEnc(&minerInfos[i].maddr)
|
||||
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
|
||||
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin0.MethodsMarket.AddBalance, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err)
|
||||
}
|
||||
@@ -158,7 +157,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
publish := func(params *market.PublishStorageDealsParams) error {
|
||||
fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker)
|
||||
|
||||
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
|
||||
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin0.MethodsMarket.PublishStorageDeals, mustEnc(params))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
|
||||
}
|
||||
@@ -290,17 +289,17 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
pledge = big.Add(pcd, pledge)
|
||||
|
||||
fmt.Println(types.FIL(pledge))
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin.MethodsMiner.PreCommitSector, mustEnc(params))
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin0.MethodsMiner.PreCommitSector, mustEnc(params))
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
|
||||
}
|
||||
|
||||
// Commit one-by-one, otherwise pledge math tends to explode
|
||||
confirmParams := &builtin.ConfirmSectorProofsParams{
|
||||
confirmParams := &builtin0.ConfirmSectorProofsParams{
|
||||
Sectors: []abi.SectorNumber{preseal.SectorID},
|
||||
}
|
||||
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin0.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
|
||||
}
|
||||
@@ -349,7 +348,7 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry
|
||||
}
|
||||
|
||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
||||
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
|
||||
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -373,7 +372,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
|
||||
market.Address,
|
||||
maddr,
|
||||
abi.NewTokenAmount(0),
|
||||
builtin.MethodsMarket.VerifyDealsForActivation,
|
||||
builtin0.MethodsMarket.VerifyDealsForActivation,
|
||||
mustEnc(params),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -387,7 +386,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
|
||||
}
|
||||
|
||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) {
|
||||
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
|
||||
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin0.MethodsReward.ThisEpochReward, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -405,7 +404,7 @@ func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.Toke
|
||||
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
|
||||
GasLimit: 1_000_000_000,
|
||||
From: maddr,
|
||||
}, maddr, 0, 0, 0)
|
||||
})
|
||||
|
||||
return rt.TotalFilCircSupply()
|
||||
}
|
||||
|
||||
@@ -50,12 +50,27 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
|
||||
return ret.Return, nil
|
||||
}
|
||||
|
||||
var GenesisNetworkVersion = func() network.Version { // TODO: Get from build/
|
||||
if build.UseNewestNetwork() { // TODO: Get from build/
|
||||
return build.NewestNetworkVersion // TODO: Get from build/
|
||||
} // TODO: Get from build/
|
||||
return network.Version1 // TODO: Get from build/
|
||||
}() // TODO: Get from build/
|
||||
// TODO: Get from build
|
||||
// TODO: make a list/schedule of these.
|
||||
var GenesisNetworkVersion = func() network.Version {
|
||||
// returns the version _before_ the first upgrade.
|
||||
if build.UpgradeBreezeHeight >= 0 {
|
||||
return network.Version0
|
||||
}
|
||||
if build.UpgradeSmokeHeight >= 0 {
|
||||
return network.Version1
|
||||
}
|
||||
if build.UpgradeIgnitionHeight >= 0 {
|
||||
return network.Version2
|
||||
}
|
||||
if build.UpgradeActorsV2Height >= 0 {
|
||||
return network.Version3
|
||||
}
|
||||
if build.UpgradeLiftoffHeight >= 0 {
|
||||
return network.Version3
|
||||
}
|
||||
return build.ActorUpgradeNetworkVersion - 1 // genesis requires actors v0.
|
||||
}()
|
||||
|
||||
func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/
|
||||
return GenesisNetworkVersion // TODO: Get from build/
|
||||
|
||||
+13
-21
@@ -4,22 +4,18 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
)
|
||||
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletAPI, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
|
||||
pts, err := sm.ChainStore().LoadTipSet(bt.Parents)
|
||||
if err != nil {
|
||||
@@ -31,7 +27,12 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
||||
return nil, xerrors.Errorf("failed to load tipset state: %w", err)
|
||||
}
|
||||
|
||||
worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, st, bt.Miner)
|
||||
_, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, sm, pts, bt.Epoch)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
|
||||
}
|
||||
|
||||
worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, lbst, bt.Miner)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
|
||||
}
|
||||
@@ -115,23 +116,14 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
||||
}
|
||||
next.ParentBaseFee = baseFee
|
||||
|
||||
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
|
||||
tree, err := state.LoadStateTree(cst, st)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load state tree: %w", err)
|
||||
}
|
||||
|
||||
waddr, err := vm.ResolveToKeyAddr(tree, cst, worker)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to resolve miner address to key address: %w", err)
|
||||
}
|
||||
|
||||
nosigbytes, err := next.SigningBytes()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err)
|
||||
}
|
||||
|
||||
sig, err := w.Sign(ctx, waddr, nosigbytes)
|
||||
sig, err := w.WalletSign(ctx, worker, nosigbytes, api.MsgMeta{
|
||||
Type: api.MTBlock,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to sign new block: %w", err)
|
||||
}
|
||||
@@ -180,8 +172,8 @@ func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toArray(store adt.Store, cids []cid.Cid) (cid.Cid, error) {
|
||||
arr := adt.MakeEmptyArray(store)
|
||||
func toArray(store blockadt.Store, cids []cid.Cid) (cid.Cid, error) {
|
||||
arr := blockadt.MakeEmptyArray(store)
|
||||
for i, c := range cids {
|
||||
oc := cbg.CborCid(c)
|
||||
if err := arr.Set(uint64(i), &oc); err != nil {
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
|
||||
|
||||
package market
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var _ = xerrors.Errorf
|
||||
|
||||
var lengthBufFundedAddressState = []byte{131}
|
||||
|
||||
func (t *FundedAddressState) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(lengthBufFundedAddressState); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Addr (address.Address) (struct)
|
||||
if err := t.Addr.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.AmtReserved (big.Int) (struct)
|
||||
if err := t.AmtReserved.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.MsgCid (cid.Cid) (struct)
|
||||
|
||||
if t.MsgCid == nil {
|
||||
if _, err := w.Write(cbg.CborNull); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteCidBuf(scratch, w, *t.MsgCid); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.MsgCid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *FundedAddressState) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = FundedAddressState{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 3 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Addr (address.Address) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Addr.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.Addr: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.AmtReserved (big.Int) (struct)
|
||||
|
||||
{
|
||||
|
||||
if err := t.AmtReserved.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.AmtReserved: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.MsgCid (cid.Cid) (struct)
|
||||
|
||||
{
|
||||
|
||||
b, err := br.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := br.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.MsgCid: %w", err)
|
||||
}
|
||||
|
||||
t.MsgCid = &c
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,707 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/impl/full"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var log = logging.Logger("market_adapter")
|
||||
|
||||
// API is the fx dependencies need to run a fund manager
|
||||
type FundManagerAPI struct {
|
||||
fx.In
|
||||
|
||||
full.StateAPI
|
||||
full.MpoolAPI
|
||||
}
|
||||
|
||||
// fundManagerAPI is the specific methods called by the FundManager
|
||||
// (used by the tests)
|
||||
type fundManagerAPI interface {
|
||||
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)
|
||||
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error)
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
||||
}
|
||||
|
||||
// FundManager keeps track of funds in a set of addresses
|
||||
type FundManager struct {
|
||||
ctx context.Context
|
||||
shutdown context.CancelFunc
|
||||
api fundManagerAPI
|
||||
str *Store
|
||||
|
||||
lk sync.Mutex
|
||||
fundedAddrs map[address.Address]*fundedAddress
|
||||
}
|
||||
|
||||
func NewFundManager(lc fx.Lifecycle, api FundManagerAPI, ds dtypes.MetadataDS) *FundManager {
|
||||
fm := newFundManager(&api, ds)
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(ctx context.Context) error {
|
||||
return fm.Start()
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
fm.Stop()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
return fm
|
||||
}
|
||||
|
||||
// newFundManager is used by the tests
|
||||
func newFundManager(api fundManagerAPI, ds datastore.Batching) *FundManager {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &FundManager{
|
||||
ctx: ctx,
|
||||
shutdown: cancel,
|
||||
api: api,
|
||||
str: newStore(ds),
|
||||
fundedAddrs: make(map[address.Address]*fundedAddress),
|
||||
}
|
||||
}
|
||||
|
||||
func (fm *FundManager) Stop() {
|
||||
fm.shutdown()
|
||||
}
|
||||
|
||||
func (fm *FundManager) Start() error {
|
||||
fm.lk.Lock()
|
||||
defer fm.lk.Unlock()
|
||||
|
||||
// TODO:
|
||||
// To save memory:
|
||||
// - in State() only load addresses with in-progress messages
|
||||
// - load the others just-in-time from getFundedAddress
|
||||
// - delete(fm.fundedAddrs, addr) when the queue has been processed
|
||||
return fm.str.forEach(func(state *FundedAddressState) {
|
||||
fa := newFundedAddress(fm, state.Addr)
|
||||
fa.state = state
|
||||
fm.fundedAddrs[fa.state.Addr] = fa
|
||||
fa.start()
|
||||
})
|
||||
}
|
||||
|
||||
// Creates a fundedAddress if it doesn't already exist, and returns it
|
||||
func (fm *FundManager) getFundedAddress(addr address.Address) *fundedAddress {
|
||||
fm.lk.Lock()
|
||||
defer fm.lk.Unlock()
|
||||
|
||||
fa, ok := fm.fundedAddrs[addr]
|
||||
if !ok {
|
||||
fa = newFundedAddress(fm, addr)
|
||||
fm.fundedAddrs[addr] = fa
|
||||
}
|
||||
return fa
|
||||
}
|
||||
|
||||
// Reserve adds amt to `reserved`. If there are not enough available funds for
|
||||
// the address, submits a message on chain to top up available funds.
|
||||
// Returns the cid of the message that was submitted on chain, or cid.Undef if
|
||||
// the required funds were already available.
|
||||
func (fm *FundManager) Reserve(ctx context.Context, wallet, addr address.Address, amt abi.TokenAmount) (cid.Cid, error) {
|
||||
return fm.getFundedAddress(addr).reserve(ctx, wallet, amt)
|
||||
}
|
||||
|
||||
// Subtract from `reserved`.
|
||||
func (fm *FundManager) Release(addr address.Address, amt abi.TokenAmount) error {
|
||||
return fm.getFundedAddress(addr).release(amt)
|
||||
}
|
||||
|
||||
// Withdraw unreserved funds. Only succeeds if there are enough unreserved
|
||||
// funds for the address.
|
||||
// Returns the cid of the message that was submitted on chain.
|
||||
func (fm *FundManager) Withdraw(ctx context.Context, wallet, addr address.Address, amt abi.TokenAmount) (cid.Cid, error) {
|
||||
return fm.getFundedAddress(addr).withdraw(ctx, wallet, amt)
|
||||
}
|
||||
|
||||
// FundedAddressState keeps track of the state of an address with funds in the
|
||||
// datastore
|
||||
type FundedAddressState struct {
|
||||
Addr address.Address
|
||||
// AmtReserved is the amount that must be kept in the address (cannot be
|
||||
// withdrawn)
|
||||
AmtReserved abi.TokenAmount
|
||||
// MsgCid is the cid of an in-progress on-chain message
|
||||
MsgCid *cid.Cid
|
||||
}
|
||||
|
||||
// fundedAddress keeps track of the state and request queues for a
|
||||
// particular address
|
||||
type fundedAddress struct {
|
||||
ctx context.Context
|
||||
env *fundManagerEnvironment
|
||||
str *Store
|
||||
|
||||
lk sync.Mutex
|
||||
state *FundedAddressState
|
||||
|
||||
// Note: These request queues are ephemeral, they are not saved to store
|
||||
reservations []*fundRequest
|
||||
releases []*fundRequest
|
||||
withdrawals []*fundRequest
|
||||
|
||||
// Used by the tests
|
||||
onProcessStartListener func() bool
|
||||
}
|
||||
|
||||
func newFundedAddress(fm *FundManager, addr address.Address) *fundedAddress {
|
||||
return &fundedAddress{
|
||||
ctx: fm.ctx,
|
||||
env: &fundManagerEnvironment{api: fm.api},
|
||||
str: fm.str,
|
||||
state: &FundedAddressState{
|
||||
Addr: addr,
|
||||
AmtReserved: abi.NewTokenAmount(0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// If there is an in-progress on-chain message, don't submit any more messages
|
||||
// on chain until it completes
|
||||
func (a *fundedAddress) start() {
|
||||
a.lk.Lock()
|
||||
defer a.lk.Unlock()
|
||||
|
||||
if a.state.MsgCid != nil {
|
||||
a.debugf("restart: wait for %s", a.state.MsgCid)
|
||||
a.startWaitForResults(*a.state.MsgCid)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *fundedAddress) reserve(ctx context.Context, wallet address.Address, amt abi.TokenAmount) (cid.Cid, error) {
|
||||
return a.requestAndWait(ctx, wallet, amt, &a.reservations)
|
||||
}
|
||||
|
||||
func (a *fundedAddress) release(amt abi.TokenAmount) error {
|
||||
_, err := a.requestAndWait(context.Background(), address.Undef, amt, &a.releases)
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *fundedAddress) withdraw(ctx context.Context, wallet address.Address, amt abi.TokenAmount) (cid.Cid, error) {
|
||||
return a.requestAndWait(ctx, wallet, amt, &a.withdrawals)
|
||||
}
|
||||
|
||||
func (a *fundedAddress) requestAndWait(ctx context.Context, wallet address.Address, amt abi.TokenAmount, reqs *[]*fundRequest) (cid.Cid, error) {
|
||||
// Create a request and add it to the request queue
|
||||
req := newFundRequest(ctx, wallet, amt)
|
||||
|
||||
a.lk.Lock()
|
||||
*reqs = append(*reqs, req)
|
||||
a.lk.Unlock()
|
||||
|
||||
// Process the queue
|
||||
go a.process()
|
||||
|
||||
// Wait for the results
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return cid.Undef, ctx.Err()
|
||||
case r := <-req.Result:
|
||||
return r.msgCid, r.err
|
||||
}
|
||||
}
|
||||
|
||||
// Used by the tests
|
||||
func (a *fundedAddress) onProcessStart(fn func() bool) {
|
||||
a.lk.Lock()
|
||||
defer a.lk.Unlock()
|
||||
|
||||
a.onProcessStartListener = fn
|
||||
}
|
||||
|
||||
// Process queued requests
|
||||
func (a *fundedAddress) process() {
|
||||
a.lk.Lock()
|
||||
defer a.lk.Unlock()
|
||||
|
||||
// Used by the tests
|
||||
if a.onProcessStartListener != nil {
|
||||
done := a.onProcessStartListener()
|
||||
if !done {
|
||||
return
|
||||
}
|
||||
a.onProcessStartListener = nil
|
||||
}
|
||||
|
||||
// Check if we're still waiting for the response to a message
|
||||
if a.state.MsgCid != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if there's anything to do
|
||||
haveReservations := len(a.reservations) > 0 || len(a.releases) > 0
|
||||
haveWithdrawals := len(a.withdrawals) > 0
|
||||
if !haveReservations && !haveWithdrawals {
|
||||
return
|
||||
}
|
||||
|
||||
// Process reservations / releases
|
||||
if haveReservations {
|
||||
res, err := a.processReservations(a.reservations, a.releases)
|
||||
if err == nil {
|
||||
a.applyStateChange(res.msgCid, res.amtReserved)
|
||||
}
|
||||
a.reservations = filterOutProcessedReqs(a.reservations)
|
||||
a.releases = filterOutProcessedReqs(a.releases)
|
||||
}
|
||||
|
||||
// If there was no message sent on chain by adding reservations, and all
|
||||
// reservations have completed processing, process withdrawals
|
||||
if haveWithdrawals && a.state.MsgCid == nil && len(a.reservations) == 0 {
|
||||
withdrawalCid, err := a.processWithdrawals(a.withdrawals)
|
||||
if err == nil && withdrawalCid != cid.Undef {
|
||||
a.applyStateChange(&withdrawalCid, types.EmptyInt)
|
||||
}
|
||||
a.withdrawals = filterOutProcessedReqs(a.withdrawals)
|
||||
}
|
||||
|
||||
// If a message was sent on-chain
|
||||
if a.state.MsgCid != nil {
|
||||
// Start waiting for results of message (async)
|
||||
a.startWaitForResults(*a.state.MsgCid)
|
||||
}
|
||||
|
||||
// Process any remaining queued requests
|
||||
go a.process()
|
||||
}
|
||||
|
||||
// Filter out completed requests
|
||||
func filterOutProcessedReqs(reqs []*fundRequest) []*fundRequest {
|
||||
filtered := make([]*fundRequest, 0, len(reqs))
|
||||
for _, req := range reqs {
|
||||
if !req.Completed() {
|
||||
filtered = append(filtered, req)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
// Apply the results of processing queues and save to the datastore
|
||||
func (a *fundedAddress) applyStateChange(msgCid *cid.Cid, amtReserved abi.TokenAmount) {
|
||||
a.state.MsgCid = msgCid
|
||||
if !amtReserved.Nil() {
|
||||
a.state.AmtReserved = amtReserved
|
||||
}
|
||||
a.saveState()
|
||||
}
|
||||
|
||||
// Clear the pending message cid so that a new message can be sent
|
||||
func (a *fundedAddress) clearWaitState() {
|
||||
a.state.MsgCid = nil
|
||||
a.saveState()
|
||||
}
|
||||
|
||||
// Save state to datastore
|
||||
func (a *fundedAddress) saveState() {
|
||||
// Not much we can do if saving to the datastore fails, just log
|
||||
err := a.str.save(a.state)
|
||||
if err != nil {
|
||||
log.Errorf("saving state to store for addr %s: %w", a.state.Addr, err)
|
||||
}
|
||||
}
|
||||
|
||||
// The result of processing the reservation / release queues
|
||||
type processResult struct {
|
||||
// Requests that completed without adding funds
|
||||
covered []*fundRequest
|
||||
// Requests that added funds
|
||||
added []*fundRequest
|
||||
|
||||
// The new reserved amount
|
||||
amtReserved abi.TokenAmount
|
||||
// The message cid, if a message was submitted on-chain
|
||||
msgCid *cid.Cid
|
||||
}
|
||||
|
||||
// process reservations and releases, and return the resulting changes to state
|
||||
func (a *fundedAddress) processReservations(reservations []*fundRequest, releases []*fundRequest) (pr *processResult, prerr error) {
|
||||
// When the function returns
|
||||
defer func() {
|
||||
// If there's an error, mark all requests as errored
|
||||
if prerr != nil {
|
||||
for _, req := range append(reservations, releases...) {
|
||||
req.Complete(cid.Undef, prerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Complete all release requests
|
||||
for _, req := range releases {
|
||||
req.Complete(cid.Undef, nil)
|
||||
}
|
||||
|
||||
// Complete all requests that were covered by released amounts
|
||||
for _, req := range pr.covered {
|
||||
req.Complete(cid.Undef, nil)
|
||||
}
|
||||
|
||||
// If a message was sent
|
||||
if pr.msgCid != nil {
|
||||
// Complete all add funds requests
|
||||
for _, req := range pr.added {
|
||||
req.Complete(*pr.msgCid, nil)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Split reservations into those that are covered by released amounts,
|
||||
// and those to add to the reserved amount.
|
||||
// Note that we process requests from the same wallet in batches. So some
|
||||
// requests may not be included in covered if they don't match the first
|
||||
// covered request's wallet. These will be processed on a subsequent
|
||||
// invocation of processReservations.
|
||||
toCancel, toAdd, reservedDelta := splitReservations(reservations, releases)
|
||||
|
||||
// Apply the reserved delta to the reserved amount
|
||||
reserved := types.BigAdd(a.state.AmtReserved, reservedDelta)
|
||||
if reserved.LessThan(abi.NewTokenAmount(0)) {
|
||||
reserved = abi.NewTokenAmount(0)
|
||||
}
|
||||
res := &processResult{
|
||||
amtReserved: reserved,
|
||||
covered: toCancel,
|
||||
}
|
||||
|
||||
// Work out the amount to add to the balance
|
||||
amtToAdd := abi.NewTokenAmount(0)
|
||||
if len(toAdd) > 0 && reserved.GreaterThan(abi.NewTokenAmount(0)) {
|
||||
// Get available funds for address
|
||||
avail, err := a.env.AvailableFunds(a.ctx, a.state.Addr)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// amount to add = new reserved amount - available
|
||||
amtToAdd = types.BigSub(reserved, avail)
|
||||
a.debugf("reserved %d - avail %d = to add %d", reserved, avail, amtToAdd)
|
||||
}
|
||||
|
||||
// If there's nothing to add to the balance, bail out
|
||||
if amtToAdd.LessThanEqual(abi.NewTokenAmount(0)) {
|
||||
res.covered = append(res.covered, toAdd...)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Add funds to address
|
||||
a.debugf("add funds %d", amtToAdd)
|
||||
addFundsCid, err := a.env.AddFunds(a.ctx, toAdd[0].Wallet, a.state.Addr, amtToAdd)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Mark reservation requests as complete
|
||||
res.added = toAdd
|
||||
|
||||
// Save the message CID to state
|
||||
res.msgCid = &addFundsCid
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Split reservations into those that are under the total release amount
|
||||
// (covered) and those that exceed it (to add).
|
||||
// Note that we process requests from the same wallet in batches. So some
|
||||
// requests may not be included in covered if they don't match the first
|
||||
// covered request's wallet.
|
||||
func splitReservations(reservations []*fundRequest, releases []*fundRequest) ([]*fundRequest, []*fundRequest, abi.TokenAmount) {
|
||||
toCancel := make([]*fundRequest, 0, len(reservations))
|
||||
toAdd := make([]*fundRequest, 0, len(reservations))
|
||||
toAddAmt := abi.NewTokenAmount(0)
|
||||
|
||||
// Sum release amounts
|
||||
releaseAmt := abi.NewTokenAmount(0)
|
||||
for _, req := range releases {
|
||||
releaseAmt = types.BigAdd(releaseAmt, req.Amount())
|
||||
}
|
||||
|
||||
// We only want to combine requests that come from the same wallet
|
||||
batchWallet := address.Undef
|
||||
for _, req := range reservations {
|
||||
amt := req.Amount()
|
||||
|
||||
// If the amount to add to the reserve is cancelled out by a release
|
||||
if amt.LessThanEqual(releaseAmt) {
|
||||
// Cancel the request and update the release total
|
||||
releaseAmt = types.BigSub(releaseAmt, amt)
|
||||
toCancel = append(toCancel, req)
|
||||
continue
|
||||
}
|
||||
|
||||
// The amount to add is greater that the release total so we want
|
||||
// to send an add funds request
|
||||
|
||||
// The first time the wallet will be undefined
|
||||
if batchWallet == address.Undef {
|
||||
batchWallet = req.Wallet
|
||||
}
|
||||
// If this request's wallet is the same as the batch wallet,
|
||||
// the requests will be combined
|
||||
if batchWallet == req.Wallet {
|
||||
delta := types.BigSub(amt, releaseAmt)
|
||||
toAddAmt = types.BigAdd(toAddAmt, delta)
|
||||
releaseAmt = abi.NewTokenAmount(0)
|
||||
toAdd = append(toAdd, req)
|
||||
}
|
||||
}
|
||||
|
||||
// The change in the reserved amount is "amount to add" - "amount to release"
|
||||
reservedDelta := types.BigSub(toAddAmt, releaseAmt)
|
||||
|
||||
return toCancel, toAdd, reservedDelta
|
||||
}
|
||||
|
||||
// process withdrawal queue
|
||||
func (a *fundedAddress) processWithdrawals(withdrawals []*fundRequest) (msgCid cid.Cid, prerr error) {
|
||||
// If there's an error, mark all withdrawal requests as errored
|
||||
defer func() {
|
||||
if prerr != nil {
|
||||
for _, req := range withdrawals {
|
||||
req.Complete(cid.Undef, prerr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Get the net available balance
|
||||
avail, err := a.env.AvailableFunds(a.ctx, a.state.Addr)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
netAvail := types.BigSub(avail, a.state.AmtReserved)
|
||||
|
||||
// Fit as many withdrawals as possible into the available balance, and fail
|
||||
// the rest
|
||||
withdrawalAmt := abi.NewTokenAmount(0)
|
||||
allowedAmt := abi.NewTokenAmount(0)
|
||||
allowed := make([]*fundRequest, 0, len(withdrawals))
|
||||
var batchWallet address.Address
|
||||
for _, req := range withdrawals {
|
||||
amt := req.Amount()
|
||||
if amt.IsZero() {
|
||||
// If the context for the request was cancelled, bail out
|
||||
req.Complete(cid.Undef, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// If the amount would exceed the available amount, complete the
|
||||
// request with an error
|
||||
newWithdrawalAmt := types.BigAdd(withdrawalAmt, amt)
|
||||
if newWithdrawalAmt.GreaterThan(netAvail) {
|
||||
err := xerrors.Errorf("insufficient funds for withdrawal of %d", amt)
|
||||
a.debugf("%s", err)
|
||||
req.Complete(cid.Undef, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// If this is the first allowed withdrawal request in this batch, save
|
||||
// its wallet address
|
||||
if batchWallet == address.Undef {
|
||||
batchWallet = req.Wallet
|
||||
}
|
||||
// If the request wallet doesn't match the batch wallet, bail out
|
||||
// (the withdrawal will be processed after the current batch has
|
||||
// completed)
|
||||
if req.Wallet != batchWallet {
|
||||
continue
|
||||
}
|
||||
|
||||
// Include this withdrawal request in the batch
|
||||
withdrawalAmt = newWithdrawalAmt
|
||||
a.debugf("withdraw %d", amt)
|
||||
allowed = append(allowed, req)
|
||||
allowedAmt = types.BigAdd(allowedAmt, amt)
|
||||
}
|
||||
|
||||
// Check if there is anything to withdraw.
|
||||
// Note that if the context for a request is cancelled,
|
||||
// req.Amount() returns zero
|
||||
if allowedAmt.Equals(abi.NewTokenAmount(0)) {
|
||||
// Mark allowed requests as complete
|
||||
for _, req := range allowed {
|
||||
req.Complete(cid.Undef, nil)
|
||||
}
|
||||
return cid.Undef, nil
|
||||
}
|
||||
|
||||
// Withdraw funds
|
||||
a.debugf("withdraw funds %d", allowedAmt)
|
||||
withdrawFundsCid, err := a.env.WithdrawFunds(a.ctx, allowed[0].Wallet, a.state.Addr, allowedAmt)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
// Mark allowed requests as complete
|
||||
for _, req := range allowed {
|
||||
req.Complete(withdrawFundsCid, nil)
|
||||
}
|
||||
|
||||
// Save the message CID to state
|
||||
return withdrawFundsCid, nil
|
||||
}
|
||||
|
||||
// asynchonously wait for results of message
|
||||
func (a *fundedAddress) startWaitForResults(msgCid cid.Cid) {
|
||||
go func() {
|
||||
err := a.env.WaitMsg(a.ctx, msgCid)
|
||||
if err != nil {
|
||||
// We don't really care about the results here, we're just waiting
|
||||
// so as to only process one on-chain message at a time
|
||||
log.Errorf("waiting for results of message %s for addr %s: %w", msgCid, a.state.Addr, err)
|
||||
}
|
||||
|
||||
a.lk.Lock()
|
||||
a.debugf("complete wait")
|
||||
a.clearWaitState()
|
||||
a.lk.Unlock()
|
||||
|
||||
a.process()
|
||||
}()
|
||||
}
|
||||
|
||||
func (a *fundedAddress) debugf(args ...interface{}) {
|
||||
fmtStr := args[0].(string)
|
||||
args = args[1:]
|
||||
log.Debugf(a.state.Addr.String()+": "+fmtStr, args...)
|
||||
}
|
||||
|
||||
// The result of a fund request
|
||||
type reqResult struct {
|
||||
msgCid cid.Cid
|
||||
err error
|
||||
}
|
||||
|
||||
// A request to change funds
|
||||
type fundRequest struct {
|
||||
ctx context.Context
|
||||
amt abi.TokenAmount
|
||||
completed chan struct{}
|
||||
Wallet address.Address
|
||||
Result chan reqResult
|
||||
}
|
||||
|
||||
func newFundRequest(ctx context.Context, wallet address.Address, amt abi.TokenAmount) *fundRequest {
|
||||
return &fundRequest{
|
||||
ctx: ctx,
|
||||
amt: amt,
|
||||
Wallet: wallet,
|
||||
Result: make(chan reqResult),
|
||||
completed: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Amount returns zero if the context has expired
|
||||
func (frp *fundRequest) Amount() abi.TokenAmount {
|
||||
if frp.ctx.Err() != nil {
|
||||
return abi.NewTokenAmount(0)
|
||||
}
|
||||
return frp.amt
|
||||
}
|
||||
|
||||
// Complete is called with the message CID when the funds request has been
|
||||
// started or with the error if there was an error
|
||||
func (frp *fundRequest) Complete(msgCid cid.Cid, err error) {
|
||||
select {
|
||||
case <-frp.completed:
|
||||
case <-frp.ctx.Done():
|
||||
case frp.Result <- reqResult{msgCid: msgCid, err: err}:
|
||||
}
|
||||
close(frp.completed)
|
||||
}
|
||||
|
||||
// Completed indicates if Complete has already been called
|
||||
func (frp *fundRequest) Completed() bool {
|
||||
select {
|
||||
case <-frp.completed:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// fundManagerEnvironment simplifies some API calls
|
||||
type fundManagerEnvironment struct {
|
||||
api fundManagerAPI
|
||||
}
|
||||
|
||||
func (env *fundManagerEnvironment) AvailableFunds(ctx context.Context, addr address.Address) (abi.TokenAmount, error) {
|
||||
bal, err := env.api.StateMarketBalance(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return abi.NewTokenAmount(0), err
|
||||
}
|
||||
|
||||
return types.BigSub(bal.Escrow, bal.Locked), nil
|
||||
}
|
||||
|
||||
func (env *fundManagerEnvironment) AddFunds(
|
||||
ctx context.Context,
|
||||
wallet address.Address,
|
||||
addr address.Address,
|
||||
amt abi.TokenAmount,
|
||||
) (cid.Cid, error) {
|
||||
params, err := actors.SerializeParams(&addr)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
smsg, aerr := env.api.MpoolPushMessage(ctx, &types.Message{
|
||||
To: market.Address,
|
||||
From: wallet,
|
||||
Value: amt,
|
||||
Method: market.Methods.AddBalance,
|
||||
Params: params,
|
||||
}, nil)
|
||||
|
||||
if aerr != nil {
|
||||
return cid.Undef, aerr
|
||||
}
|
||||
|
||||
return smsg.Cid(), nil
|
||||
}
|
||||
|
||||
func (env *fundManagerEnvironment) WithdrawFunds(
|
||||
ctx context.Context,
|
||||
wallet address.Address,
|
||||
addr address.Address,
|
||||
amt abi.TokenAmount,
|
||||
) (cid.Cid, error) {
|
||||
params, err := actors.SerializeParams(&market.WithdrawBalanceParams{
|
||||
ProviderOrClientAddress: addr,
|
||||
Amount: amt,
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("serializing params: %w", err)
|
||||
}
|
||||
|
||||
smsg, aerr := env.api.MpoolPushMessage(ctx, &types.Message{
|
||||
To: market.Address,
|
||||
From: wallet,
|
||||
Value: types.NewInt(0),
|
||||
Method: market.Methods.WithdrawBalance,
|
||||
Params: params,
|
||||
}, nil)
|
||||
|
||||
if aerr != nil {
|
||||
return cid.Undef, aerr
|
||||
}
|
||||
|
||||
return smsg.Cid(), nil
|
||||
}
|
||||
|
||||
func (env *fundManagerEnvironment) WaitMsg(ctx context.Context, c cid.Cid) error {
|
||||
_, err := env.api.StateWaitMsg(ctx, c, build.MessageConfidence)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,820 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
tutils "github.com/filecoin-project/specs-actors/v2/support/testing"
|
||||
"github.com/ipfs/go-cid"
|
||||
ds "github.com/ipfs/go-datastore"
|
||||
ds_sync "github.com/ipfs/go-datastore/sync"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestFundManagerBasic verifies that the basic fund manager operations work
|
||||
func TestFundManagerBasic(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
// Reserve 10
|
||||
// balance: 0 -> 10
|
||||
// reserved: 0 -> 10
|
||||
amt := abi.NewTokenAmount(10)
|
||||
sentinel, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
msg := s.mockApi.getSentMessage(sentinel)
|
||||
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
|
||||
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Reserve 7
|
||||
// balance: 10 -> 17
|
||||
// reserved: 10 -> 17
|
||||
amt = abi.NewTokenAmount(7)
|
||||
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
msg = s.mockApi.getSentMessage(sentinel)
|
||||
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
|
||||
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Release 5
|
||||
// balance: 17
|
||||
// reserved: 17 -> 12
|
||||
amt = abi.NewTokenAmount(5)
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Withdraw 2
|
||||
// balance: 17 -> 15
|
||||
// reserved: 12
|
||||
amt = abi.NewTokenAmount(2)
|
||||
sentinel, err = s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
msg = s.mockApi.getSentMessage(sentinel)
|
||||
checkWithdrawMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
|
||||
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Reserve 3
|
||||
// balance: 15
|
||||
// reserved: 12 -> 15
|
||||
// Note: reserved (15) is <= balance (15) so should not send on-chain
|
||||
// message
|
||||
msgCount := s.mockApi.messageCount()
|
||||
amt = abi.NewTokenAmount(3)
|
||||
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, msgCount, s.mockApi.messageCount())
|
||||
require.Equal(t, sentinel, cid.Undef)
|
||||
|
||||
// Reserve 1
|
||||
// balance: 15 -> 16
|
||||
// reserved: 15 -> 16
|
||||
// Note: reserved (16) is above balance (15) so *should* send on-chain
|
||||
// message to top up balance
|
||||
amt = abi.NewTokenAmount(1)
|
||||
topUp := abi.NewTokenAmount(1)
|
||||
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
msg = s.mockApi.getSentMessage(sentinel)
|
||||
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, topUp)
|
||||
|
||||
// Withdraw 1
|
||||
// balance: 16
|
||||
// reserved: 16
|
||||
// Note: Expect failure because there is no available balance to withdraw:
|
||||
// balance - reserved = 16 - 16 = 0
|
||||
amt = abi.NewTokenAmount(1)
|
||||
sentinel, err = s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// TestFundManagerParallel verifies that operations can be run in parallel
|
||||
func TestFundManagerParallel(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
// Reserve 10
|
||||
amt := abi.NewTokenAmount(10)
|
||||
sentinelReserve10, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Wait until all the subsequent requests are queued up
|
||||
queueReady := make(chan struct{})
|
||||
fa := s.fm.getFundedAddress(s.acctAddr)
|
||||
fa.onProcessStart(func() bool {
|
||||
if len(fa.withdrawals) == 1 && len(fa.reservations) == 2 && len(fa.releases) == 1 {
|
||||
close(queueReady)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// Withdraw 5 (should not run until after reserves / releases)
|
||||
withdrawReady := make(chan error)
|
||||
go func() {
|
||||
amt = abi.NewTokenAmount(5)
|
||||
_, err := s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
withdrawReady <- err
|
||||
}()
|
||||
|
||||
reserveSentinels := make(chan cid.Cid)
|
||||
|
||||
// Reserve 3
|
||||
go func() {
|
||||
amt := abi.NewTokenAmount(3)
|
||||
sentinelReserve3, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
reserveSentinels <- sentinelReserve3
|
||||
}()
|
||||
|
||||
// Reserve 5
|
||||
go func() {
|
||||
amt := abi.NewTokenAmount(5)
|
||||
sentinelReserve5, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
reserveSentinels <- sentinelReserve5
|
||||
}()
|
||||
|
||||
// Release 2
|
||||
go func() {
|
||||
amt := abi.NewTokenAmount(2)
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
// Everything is queued up
|
||||
<-queueReady
|
||||
|
||||
// Complete the "Reserve 10" message
|
||||
s.mockApi.completeMsg(sentinelReserve10)
|
||||
msg := s.mockApi.getSentMessage(sentinelReserve10)
|
||||
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, abi.NewTokenAmount(10))
|
||||
|
||||
// The other requests should now be combined and be submitted on-chain as
|
||||
// a single message
|
||||
rs1 := <-reserveSentinels
|
||||
rs2 := <-reserveSentinels
|
||||
require.Equal(t, rs1, rs2)
|
||||
|
||||
// Withdraw should not have been called yet, because reserve / release
|
||||
// requests run first
|
||||
select {
|
||||
case <-withdrawReady:
|
||||
require.Fail(t, "Withdraw should run after reserve / release")
|
||||
default:
|
||||
}
|
||||
|
||||
// Complete the message
|
||||
s.mockApi.completeMsg(rs1)
|
||||
msg = s.mockApi.getSentMessage(rs1)
|
||||
|
||||
// "Reserve 3" +3
|
||||
// "Reserve 5" +5
|
||||
// "Release 2" -2
|
||||
// Result: 6
|
||||
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, abi.NewTokenAmount(6))
|
||||
|
||||
// Expect withdraw to fail because not enough available funds
|
||||
err = <-withdrawReady
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// TestFundManagerReserveByWallet verifies that reserve requests are grouped by wallet
|
||||
func TestFundManagerReserveByWallet(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
walletAddrA, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
walletAddrB, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Wait until all the reservation requests are queued up
|
||||
walletAQueuedUp := make(chan struct{})
|
||||
queueReady := make(chan struct{})
|
||||
fa := s.fm.getFundedAddress(s.acctAddr)
|
||||
fa.onProcessStart(func() bool {
|
||||
if len(fa.reservations) == 1 {
|
||||
close(walletAQueuedUp)
|
||||
}
|
||||
if len(fa.reservations) == 3 {
|
||||
close(queueReady)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
type reserveResult struct {
|
||||
ws cid.Cid
|
||||
err error
|
||||
}
|
||||
results := make(chan *reserveResult)
|
||||
|
||||
amtA1 := abi.NewTokenAmount(1)
|
||||
go func() {
|
||||
// Wallet A: Reserve 1
|
||||
sentinelA1, err := s.fm.Reserve(s.ctx, walletAddrA, s.acctAddr, amtA1)
|
||||
results <- &reserveResult{
|
||||
ws: sentinelA1,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
amtB1 := abi.NewTokenAmount(2)
|
||||
amtB2 := abi.NewTokenAmount(3)
|
||||
go func() {
|
||||
// Wait for reservation for wallet A to be queued up
|
||||
<-walletAQueuedUp
|
||||
|
||||
// Wallet B: Reserve 2
|
||||
go func() {
|
||||
sentinelB1, err := s.fm.Reserve(s.ctx, walletAddrB, s.acctAddr, amtB1)
|
||||
results <- &reserveResult{
|
||||
ws: sentinelB1,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Wallet B: Reserve 3
|
||||
sentinelB2, err := s.fm.Reserve(s.ctx, walletAddrB, s.acctAddr, amtB2)
|
||||
results <- &reserveResult{
|
||||
ws: sentinelB2,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// All reservation requests are queued up
|
||||
<-queueReady
|
||||
|
||||
resA := <-results
|
||||
sentinelA1 := resA.ws
|
||||
|
||||
// Should send to wallet A
|
||||
msg := s.mockApi.getSentMessage(sentinelA1)
|
||||
checkAddMessageFields(t, msg, walletAddrA, s.acctAddr, amtA1)
|
||||
|
||||
// Complete wallet A message
|
||||
s.mockApi.completeMsg(sentinelA1)
|
||||
|
||||
resB1 := <-results
|
||||
resB2 := <-results
|
||||
require.NoError(t, resB1.err)
|
||||
require.NoError(t, resB2.err)
|
||||
sentinelB1 := resB1.ws
|
||||
sentinelB2 := resB2.ws
|
||||
|
||||
// Should send different message to wallet B
|
||||
require.NotEqual(t, sentinelA1, sentinelB1)
|
||||
// Should be single message combining amount 1 and 2
|
||||
require.Equal(t, sentinelB1, sentinelB2)
|
||||
msg = s.mockApi.getSentMessage(sentinelB1)
|
||||
checkAddMessageFields(t, msg, walletAddrB, s.acctAddr, types.BigAdd(amtB1, amtB2))
|
||||
}
|
||||
|
||||
// TestFundManagerWithdrawal verifies that as many withdraw operations as
|
||||
// possible are processed
|
||||
func TestFundManagerWithdrawalLimit(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
// Reserve 10
|
||||
amt := abi.NewTokenAmount(10)
|
||||
sentinelReserve10, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Complete the "Reserve 10" message
|
||||
s.mockApi.completeMsg(sentinelReserve10)
|
||||
|
||||
// Release 10
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Queue up withdraw requests
|
||||
queueReady := make(chan struct{})
|
||||
fa := s.fm.getFundedAddress(s.acctAddr)
|
||||
withdrawalReqTotal := 3
|
||||
withdrawalReqEnqueued := 0
|
||||
withdrawalReqQueue := make(chan func(), withdrawalReqTotal)
|
||||
fa.onProcessStart(func() bool {
|
||||
// If a new withdrawal request was enqueued
|
||||
if len(fa.withdrawals) > withdrawalReqEnqueued {
|
||||
withdrawalReqEnqueued++
|
||||
|
||||
// Pop the next request and run it
|
||||
select {
|
||||
case fn := <-withdrawalReqQueue:
|
||||
go fn()
|
||||
default:
|
||||
}
|
||||
}
|
||||
// Once all the requests have arrived, we're ready to process the queue
|
||||
if withdrawalReqEnqueued == withdrawalReqTotal {
|
||||
close(queueReady)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
type withdrawResult struct {
|
||||
reqIndex int
|
||||
ws cid.Cid
|
||||
err error
|
||||
}
|
||||
withdrawRes := make(chan *withdrawResult)
|
||||
|
||||
// Queue up three "Withdraw 5" requests
|
||||
enqueuedCount := 0
|
||||
for i := 0; i < withdrawalReqTotal; i++ {
|
||||
withdrawalReqQueue <- func() {
|
||||
idx := enqueuedCount
|
||||
enqueuedCount++
|
||||
|
||||
amt := abi.NewTokenAmount(5)
|
||||
ws, err := s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
withdrawRes <- &withdrawResult{reqIndex: idx, ws: ws, err: err}
|
||||
}
|
||||
}
|
||||
// Start the first request
|
||||
fn := <-withdrawalReqQueue
|
||||
go fn()
|
||||
|
||||
// All withdrawal requests are queued up and ready to be processed
|
||||
<-queueReady
|
||||
|
||||
// Organize results in request order
|
||||
results := make([]*withdrawResult, withdrawalReqTotal)
|
||||
for i := 0; i < 3; i++ {
|
||||
res := <-withdrawRes
|
||||
results[res.reqIndex] = res
|
||||
}
|
||||
|
||||
// Available 10
|
||||
// Withdraw 5
|
||||
// Expect Success
|
||||
require.NoError(t, results[0].err)
|
||||
// Available 5
|
||||
// Withdraw 5
|
||||
// Expect Success
|
||||
require.NoError(t, results[1].err)
|
||||
// Available 0
|
||||
// Withdraw 5
|
||||
// Expect FAIL
|
||||
require.Error(t, results[2].err)
|
||||
|
||||
// Expect withdrawal requests that fit under reserved amount to be combined
|
||||
// into a single message on-chain
|
||||
require.Equal(t, results[0].ws, results[1].ws)
|
||||
}
|
||||
|
||||
// TestFundManagerWithdrawByWallet verifies that withdraw requests are grouped by wallet
|
||||
func TestFundManagerWithdrawByWallet(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
walletAddrA, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
walletAddrB, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Reserve 10
|
||||
reserveAmt := abi.NewTokenAmount(10)
|
||||
sentinelReserve, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, reserveAmt)
|
||||
require.NoError(t, err)
|
||||
s.mockApi.completeMsg(sentinelReserve)
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
// Release 10
|
||||
err = s.fm.Release(s.acctAddr, reserveAmt)
|
||||
require.NoError(t, err)
|
||||
|
||||
type withdrawResult struct {
|
||||
ws cid.Cid
|
||||
err error
|
||||
}
|
||||
results := make(chan *withdrawResult)
|
||||
|
||||
// Wait until withdrawals are queued up
|
||||
walletAQueuedUp := make(chan struct{})
|
||||
queueReady := make(chan struct{})
|
||||
withdrawalCount := 0
|
||||
fa := s.fm.getFundedAddress(s.acctAddr)
|
||||
fa.onProcessStart(func() bool {
|
||||
if len(fa.withdrawals) == withdrawalCount {
|
||||
return false
|
||||
}
|
||||
withdrawalCount = len(fa.withdrawals)
|
||||
|
||||
if withdrawalCount == 1 {
|
||||
close(walletAQueuedUp)
|
||||
} else if withdrawalCount == 3 {
|
||||
close(queueReady)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
amtA1 := abi.NewTokenAmount(1)
|
||||
go func() {
|
||||
// Wallet A: Withdraw 1
|
||||
sentinelA1, err := s.fm.Withdraw(s.ctx, walletAddrA, s.acctAddr, amtA1)
|
||||
results <- &withdrawResult{
|
||||
ws: sentinelA1,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
amtB1 := abi.NewTokenAmount(2)
|
||||
amtB2 := abi.NewTokenAmount(3)
|
||||
go func() {
|
||||
// Wait until withdraw for wallet A is queued up
|
||||
<-walletAQueuedUp
|
||||
|
||||
// Wallet B: Withdraw 2
|
||||
go func() {
|
||||
sentinelB1, err := s.fm.Withdraw(s.ctx, walletAddrB, s.acctAddr, amtB1)
|
||||
results <- &withdrawResult{
|
||||
ws: sentinelB1,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Wallet B: Withdraw 3
|
||||
sentinelB2, err := s.fm.Withdraw(s.ctx, walletAddrB, s.acctAddr, amtB2)
|
||||
results <- &withdrawResult{
|
||||
ws: sentinelB2,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
// Withdrawals are queued up
|
||||
<-queueReady
|
||||
|
||||
// Should withdraw from wallet A first
|
||||
resA1 := <-results
|
||||
sentinelA1 := resA1.ws
|
||||
msg := s.mockApi.getSentMessage(sentinelA1)
|
||||
checkWithdrawMessageFields(t, msg, walletAddrA, s.acctAddr, amtA1)
|
||||
|
||||
// Complete wallet A message
|
||||
s.mockApi.completeMsg(sentinelA1)
|
||||
|
||||
resB1 := <-results
|
||||
resB2 := <-results
|
||||
require.NoError(t, resB1.err)
|
||||
require.NoError(t, resB2.err)
|
||||
sentinelB1 := resB1.ws
|
||||
sentinelB2 := resB2.ws
|
||||
|
||||
// Should send different message for wallet B from wallet A
|
||||
require.NotEqual(t, sentinelA1, sentinelB1)
|
||||
// Should be single message combining amount 1 and 2
|
||||
require.Equal(t, sentinelB1, sentinelB2)
|
||||
msg = s.mockApi.getSentMessage(sentinelB1)
|
||||
checkWithdrawMessageFields(t, msg, walletAddrB, s.acctAddr, types.BigAdd(amtB1, amtB2))
|
||||
}
|
||||
|
||||
// TestFundManagerRestart verifies that waiting for incomplete requests resumes
|
||||
// on restart
|
||||
func TestFundManagerRestart(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
acctAddr2 := tutils.NewActorAddr(t, "addr2")
|
||||
|
||||
// Address 1: Reserve 10
|
||||
amt := abi.NewTokenAmount(10)
|
||||
sentinelAddr1, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
msg := s.mockApi.getSentMessage(sentinelAddr1)
|
||||
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
|
||||
|
||||
// Address 2: Reserve 7
|
||||
amt2 := abi.NewTokenAmount(7)
|
||||
sentinelAddr2Res7, err := s.fm.Reserve(s.ctx, s.walletAddr, acctAddr2, amt2)
|
||||
require.NoError(t, err)
|
||||
|
||||
msg2 := s.mockApi.getSentMessage(sentinelAddr2Res7)
|
||||
checkAddMessageFields(t, msg2, s.walletAddr, acctAddr2, amt2)
|
||||
|
||||
// Complete "Address 1: Reserve 10"
|
||||
s.mockApi.completeMsg(sentinelAddr1)
|
||||
|
||||
// Give the completed state a moment to be stored before restart
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
|
||||
// Restart
|
||||
mockApiAfter := s.mockApi
|
||||
fmAfter := newFundManager(mockApiAfter, s.ds)
|
||||
err = fmAfter.Start()
|
||||
require.NoError(t, err)
|
||||
|
||||
amt3 := abi.NewTokenAmount(9)
|
||||
reserveSentinel := make(chan cid.Cid)
|
||||
go func() {
|
||||
// Address 2: Reserve 9
|
||||
sentinel3, err := fmAfter.Reserve(s.ctx, s.walletAddr, acctAddr2, amt3)
|
||||
require.NoError(t, err)
|
||||
reserveSentinel <- sentinel3
|
||||
}()
|
||||
|
||||
// Expect no message to be sent, because still waiting for previous
|
||||
// message "Address 2: Reserve 7" to complete on-chain
|
||||
select {
|
||||
case <-reserveSentinel:
|
||||
require.Fail(t, "Expected no message to be sent")
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
}
|
||||
|
||||
// Complete "Address 2: Reserve 7"
|
||||
mockApiAfter.completeMsg(sentinelAddr2Res7)
|
||||
|
||||
// Expect waiting message to now be sent
|
||||
sentinel3 := <-reserveSentinel
|
||||
msg3 := mockApiAfter.getSentMessage(sentinel3)
|
||||
checkAddMessageFields(t, msg3, s.walletAddr, acctAddr2, amt3)
|
||||
}
|
||||
|
||||
// TestFundManagerReleaseAfterPublish verifies that release is successful in
|
||||
// the following scenario:
|
||||
// 1. Deal A adds 5 to addr1: reserved 0 -> 5 available 0 -> 5
|
||||
// 2. Deal B adds 7 to addr1: reserved 5 -> 12 available 5 -> 12
|
||||
// 3. Deal B completes, reducing addr1 by 7: reserved 12 available 12 -> 5
|
||||
// 4. Deal A releases 5 from addr1: reserved 12 -> 7 available 5
|
||||
func TestFundManagerReleaseAfterPublish(t *testing.T) {
|
||||
s := setup(t)
|
||||
defer s.fm.Stop()
|
||||
|
||||
// Deal A: Reserve 5
|
||||
// balance: 0 -> 5
|
||||
// reserved: 0 -> 5
|
||||
amt := abi.NewTokenAmount(5)
|
||||
sentinel, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Deal B: Reserve 7
|
||||
// balance: 5 -> 12
|
||||
// reserved: 5 -> 12
|
||||
amt = abi.NewTokenAmount(7)
|
||||
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
s.mockApi.completeMsg(sentinel)
|
||||
|
||||
// Deal B: Publish (removes Deal B amount from balance)
|
||||
// balance: 12 -> 5
|
||||
// reserved: 12
|
||||
amt = abi.NewTokenAmount(7)
|
||||
s.mockApi.publish(s.acctAddr, amt)
|
||||
|
||||
// Deal A: Release 5
|
||||
// balance: 5
|
||||
// reserved: 12 -> 7
|
||||
amt = abi.NewTokenAmount(5)
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Deal B: Release 7
|
||||
// balance: 5
|
||||
// reserved: 12 -> 7
|
||||
amt = abi.NewTokenAmount(5)
|
||||
err = s.fm.Release(s.acctAddr, amt)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
type scaffold struct {
|
||||
ctx context.Context
|
||||
ds *ds_sync.MutexDatastore
|
||||
wllt *wallet.LocalWallet
|
||||
walletAddr address.Address
|
||||
acctAddr address.Address
|
||||
mockApi *mockFundManagerAPI
|
||||
fm *FundManager
|
||||
}
|
||||
|
||||
func setup(t *testing.T) *scaffold {
|
||||
ctx := context.Background()
|
||||
|
||||
wllt, err := wallet.NewWallet(wallet.NewMemKeyStore())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
walletAddr, err := wllt.WalletNew(context.Background(), types.KTSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
acctAddr := tutils.NewActorAddr(t, "addr")
|
||||
|
||||
mockApi := newMockFundManagerAPI(walletAddr)
|
||||
dstore := ds_sync.MutexWrap(ds.NewMapDatastore())
|
||||
fm := newFundManager(mockApi, dstore)
|
||||
return &scaffold{
|
||||
ctx: ctx,
|
||||
ds: dstore,
|
||||
wllt: wllt,
|
||||
walletAddr: walletAddr,
|
||||
acctAddr: acctAddr,
|
||||
mockApi: mockApi,
|
||||
fm: fm,
|
||||
}
|
||||
}
|
||||
|
||||
func checkAddMessageFields(t *testing.T, msg *types.Message, from address.Address, to address.Address, amt abi.TokenAmount) {
|
||||
require.Equal(t, from, msg.From)
|
||||
require.Equal(t, market.Address, msg.To)
|
||||
require.Equal(t, amt, msg.Value)
|
||||
|
||||
var paramsTo address.Address
|
||||
err := paramsTo.UnmarshalCBOR(bytes.NewReader(msg.Params))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, to, paramsTo)
|
||||
}
|
||||
|
||||
func checkWithdrawMessageFields(t *testing.T, msg *types.Message, from address.Address, addr address.Address, amt abi.TokenAmount) {
|
||||
require.Equal(t, from, msg.From)
|
||||
require.Equal(t, market.Address, msg.To)
|
||||
require.Equal(t, abi.NewTokenAmount(0), msg.Value)
|
||||
|
||||
var params market.WithdrawBalanceParams
|
||||
err := params.UnmarshalCBOR(bytes.NewReader(msg.Params))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, addr, params.ProviderOrClientAddress)
|
||||
require.Equal(t, amt, params.Amount)
|
||||
}
|
||||
|
||||
type sentMsg struct {
|
||||
msg *types.SignedMessage
|
||||
ready chan struct{}
|
||||
}
|
||||
|
||||
type mockFundManagerAPI struct {
|
||||
wallet address.Address
|
||||
|
||||
lk sync.Mutex
|
||||
escrow map[address.Address]abi.TokenAmount
|
||||
sentMsgs map[cid.Cid]*sentMsg
|
||||
completedMsgs map[cid.Cid]struct{}
|
||||
waitingFor map[cid.Cid]chan struct{}
|
||||
}
|
||||
|
||||
func newMockFundManagerAPI(wallet address.Address) *mockFundManagerAPI {
|
||||
return &mockFundManagerAPI{
|
||||
wallet: wallet,
|
||||
escrow: make(map[address.Address]abi.TokenAmount),
|
||||
sentMsgs: make(map[cid.Cid]*sentMsg),
|
||||
completedMsgs: make(map[cid.Cid]struct{}),
|
||||
waitingFor: make(map[cid.Cid]chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) MpoolPushMessage(ctx context.Context, message *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
|
||||
mapi.lk.Lock()
|
||||
defer mapi.lk.Unlock()
|
||||
|
||||
smsg := &types.SignedMessage{Message: *message}
|
||||
mapi.sentMsgs[smsg.Cid()] = &sentMsg{msg: smsg, ready: make(chan struct{})}
|
||||
|
||||
return smsg, nil
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) getSentMessage(c cid.Cid) *types.Message {
|
||||
mapi.lk.Lock()
|
||||
defer mapi.lk.Unlock()
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
if pending, ok := mapi.sentMsgs[c]; ok {
|
||||
return &pending.msg.Message
|
||||
}
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
panic("expected message to be sent")
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) messageCount() int {
|
||||
mapi.lk.Lock()
|
||||
defer mapi.lk.Unlock()
|
||||
|
||||
return len(mapi.sentMsgs)
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) completeMsg(msgCid cid.Cid) {
|
||||
mapi.lk.Lock()
|
||||
|
||||
pmsg, ok := mapi.sentMsgs[msgCid]
|
||||
if ok {
|
||||
if pmsg.msg.Message.Method == market.Methods.AddBalance {
|
||||
var escrowAcct address.Address
|
||||
err := escrowAcct.UnmarshalCBOR(bytes.NewReader(pmsg.msg.Message.Params))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
escrow := mapi.getEscrow(escrowAcct)
|
||||
before := escrow
|
||||
escrow = types.BigAdd(escrow, pmsg.msg.Message.Value)
|
||||
mapi.escrow[escrowAcct] = escrow
|
||||
log.Debugf("%s: escrow %d -> %d", escrowAcct, before, escrow)
|
||||
} else {
|
||||
var params market.WithdrawBalanceParams
|
||||
err := params.UnmarshalCBOR(bytes.NewReader(pmsg.msg.Message.Params))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
escrowAcct := params.ProviderOrClientAddress
|
||||
|
||||
escrow := mapi.getEscrow(escrowAcct)
|
||||
before := escrow
|
||||
escrow = types.BigSub(escrow, params.Amount)
|
||||
mapi.escrow[escrowAcct] = escrow
|
||||
log.Debugf("%s: escrow %d -> %d", escrowAcct, before, escrow)
|
||||
}
|
||||
}
|
||||
|
||||
mapi.completedMsgs[msgCid] = struct{}{}
|
||||
|
||||
ready, ok := mapi.waitingFor[msgCid]
|
||||
|
||||
mapi.lk.Unlock()
|
||||
|
||||
if ok {
|
||||
close(ready)
|
||||
}
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) StateMarketBalance(ctx context.Context, a address.Address, key types.TipSetKey) (api.MarketBalance, error) {
|
||||
mapi.lk.Lock()
|
||||
defer mapi.lk.Unlock()
|
||||
|
||||
return api.MarketBalance{
|
||||
Locked: abi.NewTokenAmount(0),
|
||||
Escrow: mapi.getEscrow(a),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) getEscrow(a address.Address) abi.TokenAmount {
|
||||
escrow := mapi.escrow[a]
|
||||
if escrow.Nil() {
|
||||
return abi.NewTokenAmount(0)
|
||||
}
|
||||
return escrow
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) publish(addr address.Address, amt abi.TokenAmount) {
|
||||
mapi.lk.Lock()
|
||||
defer mapi.lk.Unlock()
|
||||
|
||||
escrow := mapi.escrow[addr]
|
||||
if escrow.Nil() {
|
||||
return
|
||||
}
|
||||
escrow = types.BigSub(escrow, amt)
|
||||
if escrow.LessThan(abi.NewTokenAmount(0)) {
|
||||
escrow = abi.NewTokenAmount(0)
|
||||
}
|
||||
mapi.escrow[addr] = escrow
|
||||
}
|
||||
|
||||
func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
res := &api.MsgLookup{
|
||||
Message: c,
|
||||
Receipt: types.MessageReceipt{
|
||||
ExitCode: 0,
|
||||
Return: nil,
|
||||
},
|
||||
}
|
||||
ready := make(chan struct{})
|
||||
|
||||
mapi.lk.Lock()
|
||||
_, ok := mapi.completedMsgs[c]
|
||||
if !ok {
|
||||
mapi.waitingFor[c] = ready
|
||||
}
|
||||
mapi.lk.Unlock()
|
||||
|
||||
if !ok {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-ready:
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user