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 | ||
|
|
8f35a5c036 | ||
|
|
dea7042668 | ||
|
|
bd8f3f05be | ||
|
|
304d835739 | ||
|
|
0f53eca883 | ||
|
|
cb8678e4c2 | ||
|
|
da34548a05 | ||
|
|
cd9af278b4 | ||
|
|
b1fe92f8ff | ||
|
|
8dd8892b81 | ||
|
|
79dba816c7 | ||
|
|
14bb4c9a0b | ||
|
|
f9f54819d4 | ||
|
|
d1555106a4 | ||
|
|
413c357361 | ||
|
|
d97eb10349 | ||
|
|
e8253d22c6 | ||
|
|
4cc1fcb37b | ||
|
|
a4e954197c | ||
|
|
8f4911ac0d | ||
|
|
b0bea5f145 | ||
|
|
7c7e0d73d5 | ||
|
|
1fea550ce5 | ||
|
|
9b7b6146eb | ||
|
|
dab1107f5b | ||
|
|
fe912223bd | ||
|
|
12cd478e11 | ||
|
|
ae3691e0a2 | ||
|
|
e55b00f358 | ||
|
|
de3f4111f4 | ||
|
|
767c346cf8 | ||
|
|
6f4a762664 | ||
|
|
c02daca9e9 | ||
|
|
cca17f6078 | ||
|
|
c17fa4bc35 | ||
|
|
e803cf151f | ||
|
|
1268cfbfcd | ||
|
|
5ef929f130 | ||
|
|
5bd6a3cdad | ||
|
|
df4b068d0e | ||
|
|
0d34881a0c | ||
|
|
44af7e43b6 | ||
|
|
6eb49b717f | ||
|
|
099b982ea8 | ||
|
|
10c120bd3c | ||
|
|
7cd1330acd | ||
|
|
39bc816a79 | ||
|
|
81fb552e1d | ||
|
|
cfd126ee9f | ||
|
|
d6fa644974 | ||
|
|
d3dc560f53 | ||
|
|
673de6aeb6 | ||
|
|
25bc00eec8 | ||
|
|
bf959e45fb | ||
|
|
3b12a9f425 | ||
|
|
b7c8f65af5 | ||
|
|
c6e0cb4ff2 | ||
|
|
f6eb530cba | ||
|
|
ce247bcab3 | ||
|
|
f4991e868e | ||
|
|
0ec2a10ebc | ||
|
|
be92dd9e63 | ||
|
|
e90ca96289 | ||
|
|
c23f1623a1 | ||
|
|
839d1121ce | ||
|
|
a98b0f18fc | ||
|
|
15670942c3 | ||
|
|
74016ab1cc | ||
|
|
bd474617ed | ||
|
|
087030fe37 | ||
|
|
2a6e05b776 | ||
|
|
fe1ef154cf | ||
|
|
2f70a91665 | ||
|
|
60ad339033 | ||
|
|
00187d4aa8 | ||
|
|
dfaabb4596 | ||
|
|
0edecbd043 | ||
|
|
4d6a0f7b8c | ||
|
|
5043247958 | ||
|
|
282c99bdbd | ||
|
|
9857e42206 | ||
|
|
6919ff3881 | ||
|
|
d9fad5fad0 | ||
|
|
757aa1039f | ||
|
|
b71b743420 | ||
|
|
8739b938db | ||
|
|
4a3081c77a | ||
|
|
b1818a1055 | ||
|
|
256be285ba | ||
|
|
4a6e9c920d | ||
|
|
d4cbd4fb55 | ||
|
|
15330396bb | ||
|
|
6b3ffdbd3d | ||
|
|
0017ea8fd0 | ||
|
|
2bf42d5318 | ||
|
|
a179cadf0e | ||
|
|
405aba4d8f | ||
|
|
7b556252db | ||
|
|
7a80e356de | ||
|
|
c53cef1526 | ||
|
|
4a9155ba85 | ||
|
|
1a170e18ad | ||
|
|
f8c886a611 | ||
|
|
b5907c665b | ||
|
|
ba25806fbd | ||
|
|
d02fc08ca4 | ||
|
|
de390749fc | ||
|
|
3672f2cc44 | ||
|
|
14ad91c53f | ||
|
|
f55b18eabe | ||
|
|
c920257a33 | ||
|
|
0e2f697217 | ||
|
|
16243b97aa | ||
|
|
89b88c1e0d | ||
|
|
8cdf078999 | ||
|
|
70d88f226e | ||
|
|
937d7fcca9 | ||
|
|
c8822fc9b6 | ||
|
|
dd1661c0b1 | ||
|
|
e9417562e0 | ||
|
|
40f4266070 | ||
|
|
6d25f3d2ae | ||
|
|
1e78cd21ec | ||
|
|
17846aad2f | ||
|
|
bd0633ff90 | ||
|
|
9621dbb4f1 | ||
|
|
c55b9baf37 | ||
|
|
1227bf2893 | ||
|
|
550f3771ea | ||
|
|
f8b2022f82 | ||
|
|
5a08b881d6 | ||
|
|
8bcc201fc0 | ||
|
|
420c44ed2c | ||
|
|
b6500beaab | ||
|
|
d0c52535a6 | ||
|
|
4be8964062 | ||
|
|
feb85a272c | ||
|
|
fee84c4b44 | ||
|
|
b9f8831aaf | ||
|
|
a5b57068d4 | ||
|
|
7c3f622fae | ||
|
|
140671599c | ||
|
|
ed03202c1d | ||
|
|
0162a485d8 | ||
|
|
97087fe576 | ||
|
|
e3269770d8 | ||
|
|
0fee5dab8a | ||
|
|
921d78f820 | ||
|
|
1fc23fb466 | ||
|
|
306dfaa11f | ||
|
|
8fe8da6f4c | ||
|
|
4631cee564 | ||
|
|
8292d60196 | ||
|
|
f6ccab1c6c | ||
|
|
6aba3e3b94 | ||
|
|
863a6ed38c | ||
|
|
f1e5e9fe72 | ||
|
|
a57288a4b9 | ||
|
|
c5de617af6 | ||
|
|
bd964b4c3e | ||
|
|
5e256be81e | ||
|
|
04db9ea72d | ||
|
|
6f33706025 | ||
|
|
44e352cd8e | ||
|
|
1319d7072e | ||
|
|
ef3987e2ab | ||
|
|
f147072284 | ||
|
|
43bd7cb055 | ||
|
|
a3a3df9b30 | ||
|
|
d3effe52a5 | ||
|
|
0591bac768 | ||
|
|
db91d22a8a | ||
|
|
fecc1ee0ef | ||
|
|
3bebdb3882 | ||
|
|
73b9fe36e3 | ||
|
|
2c1ef3708e | ||
|
|
53cc1f18d0 | ||
|
|
e848c13ff1 | ||
|
|
6b5f8a6b1d | ||
|
|
8fe8a5df45 | ||
|
|
a572bef8b2 | ||
|
|
ed86ac14a1 | ||
|
|
101d07f704 | ||
|
|
8ad8a945fb | ||
|
|
e865ba0c64 | ||
|
|
1cc0f74744 | ||
|
|
efc1b24f4e | ||
|
|
078044153f | ||
|
|
9b4274638c | ||
|
|
1253a5600e | ||
|
|
bceb880ee2 | ||
|
|
15885ad535 | ||
|
|
ec7282ff09 | ||
|
|
738efe3f9a | ||
|
|
e444977891 | ||
|
|
5c33982f72 | ||
|
|
44747446a9 | ||
|
|
d7ec5e3618 | ||
|
|
9b5a0815fc | ||
|
|
deac7166b5 | ||
|
|
c8a3269c4b | ||
|
|
2dc9a1ee4e | ||
|
|
d20ebe93b9 | ||
|
|
6875527224 | ||
|
|
889dd3cb3f | ||
|
|
594ec8855c | ||
|
|
e2ecc35dff | ||
|
|
9dc75a7bc4 | ||
|
|
3d91633699 | ||
|
|
93e4eae94c | ||
|
|
6f0453c581 | ||
|
|
60d442e36a | ||
|
|
1ebad94da9 | ||
|
|
636810daa5 | ||
|
|
5932f28519 | ||
|
|
196bf39574 | ||
|
|
954d806367 | ||
|
|
7699f195f1 | ||
|
|
6981f776f4 | ||
|
|
1b7cdb9341 | ||
|
|
47a83b422e | ||
|
|
5e08d56630 | ||
|
|
9705b25bbd | ||
|
|
9d59635b42 | ||
|
|
42d5d8d784 | ||
|
|
486812e082 | ||
|
|
6825a485eb | ||
|
|
8091bb3117 | ||
|
|
8dcbd525da | ||
|
|
35e606d397 | ||
|
|
99fe63716b | ||
|
|
941c1947be | ||
|
|
feecee310d | ||
|
|
b01a1d457a | ||
|
|
79d2ddf24f | ||
|
|
2cfe22d4e5 | ||
|
|
e3ee4e4718 | ||
|
|
2e9915ac28 | ||
|
|
be884e27be | ||
|
|
2d16af6ee6 | ||
|
|
4f97d9637e | ||
|
|
5253c0d959 | ||
|
|
4c60d7b5ce | ||
|
|
23b729a056 | ||
|
|
724306c110 | ||
|
|
4989b1cc90 | ||
|
|
c228598098 | ||
|
|
a783bf9b8b | ||
|
|
54fdd6ba5a | ||
|
|
6ddea62d09 | ||
|
|
6855284d88 | ||
|
|
46a5beafe4 | ||
|
|
5bffea6f54 | ||
|
|
1c4f8e83d7 | ||
|
|
ff8663faa0 | ||
|
|
f58881e966 | ||
|
|
d2f279c3de | ||
|
|
4d4bab12eb | ||
|
|
eb6191d0ff | ||
|
|
54dfeb1fd9 | ||
|
|
c2c64caefe | ||
|
|
90be8d801b | ||
|
|
430897c9ac | ||
|
|
c77ab47cb5 | ||
|
|
bc85e3ce50 | ||
|
|
76b1ec1de0 | ||
|
|
6abccc4d5e | ||
|
|
7a3a2f8db9 | ||
|
|
4e8ccb2158 | ||
|
|
1affd498c1 | ||
|
|
e250429f56 | ||
|
|
bc4cbdc895 | ||
|
|
a388bcfad6 | ||
|
|
e39c5dc372 | ||
|
|
c45c8f34a1 | ||
|
|
73d193bd9c | ||
|
|
a4e7117429 | ||
|
|
9fe32b7777 | ||
|
|
6025bceaa1 | ||
|
|
91d04ede0f | ||
|
|
237c8c4deb | ||
|
|
0ba911279a | ||
|
|
baef3c8dd2 | ||
|
|
867ca2f25d | ||
|
|
247a5e2c49 | ||
|
|
7e8c6e5070 | ||
|
|
0d914ac1d4 | ||
|
|
76db65b1af | ||
|
|
ff8c0af8c8 | ||
|
|
55c6b88537 | ||
|
|
0771c23fb0 | ||
|
|
1c6214b76d | ||
|
|
b7f18b4601 | ||
|
|
242a77b391 | ||
|
|
35cf69ae64 | ||
|
|
ebc8489ff1 | ||
|
|
f21c5cbbe2 | ||
|
|
01386a206c | ||
|
|
3858309368 | ||
|
|
782717948a | ||
|
|
108fe7823c | ||
|
|
12a0dd3d0a | ||
|
|
1f4d1dcc58 | ||
|
|
53ab17cf50 | ||
|
|
79ba4598d6 | ||
|
|
96193c2044 | ||
|
|
09e5cc90a4 | ||
|
|
edf1875e88 | ||
|
|
1479142047 | ||
|
|
d1c10a61dd | ||
|
|
8205149675 | ||
|
|
eaece306b6 | ||
|
|
0f2dcf28b1 | ||
|
|
be9d23b329 | ||
|
|
dd65e57d4b | ||
|
|
e658ab3287 | ||
|
|
c0e190344d | ||
|
|
1c03862854 | ||
|
|
2315db161b | ||
|
|
9344bc4e9b | ||
|
|
01272f850d | ||
|
|
b95b871943 | ||
|
|
a314cfd237 | ||
|
|
c0b316fd9c | ||
|
|
3e6323a503 | ||
|
|
d1000e38d7 | ||
|
|
044674487e | ||
|
|
0070d2716c | ||
|
|
9b403e26e5 | ||
|
|
4b3b35c9de | ||
|
|
c88d124954 | ||
|
|
233d8a9b72 | ||
|
|
52e064dabb | ||
|
|
1a7fb06dd9 | ||
|
|
bc7f20e179 | ||
|
|
6fcf57ed1f | ||
|
|
ca9448bc11 | ||
|
|
2049daa008 | ||
|
|
1e6a69f8aa | ||
|
|
9bd2537971 | ||
|
|
947d1e2902 | ||
|
|
5f3160cf5b | ||
|
|
64f24fd276 | ||
|
|
bf554d0e43 | ||
|
|
810c767200 | ||
|
|
124bd0c765 | ||
|
|
4ba7af6061 | ||
|
|
4b61f1756e | ||
|
|
2633198e6c | ||
|
|
b84cc46c3d | ||
|
|
86cf3c835e | ||
|
|
96f882860f | ||
|
|
cfe6f595b0 | ||
|
|
6b16d48bad | ||
|
|
9f6862a456 | ||
|
|
4c9717187f | ||
|
|
a0dffb44d3 | ||
|
|
8f3be78667 | ||
|
|
dfdcbd184d | ||
|
|
9e7d6823b1 | ||
|
|
f05a40feed | ||
|
|
aa7090df49 | ||
|
|
f809529699 | ||
|
|
a3145bae07 | ||
|
|
a9d1ca4d83 | ||
|
|
b14afba859 | ||
|
|
c33b3dfa55 | ||
|
|
c448d85cf5 | ||
|
|
bc495a5c8c | ||
|
|
18dac6d415 | ||
|
|
5a72662d26 | ||
|
|
b479988044 | ||
|
|
a2d24b5b33 | ||
|
|
9a355c4bc5 | ||
|
|
fe869c9c22 | ||
|
|
f5f23f7291 | ||
|
|
a712c109d8 | ||
|
|
e5c56da321 | ||
|
|
be5dc2c57f | ||
|
|
e4c1f090af | ||
|
|
400af0d2fa | ||
|
|
41ab87e904 | ||
|
|
7a14455ac8 | ||
|
|
04876c663e | ||
|
|
70071e273d | ||
|
|
fb3bcc4ce5 | ||
|
|
1483f1e59a | ||
|
|
10cdbadd82 | ||
|
|
8955b8d8a7 | ||
|
|
1c5cb50da3 | ||
|
|
bddd6dd8a8 | ||
|
|
cf71f034dc | ||
|
|
650725d71e | ||
|
|
c243378cab | ||
|
|
e15065b142 | ||
|
|
71fa198eee | ||
|
|
ca1715616f | ||
|
|
b12bade989 | ||
|
|
28566b4d64 | ||
|
|
dfd1473384 | ||
|
|
3fe0aa5026 | ||
|
|
6a502090f4 | ||
|
|
3d40fb294e | ||
|
|
81a30cbf06 | ||
|
|
2c1d96bcaa | ||
|
|
45eadc1b3a | ||
|
|
b453b8da99 | ||
|
|
567261e2c7 | ||
|
|
12e97dbea7 | ||
|
|
ef28ebb14a | ||
|
|
8545c08f30 | ||
|
|
eaf3424938 | ||
|
|
a5f13a5b31 | ||
|
|
d8431ff611 | ||
|
|
4eec4a0141 | ||
|
|
6db6a90b1e | ||
|
|
a13d10e42d | ||
|
|
271ceb968a | ||
|
|
b8d9d7894f | ||
|
|
7d3bd146e6 | ||
|
|
8b35f480c4 | ||
|
|
d9656f5220 | ||
|
|
87351fa35c | ||
|
|
edb31e606a | ||
|
|
8806f27220 | ||
|
|
858f11992f | ||
|
|
35562bd2f9 | ||
|
|
ebad0ded3d | ||
|
|
60e43ccbb1 | ||
|
|
ddcbcdea48 | ||
|
|
3491e7b707 | ||
|
|
bdc782617f | ||
|
|
1a7aea1906 | ||
|
|
3207bc4704 | ||
|
|
60e950015c | ||
|
|
80a7ed8116 | ||
|
|
13b38815c2 | ||
|
|
9dfce400a7 | ||
|
|
4ff38aa856 | ||
|
|
e5873d5dea | ||
|
|
8fbbebbaf1 | ||
|
|
89bfe84f36 | ||
|
|
585b8cc51d | ||
|
|
08fc0b7aec | ||
|
|
a8fcb86c10 | ||
|
|
306c098d30 | ||
|
|
6db37b72a8 | ||
|
|
80ee3be4d0 | ||
|
|
e48c525053 | ||
|
|
cf9dfdb972 | ||
|
|
6ca5308c82 | ||
|
|
68663060dc | ||
|
|
87b48c94a6 | ||
|
|
45d8cb08ba | ||
|
|
130ae3ccb3 | ||
|
|
4eaa05db52 | ||
|
|
a19023fada | ||
|
|
85caa48814 | ||
|
|
cdda66a154 | ||
|
|
f8f335df55 | ||
|
|
28b46ad08c | ||
|
|
43323b2188 | ||
|
|
17a84c9a2c | ||
|
|
48b7945714 | ||
|
|
c507f409a5 | ||
|
|
7eb9bec13f | ||
|
|
2867b31d2b | ||
|
|
3c524ac0e0 | ||
|
|
1a70dd4fb4 | ||
|
|
15eddf0c96 | ||
|
|
72537b6614 | ||
|
|
c839c5721c | ||
|
|
bbcad52ce0 | ||
|
|
ded3a30f55 | ||
|
|
04ee53e061 | ||
|
|
38e256cece | ||
|
|
b4e03d1759 | ||
|
|
32a699d6a3 | ||
|
|
46f5b62a76 | ||
|
|
f57652524c | ||
|
|
d817dceb05 | ||
|
|
c17f0d7e61 | ||
|
|
3003789288 | ||
|
|
86c222ab58 | ||
|
|
a4ade158f4 | ||
|
|
f21ca8591c | ||
|
|
ce6b92484f | ||
|
|
80619fa8a0 | ||
|
|
9a0d5cd739 | ||
|
|
6185e157e9 | ||
|
|
04ad1791b0 | ||
|
|
bb5cc06677 | ||
|
|
c66f087f4c | ||
|
|
706f4f2ef5 | ||
|
|
36b8a017bd | ||
|
|
001ba17d37 | ||
|
|
b8865fb182 | ||
|
|
03c3d8bdb3 | ||
|
|
aa5bd7bc17 | ||
|
|
ad3db0e83c | ||
|
|
a5e7fd8f5c | ||
|
|
e6bbc03ca8 | ||
|
|
e39036dd49 | ||
|
|
26de0db757 | ||
|
|
9e2df907f8 | ||
|
|
3c72461969 | ||
|
|
dfd28ab0c4 | ||
|
|
784399738a | ||
|
|
bc9232544c | ||
|
|
591e32af48 | ||
|
|
a4fd356fcb | ||
|
|
6849d18b03 | ||
|
|
1c9257d537 | ||
|
|
ea56e56ec1 | ||
|
|
17680fff55 | ||
|
|
d9d644b27f | ||
|
|
5e09581256 | ||
|
|
ed7423b2b5 | ||
|
|
77a956cda4 | ||
|
|
a9253837ac | ||
|
|
63f903a3fb | ||
|
|
f702ce331a | ||
|
|
ca956ca57e | ||
|
|
b1361aaf8b | ||
|
|
8b7e7d438c | ||
|
|
097d82535d | ||
|
|
6670d22fb5 | ||
|
|
2ca1d111c5 | ||
|
|
b20f558abb | ||
|
|
c2148ba106 | ||
|
|
e53aee26a3 | ||
|
|
03cf6cca40 | ||
|
|
20a0f7ac68 | ||
|
|
6cff57ab43 | ||
|
|
e9d25e5919 | ||
|
|
381a6cdfac | ||
|
|
1ebca8f732 | ||
|
|
172204c933 | ||
|
|
77000db747 | ||
|
|
6563a68ae2 | ||
|
|
c610bd818e | ||
|
|
d9bcdfe61b | ||
|
|
5f08fe7ead | ||
|
|
d3f6657032 | ||
|
|
554570f884 | ||
|
|
231a9e4051 | ||
|
|
9e6f974f3c | ||
|
|
06e3852cef | ||
|
|
5d73943929 | ||
|
|
159ce13f5e | ||
|
|
780f6dba34 | ||
|
|
f90cfda2e6 | ||
|
|
bd0c6a4ccc | ||
|
|
af38c902f8 | ||
|
|
a153e1d586 | ||
|
|
fe52c47570 | ||
|
|
6b63fa379f | ||
|
|
485f13de12 | ||
|
|
7f3ba0e6eb | ||
|
|
f58e8bc9a3 | ||
|
|
cac848c106 | ||
|
|
ed12b83b4e | ||
|
|
6be293e848 | ||
|
|
9cebb09a5f | ||
|
|
f6f3ffc254 | ||
|
|
e4daadbfcf | ||
|
|
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:
|
executors:
|
||||||
golang:
|
golang:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.14.6
|
- image: circleci/golang:1.15.5
|
||||||
resource_class: 2xlarge
|
resource_class: 2xlarge
|
||||||
ubuntu:
|
ubuntu:
|
||||||
docker:
|
docker:
|
||||||
@@ -34,7 +34,7 @@ commands:
|
|||||||
condition: << parameters.linux >>
|
condition: << parameters.linux >>
|
||||||
steps:
|
steps:
|
||||||
- run: sudo apt-get update
|
- 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 sync
|
||||||
- run: git submodule update --init
|
- run: git submodule update --init
|
||||||
download-params:
|
download-params:
|
||||||
@@ -188,6 +188,14 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
bash <(curl -s https://codecov.io/bash)
|
bash <(curl -s https://codecov.io/bash)
|
||||||
|
|
||||||
|
test-chain:
|
||||||
|
<<: *test
|
||||||
|
test-node:
|
||||||
|
<<: *test
|
||||||
|
test-storage:
|
||||||
|
<<: *test
|
||||||
|
test-cli:
|
||||||
|
<<: *test
|
||||||
test-short:
|
test-short:
|
||||||
<<: *test
|
<<: *test
|
||||||
test-window-post:
|
test-window-post:
|
||||||
@@ -256,22 +264,44 @@ jobs:
|
|||||||
path: /tmp/test-artifacts/conformance-coverage.html
|
path: /tmp/test-artifacts/conformance-coverage.html
|
||||||
build-lotus-soup:
|
build-lotus-soup:
|
||||||
description: |
|
description: |
|
||||||
Compile `lotus-soup` Testground test plan using the current version of Lotus.
|
Compile `lotus-soup` Testground test plan
|
||||||
parameters:
|
parameters:
|
||||||
<<: *test-params
|
<<: *test-params
|
||||||
executor: << parameters.executor >>
|
executor: << parameters.executor >>
|
||||||
steps:
|
steps:
|
||||||
- install-deps
|
- install-deps
|
||||||
- prepare
|
- prepare
|
||||||
- run: cd extern/oni && git submodule sync
|
|
||||||
- run: cd extern/oni && git submodule update --init
|
|
||||||
- run: cd extern/filecoin-ffi && make
|
- 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:
|
- run:
|
||||||
name: "build lotus-soup testplan"
|
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:
|
build-macos:
|
||||||
@@ -286,8 +316,8 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Install go
|
name: Install go
|
||||||
command: |
|
command: |
|
||||||
curl -O https://dl.google.com/go/go1.14.2.darwin-amd64.pkg && \
|
curl -O https://dl.google.com/go/go1.15.5.darwin-amd64.pkg && \
|
||||||
sudo installer -pkg go1.14.2.darwin-amd64.pkg -target /
|
sudo installer -pkg go1.15.5.darwin-amd64.pkg -target /
|
||||||
- run:
|
- run:
|
||||||
name: Install pkg-config
|
name: Install pkg-config
|
||||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config
|
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config
|
||||||
@@ -351,6 +381,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- install-deps
|
- install-deps
|
||||||
- prepare
|
- prepare
|
||||||
|
- run: make deps
|
||||||
- run: make docsgen
|
- run: make docsgen
|
||||||
- run: git --no-pager diff
|
- run: git --no-pager diff
|
||||||
- run: git --no-pager diff --quiet
|
- run: git --no-pager diff --quiet
|
||||||
@@ -428,6 +459,22 @@ workflows:
|
|||||||
- test:
|
- test:
|
||||||
codecov-upload: true
|
codecov-upload: true
|
||||||
test-suite-name: full
|
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:
|
- test-window-post:
|
||||||
go-test-flags: "-run=TestWindowedPost"
|
go-test-flags: "-run=TestWindowedPost"
|
||||||
winpost-test: "1"
|
winpost-test: "1"
|
||||||
@@ -448,6 +495,11 @@ workflows:
|
|||||||
packages: "./conformance"
|
packages: "./conformance"
|
||||||
vectors-branch: master
|
vectors-branch: master
|
||||||
- build-lotus-soup
|
- build-lotus-soup
|
||||||
|
- trigger-testplans:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
- build-debug
|
- build-debug
|
||||||
- build-all:
|
- build-all:
|
||||||
requires:
|
requires:
|
||||||
|
|||||||
+5
-1
@@ -1,5 +1,9 @@
|
|||||||
comment: off
|
comment: off
|
||||||
ignore:
|
ignore:
|
||||||
- "cbor_gen.go"
|
- "**/cbor_gen.go"
|
||||||
|
- "api/test/**/*"
|
||||||
|
- "api/test/*"
|
||||||
|
- "gen/**/*"
|
||||||
|
- "gen/*"
|
||||||
github_checks:
|
github_checks:
|
||||||
annotations: false
|
annotations: false
|
||||||
|
|||||||
@@ -13,3 +13,4 @@
|
|||||||
### Conformance testing.
|
### Conformance testing.
|
||||||
conformance/ @raulk
|
conformance/ @raulk
|
||||||
extern/test-vectors @raulk
|
extern/test-vectors @raulk
|
||||||
|
cmd/tvx @raulk
|
||||||
@@ -12,6 +12,8 @@
|
|||||||
/lotus-bench
|
/lotus-bench
|
||||||
/lotus-gateway
|
/lotus-gateway
|
||||||
/lotus-pcr
|
/lotus-pcr
|
||||||
|
/lotus-wallet
|
||||||
|
/lotus-keygen
|
||||||
/bench.json
|
/bench.json
|
||||||
/lotuspond/front/node_modules
|
/lotuspond/front/node_modules
|
||||||
/lotuspond/front/build
|
/lotuspond/front/build
|
||||||
|
|||||||
+4
-8
@@ -1,16 +1,12 @@
|
|||||||
[submodule "extern/filecoin-ffi"]
|
[submodule "extern/filecoin-ffi"]
|
||||||
path = extern/filecoin-ffi
|
path = extern/filecoin-ffi
|
||||||
url = https://github.com/filecoin-project/filecoin-ffi.git
|
url = https://github.com/filecoin-project/filecoin-ffi.git
|
||||||
branch = master
|
|
||||||
[submodule "extern/serialization-vectors"]
|
[submodule "extern/serialization-vectors"]
|
||||||
path = 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"]
|
[submodule "extern/test-vectors"]
|
||||||
path = extern/test-vectors
|
path = extern/test-vectors
|
||||||
url = https://github.com/filecoin-project/test-vectors.git
|
url = https://github.com/filecoin-project/test-vectors.git
|
||||||
[submodule "extern/fil-blst"]
|
[submodule "extern/blst"]
|
||||||
path = extern/fil-blst
|
path = extern/blst
|
||||||
url = https://github.com/filecoin-project/fil-blst.git
|
url = https://github.com/supranational/blst.git
|
||||||
[submodule "extern/oni"]
|
|
||||||
path = extern/oni
|
|
||||||
url = https://github.com/filecoin-project/oni
|
|
||||||
|
|||||||
+686
@@ -1,5 +1,691 @@
|
|||||||
# Lotus changelog
|
# 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:
|
||||||
|
|
||||||
|
- Introducing v2 actors and its migration (https://github.com/filecoin-project/lotus/pull/3936)
|
||||||
|
- Runtime's Receiver() should only return ID addresses (https://github.com/filecoin-project/lotus/pull/3589)
|
||||||
|
- Update miner eligibility checks for v2 actors (https://github.com/filecoin-project/lotus/pull/4188)
|
||||||
|
- Add funds that have left FilReserve to circ supply (https://github.com/filecoin-project/lotus/pull/4160)
|
||||||
|
- Set WinningPoStSectorSetLookback to finality post-v2 actors (https://github.com/filecoin-project/lotus/pull/4190)
|
||||||
|
- fix: error when actor panics directly (https://github.com/filecoin-project/lotus/pull/3697)
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
#### Dependencies
|
||||||
|
|
||||||
|
- Update go-bitfield (https://github.com/filecoin-project/lotus/pull/4171)
|
||||||
|
- update the AMT implementation (https://github.com/filecoin-project/lotus/pull/4194)
|
||||||
|
- Update to actors v0.2.1 (https://github.com/filecoin-project/lotus/pull/4199)
|
||||||
|
|
||||||
|
#### Core Lotus
|
||||||
|
|
||||||
|
- Paych: fix voucher amount verification (https://github.com/filecoin-project/lotus/pull/3821)
|
||||||
|
- Cap market provider messages (https://github.com/filecoin-project/lotus/pull/4141)
|
||||||
|
- Run fork function after cron for null block safety (https://github.com/filecoin-project/lotus/pull/4114)
|
||||||
|
- use bitswap sessions when fetching messages, and cancel them (https://github.com/filecoin-project/lotus/pull/4142)
|
||||||
|
- relax pubsub IPColocationFactorThreshold to 5 (https://github.com/filecoin-project/lotus/pull/4183)
|
||||||
|
- Support addresses with mainnet prefixes (https://github.com/filecoin-project/lotus/pull/4186)
|
||||||
|
- fix: make message signer nonce generation transactional (https://github.com/filecoin-project/lotus/pull/4165)
|
||||||
|
- build: Env var to keep test address output (https://github.com/filecoin-project/lotus/pull/4213)
|
||||||
|
- make vm.EnableGasTracing public (https://github.com/filecoin-project/lotus/pull/4214)
|
||||||
|
- introduce separate state-tree versions (https://github.com/filecoin-project/lotus/pull/4197)
|
||||||
|
- reject explicit "calls" at the upgrade height (https://github.com/filecoin-project/lotus/pull/4231)
|
||||||
|
- return an illegal actor error when we see an unsupported actor version (https://github.com/filecoin-project/lotus/pull/4232)
|
||||||
|
- Set head should unmark blocks as valid (https://gist.github.com/travisperson/3c7cddd77a33979a519ccef4e6515f20)
|
||||||
|
|
||||||
|
#### Mining
|
||||||
|
|
||||||
|
- Increased ExpectedSealDuration and and WaitDealsDelay (https://github.com/filecoin-project/lotus/pull/3743)
|
||||||
|
- Miner backup/restore commands (https://github.com/filecoin-project/lotus/pull/4133)
|
||||||
|
- lotus-miner: add more help text to storage / attach (https://github.com/filecoin-project/lotus/pull/3961)
|
||||||
|
- Reject deals that are > 7 days in the future in the BasicDealFilter (https://github.com/filecoin-project/lotus/pull/4173)
|
||||||
|
- feat(miner): add miner deadline diffing logic (https://github.com/filecoin-project/lotus/pull/4178)
|
||||||
|
|
||||||
|
#### UX
|
||||||
|
|
||||||
|
- Improve the UX for replacing messages (https://github.com/filecoin-project/lotus/pull/4134)
|
||||||
|
- Add verified flag to interactive deal creation (https://github.com/filecoin-project/lotus/pull/4145)
|
||||||
|
- Add command to (slowly) prune lotus chain datastore (https://github.com/filecoin-project/lotus/pull/3876)
|
||||||
|
- Some helpers for verifreg work (https://github.com/filecoin-project/lotus/pull/4124)
|
||||||
|
- Always use default 720h for setask duration and hide the duration param option (https://github.com/filecoin-project/lotus/pull/4077)
|
||||||
|
- Convert ID addresses to key addresses before checking wallet (https://github.com/filecoin-project/lotus/pull/4122)
|
||||||
|
- add a command to view block space utilization (https://github.com/filecoin-project/lotus/pull/4176)
|
||||||
|
- allow usage inspection on a chain segment (https://github.com/filecoin-project/lotus/pull/4177)
|
||||||
|
- Add mpool stats for base fee (https://github.com/filecoin-project/lotus/pull/4170)
|
||||||
|
- Add verified status to api.DealInfo (https://github.com/filecoin-project/lotus/pull/4153)
|
||||||
|
- Add a CLI command to set a miner's owner address (https://github.com/filecoin-project/lotus/pull/4189)
|
||||||
|
|
||||||
|
#### Tooling and validation
|
||||||
|
|
||||||
|
- Lotus-pcr: add recover-miners command (https://github.com/filecoin-project/lotus/pull/3714)
|
||||||
|
- MpoolPushUntrusted API for gateway (https://github.com/filecoin-project/lotus/pull/3915)
|
||||||
|
- Test lotus-miner info all (https://github.com/filecoin-project/lotus/pull/4166)
|
||||||
|
- chain export: Error with unfinished exports (https://github.com/filecoin-project/lotus/pull/4179)
|
||||||
|
- add printf in TestWindowPost (https://github.com/filecoin-project/lotus/pull/4043)
|
||||||
|
- add trace wdpost (https://github.com/filecoin-project/lotus/pull/4020)
|
||||||
|
- Fix noncefix (https://github.com/filecoin-project/lotus/pull/4202)
|
||||||
|
- Lotus-pcr: Limit the fee cap of messages we will process, refund gas fees for windowed post and storage deals (https://github.com/filecoin-project/lotus/pull/4198)
|
||||||
|
- Fix pond (https://github.com/filecoin-project/lotus/pull/4203)
|
||||||
|
- allow manual setting of noncefix fee cap (https://github.com/filecoin-project/lotus/pull/4205)
|
||||||
|
- implement command to get execution traces of any message (https://github.com/filecoin-project/lotus/pull/4200)
|
||||||
|
- conformance: minor driver refactors (https://github.com/filecoin-project/lotus/pull/4211)
|
||||||
|
- lotus-pcr: ignore all other messages (https://github.com/filecoin-project/lotus/pull/4218)
|
||||||
|
- lotus-pcr: zero refund (https://github.com/filecoin-project/lotus/pull/4229)
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
The following contributors had 5 or more commits go into this release.
|
||||||
|
We are grateful for every contribution!
|
||||||
|
|
||||||
|
| Contributor | Commits | Lines ± |
|
||||||
|
|--------------------|---------|---------------|
|
||||||
|
| Stebalien | 84 | +3425/-2287 |
|
||||||
|
| magik6k | 41 | +2121/-506 |
|
||||||
|
| arajasek | 39 | +2467/-424 |
|
||||||
|
| Kubuxu | 25 | +2344/-775 |
|
||||||
|
| raulk | 21 | +287/-196 |
|
||||||
|
| whyrusleeping | 13 | +727/-71 |
|
||||||
|
| hsanjuan | 13 | +5886/-7956 |
|
||||||
|
| dirkmc | 11 | +2634/-576 |
|
||||||
|
| travisperson | 8 | +923/-202 |
|
||||||
|
| ribasushi | 6 | +188/-128 |
|
||||||
|
| zgfzgf | 5 | +21/-17 |
|
||||||
|
|
||||||
|
# 0.8.1 / 2020-09-30
|
||||||
|
|
||||||
|
This optional release of Lotus introduces a new version of markets which switches to CBOR-map encodings, and allows datastore migrations. The release also introduces several improvements to the mining process, a few performance optimizations, and a battery of UX additions and enhancements.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
#### Dependencies
|
||||||
|
|
||||||
|
- Markets 0.7.0 with updated data stores (https://github.com/filecoin-project/lotus/pull/4089)
|
||||||
|
- Update ffi to code with blst fixes (https://github.com/filecoin-project/lotus/pull/3998)
|
||||||
|
|
||||||
|
#### Core Lotus
|
||||||
|
|
||||||
|
- Fix GetPower with no miner address (https://github.com/filecoin-project/lotus/pull/4049)
|
||||||
|
- Refactor: Move nonce generation out of mpool (https://github.com/filecoin-project/lotus/pull/3970)
|
||||||
|
|
||||||
|
#### Performance
|
||||||
|
|
||||||
|
- Implement caching syscalls for import-bench (https://github.com/filecoin-project/lotus/pull/3888)
|
||||||
|
- Fetch tipset blocks in parallel (https://github.com/filecoin-project/lotus/pull/4074)
|
||||||
|
- Optimize Tipset equals() (https://github.com/filecoin-project/lotus/pull/4056)
|
||||||
|
- Make state transition in validation async (https://github.com/filecoin-project/lotus/pull/3868)
|
||||||
|
|
||||||
|
#### Mining
|
||||||
|
|
||||||
|
- Add trace window post (https://github.com/filecoin-project/lotus/pull/4020)
|
||||||
|
- Use abstract types for Dont recompute post on revert (https://github.com/filecoin-project/lotus/pull/4022)
|
||||||
|
- Fix injectNulls logic in test miner (https://github.com/filecoin-project/lotus/pull/4058)
|
||||||
|
- Fix potential panic in FinalizeSector (https://github.com/filecoin-project/lotus/pull/4092)
|
||||||
|
- Don't recompute post on revert (https://github.com/filecoin-project/lotus/pull/3924)
|
||||||
|
- Fix some failed precommit handling (https://github.com/filecoin-project/lotus/pull/3445)
|
||||||
|
- Add --no-swap flag for worker (https://github.com/filecoin-project/lotus/pull/4107)
|
||||||
|
- Allow some single-thread tasks to run in parallel with PC2/C2 (https://github.com/filecoin-project/lotus/pull/4116)
|
||||||
|
|
||||||
|
#### UX
|
||||||
|
|
||||||
|
- Add an envvar to set address network version (https://github.com/filecoin-project/lotus/pull/4028)
|
||||||
|
- Add logging to chain export (https://github.com/filecoin-project/lotus/pull/4030)
|
||||||
|
- Add JSON output to state compute (https://github.com/filecoin-project/lotus/pull/4038)
|
||||||
|
- Wallet list CLI: Print balances/nonces (https://github.com/filecoin-project/lotus/pull/4088)
|
||||||
|
- Added an option to show or not show sector info for `lotus-miner info` (https://github.com/filecoin-project/lotus/pull/4003)
|
||||||
|
- Add a command to import an ipld object into the chainstore (https://github.com/filecoin-project/lotus/pull/3434)
|
||||||
|
- Improve the lotus-shed dealtracker (https://github.com/filecoin-project/lotus/pull/4051)
|
||||||
|
- Docs review and re-organization (https://github.com/filecoin-project/lotus/pull/3431)
|
||||||
|
- Fix wallet list (https://github.com/filecoin-project/lotus/pull/4104)
|
||||||
|
- Add an endpoint to validate whether a string is a well-formed address (https://github.com/filecoin-project/lotus/pull/4106)
|
||||||
|
- Add an option to set config path (https://github.com/filecoin-project/lotus/pull/4103)
|
||||||
|
- Add printf in TestWindowPost (https://github.com/filecoin-project/lotus/pull/4043)
|
||||||
|
- Improve miner sectors list UX (https://github.com/filecoin-project/lotus/pull/4108)
|
||||||
|
|
||||||
|
#### Tooling
|
||||||
|
|
||||||
|
- Move policy change to seal bench (https://github.com/filecoin-project/lotus/pull/4032)
|
||||||
|
- Add back network power to stats (https://github.com/filecoin-project/lotus/pull/4050)
|
||||||
|
- Conformance: Record and feed circulating supply (https://github.com/filecoin-project/lotus/pull/4078)
|
||||||
|
- Snapshot import progress bar, add HTTP support (https://github.com/filecoin-project/lotus/pull/4070)
|
||||||
|
- Add lotus shed util to validate a tipset (https://github.com/filecoin-project/lotus/pull/4065)
|
||||||
|
- tvx: a test vector extraction and execution tool (https://github.com/filecoin-project/lotus/pull/4064)
|
||||||
|
|
||||||
|
#### Bootstrap
|
||||||
|
|
||||||
|
- Add new bootstrappers (https://github.com/filecoin-project/lotus/pull/4007)
|
||||||
|
- Add Glif node to bootstrap peers (https://github.com/filecoin-project/lotus/pull/4004)
|
||||||
|
- Add one more node located in China (https://github.com/filecoin-project/lotus/pull/4041)
|
||||||
|
- Add ipfsmain bootstrapper (https://github.com/filecoin-project/lotus/pull/4067)
|
||||||
|
|
||||||
|
# 0.8.0 / 2020-09-26
|
||||||
|
|
||||||
|
This consensus-breaking release of Lotus introduces an upgrade to the network. The changes that break consensus are:
|
||||||
|
|
||||||
|
- Upgrading to specs-actors v0.9.11, which reduces WindowPoSt faults per [FIP 0002](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0002.md) to reduce cost for honest miners with occasional faults (see https://github.com/filecoin-project/specs-actors/pull/1181)
|
||||||
|
- Revisions to some cryptoeconomics and network params
|
||||||
|
|
||||||
|
This release also updates go-fil-markets to fix an incompatibility issue between v0.7.2 and earlier versions.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
#### Dependencies
|
||||||
|
|
||||||
|
- Update spec actors to 0.9.11 (https://github.com/filecoin-project/lotus/pull/4039)
|
||||||
|
- Update markets to 0.6.3 (https://github.com/filecoin-project/lotus/pull/4013)
|
||||||
|
|
||||||
|
#### Core Lotus
|
||||||
|
|
||||||
|
- Network upgrade (https://github.com/filecoin-project/lotus/pull/4039)
|
||||||
|
- Fix AddSupportedProofTypes (https://github.com/filecoin-project/lotus/pull/4033)
|
||||||
|
- Return an error when we fail to find a sector when checking sector expiration (https://github.com/filecoin-project/lotus/pull/4026)
|
||||||
|
- Batch blockstore copies after block validation (https://github.com/filecoin-project/lotus/pull/3980)
|
||||||
|
- Remove a misleading miner actor abstraction (https://github.com/filecoin-project/lotus/pull/3977)
|
||||||
|
- Fix out-of-bounds when loading all sector infos (https://github.com/filecoin-project/lotus/pull/3976)
|
||||||
|
- Fix break condition in the miner (https://github.com/filecoin-project/lotus/pull/3953)
|
||||||
|
|
||||||
|
#### UX
|
||||||
|
|
||||||
|
- Correct helptext around miners setting ask (https://github.com/filecoin-project/lotus/pull/4009)
|
||||||
|
- Make sync wait nicer (https://github.com/filecoin-project/lotus/pull/3991)
|
||||||
|
|
||||||
|
#### Tooling and validation
|
||||||
|
|
||||||
|
- Small adjustments following network upgradability changes (https://github.com/filecoin-project/lotus/pull/3996)
|
||||||
|
- Add some more big pictures stats to stateroot stat (https://github.com/filecoin-project/lotus/pull/3995)
|
||||||
|
- Add some actors policy setters for testing (https://github.com/filecoin-project/lotus/pull/3975)
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
The following contributors had 5 or more commits go into this release.
|
||||||
|
We are grateful for every contribution!
|
||||||
|
|
||||||
|
| Contributor | Commits | Lines ± |
|
||||||
|
|--------------------|---------|---------------|
|
||||||
|
| arajasek | 66 | +3140/-1261 |
|
||||||
|
| Stebalien | 64 | +3797/-3434 |
|
||||||
|
| magik6k | 48 | +1892/-976 |
|
||||||
|
| raulk | 40 | +2412/-1549 |
|
||||||
|
| vyzo | 22 | +287/-196 |
|
||||||
|
| alanshaw | 15 | +761/-146 |
|
||||||
|
| whyrusleeping | 15 | +736/-52 |
|
||||||
|
| hannahhoward | 14 | +1237/-837 |
|
||||||
|
| anton | 6 | +32/-8 |
|
||||||
|
| travisperson | 5 | +502/-6 |
|
||||||
|
| Frank | 5 | +78/-39 |
|
||||||
|
| Jennifer | 5 | +148/-41 |
|
||||||
|
|
||||||
# 0.7.2 / 2020-09-23
|
# 0.7.2 / 2020-09-23
|
||||||
|
|
||||||
This optional release of Lotus introduces a major refactor around how a Lotus node interacts with code from the specs-actors repo. We now use interfaces to read the state of actors, which is required to be able to reason about different versions of actors code at the same time.
|
This optional release of Lotus introduces a major refactor around how a Lotus node interacts with code from the specs-actors repo. We now use interfaces to read the state of actors, which is required to be able to reason about different versions of actors code at the same time.
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ all: build
|
|||||||
|
|
||||||
unexport GOFLAGS
|
unexport GOFLAGS
|
||||||
|
|
||||||
GOVERSION:=$(shell go version | cut -d' ' -f 3 | cut -d. -f 2)
|
GOVERSION:=$(shell go version | cut -d' ' -f 3 | sed 's/^go//' | awk -F. '{printf "%d%03d%03d", $$1, $$2, $$3}')
|
||||||
ifeq ($(shell expr $(GOVERSION) \< 14), 1)
|
ifeq ($(shell expr $(GOVERSION) \< 1015005), 1)
|
||||||
$(warning Your Golang version is go 1.$(GOVERSION))
|
$(warning Your Golang version is go$(shell expr $(GOVERSION) / 1000000).$(shell expr $(GOVERSION) % 1000000 / 1000).$(shell expr $(GOVERSION) % 1000))
|
||||||
$(error Update Golang to version $(shell grep '^go' go.mod))
|
$(error Update Golang to version to at least 1.15.5)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# git modules that need to be loaded
|
# git modules that need to be loaded
|
||||||
@@ -133,18 +133,30 @@ benchmarks:
|
|||||||
|
|
||||||
lotus-pond: 2k
|
lotus-pond: 2k
|
||||||
go build -o lotus-pond ./lotuspond
|
go build -o lotus-pond ./lotuspond
|
||||||
(cd lotuspond/front && npm i && CI=false npm run build)
|
|
||||||
.PHONY: lotus-pond
|
.PHONY: lotus-pond
|
||||||
BINS+=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:
|
lotus-townhall:
|
||||||
rm -f lotus-townhall
|
rm -f lotus-townhall
|
||||||
go build -o lotus-townhall ./cmd/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
|
.PHONY: lotus-townhall
|
||||||
BINS+=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:
|
lotus-fountain:
|
||||||
rm -f lotus-fountain
|
rm -f lotus-fountain
|
||||||
go build -o lotus-fountain ./cmd/lotus-fountain
|
go build -o lotus-fountain ./cmd/lotus-fountain
|
||||||
@@ -167,7 +179,7 @@ BINS+=lotus-bench
|
|||||||
|
|
||||||
lotus-stats:
|
lotus-stats:
|
||||||
rm -f 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
|
go run github.com/GeertJohan/go.rice/rice append --exec lotus-stats -i ./build
|
||||||
.PHONY: lotus-stats
|
.PHONY: lotus-stats
|
||||||
BINS+=lotus-stats
|
BINS+=lotus-stats
|
||||||
@@ -186,6 +198,18 @@ lotus-health:
|
|||||||
.PHONY: lotus-health
|
.PHONY: lotus-health
|
||||||
BINS+=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:
|
testground:
|
||||||
go build -tags testground -o /dev/null ./cmd/lotus
|
go build -tags testground -o /dev/null ./cmd/lotus
|
||||||
.PHONY: testground
|
.PHONY: testground
|
||||||
@@ -286,7 +310,9 @@ method-gen:
|
|||||||
gen: type-gen method-gen
|
gen: type-gen method-gen
|
||||||
|
|
||||||
docsgen:
|
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-%:
|
print-%:
|
||||||
@echo $*=$($*)
|
@echo $*=$($*)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://lotu.sh/" title="Lotus Docs">
|
<a href="https://docs.filecoin.io/" title="Filecoin Docs">
|
||||||
<img src="documentation/images/lotus_logo_h.png" alt="Project Lotus Logo" width="244" />
|
<img src="documentation/images/lotus_logo_h.png" alt="Project Lotus Logo" width="244" />
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -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://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://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="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>
|
<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more
|
|||||||
|
|
||||||
## Building & Documentation
|
## Building & Documentation
|
||||||
|
|
||||||
For instructions on how to build lotus from source, please visit [Lotus build and setup instruction](https://docs.filecoin.io/get-started/lotus/installation/#minimal-requirements) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
|
For instructions on how to build, install and setup lotus, please visit [https://docs.filecoin.io/get-started/lotus](https://docs.filecoin.io/get-started/lotus/).
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
|||||||
+3
-9
@@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
For *critical* bugs, please send an email to security@filecoin.org.
|
For *critical* bugs, please consult our Security Policy and Responsible Disclosure Program information at https://github.com/filecoin-project/community/blob/master/SECURITY.md
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
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.
|
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'.
|
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.
|
For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
|
||||||
|
|
||||||
| Version | Supported |
|
|
||||||
| ------- | ------------------ |
|
|
||||||
| Testnet | :white_check_mark: |
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||||
"github.com/libp2p/go-libp2p-core/network"
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
@@ -44,6 +46,11 @@ type Common interface {
|
|||||||
// usage and current rate per protocol
|
// usage and current rate per protocol
|
||||||
NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error)
|
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
|
// MethodGroup: Common
|
||||||
|
|
||||||
// ID returns peerID of libp2p node backing this API
|
// ID returns peerID of libp2p node backing this API
|
||||||
@@ -58,6 +65,9 @@ type Common interface {
|
|||||||
// trigger graceful shutdown
|
// trigger graceful shutdown
|
||||||
Shutdown(context.Context) error
|
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)
|
Closing(context.Context) (<-chan struct{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+151
-24
@@ -2,9 +2,11 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@@ -172,10 +174,16 @@ type FullNode interface {
|
|||||||
// SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
// SyncUnmarkBad unmarks a blocks as bad, making it possible to be validated and synced again.
|
||||||
SyncUnmarkBad(ctx context.Context, bcid cid.Cid) error
|
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
|
// SyncCheckBad checks if a block was marked as bad, and if it was, returns
|
||||||
// the reason.
|
// the reason.
|
||||||
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
|
||||||
|
|
||||||
|
// SyncValidateTipset indicates whether the provided tipset is valid or not
|
||||||
|
SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error)
|
||||||
|
|
||||||
// MethodGroup: Mpool
|
// MethodGroup: Mpool
|
||||||
// The Mpool methods are for interacting with the message pool. The message pool
|
// The Mpool methods are for interacting with the message pool. The message pool
|
||||||
// manages all incoming and outgoing 'messages' going over the network.
|
// manages all incoming and outgoing 'messages' going over the network.
|
||||||
@@ -189,6 +197,9 @@ type FullNode interface {
|
|||||||
// MpoolPush pushes a signed message to mempool.
|
// MpoolPush pushes a signed message to mempool.
|
||||||
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||||
|
|
||||||
|
// MpoolPushUntrusted pushes a signed message to mempool from untrusted sources.
|
||||||
|
MpoolPushUntrusted(context.Context, *types.SignedMessage) (cid.Cid, error)
|
||||||
|
|
||||||
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
|
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
|
||||||
// to mempool.
|
// to mempool.
|
||||||
// maxFee is only used when GasFeeCap/GasPremium fields aren't specified
|
// maxFee is only used when GasFeeCap/GasPremium fields aren't specified
|
||||||
@@ -197,6 +208,15 @@ type FullNode interface {
|
|||||||
// based on current chain conditions
|
// based on current chain conditions
|
||||||
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
|
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.
|
// MpoolGetNonce gets next nonce for the specified sender.
|
||||||
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
||||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||||
@@ -220,7 +240,9 @@ type FullNode interface {
|
|||||||
// MethodGroup: Wallet
|
// MethodGroup: Wallet
|
||||||
|
|
||||||
// WalletNew creates a new address in the wallet with the given sigType.
|
// 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 indicates whether the given address is in the wallet.
|
||||||
WalletHas(context.Context, address.Address) (bool, error)
|
WalletHas(context.Context, address.Address) (bool, error)
|
||||||
// WalletList lists all the addresses in the wallet.
|
// WalletList lists all the addresses in the wallet.
|
||||||
@@ -244,6 +266,8 @@ type FullNode interface {
|
|||||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
||||||
// WalletDelete deletes an address from the wallet.
|
// WalletDelete deletes an address from the wallet.
|
||||||
WalletDelete(context.Context, address.Address) error
|
WalletDelete(context.Context, address.Address) error
|
||||||
|
// WalletValidateAddress validates whether a given string can be decoded as a well-formed address
|
||||||
|
WalletValidateAddress(context.Context, string) (address.Address, error)
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
@@ -263,6 +287,8 @@ type FullNode interface {
|
|||||||
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
ClientListDeals(ctx context.Context) ([]DealInfo, error)
|
||||||
// ClientGetDealUpdates returns the status of updated deals
|
// ClientGetDealUpdates returns the status of updated deals
|
||||||
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error)
|
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 indicates whether a certain CID is locally stored.
|
||||||
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
|
||||||
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
|
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
|
||||||
@@ -275,7 +301,9 @@ type FullNode interface {
|
|||||||
// of status updates.
|
// of status updates.
|
||||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
|
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
|
||||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
||||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error)
|
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 calculates the CommP for a specified file
|
||||||
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
|
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
|
||||||
// ClientGenCar generates a CAR file for the specified file.
|
// ClientGenCar generates a CAR file for the specified file.
|
||||||
@@ -285,6 +313,10 @@ type FullNode interface {
|
|||||||
// ClientListTransfers returns the status of all ongoing transfers of data
|
// ClientListTransfers returns the status of all ongoing transfers of data
|
||||||
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
||||||
ClientDataTransferUpdates(ctx context.Context) (<-chan 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
|
// ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel
|
||||||
// which are stuck due to insufficient funds
|
// which are stuck due to insufficient funds
|
||||||
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
|
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
|
||||||
@@ -299,19 +331,22 @@ type FullNode interface {
|
|||||||
|
|
||||||
// MethodGroup: State
|
// MethodGroup: State
|
||||||
// The State methods are used to query, inspect, and interact with chain 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.
|
// 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 runs the given message and returns its result without any persisted changes.
|
||||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
|
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)
|
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
||||||
// StateGetActor returns the indicated actor's nonce and balance.
|
// StateGetActor returns the indicated actor's nonce and balance.
|
||||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||||
// StateReadState returns the indicated actor's state.
|
// StateReadState returns the indicated actor's state.
|
||||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
|
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 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 returns the name of the network the node is synced to
|
||||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||||
@@ -342,6 +377,8 @@ type FullNode interface {
|
|||||||
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
|
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 returns the portion of a miner's balance that can be withdrawn or spent
|
||||||
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
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 returns the PreCommit info for the specified miner's sector
|
||||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
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
|
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
|
||||||
@@ -354,11 +391,13 @@ type FullNode interface {
|
|||||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
|
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 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)
|
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
|
// 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.
|
// message arrives on chain, and gets to the indicated confidence depth.
|
||||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
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 returns the addresses of every miner that has claimed power in the Power Actor
|
||||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||||
// StateListActors returns the addresses of every actor in the state
|
// StateListActors returns the addresses of every actor in the state
|
||||||
@@ -385,16 +424,26 @@ type FullNode interface {
|
|||||||
// StateCompute is a flexible command that applies the given messages on the given tipset.
|
// StateCompute is a flexible command that applies the given messages on the given tipset.
|
||||||
// The messages are run as though the VM were at the provided height.
|
// The messages are run as though the VM were at the provided height.
|
||||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error)
|
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*ComputeStateOutput, error)
|
||||||
|
// StateVerifierStatus returns the data cap for the given address.
|
||||||
|
// Returns nil if there is no entry in the data cap table for the
|
||||||
|
// address.
|
||||||
|
StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||||
// StateVerifiedClientStatus returns the data cap for the given address.
|
// StateVerifiedClientStatus returns the data cap for the given address.
|
||||||
// Returns nil if there is no entry in the data cap table for the
|
// Returns nil if there is no entry in the data cap table for the
|
||||||
// address.
|
// address.
|
||||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||||
|
// StateVerifiedClientStatus returns the address of the Verified Registry's root key
|
||||||
|
StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error)
|
||||||
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
|
// StateDealProviderCollateralBounds returns the min and max collateral a storage provider
|
||||||
// can issue. It takes the deal size and verified status as parameters.
|
// can issue. It takes the deal size and verified status as parameters.
|
||||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
||||||
|
|
||||||
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
|
// StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
|
||||||
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
// 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 returns the network version at the given tipset
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||||
|
|
||||||
@@ -404,6 +453,8 @@ type FullNode interface {
|
|||||||
|
|
||||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
// 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)
|
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.
|
// 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>
|
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
||||||
@@ -415,12 +466,21 @@ type FullNode interface {
|
|||||||
// It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
// 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>
|
// <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)
|
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>,
|
// 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>
|
// <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
|
// 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>
|
// <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)
|
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
|
// MsigAddPropose proposes adding a signer in the multisig
|
||||||
@@ -448,8 +508,19 @@ type FullNode interface {
|
|||||||
// <old signer>, <new signer>
|
// <old signer>, <new signer>
|
||||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error)
|
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)
|
// MsigRemoveSigner proposes the removal of a signer from the multisig.
|
||||||
// MarketFreeBalance
|
// 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
|
// MethodGroup: Paych
|
||||||
// The Paych methods are for interacting with and managing payment channels
|
// The Paych methods are for interacting with and managing payment channels
|
||||||
@@ -470,6 +541,12 @@ type FullNode interface {
|
|||||||
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
||||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
|
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
|
||||||
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error)
|
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error)
|
||||||
|
|
||||||
|
// CreateBackup creates node backup onder the specified file name. The
|
||||||
|
// method requires that the lotus daemon is running with the
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileRef struct {
|
type FileRef struct {
|
||||||
@@ -516,6 +593,10 @@ type DealInfo struct {
|
|||||||
DealID abi.DealID
|
DealID abi.DealID
|
||||||
|
|
||||||
CreationTime time.Time
|
CreationTime time.Time
|
||||||
|
Verified bool
|
||||||
|
|
||||||
|
TransferChannelID *datatransfer.ChannelID
|
||||||
|
DataTransfer *DataTransferChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgLookup struct {
|
type MsgLookup struct {
|
||||||
@@ -537,6 +618,8 @@ type MsgGasCost struct {
|
|||||||
TotalCost abi.TokenAmount
|
TotalCost abi.TokenAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlsMessages[x].cid = Cids[x]
|
||||||
|
// SecpkMessages[y].cid = Cids[BlsMessages.length + y]
|
||||||
type BlockMessages struct {
|
type BlockMessages struct {
|
||||||
BlsMessages []*types.Message
|
BlsMessages []*types.Message
|
||||||
SecpkMessages []*types.SignedMessage
|
SecpkMessages []*types.SignedMessage
|
||||||
@@ -682,8 +765,10 @@ type RetrievalOrder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InvocResult struct {
|
type InvocResult struct {
|
||||||
|
MsgCid cid.Cid
|
||||||
Msg *types.Message
|
Msg *types.Message
|
||||||
MsgRct *types.MessageReceipt
|
MsgRct *types.MessageReceipt
|
||||||
|
GasCost MsgGasCost
|
||||||
ExecutionTrace types.ExecutionTrace
|
ExecutionTrace types.ExecutionTrace
|
||||||
Error string
|
Error string
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
@@ -706,14 +791,31 @@ type StartDealParams struct {
|
|||||||
VerifiedDeal bool
|
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 {
|
type IpldObject struct {
|
||||||
Cid cid.Cid
|
Cid cid.Cid
|
||||||
Obj interface{}
|
Obj interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActiveSync struct {
|
type ActiveSync struct {
|
||||||
Base *types.TipSet
|
WorkerID uint64
|
||||||
Target *types.TipSet
|
Base *types.TipSet
|
||||||
|
Target *types.TipSet
|
||||||
|
|
||||||
Stage SyncStateStage
|
Stage SyncStateStage
|
||||||
Height abi.ChainEpoch
|
Height abi.ChainEpoch
|
||||||
@@ -725,6 +827,8 @@ type ActiveSync struct {
|
|||||||
|
|
||||||
type SyncState struct {
|
type SyncState struct {
|
||||||
ActiveSyncs []ActiveSync
|
ActiveSyncs []ActiveSync
|
||||||
|
|
||||||
|
VMApplied uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type SyncStateStage int
|
type SyncStateStage int
|
||||||
@@ -789,14 +893,14 @@ type CirculatingSupply struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MiningBaseInfo struct {
|
type MiningBaseInfo struct {
|
||||||
MinerPower types.BigInt
|
MinerPower types.BigInt
|
||||||
NetworkPower types.BigInt
|
NetworkPower types.BigInt
|
||||||
Sectors []builtin.SectorInfo
|
Sectors []builtin.SectorInfo
|
||||||
WorkerKey address.Address
|
WorkerKey address.Address
|
||||||
SectorSize abi.SectorSize
|
SectorSize abi.SectorSize
|
||||||
PrevBeaconEntry types.BeaconEntry
|
PrevBeaconEntry types.BeaconEntry
|
||||||
BeaconEntries []types.BeaconEntry
|
BeaconEntries []types.BeaconEntry
|
||||||
HasMinPower bool
|
EligibleForMining bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockTemplate struct {
|
type BlockTemplate struct {
|
||||||
@@ -816,6 +920,12 @@ type DataSize struct {
|
|||||||
PieceSize abi.PaddedPieceSize
|
PieceSize abi.PaddedPieceSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DataCIDSize struct {
|
||||||
|
PayloadSize int64
|
||||||
|
PieceSize abi.PaddedPieceSize
|
||||||
|
PieceCID cid.Cid
|
||||||
|
}
|
||||||
|
|
||||||
type CommPRet struct {
|
type CommPRet struct {
|
||||||
Root cid.Cid
|
Root cid.Cid
|
||||||
Size abi.UnpaddedPieceSize
|
Size abi.UnpaddedPieceSize
|
||||||
@@ -848,3 +958,20 @@ type Fault struct {
|
|||||||
Miner address.Address
|
Miner address.Address
|
||||||
Epoch abi.ChainEpoch
|
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)
|
||||||
|
}
|
||||||
+46
-3
@@ -5,13 +5,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"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/piecestore"
|
||||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"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/chain/types"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||||
@@ -25,6 +30,7 @@ type StorageMiner interface {
|
|||||||
ActorAddress(context.Context) (address.Address, error)
|
ActorAddress(context.Context) (address.Address, error)
|
||||||
|
|
||||||
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error)
|
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error)
|
||||||
|
ActorAddressConfig(ctx context.Context) (AddressConfig, error)
|
||||||
|
|
||||||
MiningBase(context.Context) (*types.TipSet, error)
|
MiningBase(context.Context) (*types.TipSet, error)
|
||||||
|
|
||||||
@@ -37,6 +43,12 @@ type StorageMiner interface {
|
|||||||
// List all staged sectors
|
// List all staged sectors
|
||||||
SectorsList(context.Context) ([]abi.SectorNumber, error)
|
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)
|
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
||||||
|
|
||||||
// SectorStartSealing can be called on sectors in Empty or WaitDeals states
|
// 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 tells the node to connect to workers RPC
|
||||||
WorkerConnect(context.Context, string) error
|
WorkerConnect(context.Context, string) error
|
||||||
WorkerStats(context.Context) (map[uint64]storiface.WorkerStats, error)
|
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error)
|
||||||
WorkerJobs(context.Context) (map[uint64][]storiface.WorkerJob, error)
|
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error)
|
||||||
|
storiface.WorkerReturn
|
||||||
|
|
||||||
// SealingSchedDiag dumps internal sealing scheduler state
|
// 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
|
stores.SectorIndex
|
||||||
|
|
||||||
@@ -81,6 +95,10 @@ type StorageMiner interface {
|
|||||||
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
|
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
|
||||||
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
|
||||||
MarketDataTransferUpdates(ctx context.Context) (<-chan 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
|
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||||
DealsList(ctx context.Context) ([]MarketDeal, error)
|
DealsList(ctx context.Context) ([]MarketDeal, error)
|
||||||
@@ -94,6 +112,10 @@ type StorageMiner interface {
|
|||||||
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error
|
DealsSetConsiderOfflineStorageDeals(context.Context, bool) error
|
||||||
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error)
|
DealsConsiderOfflineRetrievalDeals(context.Context) (bool, error)
|
||||||
DealsSetConsiderOfflineRetrievalDeals(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
|
StorageAddLocal(ctx context.Context, path string) error
|
||||||
|
|
||||||
@@ -101,6 +123,14 @@ type StorageMiner interface {
|
|||||||
PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error)
|
PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error)
|
||||||
PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error)
|
PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error)
|
||||||
PiecesGetCIDInfo(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error)
|
PiecesGetCIDInfo(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error)
|
||||||
|
|
||||||
|
// CreateBackup creates node backup onder the specified file name. The
|
||||||
|
// method requires that the lotus-miner is running with the
|
||||||
|
// 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 {
|
type SealRes struct {
|
||||||
@@ -180,3 +210,16 @@ func (st *SealSeed) Equals(ost *SealSeed) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorState string
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"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/sealtasks"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
)
|
)
|
||||||
@@ -23,18 +21,29 @@ type WorkerAPI interface {
|
|||||||
Paths(context.Context) ([]stores.StoragePath, error)
|
Paths(context.Context) ([]stores.StoragePath, error)
|
||||||
Info(context.Context) (storiface.WorkerInfo, 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
|
// Storage / Other
|
||||||
|
Remove(ctx context.Context, sector abi.SectorID) 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)
|
|
||||||
|
|
||||||
StorageAddLocal(ctx context.Context, path string) 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)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||||
return &out
|
return &out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PermissionedWalletAPI(a api.WalletAPI) api.WalletAPI {
|
||||||
|
var out WalletStruct
|
||||||
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||||
|
return &out
|
||||||
|
}
|
||||||
|
|||||||
+576
-109
File diff suppressed because it is too large
Load Diff
@@ -82,3 +82,29 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (
|
|||||||
|
|
||||||
return &res, closer, err
|
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/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-filestore"
|
"github.com/ipfs/go-filestore"
|
||||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||||
@@ -24,6 +26,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
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-fil-markets/retrievalmarket"
|
||||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
"github.com/filecoin-project/go-multistore"
|
"github.com/filecoin-project/go-multistore"
|
||||||
@@ -36,6 +39,10 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||||
|
"github.com/filecoin-project/lotus/extern/sector-storage/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"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,10 +90,11 @@ func init() {
|
|||||||
addExample(&pid)
|
addExample(&pid)
|
||||||
|
|
||||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1)
|
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1_1)
|
||||||
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
|
||||||
addExample(abi.ChainEpoch(10101))
|
addExample(abi.ChainEpoch(10101))
|
||||||
addExample(crypto.SigTypeBLS)
|
addExample(crypto.SigTypeBLS)
|
||||||
|
addExample(types.KTBLS)
|
||||||
addExample(int64(9))
|
addExample(int64(9))
|
||||||
addExample(12.3)
|
addExample(12.3)
|
||||||
addExample(123)
|
addExample(123)
|
||||||
@@ -116,17 +124,17 @@ func init() {
|
|||||||
addExample(network.ReachabilityPublic)
|
addExample(network.ReachabilityPublic)
|
||||||
addExample(build.NewestNetworkVersion)
|
addExample(build.NewestNetworkVersion)
|
||||||
addExample(&types.ExecutionTrace{
|
addExample(&types.ExecutionTrace{
|
||||||
Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
Msg: exampleValue("init", reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
MsgRct: exampleValue("init", reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||||
})
|
})
|
||||||
addExample(map[string]types.Actor{
|
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{
|
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{
|
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{
|
addExample(map[string]*pubsub.TopicScoreSnapshot{
|
||||||
"/blocks": {
|
"/blocks": {
|
||||||
@@ -161,9 +169,89 @@ func init() {
|
|||||||
// because reflect.TypeOf(maddr) returns the concrete type...
|
// because reflect.TypeOf(maddr) returns the concrete type...
|
||||||
ExampleValues[reflect.TypeOf(struct{ A multiaddr.Multiaddr }{}).Field(0).Type] = maddr
|
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]
|
v, ok := ExampleValues[t]
|
||||||
if ok {
|
if ok {
|
||||||
return v
|
return v
|
||||||
@@ -172,25 +260,25 @@ func exampleValue(t, parent reflect.Type) interface{} {
|
|||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
out := reflect.New(t).Elem()
|
out := reflect.New(t).Elem()
|
||||||
reflect.Append(out, reflect.ValueOf(exampleValue(t.Elem(), t)))
|
reflect.Append(out, reflect.ValueOf(exampleValue(method, t.Elem(), t)))
|
||||||
return out.Interface()
|
return out.Interface()
|
||||||
case reflect.Chan:
|
case reflect.Chan:
|
||||||
return exampleValue(t.Elem(), nil)
|
return exampleValue(method, t.Elem(), nil)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
es := exampleStruct(t, parent)
|
es := exampleStruct(method, t, parent)
|
||||||
v := reflect.ValueOf(es).Elem().Interface()
|
v := reflect.ValueOf(es).Elem().Interface()
|
||||||
ExampleValues[t] = v
|
ExampleValues[t] = v
|
||||||
return v
|
return v
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
out := reflect.New(t).Elem()
|
out := reflect.New(t).Elem()
|
||||||
for i := 0; i < t.Len(); i++ {
|
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()
|
return out.Interface()
|
||||||
|
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if t.Elem().Kind() == reflect.Struct {
|
if t.Elem().Kind() == reflect.Struct {
|
||||||
es := exampleStruct(t.Elem(), t)
|
es := exampleStruct(method, t.Elem(), t)
|
||||||
//ExampleValues[t] = es
|
//ExampleValues[t] = es
|
||||||
return es
|
return es
|
||||||
}
|
}
|
||||||
@@ -198,10 +286,10 @@ func exampleValue(t, parent reflect.Type) interface{} {
|
|||||||
return struct{}{}
|
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)
|
ns := reflect.New(t)
|
||||||
for i := 0; i < t.NumField(); i++ {
|
for i := 0; i < t.NumField(); i++ {
|
||||||
f := t.Field(i)
|
f := t.Field(i)
|
||||||
@@ -209,7 +297,7 @@ func exampleStruct(t, parent reflect.Type) interface{} {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.Title(f.Name) == f.Name {
|
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 {
|
type Visitor struct {
|
||||||
|
Root string
|
||||||
Methods map[string]ast.Node
|
Methods map[string]ast.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +315,7 @@ func (v *Visitor) Visit(node ast.Node) ast.Visitor {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
if st.Name.Name != "FullNode" {
|
if st.Name.Name != v.Root {
|
||||||
return nil
|
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."
|
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()
|
fset := token.NewFileSet()
|
||||||
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
pkgs, err := parser.ParseDir(fset, "./api", nil, parser.AllErrors|parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -251,11 +340,11 @@ func parseApiASTInfo() (map[string]string, map[string]string) { //nolint:golint
|
|||||||
|
|
||||||
ap := pkgs["api"]
|
ap := pkgs["api"]
|
||||||
|
|
||||||
f := ap.Files["api/api_full.go"]
|
f := ap.Files[apiFile]
|
||||||
|
|
||||||
cmap := ast.NewCommentMap(fset, f, f.Comments)
|
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"])
|
ast.Walk(v, pkgs["api"])
|
||||||
|
|
||||||
groupDocs := make(map[string]string)
|
groupDocs := make(map[string]string)
|
||||||
@@ -311,13 +400,30 @@ func methodGroupFromName(mn string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
comments, groupComments := parseApiASTInfo(os.Args[1], os.Args[2])
|
||||||
comments, groupComments := parseApiASTInfo()
|
|
||||||
|
|
||||||
groups := make(map[string]*MethodGroup)
|
groups := make(map[string]*MethodGroup)
|
||||||
|
|
||||||
var api struct{ api.FullNode }
|
var t reflect.Type
|
||||||
t := reflect.TypeOf(api)
|
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++ {
|
for i := 0; i < t.NumMethod(); i++ {
|
||||||
m := t.Method(i)
|
m := t.Method(i)
|
||||||
|
|
||||||
@@ -335,7 +441,7 @@ func main() {
|
|||||||
ft := m.Func.Type()
|
ft := m.Func.Type()
|
||||||
for j := 2; j < ft.NumIn(); j++ {
|
for j := 2; j < ft.NumIn(); j++ {
|
||||||
inp := ft.In(j)
|
inp := ft.In(j)
|
||||||
args = append(args, exampleValue(inp, nil))
|
args = append(args, exampleValue(m.Name, inp, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := json.MarshalIndent(args, "", " ")
|
v, err := json.MarshalIndent(args, "", " ")
|
||||||
@@ -343,7 +449,7 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
outv := exampleValue(ft.Out(0), nil)
|
outv := exampleValue(m.Name, ft.Out(0), nil)
|
||||||
|
|
||||||
ov, err := json.MarshalIndent(outv, "", " ")
|
ov, err := json.MarshalIndent(outv, "", " ")
|
||||||
if err != nil {
|
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 {
|
for _, g := range groupslice {
|
||||||
g := g
|
g := g
|
||||||
fmt.Printf("## %s\n", g.GroupName)
|
fmt.Printf("## %s\n", g.GroupName)
|
||||||
|
|||||||
@@ -37,7 +37,12 @@ func (bm *BlockMiner) MineBlocks() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer close(bm.done)
|
defer close(bm.done)
|
||||||
for atomic.LoadInt64(&bm.mine) == 1 {
|
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)
|
nulls := atomic.SwapInt64(&bm.nulls, 0)
|
||||||
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
|
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
|
||||||
InjectNulls: abi.ChainEpoch(nulls),
|
InjectNulls: abi.ChainEpoch(nulls),
|
||||||
|
|||||||
+31
-4
@@ -3,7 +3,6 @@ package test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -17,10 +16,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
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
|
||||||
|
520, // after upgrade deal
|
||||||
|
5000, // after
|
||||||
|
} {
|
||||||
|
height := height // make linters happy by copying
|
||||||
|
t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) {
|
||||||
|
testCCUpgrade(t, b, blocktime, height)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeHeight abi.ChainEpoch) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 1, OneMiner)
|
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -78,7 +89,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
makeDeal(t, ctx, 6, client, miner, false, false)
|
MakeDeal(t, ctx, 6, client, miner, false, false, 0)
|
||||||
|
|
||||||
// Validate upgrade
|
// Validate upgrade
|
||||||
|
|
||||||
@@ -94,6 +105,22 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
require.Less(t, 50000, int(exp.OnTime))
|
require.Less(t, 50000, int(exp.OnTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dlInfo, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Sector should expire.
|
||||||
|
for {
|
||||||
|
// Wait for the sector to expire.
|
||||||
|
status, err := miner.SectorsStatus(ctx, CC, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if status.OnTime == 0 && status.Early == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t.Log("waiting for sector to expire")
|
||||||
|
// wait one deadline per loop.
|
||||||
|
time.Sleep(time.Duration(dlInfo.WPoStChallengeWindow) * blocktime)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println("shutting down mining")
|
fmt.Println("shutting down mining")
|
||||||
atomic.AddInt64(&mine, -1)
|
atomic.AddInt64(&mine, -1)
|
||||||
<-done
|
<-done
|
||||||
|
|||||||
+52
-44
@@ -12,19 +12,18 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
files "github.com/ipfs/go-ipfs-files"
|
files "github.com/ipfs/go-ipfs-files"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
|
||||||
"github.com/ipld/go-car"
|
"github.com/ipld/go-car"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"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/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
|
||||||
dag "github.com/ipfs/go-merkledag"
|
dag "github.com/ipfs/go-merkledag"
|
||||||
dstest "github.com/ipfs/go-merkledag/test"
|
dstest "github.com/ipfs/go-merkledag/test"
|
||||||
unixfile "github.com/ipfs/go-unixfs/file"
|
unixfile "github.com/ipfs/go-unixfs/file"
|
||||||
@@ -34,21 +33,10 @@ import (
|
|||||||
ipld "github.com/ipfs/go-ipld-format"
|
ipld "github.com/ipfs/go-ipld-format"
|
||||||
)
|
)
|
||||||
|
|
||||||
var MineNext = miner.MineReq{
|
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||||
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")
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 1, OneMiner)
|
n, sn := b(t, OneFull, OneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
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)
|
atomic.AddInt64(&mine, -1)
|
||||||
fmt.Println("shutting down mining")
|
fmt.Println("shutting down mining")
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 1, OneMiner)
|
n, sn := b(t, OneFull, OneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
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, 6, client, miner, false, false, startEpoch)
|
||||||
makeDeal(t, ctx, 7, client, miner, false, false)
|
MakeDeal(t, ctx, 7, client, miner, false, false, startEpoch)
|
||||||
|
|
||||||
atomic.AddInt64(&mine, -1)
|
atomic.AddInt64(&mine, -1)
|
||||||
fmt.Println("shutting down mining")
|
fmt.Println("shutting down mining")
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNodeAPI, miner TestStorageNode, carExport, fastRet bool) {
|
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||||
data := make([]byte, 1600)
|
res, data, err := CreateClientFile(ctx, client, rseed)
|
||||||
rand.New(rand.NewSource(int64(rseed))).Read(data)
|
|
||||||
|
|
||||||
r := bytes.NewReader(data)
|
|
||||||
fcid, err := client.ClientImportLocal(ctx, r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fcid := res.Root
|
||||||
fmt.Println("FILE CID: ", fcid)
|
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
|
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||||
time.Sleep(time.Second)
|
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)
|
testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api.ImportRes, []byte, error) {
|
||||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
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()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 1, OneMiner)
|
n, sn := b(t, OneFull, OneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -186,7 +191,7 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
|||||||
|
|
||||||
fmt.Println("FILE CID: ", fcid)
|
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)
|
waitDealPublished(t, ctx, miner, deal)
|
||||||
fmt.Println("deal published, retrieving")
|
fmt.Println("deal published, retrieving")
|
||||||
@@ -200,11 +205,10 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
|||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
func TestSecondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 1, OneMiner)
|
n, sn := b(t, OneFull, OneMiner)
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -250,13 +254,13 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
|
|||||||
t.Fatal(err)
|
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
|
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
waitDealSealed(t, ctx, miner, client, deal1, true)
|
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)
|
time.Sleep(time.Second)
|
||||||
waitDealSealed(t, ctx, miner, client, deal2, false)
|
waitDealSealed(t, ctx, miner, client, deal2, false)
|
||||||
@@ -276,7 +280,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
|
|||||||
<-done
|
<-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)
|
maddr, err := miner.ActorAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -294,6 +298,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
|
|||||||
Wallet: addr,
|
Wallet: addr,
|
||||||
Miner: maddr,
|
Miner: maddr,
|
||||||
EpochPrice: types.NewInt(1000000),
|
EpochPrice: types.NewInt(1000000),
|
||||||
|
DealStartEpoch: startEpoch,
|
||||||
MinBlocksDuration: uint64(build.MinDealDuration),
|
MinBlocksDuration: uint64(build.MinDealDuration),
|
||||||
FastRetrieval: fastRet,
|
FastRetrieval: fastRet,
|
||||||
})
|
})
|
||||||
@@ -303,7 +308,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
|
|||||||
return deal
|
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:
|
loop:
|
||||||
for {
|
for {
|
||||||
di, err := client.ClientGetDealInfo(ctx, *deal)
|
di, err := client.ClientGetDealInfo(ctx, *deal)
|
||||||
@@ -311,7 +316,7 @@ loop:
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
switch di.State {
|
switch di.State {
|
||||||
case storagemarket.StorageDealSealing:
|
case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing:
|
||||||
if noseal {
|
if noseal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -351,7 +356,7 @@ func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode,
|
|||||||
t.Fatal("deal failed")
|
t.Fatal("deal failed")
|
||||||
case storagemarket.StorageDealError:
|
case storagemarket.StorageDealError:
|
||||||
t.Fatal("deal errored", di.Message)
|
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)
|
fmt.Println("COMPLETE", di)
|
||||||
return
|
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)
|
offers, err := client.ClientFindData(ctx, fcid, piece)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -402,9 +407,12 @@ func testRetrieval(t *testing.T, ctx context.Context, client *impl.FullNodeAPI,
|
|||||||
IsCAR: carExport,
|
IsCAR: carExport,
|
||||||
}
|
}
|
||||||
updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref)
|
updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
for update := range updates {
|
for update := range updates {
|
||||||
if update.Err != "" {
|
if update.Err != "" {
|
||||||
t.Fatalf("%v", err)
|
t.Fatalf("retrieval failed: %s", update.Err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-15
@@ -5,7 +5,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -25,7 +24,7 @@ var log = logging.Logger("apitest")
|
|||||||
|
|
||||||
func (ts *testSuite) testMining(t *testing.T) {
|
func (ts *testSuite) testMining(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, sn := ts.makeNodes(t, 1, OneMiner)
|
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
newHeads, err := api.ChainNotify(ctx)
|
newHeads, err := api.ChainNotify(ctx)
|
||||||
@@ -54,19 +53,16 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, sn := ts.makeNodes(t, 1, OneMiner)
|
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
newHeads, err := api.ChainNotify(ctx)
|
newHeads, err := api.ChainNotify(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
initHead := (<-newHeads)[0]
|
at := (<-newHeads)[0].Val.Height()
|
||||||
if initHead.Val.Height() != 2 {
|
|
||||||
<-newHeads
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, err := api.ChainHead(ctx)
|
h1, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
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)
|
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -75,25 +71,23 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
|||||||
|
|
||||||
h2, err := api.ChainHead(ctx)
|
h2, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
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)
|
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
<-newHeads
|
<-newHeads
|
||||||
|
|
||||||
h2, err = api.ChainHead(ctx)
|
h3, err := api.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
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) {
|
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
|
// test making a deal with a fresh miner, and see if it starts to mine
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 1, []StorageMiner{
|
n, sn := b(t, OneFull, []StorageMiner{
|
||||||
{Full: 0, Preseal: PresealGenesis},
|
{Full: 0, Preseal: PresealGenesis},
|
||||||
{Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node
|
{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
|
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|||||||
+68
-15
@@ -3,33 +3,32 @@ package test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/api/apibstore"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"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"
|
||||||
"github.com/filecoin-project/lotus/chain/events/state"
|
"github.com/filecoin-project/lotus/chain/events/state"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
n, sn := b(t, 2, OneMiner)
|
n, sn := b(t, TwoFull, OneMiner)
|
||||||
|
|
||||||
paymentCreator := n[0]
|
paymentCreator := n[0]
|
||||||
paymentReceiver := n[1]
|
paymentReceiver := n[1]
|
||||||
@@ -54,7 +53,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
bm.MineBlocks()
|
bm.MineBlocks()
|
||||||
|
|
||||||
// send some funds to register the receiver
|
// 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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -67,7 +66,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
channelAmt := int64(100000)
|
channelAmt := int64(7000)
|
||||||
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt))
|
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -133,17 +132,26 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
t.Fatal("Unable to settle payment channel")
|
t.Fatal("Unable to settle payment channel")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
creatorStore := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(paymentCreator)))
|
||||||
|
|
||||||
// wait for the receiver to submit their vouchers
|
// wait for the receiver to submit their vouchers
|
||||||
ev := events.NewEvents(ctx, paymentCreator)
|
ev := events.NewEvents(ctx, paymentCreator)
|
||||||
preds := state.NewStatePredicates(paymentCreator)
|
preds := state.NewStatePredicates(paymentCreator)
|
||||||
finished := make(chan struct{})
|
finished := make(chan struct{})
|
||||||
err = ev.StateChanged(func(ts *types.TipSet) (done bool, more bool, err error) {
|
err = ev.StateChanged(func(ts *types.TipSet) (done bool, more bool, err error) {
|
||||||
act, err := paymentCreator.StateReadState(ctx, channel, ts.Key())
|
act, err := paymentCreator.StateGetActor(ctx, channel, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, false, err
|
return false, false, err
|
||||||
}
|
}
|
||||||
state := act.State.(paych.State)
|
state, err := paych.Load(creatorStore, act)
|
||||||
if state.ToSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
if err != nil {
|
||||||
|
return false, false, err
|
||||||
|
}
|
||||||
|
toSend, err := state.ToSend()
|
||||||
|
if err != nil {
|
||||||
|
return false, false, err
|
||||||
|
}
|
||||||
|
if toSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
||||||
return true, false, nil
|
return true, false, nil
|
||||||
}
|
}
|
||||||
return false, true, nil
|
return false, true, nil
|
||||||
@@ -156,7 +164,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}, func(ctx context.Context, ts *types.TipSet) error {
|
}, func(ctx context.Context, ts *types.TipSet) error {
|
||||||
return nil
|
return nil
|
||||||
}, int(build.MessageConfidence)+1, build.SealRandomnessLookbackLimit, func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) {
|
}, int(build.MessageConfidence)+1, build.Finality, func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) {
|
||||||
return preds.OnPaymentChannelActorChanged(channel, preds.OnToSendAmountChanges())(ctx, oldTs.Key(), newTs.Key())
|
return preds.OnPaymentChannelActorChanged(channel, preds.OnToSendAmountChanges())(ctx, oldTs.Key(), newTs.Key())
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -169,8 +177,53 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
t.Fatal("Timed out waiting for receiver to submit vouchers")
|
t.Fatal("Timed out waiting for receiver to submit vouchers")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a new voucher now that some vouchers have already been submitted
|
||||||
|
vouchRes, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(1000), 3)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if vouchRes.Voucher == nil {
|
||||||
|
t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouchRes.Shortfall))
|
||||||
|
}
|
||||||
|
vdelta, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouchRes.Voucher, nil, abi.NewTokenAmount(1000))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !vdelta.Equals(abi.NewTokenAmount(1000)) {
|
||||||
|
t.Fatal("voucher didn't have the right amount")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new voucher whose value would exceed the channel balance
|
||||||
|
excessAmt := abi.NewTokenAmount(1000)
|
||||||
|
vouchRes, err = paymentCreator.PaychVoucherCreate(ctx, channel, excessAmt, 4)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if vouchRes.Voucher != nil {
|
||||||
|
t.Fatal("Expected not to be able to create voucher whose value would exceed channel balance")
|
||||||
|
}
|
||||||
|
if !vouchRes.Shortfall.Equals(excessAmt) {
|
||||||
|
t.Fatal(fmt.Errorf("Expected voucher shortfall of %d, got %d", excessAmt, vouchRes.Shortfall))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a voucher whose value would exceed the channel balance
|
||||||
|
vouch := &paych.SignedVoucher{ChannelAddr: channel, Amount: excessAmt, Lane: 4, Nonce: 1}
|
||||||
|
vb, err := vouch.SigningBytes()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
sig, err := paymentCreator.WalletSign(ctx, createrAddr, vb)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
vouch.Signature = sig
|
||||||
|
_, err = paymentReceiver.PaychVoucherAdd(ctx, channel, vouch, nil, abi.NewTokenAmount(1000))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal(fmt.Errorf("Expected shortfall error of %d", excessAmt))
|
||||||
|
}
|
||||||
|
|
||||||
// wait for the settlement period to pass before collecting
|
// wait for the settlement period to pass before collecting
|
||||||
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych.SettleDelay)
|
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, policy.PaychSettleDelay)
|
||||||
|
|
||||||
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
||||||
if err != nil {
|
if err != 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+129
-4
@@ -2,18 +2,38 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"testing"
|
"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/multiformats/go-multiaddr"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"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/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
"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 {
|
type TestNode struct {
|
||||||
api.FullNode
|
api.FullNode
|
||||||
// ListenAddr is the address on which an API server is listening, if an
|
// ListenAddr is the address on which an API server is listening, if an
|
||||||
@@ -34,17 +54,27 @@ var PresealGenesis = -1
|
|||||||
|
|
||||||
const GenesisPreseals = 2
|
const GenesisPreseals = 2
|
||||||
|
|
||||||
|
// Options for setting up a mock storage miner
|
||||||
type StorageMiner struct {
|
type StorageMiner struct {
|
||||||
Full int
|
Full int
|
||||||
Preseal 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
|
// APIBuilder is a function which is invoked in test suite to provide
|
||||||
// test nodes and networks
|
// test nodes and networks
|
||||||
//
|
//
|
||||||
|
// fullOpts array defines options for each full node
|
||||||
// storage array defines storage nodes, numbers in the array specify full node
|
// storage array defines storage nodes, numbers in the array specify full node
|
||||||
// index the storage node 'belongs' to
|
// index the storage node 'belongs' to
|
||||||
type APIBuilder func(t *testing.T, nFull int, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
||||||
type testSuite struct {
|
type testSuite struct {
|
||||||
makeNodes APIBuilder
|
makeNodes APIBuilder
|
||||||
}
|
}
|
||||||
@@ -60,15 +90,67 @@ func TestApis(t *testing.T, b APIBuilder) {
|
|||||||
t.Run("testConnectTwo", ts.testConnectTwo)
|
t.Run("testConnectTwo", ts.testConnectTwo)
|
||||||
t.Run("testMining", ts.testMining)
|
t.Run("testMining", ts.testMining)
|
||||||
t.Run("testMiningReal", ts.testMiningReal)
|
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 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) {
|
func (ts *testSuite) testVersion(t *testing.T) {
|
||||||
build.RunningNodeType = build.NodeFull
|
build.RunningNodeType = build.NodeFull
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
v, err := api.Version(ctx)
|
v, err := api.Version(ctx)
|
||||||
@@ -78,9 +160,52 @@ func (ts *testSuite) testVersion(t *testing.T) {
|
|||||||
require.Equal(t, v.Version, build.BuildVersion)
|
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) {
|
func (ts *testSuite) testID(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||||
api := apis[0]
|
api := apis[0]
|
||||||
|
|
||||||
id, err := api.ID(ctx)
|
id, err := api.ID(ctx)
|
||||||
@@ -92,7 +217,7 @@ func (ts *testSuite) testID(t *testing.T) {
|
|||||||
|
|
||||||
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
apis, _ := ts.makeNodes(t, 2, OneMiner)
|
apis, _ := ts.makeNodes(t, TwoFull, OneMiner)
|
||||||
|
|
||||||
p, err := apis[0].NetPeers(ctx)
|
p, err := apis[0].NetPeers(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+152
-46
@@ -3,18 +3,22 @@ package test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||||
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
@@ -23,16 +27,11 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/node/impl"
|
"github.com/filecoin-project/lotus/node/impl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func TestSDRUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
if err != nil {
|
defer cancel()
|
||||||
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
n, sn := b(t, []FullNodeOpts{FullNodeWithSDRAt(500, 1000)}, OneMiner)
|
||||||
ctx := context.Background()
|
|
||||||
n, sn := b(t, 1, OneMiner)
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -46,11 +45,95 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
|
|||||||
}
|
}
|
||||||
build.Clock.Sleep(time.Second)
|
build.Clock.Sleep(time.Second)
|
||||||
|
|
||||||
mine := true
|
pledge := make(chan struct{})
|
||||||
|
mine := int64(1)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
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)
|
build.Clock.Sleep(blocktime)
|
||||||
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
|
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
|
||||||
|
|
||||||
@@ -62,17 +145,19 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
|
|||||||
|
|
||||||
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
||||||
|
|
||||||
mine = false
|
atomic.StoreInt64(&mine, 0)
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) {
|
func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n, existing int, blockNotif <-chan struct{}) {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
err := miner.PledgeSector(ctx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
if i%3 == 0 && blockNotif != nil {
|
if i%3 == 0 && blockNotif != nil {
|
||||||
<-blockNotif
|
<-blockNotif
|
||||||
|
log.Errorf("WAIT")
|
||||||
}
|
}
|
||||||
|
log.Errorf("PLEDGING %d", i)
|
||||||
|
err := miner.PledgeSector(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@@ -114,8 +199,25 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||||
ctx := context.Background()
|
for _, height := range []abi.ChainEpoch{
|
||||||
n, sn := b(t, 1, OneMiner)
|
1, // before
|
||||||
|
162, // while sealing
|
||||||
|
5000, // while proving
|
||||||
|
} {
|
||||||
|
height := height // copy to satisfy lints
|
||||||
|
t.Run(fmt.Sprintf("upgrade-%d", height), func(t *testing.T) {
|
||||||
|
testWindowPostUpgrade(t, b, blocktime, nSectors, height)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
func testWindowPostUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int,
|
||||||
|
upgradeHeight abi.ChainEpoch) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
n, sn := b(t, []FullNodeOpts{FullNodeWithActorsV2At(upgradeHeight)}, OneMiner)
|
||||||
|
|
||||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||||
miner := sn[0]
|
miner := sn[0]
|
||||||
|
|
||||||
@@ -129,17 +231,24 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
}
|
}
|
||||||
build.Clock.Sleep(time.Second)
|
build.Clock.Sleep(time.Second)
|
||||||
|
|
||||||
mine := true
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for mine {
|
for ctx.Err() == nil {
|
||||||
build.Clock.Sleep(blocktime)
|
build.Clock.Sleep(blocktime)
|
||||||
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
if err := sn[0].MineOne(ctx, MineNext); err != nil {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
// context was canceled, ignore the error.
|
||||||
|
return
|
||||||
|
}
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
<-done
|
||||||
|
}()
|
||||||
|
|
||||||
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
||||||
|
|
||||||
@@ -153,18 +262,16 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fmt.Printf("Running one proving period\n")
|
fmt.Printf("Running one proving period\n")
|
||||||
|
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
head, err := client.ChainHead(ctx)
|
head, err := client.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
||||||
|
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if head.Height()%100 == 0 {
|
|
||||||
fmt.Printf("@%d\n", head.Height())
|
|
||||||
}
|
|
||||||
build.Clock.Sleep(blocktime)
|
build.Clock.Sleep(blocktime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,22 +293,23 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
require.Greater(t, len(parts), 0)
|
require.Greater(t, len(parts), 0)
|
||||||
|
|
||||||
secs := parts[0].AllSectors
|
secs := parts[0].AllSectors
|
||||||
require.NoError(t, err)
|
|
||||||
n, err := secs.Count()
|
n, err := secs.Count()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(2), n)
|
require.Equal(t, uint64(2), n)
|
||||||
|
|
||||||
// Drop the partition
|
// Drop the partition
|
||||||
err = secs.ForEach(func(sid uint64) error {
|
err = secs.ForEach(func(sid uint64) error {
|
||||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(abi.SectorID{
|
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(storage.SectorRef{
|
||||||
Miner: abi.ActorID(mid),
|
ID: abi.SectorID{
|
||||||
Number: abi.SectorNumber(sid),
|
Miner: abi.ActorID(mid),
|
||||||
|
Number: abi.SectorNumber(sid),
|
||||||
|
},
|
||||||
}, true)
|
}, true)
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var s abi.SectorID
|
var s storage.SectorRef
|
||||||
|
|
||||||
// Drop 1 sectors from deadline 3 partition 0
|
// Drop 1 sectors from deadline 3 partition 0
|
||||||
{
|
{
|
||||||
@@ -210,7 +318,6 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
require.Greater(t, len(parts), 0)
|
require.Greater(t, len(parts), 0)
|
||||||
|
|
||||||
secs := parts[0].AllSectors
|
secs := parts[0].AllSectors
|
||||||
require.NoError(t, err)
|
|
||||||
n, err := secs.Count()
|
n, err := secs.Count()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uint64(2), n)
|
require.Equal(t, uint64(2), n)
|
||||||
@@ -223,9 +330,11 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fmt.Println("the sectors", all)
|
fmt.Println("the sectors", all)
|
||||||
|
|
||||||
s = abi.SectorID{
|
s = storage.SectorRef{
|
||||||
Miner: abi.ActorID(mid),
|
ID: abi.SectorID{
|
||||||
Number: abi.SectorNumber(sn),
|
Miner: abi.ActorID(mid),
|
||||||
|
Number: abi.SectorNumber(sn),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true)
|
err = miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkFailed(s, true)
|
||||||
@@ -236,18 +345,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fmt.Printf("Go through another PP, wait for sectors to become faulty\n")
|
fmt.Printf("Go through another PP, wait for sectors to become faulty\n")
|
||||||
|
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
head, err := client.ChainHead(ctx)
|
head, err := client.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
||||||
|
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if head.Height()%100 == 0 {
|
|
||||||
fmt.Printf("@%d\n", head.Height())
|
|
||||||
}
|
|
||||||
build.Clock.Sleep(blocktime)
|
build.Clock.Sleep(blocktime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,17 +375,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
head, err := client.ChainHead(ctx)
|
head, err := client.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
||||||
|
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if head.Height()%100 == 0 {
|
|
||||||
fmt.Printf("@%d\n", head.Height())
|
|
||||||
}
|
|
||||||
build.Clock.Sleep(blocktime)
|
build.Clock.Sleep(blocktime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,18 +402,19 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
pledgeSectors(t, ctx, miner, 1, nSectors, nil)
|
pledgeSectors(t, ctx, miner, 1, nSectors, nil)
|
||||||
|
|
||||||
{
|
{
|
||||||
// wait a bit more
|
// Wait until proven.
|
||||||
|
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
head, err := client.ChainHead(ctx)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
waitUntil := head.Height() + 10
|
waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2
|
||||||
|
fmt.Printf("End for head.Height > %d\n", waitUntil)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
head, err := client.ChainHead(ctx)
|
head, err := client.ChainHead(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if head.Height() > waitUntil {
|
if head.Height() > waitUntil {
|
||||||
|
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,7 +427,4 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
|||||||
|
|
||||||
sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
||||||
require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged
|
require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged
|
||||||
|
|
||||||
mine = false
|
|
||||||
<-done
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-14
@@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
@@ -51,19 +50,6 @@ type MessageSendSpec struct {
|
|||||||
MaxFee abi.TokenAmount
|
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 {
|
type DataTransferChannel struct {
|
||||||
TransferID datatransfer.TransferID
|
TransferID datatransfer.TransferID
|
||||||
Status datatransfer.Status
|
Status datatransfer.Status
|
||||||
@@ -107,3 +93,9 @@ func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelSta
|
|||||||
}
|
}
|
||||||
return channel
|
return channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NetBlockList struct {
|
||||||
|
Peers []peer.ID
|
||||||
|
IPAddrs []string
|
||||||
|
IPSubnets []string
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
/dns4/bootstrap-0.testnet.fildev.network/tcp/1347/p2p/12D3KooWJTUBUjtzWJGWU1XSiY21CwmHaCNLNYn2E7jqHEHyZaP7
|
/dns4/bootstrap-0.mainnet.filops.net/tcp/1347/p2p/12D3KooWCVe8MmsEMes2FzgTpt9fXtmCY7wrq91GRiaC8PHSCCBj
|
||||||
/dns4/bootstrap-1.testnet.fildev.network/tcp/1347/p2p/12D3KooW9yeKXha4hdrJKq74zEo99T8DhriQdWNoojWnnQbsgB3v
|
/dns4/bootstrap-1.mainnet.filops.net/tcp/1347/p2p/12D3KooWCwevHg1yLCvktf2nvLu7L9894mcrJR4MsBCcm4syShVc
|
||||||
/dns4/bootstrap-2.testnet.fildev.network/tcp/1347/p2p/12D3KooWCrx8yVG9U9Kf7w8KLN3Edkj5ZKDhgCaeMqQbcQUoB6CT
|
/dns4/bootstrap-2.mainnet.filops.net/tcp/1347/p2p/12D3KooWEWVwHGn2yR36gKLozmb4YjDJGerotAPGxmdWZx2nxMC4
|
||||||
/dns4/bootstrap-4.testnet.fildev.network/tcp/1347/p2p/12D3KooWPkL9LrKRQgHtq7kn9ecNhGU9QaziG8R5tX8v9v7t3h34
|
/dns4/bootstrap-3.mainnet.filops.net/tcp/1347/p2p/12D3KooWKhgq8c7NQ9iGjbyK7v7phXvG6492HQfiDaGHLHLQjk7R
|
||||||
/dns4/bootstrap-3.testnet.fildev.network/tcp/1347/p2p/12D3KooWKYSsbpgZ3HAjax5M1BXCwXLa6gVkUARciz7uN3FNtr7T
|
/dns4/bootstrap-4.mainnet.filops.net/tcp/1347/p2p/12D3KooWL6PsFNPhYftrJzGgF5U18hFoaVhfGk7xwzD8yVrHJ3Uc
|
||||||
/dns4/bootstrap-5.testnet.fildev.network/tcp/1347/p2p/12D3KooWQYzqnLASJAabyMpPb1GcWZvNSe7JDcRuhdRqonFoiK9W
|
/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
|
||||||
|
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
|
||||||
|
/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
|
||||||
|
/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
|
||||||
|
|||||||
+1
-10
@@ -35,6 +35,7 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
|
|||||||
"https://api.drand.sh",
|
"https://api.drand.sh",
|
||||||
"https://api2.drand.sh",
|
"https://api2.drand.sh",
|
||||||
"https://api3.drand.sh",
|
"https://api3.drand.sh",
|
||||||
|
"https://drand.cloudflare.com",
|
||||||
},
|
},
|
||||||
Relays: []string{
|
Relays: []string{
|
||||||
"/dnsaddr/api.drand.sh/",
|
"/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"}`,
|
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
|
||||||
},
|
},
|
||||||
DrandIncentinet: {
|
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"}`,
|
ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-8
@@ -3,28 +3,42 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
||||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
|
||||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const UpgradeBreezeHeight = -1
|
const UpgradeBreezeHeight = -1
|
||||||
const BreezeGasTampingDuration = 0
|
const BreezeGasTampingDuration = 0
|
||||||
|
|
||||||
const UpgradeSmokeHeight = -1
|
const UpgradeSmokeHeight = -1
|
||||||
|
const UpgradeIgnitionHeight = -2
|
||||||
|
const UpgradeRefuelHeight = -3
|
||||||
|
const UpgradeTapeHeight = -4
|
||||||
|
|
||||||
|
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||||
|
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
||||||
|
|
||||||
|
const UpgradeKumquatHeight = 15
|
||||||
|
const UpgradeCalicoHeight = 20
|
||||||
|
const UpgradePersianHeight = 25
|
||||||
|
const UpgradeClausHeight = 30
|
||||||
|
|
||||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||||
0: DrandMainnet,
|
0: DrandMainnet,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
power0.ConsensusMinerMinPower = big.NewInt(2048)
|
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||||
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||||
|
|
||||||
|
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||||
|
UpgradeActorsV2Height = math.MaxInt64
|
||||||
|
UpgradeLiftoffHeight = 11
|
||||||
}
|
}
|
||||||
verifreg0.MinVerifiedDealSize = big.NewInt(256)
|
|
||||||
|
|
||||||
BuildType |= Build2k
|
BuildType |= Build2k
|
||||||
}
|
}
|
||||||
@@ -41,3 +55,5 @@ const SlashablePowerDelay = 20
|
|||||||
|
|
||||||
// Epochs
|
// Epochs
|
||||||
const InteractivePoRepConfidence = 6
|
const InteractivePoRepConfidence = 6
|
||||||
|
|
||||||
|
const BootstrapPeerThreshold = 1
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// +build !debug
|
||||||
|
// +build !2k
|
||||||
|
// +build !testground
|
||||||
|
|
||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||||
|
0: DrandIncentinet,
|
||||||
|
UpgradeSmokeHeight: DrandMainnet,
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpgradeBreezeHeight = 41280
|
||||||
|
const BreezeGasTampingDuration = 120
|
||||||
|
|
||||||
|
const UpgradeSmokeHeight = 51000
|
||||||
|
|
||||||
|
const UpgradeIgnitionHeight = 94000
|
||||||
|
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))
|
||||||
|
|
||||||
|
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
||||||
|
SetAddressNetwork(address.Mainnet)
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||||
|
UpgradeActorsV2Height = math.MaxInt64
|
||||||
|
}
|
||||||
|
|
||||||
|
Devnet = false
|
||||||
|
}
|
||||||
|
|
||||||
|
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,34 +1,13 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/protocol"
|
"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"
|
"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
|
// Core network constants
|
||||||
|
|
||||||
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
|
||||||
@@ -37,10 +16,15 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
|||||||
return protocol.ID("/fil/kad/" + string(netName))
|
return protocol.ID("/fil/kad/" + string(netName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func UseNewestNetwork() bool {
|
func SetAddressNetwork(n address.Network) {
|
||||||
// TODO: Put these in a container we can iterate over
|
address.CurrentNetwork = n
|
||||||
if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 {
|
}
|
||||||
return true
|
|
||||||
|
func MustParseAddress(addr string) address.Address {
|
||||||
|
ret, err := address.NewFromString(addr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-16
@@ -4,12 +4,15 @@ package build
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"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/go-state-types/network"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
@@ -22,17 +25,17 @@ const UnixfsLinksPerLevel = 1024
|
|||||||
// Consensus / Network
|
// Consensus / Network
|
||||||
|
|
||||||
const AllowableClockDriftSecs = uint64(1)
|
const AllowableClockDriftSecs = uint64(1)
|
||||||
const NewestNetworkVersion = network.Version2
|
const NewestNetworkVersion = network.Version8
|
||||||
const ActorUpgradeNetworkVersion = network.Version3
|
const ActorUpgradeNetworkVersion = network.Version4
|
||||||
|
|
||||||
// Epochs
|
// Epochs
|
||||||
const ForkLengthThreshold = Finality
|
const ForkLengthThreshold = Finality
|
||||||
|
|
||||||
// Blocks (e)
|
// Blocks (e)
|
||||||
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
var BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
|
||||||
|
|
||||||
// Epochs
|
// Epochs
|
||||||
const Finality = miner0.ChainFinality
|
const Finality = policy.ChainFinality
|
||||||
const MessageConfidence = uint64(5)
|
const MessageConfidence = uint64(5)
|
||||||
|
|
||||||
// constants for Weight calculation
|
// constants for Weight calculation
|
||||||
@@ -44,13 +47,8 @@ const WRatioDen = uint64(2)
|
|||||||
// Proofs
|
// Proofs
|
||||||
|
|
||||||
// Epochs
|
// Epochs
|
||||||
const SealRandomnessLookback = Finality
|
// TODO: unused
|
||||||
|
const SealRandomnessLookback = policy.SealRandomnessLookback
|
||||||
// Epochs
|
|
||||||
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000 // TODO: Get from spec specs-actors
|
|
||||||
|
|
||||||
// Maximum lookback that randomness can be sourced from for a seal proof submission
|
|
||||||
const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from specs-actors
|
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
// Mining
|
// Mining
|
||||||
@@ -58,23 +56,40 @@ const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from spe
|
|||||||
// Epochs
|
// Epochs
|
||||||
const TicketRandomnessLookback = abi.ChainEpoch(1)
|
const TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||||
|
|
||||||
const WinningPoStSectorSetLookback = abi.ChainEpoch(10)
|
// /////
|
||||||
|
// Address
|
||||||
|
|
||||||
|
const AddressMainnetEnvVar = "_mainnet_"
|
||||||
|
|
||||||
|
// the 'f' prefix doesn't matter
|
||||||
|
var ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
// Devnet settings
|
// Devnet settings
|
||||||
|
|
||||||
|
var Devnet = true
|
||||||
|
|
||||||
const FilBase = uint64(2_000_000_000)
|
const FilBase = uint64(2_000_000_000)
|
||||||
const FilAllocStorageMining = uint64(1_100_000_000)
|
const FilAllocStorageMining = uint64(1_100_000_000)
|
||||||
|
|
||||||
const FilecoinPrecision = uint64(1_000_000_000_000_000_000)
|
const FilecoinPrecision = uint64(1_000_000_000_000_000_000)
|
||||||
|
const FilReserved = uint64(300_000_000)
|
||||||
|
|
||||||
var InitialRewardBalance *big.Int
|
var InitialRewardBalance *big.Int
|
||||||
|
var InitialFilReserved *big.Int
|
||||||
|
|
||||||
// TODO: Move other important consts here
|
// TODO: Move other important consts here
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining))
|
InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining))
|
||||||
InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision)))
|
InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision)))
|
||||||
|
|
||||||
|
InitialFilReserved = big.NewInt(int64(FilReserved))
|
||||||
|
InitialFilReserved = InitialFilReserved.Mul(InitialFilReserved, big.NewInt(int64(FilecoinPrecision)))
|
||||||
|
|
||||||
|
if os.Getenv("LOTUS_ADDRESS_TYPE") == AddressMainnetEnvVar {
|
||||||
|
SetAddressNetwork(address.Mainnet)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
@@ -104,4 +119,4 @@ const PackingEfficiencyDenom = 5
|
|||||||
|
|
||||||
// Actor consts
|
// Actor consts
|
||||||
// TODO: Pull from actors when its made not private
|
// TODO: Pull from actors when its made not private
|
||||||
var MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
|
var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
||||||
|
|||||||
+35
-14
@@ -12,27 +12,29 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
UnixfsChunkSize = uint64(1 << 20)
|
UnixfsChunkSize = uint64(1 << 20)
|
||||||
UnixfsLinksPerLevel = 1024
|
UnixfsLinksPerLevel = 1024
|
||||||
|
|
||||||
BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
|
||||||
BlockMessageLimit = 512
|
BlockMessageLimit = 512
|
||||||
BlockGasLimit = int64(100_000_000_000)
|
BlockGasLimit = int64(100_000_000_000)
|
||||||
BlockGasTarget = int64(BlockGasLimit / 2)
|
BlockGasTarget = int64(BlockGasLimit / 2)
|
||||||
BaseFeeMaxChangeDenom = int64(8) // 12.5%
|
BaseFeeMaxChangeDenom = int64(8) // 12.5%
|
||||||
InitialBaseFee = int64(100e6)
|
InitialBaseFee = int64(100e6)
|
||||||
MinimumBaseFee = int64(100)
|
MinimumBaseFee = int64(100)
|
||||||
BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
|
BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
||||||
PropagationDelaySecs = uint64(6)
|
PropagationDelaySecs = uint64(6)
|
||||||
|
|
||||||
AllowableClockDriftSecs = uint64(1)
|
AllowableClockDriftSecs = uint64(1)
|
||||||
|
|
||||||
Finality = miner0.ChainFinality
|
Finality = policy.ChainFinality
|
||||||
ForkLengthThreshold = Finality
|
ForkLengthThreshold = Finality
|
||||||
|
|
||||||
SlashablePowerDelay = 20
|
SlashablePowerDelay = 20
|
||||||
@@ -47,15 +49,13 @@ var (
|
|||||||
BlsSignatureCacheSize = 40000
|
BlsSignatureCacheSize = 40000
|
||||||
VerifSigCacheSize = 32000
|
VerifSigCacheSize = 32000
|
||||||
|
|
||||||
SealRandomnessLookback = Finality
|
SealRandomnessLookback = policy.SealRandomnessLookback
|
||||||
SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
|
|
||||||
MaxSealLookback = SealRandomnessLookbackLimit + 2000
|
|
||||||
|
|
||||||
TicketRandomnessLookback = abi.ChainEpoch(1)
|
TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||||
WinningPoStSectorSetLookback = abi.ChainEpoch(10)
|
|
||||||
|
|
||||||
FilBase uint64 = 2_000_000_000
|
FilBase uint64 = 2_000_000_000
|
||||||
FilAllocStorageMining uint64 = 1_400_000_000
|
FilAllocStorageMining uint64 = 1_400_000_000
|
||||||
|
FilReserved uint64 = 300_000_000
|
||||||
|
|
||||||
FilecoinPrecision uint64 = 1_000_000_000_000_000_000
|
FilecoinPrecision uint64 = 1_000_000_000_000_000_000
|
||||||
|
|
||||||
@@ -64,9 +64,16 @@ var (
|
|||||||
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
||||||
return v
|
return v
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
InitialFilReserved = func() *big.Int {
|
||||||
|
v := big.NewInt(int64(FilReserved))
|
||||||
|
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
||||||
|
return v
|
||||||
|
}()
|
||||||
|
|
||||||
// Actor consts
|
// Actor consts
|
||||||
// TODO: Pull from actors when its made not private
|
// TODO: Pull from actors when its made not private
|
||||||
MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
|
MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
|
||||||
|
|
||||||
PackingEfficiencyNum int64 = 4
|
PackingEfficiencyNum int64 = 4
|
||||||
PackingEfficiencyDenom int64 = 5
|
PackingEfficiencyDenom int64 = 5
|
||||||
@@ -74,12 +81,26 @@ var (
|
|||||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
UpgradeBreezeHeight abi.ChainEpoch = -1
|
||||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
BreezeGasTampingDuration abi.ChainEpoch = 0
|
||||||
|
|
||||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||||
|
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||||
|
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||||
|
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||||
|
UpgradeActorsV2Height abi.ChainEpoch = 10
|
||||||
|
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||||
|
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||||
|
UpgradeCalicoHeight abi.ChainEpoch = -7
|
||||||
|
UpgradePersianHeight abi.ChainEpoch = -8
|
||||||
|
UpgradeClausHeight abi.ChainEpoch = -9
|
||||||
|
|
||||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||||
0: DrandMainnet,
|
0: DrandMainnet,
|
||||||
}
|
}
|
||||||
|
|
||||||
NewestNetworkVersion = network.Version2
|
NewestNetworkVersion = network.Version8
|
||||||
ActorUpgradeNetworkVersion = network.Version3
|
ActorUpgradeNetworkVersion = network.Version4
|
||||||
|
|
||||||
|
Devnet = true
|
||||||
|
ZeroAddress = MustParseAddress("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const BootstrapPeerThreshold = 1
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
// +build !debug
|
|
||||||
// +build !2k
|
|
||||||
// +build !testground
|
|
||||||
|
|
||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
"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"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
|
||||||
0: DrandIncentinet,
|
|
||||||
UpgradeSmokeHeight: DrandMainnet,
|
|
||||||
}
|
|
||||||
|
|
||||||
const UpgradeBreezeHeight = 41280
|
|
||||||
const BreezeGasTampingDuration = 120
|
|
||||||
|
|
||||||
const UpgradeSmokeHeight = 51000
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
power0.ConsensusMinerMinPower = big.NewInt(10 << 40)
|
|
||||||
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
|
||||||
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
|
|
||||||
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
|
|
||||||
|
|
||||||
const PropagationDelaySecs = uint64(6)
|
|
||||||
+4
-4
@@ -29,7 +29,7 @@ func buildType() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildVersion is the local build version, set by build system
|
// BuildVersion is the local build version, set by build system
|
||||||
const BuildVersion = "0.7.2"
|
const BuildVersion = "1.3.0"
|
||||||
|
|
||||||
func UserVersion() string {
|
func UserVersion() string {
|
||||||
return BuildVersion + buildType() + CurrentCommit
|
return BuildVersion + buildType() + CurrentCommit
|
||||||
@@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
|
|||||||
|
|
||||||
// semver versions of the rpc api exposed
|
// semver versions of the rpc api exposed
|
||||||
var (
|
var (
|
||||||
FullAPIVersion = newVer(0, 16, 0)
|
FullAPIVersion = newVer(1, 0, 0)
|
||||||
MinerAPIVersion = newVer(0, 15, 0)
|
MinerAPIVersion = newVer(1, 0, 0)
|
||||||
WorkerAPIVersion = newVer(0, 15, 0)
|
WorkerAPIVersion = newVer(1, 0, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:varcheck,deadcode
|
//nolint:varcheck,deadcode
|
||||||
|
|||||||
+20
-9
@@ -7,8 +7,11 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Map interface {
|
type Map interface {
|
||||||
@@ -21,18 +24,22 @@ type Map interface {
|
|||||||
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func AsMap(store Store, root cid.Cid, version builtin.Version) (Map, error) {
|
func AsMap(store Store, root cid.Cid, version actors.Version) (Map, error) {
|
||||||
switch version {
|
switch version {
|
||||||
case builtin.Version0:
|
case actors.Version0:
|
||||||
return adt0.AsMap(store, root)
|
return adt0.AsMap(store, root)
|
||||||
|
case actors.Version2:
|
||||||
|
return adt2.AsMap(store, root)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMap(store Store, version builtin.Version) (Map, error) {
|
func NewMap(store Store, version actors.Version) (Map, error) {
|
||||||
switch version {
|
switch version {
|
||||||
case builtin.Version0:
|
case actors.Version0:
|
||||||
return adt0.MakeEmptyMap(store), nil
|
return adt0.MakeEmptyMap(store), nil
|
||||||
|
case actors.Version2:
|
||||||
|
return adt2.MakeEmptyMap(store), nil
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||||
}
|
}
|
||||||
@@ -49,17 +56,21 @@ type Array interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
||||||
switch builtin.VersionForNetwork(version) {
|
switch actors.VersionForNetwork(version) {
|
||||||
case builtin.Version0:
|
case actors.Version0:
|
||||||
return adt0.AsArray(store, root)
|
return adt0.AsArray(store, root)
|
||||||
|
case actors.Version2:
|
||||||
|
return adt2.AsArray(store, root)
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewArray(store Store, version builtin.Version) (Array, error) {
|
func NewArray(store Store, version actors.Version) (Array, error) {
|
||||||
switch version {
|
switch version {
|
||||||
case builtin.Version0:
|
case actors.Version0:
|
||||||
return adt0.MakeEmptyArray(store), nil
|
return adt0.MakeEmptyArray(store), nil
|
||||||
|
case actors.Version2:
|
||||||
|
return adt2.MakeEmptyArray(store), nil
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ import (
|
|||||||
typegen "github.com/whyrusleeping/cbor-gen"
|
typegen "github.com/whyrusleeping/cbor-gen"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"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"
|
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||||
)
|
)
|
||||||
@@ -22,24 +23,24 @@ func TestDiffAdtArray(t *testing.T) {
|
|||||||
ctxstoreA := newContextStore()
|
ctxstoreA := newContextStore()
|
||||||
ctxstoreB := newContextStore()
|
ctxstoreB := newContextStore()
|
||||||
|
|
||||||
arrA := adt0.MakeEmptyArray(ctxstoreA)
|
arrA := adt2.MakeEmptyArray(ctxstoreA)
|
||||||
arrB := adt0.MakeEmptyArray(ctxstoreB)
|
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, arrA.Set(1, builtin2.CBORBytes([]byte{0}))) // modify
|
||||||
require.NoError(t, arrB.Set(1, runtime.CBORBytes([]byte{1})))
|
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, arrA.Set(3, builtin2.CBORBytes([]byte{0}))) // noop
|
||||||
require.NoError(t, arrB.Set(3, runtime.CBORBytes([]byte{0})))
|
require.NoError(t, arrB.Set(3, builtin2.CBORBytes([]byte{0})))
|
||||||
|
|
||||||
require.NoError(t, arrA.Set(4, runtime.CBORBytes([]byte{0}))) // modify
|
require.NoError(t, arrA.Set(4, builtin2.CBORBytes([]byte{0}))) // modify
|
||||||
require.NoError(t, arrB.Set(4, runtime.CBORBytes([]byte{6})))
|
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(5, builtin2.CBORBytes{8})) // add
|
||||||
require.NoError(t, arrB.Set(6, runtime.CBORBytes{9})) // add
|
require.NoError(t, arrB.Set(6, builtin2.CBORBytes{9})) // add
|
||||||
|
|
||||||
changes := new(TestDiffArray)
|
changes := new(TestDiffArray)
|
||||||
|
|
||||||
@@ -76,24 +77,24 @@ func TestDiffAdtMap(t *testing.T) {
|
|||||||
ctxstoreA := newContextStore()
|
ctxstoreA := newContextStore()
|
||||||
ctxstoreB := newContextStore()
|
ctxstoreB := newContextStore()
|
||||||
|
|
||||||
mapA := adt0.MakeEmptyMap(ctxstoreA)
|
mapA := adt2.MakeEmptyMap(ctxstoreA)
|
||||||
mapB := adt0.MakeEmptyMap(ctxstoreB)
|
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, mapA.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{0}))) // modify
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{1})))
|
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, mapA.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) // noop
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0})))
|
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, mapA.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{0}))) // modify
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{6})))
|
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(5), builtin2.CBORBytes{8})) // add
|
||||||
require.NoError(t, mapB.Put(abi.UIntKey(6), runtime.CBORBytes{9})) // add
|
require.NoError(t, mapB.Put(abi.UIntKey(6), builtin2.CBORBytes{9})) // add
|
||||||
|
|
||||||
changes := new(TestDiffMap)
|
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 {
|
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))
|
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
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))
|
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vTo := new(runtime.CBORBytes)
|
vTo := new(builtin2.CBORBytes)
|
||||||
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
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))
|
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -212,7 +213,7 @@ func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
|
|||||||
|
|
||||||
type adtMapDiffResult struct {
|
type adtMapDiffResult struct {
|
||||||
key uint64
|
key uint64
|
||||||
val runtime.CBORBytes
|
val builtin2.CBORBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestAdtMapDiffModified struct {
|
type TestAdtMapDiffModified struct {
|
||||||
@@ -222,7 +223,7 @@ type TestAdtMapDiffModified struct {
|
|||||||
|
|
||||||
type adtArrayDiffResult struct {
|
type adtArrayDiffResult struct {
|
||||||
key uint64
|
key uint64
|
||||||
val runtime.CBORBytes
|
val builtin2.CBORBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestDiffArray struct {
|
type TestDiffArray struct {
|
||||||
@@ -239,7 +240,7 @@ type TestAdtArrayDiffModified struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
|
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))
|
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
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))
|
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vTo := new(runtime.CBORBytes)
|
vTo := new(builtin2.CBORBytes)
|
||||||
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
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))
|
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -5,21 +5,33 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var Methods = builtin2.MethodsAccount
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.AccountActorCodeID:
|
case builtin0.AccountActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.AccountActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,26 @@ package account
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
|
||||||
|
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
account.State
|
account0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
account2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/account"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
account2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) PubkeyAddress() (address.Address, error) {
|
||||||
|
return s.Address, nil
|
||||||
|
}
|
||||||
@@ -1,32 +1,46 @@
|
|||||||
package builtin
|
package builtin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||||
|
|
||||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Version int
|
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 (
|
const (
|
||||||
Version0 = iota
|
EpochDurationSeconds = builtin0.EpochDurationSeconds
|
||||||
|
EpochsInDay = builtin0.EpochsInDay
|
||||||
|
SecondsInDay = builtin0.SecondsInDay
|
||||||
)
|
)
|
||||||
|
|
||||||
// Converts a network version into a specs-actors version.
|
const (
|
||||||
func VersionForNetwork(version network.Version) Version {
|
MethodSend = builtin2.MethodSend
|
||||||
switch version {
|
MethodConstructor = builtin2.MethodConstructor
|
||||||
case network.Version0, network.Version1, network.Version2:
|
)
|
||||||
return Version0
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Why does actors have 2 different versions of this?
|
// TODO: Why does actors have 2 different versions of this?
|
||||||
type SectorInfo = proof0.SectorInfo
|
type SectorInfo = proof0.SectorInfo
|
||||||
@@ -41,3 +55,64 @@ func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
|||||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||||
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FromV2FilterEstimate(v1 smoothing2.FilterEstimate) FilterEstimate {
|
||||||
|
return (FilterEstimate)(v1)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
||||||
|
|
||||||
|
var ActorStateLoaders = make(map[cid.Cid]ActorStateLoader)
|
||||||
|
|
||||||
|
func RegisterActorState(code cid.Cid, loader ActorStateLoader) {
|
||||||
|
ActorStateLoaders[code] = loader
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
|
||||||
|
loader, found := ActorStateLoaders[act.Code]
|
||||||
|
if !found {
|
||||||
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
|
}
|
||||||
|
return loader(store, act.Head)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActorNameByCode(c cid.Cid) string {
|
||||||
|
switch {
|
||||||
|
case builtin0.IsBuiltinActor(c):
|
||||||
|
return builtin0.ActorNameByCode(c)
|
||||||
|
case builtin2.IsBuiltinActor(c):
|
||||||
|
return builtin2.ActorNameByCode(c)
|
||||||
|
default:
|
||||||
|
return "<unknown>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsBuiltinActor(c cid.Cid) bool {
|
||||||
|
return builtin0.IsBuiltinActor(c) || builtin2.IsBuiltinActor(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsAccountActor(c cid.Cid) bool {
|
||||||
|
return c == builtin0.AccountActorCodeID || c == builtin2.AccountActorCodeID
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsStorageMinerActor(c cid.Cid) bool {
|
||||||
|
return c == builtin0.StorageMinerActorCodeID || c == builtin2.StorageMinerActorCodeID
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsMultisigActor(c cid.Cid) bool {
|
||||||
|
return c == builtin0.MultisigActorCodeID || c == builtin2.MultisigActorCodeID
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsPaymentChannelActor(c cid.Cid) bool {
|
||||||
|
return c == builtin0.PaymentChannelActorCodeID || c == builtin2.PaymentChannelActorCodeID
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeAddress(addr string) address.Address {
|
||||||
|
ret, err := address.NewFromString(addr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -6,24 +6,37 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Address = builtin0.InitActorAddr
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.InitActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Address = builtin2.InitActorAddr
|
||||||
|
Methods = builtin2.MethodsInit
|
||||||
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.InitActorCodeID:
|
case builtin0.InitActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.InitActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -41,4 +54,9 @@ type State interface {
|
|||||||
// It should not be used in production code, as init actor entries are
|
// It should not be used in production code, as init actor entries are
|
||||||
// immutable.
|
// immutable.
|
||||||
Remove(addrs ...address.Address) error
|
Remove(addrs ...address.Address) error
|
||||||
|
|
||||||
|
// Sets the network's name. This should only be used on upgrade/fork.
|
||||||
|
SetNetworkName(name string) error
|
||||||
|
|
||||||
|
addressMap() (adt.Map, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,30 @@ package init
|
|||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
|
||||||
|
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
init_.State
|
init0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +57,11 @@ func (s *state0) NetworkName() (dtypes.NetworkName, error) {
|
|||||||
return dtypes.NetworkName(s.State.NetworkName), nil
|
return dtypes.NetworkName(s.State.NetworkName), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state0) SetNetworkName(name string) error {
|
||||||
|
s.State.NetworkName = name
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state0) Remove(addrs ...address.Address) (err error) {
|
func (s *state0) Remove(addrs ...address.Address) (err error) {
|
||||||
m, err := adt0.AsMap(s.store, s.State.AddressMap)
|
m, err := adt0.AsMap(s.store, s.State.AddressMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -65,3 +79,7 @@ func (s *state0) Remove(addrs ...address.Address) (err error) {
|
|||||||
s.State.AddressMap = amr
|
s.State.AddressMap = amr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state0) addressMap() (adt.Map, error) {
|
||||||
|
return adt0.AsMap(s.store, s.AddressMap)
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package init
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
|
||||||
|
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
init2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
||||||
|
return s.State.ResolveAddress(s.store, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) MapAddressToNewID(address address.Address) (address.Address, error) {
|
||||||
|
return s.State.MapAddressToNewID(s.store, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
||||||
|
addrs, err := adt2.AsMap(s.store, s.State.AddressMap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var actorID cbg.CborInt
|
||||||
|
return addrs.ForEach(&actorID, func(key string) error {
|
||||||
|
addr, err := address.NewFromBytes([]byte(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cb(abi.ActorID(actorID), addr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) NetworkName() (dtypes.NetworkName, error) {
|
||||||
|
return dtypes.NetworkName(s.State.NetworkName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) SetNetworkName(name string) error {
|
||||||
|
s.State.NetworkName = name
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) Remove(addrs ...address.Address) (err error) {
|
||||||
|
m, err := adt2.AsMap(s.store, s.State.AddressMap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if err = m.Delete(abi.AddrKey(addr)); err != nil {
|
||||||
|
return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
amr, err := m.Root()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to get address map root: %w", err)
|
||||||
|
}
|
||||||
|
s.State.AddressMap = amr
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) addressMap() (adt.Map, error) {
|
||||||
|
return adt2.AsMap(s.store, s.AddressMap)
|
||||||
|
}
|
||||||
@@ -6,26 +6,38 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Address = builtin0.StorageMarketActorAddr
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.StorageMarketActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Address = builtin2.StorageMarketActorAddr
|
||||||
|
Methods = builtin2.MethodsMarket
|
||||||
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.StorageMarketActorCodeID:
|
case builtin0.StorageMarketActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.StorageMarketActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -69,6 +81,7 @@ type DealProposals interface {
|
|||||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
||||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||||
|
type WithdrawBalanceParams = market0.WithdrawBalanceParams
|
||||||
|
|
||||||
type ClientDealProposal = market0.ClientDealProposal
|
type ClientDealProposal = market0.ClientDealProposal
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,29 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"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/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
||||||
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
market.State
|
market0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +102,7 @@ func (s *state0) LockedTable() (BalanceTable, error) {
|
|||||||
func (s *state0) VerifyDealsForActivation(
|
func (s *state0) VerifyDealsForActivation(
|
||||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||||
return market.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
type balanceTable0 struct {
|
type balanceTable0 struct {
|
||||||
@@ -114,7 +126,7 @@ type dealStates0 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
|
func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||||
var deal0 market.DealState
|
var deal0 market0.DealState
|
||||||
found, err := s.Array.Get(uint64(dealID), &deal0)
|
found, err := s.Array.Get(uint64(dealID), &deal0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
@@ -127,14 +139,14 @@ func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||||
var ds0 market.DealState
|
var ds0 market0.DealState
|
||||||
return s.Array.ForEach(&ds0, func(idx int64) error {
|
return s.Array.ForEach(&ds0, func(idx int64) error {
|
||||||
return cb(abi.DealID(idx), fromV0DealState(ds0))
|
return cb(abi.DealID(idx), fromV0DealState(ds0))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) {
|
func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) {
|
||||||
var ds0 market.DealState
|
var ds0 market0.DealState
|
||||||
if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -146,7 +158,7 @@ func (s *dealStates0) array() adt.Array {
|
|||||||
return s.Array
|
return s.Array
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromV0DealState(v0 market.DealState) DealState {
|
func fromV0DealState(v0 market0.DealState) DealState {
|
||||||
return (DealState)(v0)
|
return (DealState)(v0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +167,7 @@ type dealProposals0 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||||
var proposal0 market.DealProposal
|
var proposal0 market0.DealProposal
|
||||||
found, err := s.Array.Get(uint64(dealID), &proposal0)
|
found, err := s.Array.Get(uint64(dealID), &proposal0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
@@ -168,14 +180,14 @@ func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *dealProposals0) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
func (s *dealProposals0) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||||
var dp0 market.DealProposal
|
var dp0 market0.DealProposal
|
||||||
return s.Array.ForEach(&dp0, func(idx int64) error {
|
return s.Array.ForEach(&dp0, func(idx int64) error {
|
||||||
return cb(abi.DealID(idx), fromV0DealProposal(dp0))
|
return cb(abi.DealID(idx), fromV0DealProposal(dp0))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dealProposals0) decode(val *cbg.Deferred) (*DealProposal, error) {
|
func (s *dealProposals0) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||||
var dp0 market.DealProposal
|
var dp0 market0.DealProposal
|
||||||
if err := dp0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
if err := dp0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -187,6 +199,6 @@ func (s *dealProposals0) array() adt.Array {
|
|||||||
return s.Array
|
return s.Array
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromV0DealProposal(v0 market.DealProposal) DealProposal {
|
func fromV0DealProposal(v0 market0.DealProposal) DealProposal {
|
||||||
return (DealProposal)(v0)
|
return (DealProposal)(v0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,205 @@
|
|||||||
|
package market
|
||||||
|
|
||||||
|
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/types"
|
||||||
|
|
||||||
|
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
market2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) TotalLocked() (abi.TokenAmount, error) {
|
||||||
|
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
||||||
|
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
||||||
|
return fml, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) BalancesChanged(otherState State) (bool, error) {
|
||||||
|
otherState2, ok := otherState.(*state2)
|
||||||
|
if !ok {
|
||||||
|
// there's no way to compare different versions of the state, so let's
|
||||||
|
// just say that means the state of balances has changed
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return !s.State.EscrowTable.Equals(otherState2.State.EscrowTable) || !s.State.LockedTable.Equals(otherState2.State.LockedTable), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) StatesChanged(otherState State) (bool, error) {
|
||||||
|
otherState2, ok := otherState.(*state2)
|
||||||
|
if !ok {
|
||||||
|
// there's no way to compare different versions of the state, so let's
|
||||||
|
// just say that means the state of balances has changed
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return !s.State.States.Equals(otherState2.State.States), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) States() (DealStates, error) {
|
||||||
|
stateArray, err := adt2.AsArray(s.store, s.State.States)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &dealStates2{stateArray}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ProposalsChanged(otherState State) (bool, error) {
|
||||||
|
otherState2, ok := otherState.(*state2)
|
||||||
|
if !ok {
|
||||||
|
// there's no way to compare different versions of the state, so let's
|
||||||
|
// just say that means the state of balances has changed
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return !s.State.Proposals.Equals(otherState2.State.Proposals), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) Proposals() (DealProposals, error) {
|
||||||
|
proposalArray, err := adt2.AsArray(s.store, s.State.Proposals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &dealProposals2{proposalArray}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) EscrowTable() (BalanceTable, error) {
|
||||||
|
bt, err := adt2.AsBalanceTable(s.store, s.State.EscrowTable)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &balanceTable2{bt}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) LockedTable() (BalanceTable, error) {
|
||||||
|
bt, err := adt2.AsBalanceTable(s.store, s.State.LockedTable)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &balanceTable2{bt}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) VerifyDealsForActivation(
|
||||||
|
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||||
|
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||||
|
w, vw, _, err := market2.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||||
|
return w, vw, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceTable2 struct {
|
||||||
|
*adt2.BalanceTable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bt *balanceTable2) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
||||||
|
asMap := (*adt2.Map)(bt.BalanceTable)
|
||||||
|
var ta abi.TokenAmount
|
||||||
|
return asMap.ForEach(&ta, func(key string) error {
|
||||||
|
a, err := address.NewFromBytes([]byte(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cb(a, ta)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type dealStates2 struct {
|
||||||
|
adt.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates2) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||||
|
var deal2 market2.DealState
|
||||||
|
found, err := s.Array.Get(uint64(dealID), &deal2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
deal := fromV2DealState(deal2)
|
||||||
|
return &deal, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates2) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||||
|
var ds1 market2.DealState
|
||||||
|
return s.Array.ForEach(&ds1, func(idx int64) error {
|
||||||
|
return cb(abi.DealID(idx), fromV2DealState(ds1))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates2) decode(val *cbg.Deferred) (*DealState, error) {
|
||||||
|
var ds1 market2.DealState
|
||||||
|
if err := ds1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ds := fromV2DealState(ds1)
|
||||||
|
return &ds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealStates2) array() adt.Array {
|
||||||
|
return s.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV2DealState(v1 market2.DealState) DealState {
|
||||||
|
return (DealState)(v1)
|
||||||
|
}
|
||||||
|
|
||||||
|
type dealProposals2 struct {
|
||||||
|
adt.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals2) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||||
|
var proposal2 market2.DealProposal
|
||||||
|
found, err := s.Array.Get(uint64(dealID), &proposal2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
proposal := fromV2DealProposal(proposal2)
|
||||||
|
return &proposal, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals2) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||||
|
var dp1 market2.DealProposal
|
||||||
|
return s.Array.ForEach(&dp1, func(idx int64) error {
|
||||||
|
return cb(abi.DealID(idx), fromV2DealProposal(dp1))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals2) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||||
|
var dp1 market2.DealProposal
|
||||||
|
if err := dp1.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dp := fromV2DealProposal(dp1)
|
||||||
|
return &dp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dealProposals2) array() adt.Array {
|
||||||
|
return s.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV2DealProposal(v1 market2.DealProposal) DealProposal {
|
||||||
|
return (DealProposal)(v1)
|
||||||
|
}
|
||||||
@@ -1,313 +0,0 @@
|
|||||||
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
|
|
||||||
|
|
||||||
package miner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
abi "github.com/filecoin-project/go-state-types/abi"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
xerrors "golang.org/x/xerrors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ = xerrors.Errorf
|
|
||||||
|
|
||||||
var lengthBufSectorOnChainInfo = []byte{139}
|
|
||||||
|
|
||||||
func (t *SectorOnChainInfo) MarshalCBOR(w io.Writer) error {
|
|
||||||
if t == nil {
|
|
||||||
_, err := w.Write(cbg.CborNull)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write(lengthBufSectorOnChainInfo); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
scratch := make([]byte, 9)
|
|
||||||
|
|
||||||
// t.SectorNumber (abi.SectorNumber) (uint64)
|
|
||||||
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.SectorNumber)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.SealProof (abi.RegisteredSealProof) (int64)
|
|
||||||
if t.SealProof >= 0 {
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.SealProof)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.SealProof-1)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.SealedCID (cid.Cid) (struct)
|
|
||||||
|
|
||||||
if err := cbg.WriteCidBuf(scratch, w, t.SealedCID); err != nil {
|
|
||||||
return xerrors.Errorf("failed to write cid field t.SealedCID: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.DealIDs ([]abi.DealID) (slice)
|
|
||||||
if len(t.DealIDs) > cbg.MaxLength {
|
|
||||||
return xerrors.Errorf("Slice value in field t.DealIDs was too long")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajArray, uint64(len(t.DealIDs))); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, v := range t.DealIDs {
|
|
||||||
if err := cbg.CborWriteHeader(w, cbg.MajUnsignedInt, uint64(v)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.Activation (abi.ChainEpoch) (int64)
|
|
||||||
if t.Activation >= 0 {
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Activation)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Activation-1)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.Expiration (abi.ChainEpoch) (int64)
|
|
||||||
if t.Expiration >= 0 {
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Expiration)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Expiration-1)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.DealWeight (big.Int) (struct)
|
|
||||||
if err := t.DealWeight.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.VerifiedDealWeight (big.Int) (struct)
|
|
||||||
if err := t.VerifiedDealWeight.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.InitialPledge (big.Int) (struct)
|
|
||||||
if err := t.InitialPledge.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.ExpectedDayReward (big.Int) (struct)
|
|
||||||
if err := t.ExpectedDayReward.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.ExpectedStoragePledge (big.Int) (struct)
|
|
||||||
if err := t.ExpectedStoragePledge.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *SectorOnChainInfo) UnmarshalCBOR(r io.Reader) error {
|
|
||||||
*t = SectorOnChainInfo{}
|
|
||||||
|
|
||||||
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 != 11 {
|
|
||||||
return fmt.Errorf("cbor input had wrong number of fields")
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.SectorNumber (abi.SectorNumber) (uint64)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if maj != cbg.MajUnsignedInt {
|
|
||||||
return fmt.Errorf("wrong type for uint64 field")
|
|
||||||
}
|
|
||||||
t.SectorNumber = abi.SectorNumber(extra)
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.SealProof (abi.RegisteredSealProof) (int64)
|
|
||||||
{
|
|
||||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
|
||||||
var extraI int64
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch maj {
|
|
||||||
case cbg.MajUnsignedInt:
|
|
||||||
extraI = int64(extra)
|
|
||||||
if extraI < 0 {
|
|
||||||
return fmt.Errorf("int64 positive overflow")
|
|
||||||
}
|
|
||||||
case cbg.MajNegativeInt:
|
|
||||||
extraI = int64(extra)
|
|
||||||
if extraI < 0 {
|
|
||||||
return fmt.Errorf("int64 negative oveflow")
|
|
||||||
}
|
|
||||||
extraI = -1 - extraI
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.SealProof = abi.RegisteredSealProof(extraI)
|
|
||||||
}
|
|
||||||
// t.SealedCID (cid.Cid) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
c, err := cbg.ReadCid(br)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("failed to read cid field t.SealedCID: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.SealedCID = c
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.DealIDs ([]abi.DealID) (slice)
|
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if extra > cbg.MaxLength {
|
|
||||||
return fmt.Errorf("t.DealIDs: array too large (%d)", extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maj != cbg.MajArray {
|
|
||||||
return fmt.Errorf("expected cbor array")
|
|
||||||
}
|
|
||||||
|
|
||||||
if extra > 0 {
|
|
||||||
t.DealIDs = make([]abi.DealID, extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < int(extra); i++ {
|
|
||||||
|
|
||||||
maj, val, err := cbg.CborReadHeaderBuf(br, scratch)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("failed to read uint64 for t.DealIDs slice: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maj != cbg.MajUnsignedInt {
|
|
||||||
return xerrors.Errorf("value read for array t.DealIDs was not a uint, instead got %d", maj)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.DealIDs[i] = abi.DealID(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.Activation (abi.ChainEpoch) (int64)
|
|
||||||
{
|
|
||||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
|
||||||
var extraI int64
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch maj {
|
|
||||||
case cbg.MajUnsignedInt:
|
|
||||||
extraI = int64(extra)
|
|
||||||
if extraI < 0 {
|
|
||||||
return fmt.Errorf("int64 positive overflow")
|
|
||||||
}
|
|
||||||
case cbg.MajNegativeInt:
|
|
||||||
extraI = int64(extra)
|
|
||||||
if extraI < 0 {
|
|
||||||
return fmt.Errorf("int64 negative oveflow")
|
|
||||||
}
|
|
||||||
extraI = -1 - extraI
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Activation = abi.ChainEpoch(extraI)
|
|
||||||
}
|
|
||||||
// t.Expiration (abi.ChainEpoch) (int64)
|
|
||||||
{
|
|
||||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
|
||||||
var extraI int64
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch maj {
|
|
||||||
case cbg.MajUnsignedInt:
|
|
||||||
extraI = int64(extra)
|
|
||||||
if extraI < 0 {
|
|
||||||
return fmt.Errorf("int64 positive overflow")
|
|
||||||
}
|
|
||||||
case cbg.MajNegativeInt:
|
|
||||||
extraI = int64(extra)
|
|
||||||
if extraI < 0 {
|
|
||||||
return fmt.Errorf("int64 negative oveflow")
|
|
||||||
}
|
|
||||||
extraI = -1 - extraI
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Expiration = abi.ChainEpoch(extraI)
|
|
||||||
}
|
|
||||||
// t.DealWeight (big.Int) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.DealWeight.UnmarshalCBOR(br); err != nil {
|
|
||||||
return xerrors.Errorf("unmarshaling t.DealWeight: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.VerifiedDealWeight (big.Int) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.VerifiedDealWeight.UnmarshalCBOR(br); err != nil {
|
|
||||||
return xerrors.Errorf("unmarshaling t.VerifiedDealWeight: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.InitialPledge (big.Int) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.InitialPledge.UnmarshalCBOR(br); err != nil {
|
|
||||||
return xerrors.Errorf("unmarshaling t.InitialPledge: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.ExpectedDayReward (big.Int) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.ExpectedDayReward.UnmarshalCBOR(br); err != nil {
|
|
||||||
return xerrors.Errorf("unmarshaling t.ExpectedDayReward: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// t.ExpectedStoragePledge (big.Int) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.ExpectedStoragePledge.UnmarshalCBOR(br); err != nil {
|
|
||||||
return xerrors.Errorf("unmarshaling t.ExpectedStoragePledge: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
package miner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-bitfield"
|
||||||
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeadlinesDiff map[uint64]DeadlineDiff
|
||||||
|
|
||||||
|
func DiffDeadlines(pre, cur State) (DeadlinesDiff, error) {
|
||||||
|
changed, err := pre.DeadlinesChanged(cur)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !changed {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dlDiff := make(DeadlinesDiff)
|
||||||
|
if err := pre.ForEachDeadline(func(idx uint64, preDl Deadline) error {
|
||||||
|
curDl, err := cur.LoadDeadline(idx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
diff, err := DiffDeadline(preDl, curDl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dlDiff[idx] = diff
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dlDiff, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeadlineDiff map[uint64]*PartitionDiff
|
||||||
|
|
||||||
|
func DiffDeadline(pre, cur Deadline) (DeadlineDiff, error) {
|
||||||
|
changed, err := pre.PartitionsChanged(cur)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !changed {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
partDiff := make(DeadlineDiff)
|
||||||
|
if err := pre.ForEachPartition(func(idx uint64, prePart Partition) error {
|
||||||
|
// try loading current partition at this index
|
||||||
|
curPart, err := cur.LoadPartition(idx)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, exitcode.ErrNotFound) {
|
||||||
|
// TODO correctness?
|
||||||
|
return nil // the partition was removed.
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare it with the previous partition
|
||||||
|
diff, err := DiffPartition(prePart, curPart)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
partDiff[idx] = diff
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// all previous partitions have been walked.
|
||||||
|
// all partitions in cur and not in prev are new... can they be faulty already?
|
||||||
|
// TODO is this correct?
|
||||||
|
if err := cur.ForEachPartition(func(idx uint64, curPart Partition) error {
|
||||||
|
if _, found := partDiff[idx]; found {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
faults, err := curPart.FaultySectors()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
recovering, err := curPart.RecoveringSectors()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
partDiff[idx] = &PartitionDiff{
|
||||||
|
Removed: bitfield.New(),
|
||||||
|
Recovered: bitfield.New(),
|
||||||
|
Faulted: faults,
|
||||||
|
Recovering: recovering,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return partDiff, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type PartitionDiff struct {
|
||||||
|
Removed bitfield.BitField
|
||||||
|
Recovered bitfield.BitField
|
||||||
|
Faulted bitfield.BitField
|
||||||
|
Recovering bitfield.BitField
|
||||||
|
}
|
||||||
|
|
||||||
|
func DiffPartition(pre, cur Partition) (*PartitionDiff, error) {
|
||||||
|
prevLiveSectors, err := pre.LiveSectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
curLiveSectors, err := cur.LiveSectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
removed, err := bitfield.SubtractBitField(prevLiveSectors, curLiveSectors)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
prevRecoveries, err := pre.RecoveringSectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
curRecoveries, err := cur.RecoveringSectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
recovering, err := bitfield.SubtractBitField(curRecoveries, prevRecoveries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
prevFaults, err := pre.FaultySectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
curFaults, err := cur.FaultySectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
faulted, err := bitfield.SubtractBitField(curFaults, prevFaults)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// all current good sectors
|
||||||
|
curActiveSectors, err := cur.ActiveSectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// sectors that were previously fault and are now currently active are considered recovered.
|
||||||
|
recovered, err := bitfield.IntersectBitField(prevFaults, curActiveSectors)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &PartitionDiff{
|
||||||
|
Removed: removed,
|
||||||
|
Recovered: recovered,
|
||||||
|
Faulted: faulted,
|
||||||
|
Recovering: recovering,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package miner
|
package miner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@@ -11,28 +12,42 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
"github.com/filecoin-project/go-state-types/dline"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"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"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unchanged between v0 and v1 actors
|
func init() {
|
||||||
var PreCommitChallengeDelay = miner0.PreCommitChallengeDelay
|
builtin.RegisterActorState(builtin0.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.StorageMinerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var Methods = builtin2.MethodsMiner
|
||||||
|
|
||||||
|
// Unchanged between v0 and v2 actors
|
||||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
||||||
|
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
||||||
|
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
|
||||||
|
var WPoStChallengeLookback = miner0.WPoStChallengeLookback
|
||||||
|
var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
|
||||||
|
|
||||||
const MinSectorExpiration = miner0.MinSectorExpiration
|
const MinSectorExpiration = miner0.MinSectorExpiration
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.StorageMinerActorCodeID:
|
case builtin0.StorageMinerActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.StorageMinerActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -46,6 +61,7 @@ type State interface {
|
|||||||
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
|
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
|
||||||
// Funds locked for various reasons.
|
// Funds locked for various reasons.
|
||||||
LockedFunds() (LockedFunds, error)
|
LockedFunds() (LockedFunds, error)
|
||||||
|
FeeDebt() (abi.TokenAmount, error)
|
||||||
|
|
||||||
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
|
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
|
||||||
FindSector(abi.SectorNumber) (*SectorLocation, error)
|
FindSector(abi.SectorNumber) (*SectorLocation, error)
|
||||||
@@ -61,6 +77,7 @@ type State interface {
|
|||||||
DeadlinesChanged(State) (bool, error)
|
DeadlinesChanged(State) (bool, error)
|
||||||
|
|
||||||
Info() (MinerInfo, error)
|
Info() (MinerInfo, error)
|
||||||
|
MinerInfoChanged(State) (bool, error)
|
||||||
|
|
||||||
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
||||||
|
|
||||||
@@ -132,6 +149,21 @@ type MinerInfo struct {
|
|||||||
SealProofType abi.RegisteredSealProof
|
SealProofType abi.RegisteredSealProof
|
||||||
SectorSize abi.SectorSize
|
SectorSize abi.SectorSize
|
||||||
WindowPoStPartitionSectors uint64
|
WindowPoStPartitionSectors uint64
|
||||||
|
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 {
|
type SectorExpiration struct {
|
||||||
@@ -168,3 +200,7 @@ type LockedFunds struct {
|
|||||||
InitialPledgeRequirement abi.TokenAmount
|
InitialPledgeRequirement abi.TokenAmount
|
||||||
PreCommitDeposits 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"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"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) {
|
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...)
|
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")
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,21 +4,34 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
"github.com/filecoin-project/go-state-types/dline"
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/ipfs/go-cid"
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
miner0.State
|
miner0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
@@ -34,8 +47,16 @@ type partition0 struct {
|
|||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
func (s *state0) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
|
||||||
return s.GetAvailableBalance(bal), nil
|
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) {
|
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
@@ -50,6 +71,10 @@ func (s *state0) LockedFunds() (LockedFunds, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state0) FeeDebt() (abi.TokenAmount, error) {
|
||||||
|
return big.Zero(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state0) InitialPledge() (abi.TokenAmount, error) {
|
func (s *state0) InitialPledge() (abi.TokenAmount, error) {
|
||||||
return s.State.InitialPledgeRequirement, nil
|
return s.State.InitialPledgeRequirement, nil
|
||||||
}
|
}
|
||||||
@@ -96,9 +121,7 @@ func (s *state0) NumLiveSectors() (uint64, error) {
|
|||||||
|
|
||||||
// GetSectorExpiration returns the effective expiration of the given sector.
|
// GetSectorExpiration returns the effective expiration of the given sector.
|
||||||
//
|
//
|
||||||
// If the sector isn't found or has already been terminated, this method returns
|
// If the sector does not expire early, the Early expiration field is 0.
|
||||||
// nil and no error. If the sector does not expire early, the Early expiration
|
|
||||||
// field is 0.
|
|
||||||
func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
||||||
dls, err := s.State.LoadDeadlines(s.store)
|
dls, err := s.State.LoadDeadlines(s.store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -161,7 +184,7 @@ func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if out.Early == 0 && out.OnTime == 0 {
|
if out.Early == 0 && out.OnTime == 0 {
|
||||||
return nil, nil
|
return nil, xerrors.Errorf("failed to find sector %d", num)
|
||||||
}
|
}
|
||||||
return &out, nil
|
return &out, nil
|
||||||
}
|
}
|
||||||
@@ -251,7 +274,16 @@ func (s *state0) DeadlinesChanged(other State) (bool, error) {
|
|||||||
return true, nil
|
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) {
|
func (s *state0) Info() (MinerInfo, error) {
|
||||||
@@ -278,6 +310,7 @@ func (s *state0) Info() (MinerInfo, error) {
|
|||||||
SealProofType: info.SealProofType,
|
SealProofType: info.SealProofType,
|
||||||
SectorSize: info.SectorSize,
|
SectorSize: info.SectorSize,
|
||||||
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||||
|
ConsensusFaultElapsed: -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.PendingWorkerKey != nil {
|
if info.PendingWorkerKey != nil {
|
||||||
@@ -346,7 +379,7 @@ func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
|
|||||||
return true, nil
|
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) {
|
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
|
||||||
|
|||||||
@@ -0,0 +1,424 @@
|
|||||||
|
package miner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-bitfield"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/dline"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
miner2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
type deadline2 struct {
|
||||||
|
miner2.Deadline
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
type partition2 struct {
|
||||||
|
miner2.Partition
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return s.CheckVestedFunds(s.store, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) LockedFunds() (LockedFunds, error) {
|
||||||
|
return LockedFunds{
|
||||||
|
VestingFunds: s.State.LockedFunds,
|
||||||
|
InitialPledgeRequirement: s.State.InitialPledge,
|
||||||
|
PreCommitDeposits: s.State.PreCommitDeposits,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) FeeDebt() (abi.TokenAmount, error) {
|
||||||
|
return s.State.FeeDebt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) InitialPledge() (abi.TokenAmount, error) {
|
||||||
|
return s.State.InitialPledge, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) PreCommitDeposits() (abi.TokenAmount, error) {
|
||||||
|
return s.State.PreCommitDeposits, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
||||||
|
info, ok, err := s.State.GetSector(s.store, num)
|
||||||
|
if !ok || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := fromV2SectorOnChainInfo(*info)
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
|
||||||
|
dlIdx, partIdx, err := s.State.FindSector(s.store, num)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &SectorLocation{
|
||||||
|
Deadline: dlIdx,
|
||||||
|
Partition: partIdx,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) NumLiveSectors() (uint64, error) {
|
||||||
|
dls, err := s.State.LoadDeadlines(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var total uint64
|
||||||
|
if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner2.Deadline) error {
|
||||||
|
total += dl.LiveSectors
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSectorExpiration returns the effective expiration of the given sector.
|
||||||
|
//
|
||||||
|
// If the sector does not expire early, the Early expiration field is 0.
|
||||||
|
func (s *state2) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
|
||||||
|
dls, err := s.State.LoadDeadlines(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// NOTE: this can be optimized significantly.
|
||||||
|
// 1. If the sector is non-faulty, it will either expire on-time (can be
|
||||||
|
// learned from the sector info), or in the next quantized expiration
|
||||||
|
// epoch (i.e., the first element in the partition's expiration queue.
|
||||||
|
// 2. If it's faulty, it will expire early within the first 14 entries
|
||||||
|
// of the expiration queue.
|
||||||
|
stopErr := errors.New("stop")
|
||||||
|
out := SectorExpiration{}
|
||||||
|
err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner2.Deadline) error {
|
||||||
|
partitions, err := dl.PartitionsArray(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
quant := s.State.QuantSpecForDeadline(dlIdx)
|
||||||
|
var part miner2.Partition
|
||||||
|
return partitions.ForEach(&part, func(partIdx int64) error {
|
||||||
|
if found, err := part.Sectors.IsSet(uint64(num)); err != nil {
|
||||||
|
return err
|
||||||
|
} else if !found {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if found, err := part.Terminated.IsSet(uint64(num)); err != nil {
|
||||||
|
return err
|
||||||
|
} else if found {
|
||||||
|
// already terminated
|
||||||
|
return stopErr
|
||||||
|
}
|
||||||
|
|
||||||
|
q, err := miner2.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var exp miner2.ExpirationSet
|
||||||
|
return q.ForEach(&exp, func(epoch int64) error {
|
||||||
|
if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil {
|
||||||
|
return err
|
||||||
|
} else if early {
|
||||||
|
out.Early = abi.ChainEpoch(epoch)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil {
|
||||||
|
return err
|
||||||
|
} else if onTime {
|
||||||
|
out.OnTime = abi.ChainEpoch(epoch)
|
||||||
|
return stopErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if err == stopErr {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if out.Early == 0 && out.OnTime == 0 {
|
||||||
|
return nil, xerrors.Errorf("failed to find sector %d", num)
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
||||||
|
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
||||||
|
if !ok || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := fromV2SectorPreCommitOnChainInfo(*info)
|
||||||
|
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
||||||
|
sectors, err := miner2.LoadSectors(s.store, s.State.Sectors)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no sector numbers are specified, load all.
|
||||||
|
if snos == nil {
|
||||||
|
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
|
||||||
|
var info2 miner2.SectorOnChainInfo
|
||||||
|
if err := sectors.ForEach(&info2, func(_ int64) error {
|
||||||
|
info := fromV2SectorOnChainInfo(info2)
|
||||||
|
infos = append(infos, &info)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return infos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, load selected.
|
||||||
|
infos2, err := sectors.Load(*snos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
infos := make([]*SectorOnChainInfo, len(infos2))
|
||||||
|
for i, info2 := range infos2 {
|
||||||
|
info := fromV2SectorOnChainInfo(*info2)
|
||||||
|
infos[i] = &info
|
||||||
|
}
|
||||||
|
return infos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) IsAllocated(num abi.SectorNumber) (bool, error) {
|
||||||
|
var allocatedSectors bitfield.BitField
|
||||||
|
if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocatedSectors.IsSet(uint64(num))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) LoadDeadline(idx uint64) (Deadline, error) {
|
||||||
|
dls, err := s.State.LoadDeadlines(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dl, err := dls.LoadDeadline(s.store, idx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &deadline2{*dl, s.store}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ForEachDeadline(cb func(uint64, Deadline) error) error {
|
||||||
|
dls, err := s.State.LoadDeadlines(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return dls.ForEach(s.store, func(i uint64, dl *miner2.Deadline) error {
|
||||||
|
return cb(i, &deadline2{*dl, s.store})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) NumDeadlines() (uint64, error) {
|
||||||
|
return miner2.WPoStPeriodDeadlines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) DeadlinesChanged(other State) (bool, error) {
|
||||||
|
other2, ok := other.(*state2)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, 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) {
|
||||||
|
info, err := s.State.GetInfo(s.store)
|
||||||
|
if err != nil {
|
||||||
|
return MinerInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pid *peer.ID
|
||||||
|
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
|
||||||
|
pid = &peerID
|
||||||
|
}
|
||||||
|
|
||||||
|
mi := MinerInfo{
|
||||||
|
Owner: info.Owner,
|
||||||
|
Worker: info.Worker,
|
||||||
|
ControlAddresses: info.ControlAddresses,
|
||||||
|
|
||||||
|
NewWorker: address.Undef,
|
||||||
|
WorkerChangeEpoch: -1,
|
||||||
|
|
||||||
|
PeerId: pid,
|
||||||
|
Multiaddrs: info.Multiaddrs,
|
||||||
|
SealProofType: info.SealProofType,
|
||||||
|
SectorSize: info.SectorSize,
|
||||||
|
WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
|
||||||
|
ConsensusFaultElapsed: info.ConsensusFaultElapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.PendingWorkerKey != nil {
|
||||||
|
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||||
|
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||||
|
}
|
||||||
|
|
||||||
|
return mi, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
||||||
|
return s.State.DeadlineInfo(epoch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) sectors() (adt.Array, error) {
|
||||||
|
return adt2.AsArray(s.store, s.Sectors)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
||||||
|
var si miner2.SectorOnChainInfo
|
||||||
|
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
|
if err != nil {
|
||||||
|
return SectorOnChainInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromV2SectorOnChainInfo(si), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) precommits() (adt.Map, error) {
|
||||||
|
return adt2.AsMap(s.store, s.PreCommittedSectors)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
||||||
|
var sp miner2.SectorPreCommitOnChainInfo
|
||||||
|
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||||
|
if err != nil {
|
||||||
|
return SectorPreCommitOnChainInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromV2SectorPreCommitOnChainInfo(sp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline2) LoadPartition(idx uint64) (Partition, error) {
|
||||||
|
p, err := d.Deadline.LoadPartition(d.store, idx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &partition2{*p, d.store}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline2) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||||
|
ps, err := d.Deadline.PartitionsArray(d.store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var part miner2.Partition
|
||||||
|
return ps.ForEach(&part, func(i int64) error {
|
||||||
|
return cb(uint64(i), &partition2{part, d.store})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline2) PartitionsChanged(other Deadline) (bool, error) {
|
||||||
|
other2, ok := other.(*deadline2)
|
||||||
|
if !ok {
|
||||||
|
// treat an upgrade as a change, always
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *deadline2) PostSubmissions() (bitfield.BitField, error) {
|
||||||
|
return d.Deadline.PostSubmissions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *partition2) AllSectors() (bitfield.BitField, error) {
|
||||||
|
return p.Partition.Sectors, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *partition2) FaultySectors() (bitfield.BitField, error) {
|
||||||
|
return p.Partition.Faults, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *partition2) RecoveringSectors() (bitfield.BitField, error) {
|
||||||
|
return p.Partition.Recoveries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV2SectorOnChainInfo(v2 miner2.SectorOnChainInfo) SectorOnChainInfo {
|
||||||
|
return SectorOnChainInfo{
|
||||||
|
SectorNumber: v2.SectorNumber,
|
||||||
|
SealProof: v2.SealProof,
|
||||||
|
SealedCID: v2.SealedCID,
|
||||||
|
DealIDs: v2.DealIDs,
|
||||||
|
Activation: v2.Activation,
|
||||||
|
Expiration: v2.Expiration,
|
||||||
|
DealWeight: v2.DealWeight,
|
||||||
|
VerifiedDealWeight: v2.VerifiedDealWeight,
|
||||||
|
InitialPledge: v2.InitialPledge,
|
||||||
|
ExpectedDayReward: v2.ExpectedDayReward,
|
||||||
|
ExpectedStoragePledge: v2.ExpectedStoragePledge,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromV2SectorPreCommitOnChainInfo(v2 miner2.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||||
|
return SectorPreCommitOnChainInfo{
|
||||||
|
Info: (SectorPreCommitInfo)(v2.Info),
|
||||||
|
PreCommitDeposit: v2.PreCommitDeposit,
|
||||||
|
PreCommitEpoch: v2.PreCommitEpoch,
|
||||||
|
DealWeight: v2.DealWeight,
|
||||||
|
VerifiedDealWeight: v2.VerifiedDealWeight,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package multisig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/minio/blake2b-simd"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"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:
|
||||||
|
return message0{from}
|
||||||
|
case actors.Version2:
|
||||||
|
return message2{message0{from}}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageBuilder interface {
|
||||||
|
// Create a new multisig with the specified parameters.
|
||||||
|
Create(signers []address.Address, threshold uint64,
|
||||||
|
vestingStart, vestingDuration abi.ChainEpoch,
|
||||||
|
initialAmount abi.TokenAmount) (*types.Message, error)
|
||||||
|
|
||||||
|
// Propose a transaction to the given multisig.
|
||||||
|
Propose(msig, target address.Address, amt abi.TokenAmount,
|
||||||
|
method abi.MethodNum, params []byte) (*types.Message, error)
|
||||||
|
|
||||||
|
// Approve a multisig transaction. The "hash" is optional.
|
||||||
|
Approve(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||||
|
|
||||||
|
// Cancel a multisig transaction. The "hash" is optional.
|
||||||
|
Cancel(msig address.Address, txID uint64, hash *ProposalHashData) (*types.Message, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)}
|
||||||
|
if data != nil {
|
||||||
|
if data.Requester.Protocol() != address.ID {
|
||||||
|
return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
|
||||||
|
}
|
||||||
|
if data.Value.Sign() == -1 {
|
||||||
|
return nil, xerrors.Errorf("proposal value must be non-negative, was %s", data.Value)
|
||||||
|
}
|
||||||
|
if data.To == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("proposed destination address must be set")
|
||||||
|
}
|
||||||
|
pser, err := data.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hash := blake2b.Sum256(pser)
|
||||||
|
params.ProposalHash = hash[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return actors.SerializeParams(¶ms)
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package multisig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
|
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type message0 struct{ from address.Address }
|
||||||
|
|
||||||
|
func (m message0) Create(
|
||||||
|
signers []address.Address, threshold uint64,
|
||||||
|
unlockStart, unlockDuration abi.ChainEpoch,
|
||||||
|
initialAmount abi.TokenAmount,
|
||||||
|
) (*types.Message, error) {
|
||||||
|
|
||||||
|
lenAddrs := uint64(len(signers))
|
||||||
|
|
||||||
|
if lenAddrs < threshold {
|
||||||
|
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
||||||
|
}
|
||||||
|
|
||||||
|
if threshold == 0 {
|
||||||
|
threshold = lenAddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.from == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("must provide source address")
|
||||||
|
}
|
||||||
|
|
||||||
|
if unlockStart != 0 {
|
||||||
|
return nil, xerrors.Errorf("actors v0 does not support a non-zero vesting start time")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up constructor parameters for multisig
|
||||||
|
msigParams := &multisig0.ConstructorParams{
|
||||||
|
Signers: signers,
|
||||||
|
NumApprovalsThreshold: threshold,
|
||||||
|
UnlockDuration: unlockDuration,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr := actors.SerializeParams(msigParams)
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
||||||
|
execParams := &init0.ExecParams{
|
||||||
|
CodeCID: builtin0.MultisigActorCodeID,
|
||||||
|
ConstructorParams: enc,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr = actors.SerializeParams(execParams)
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: init_.Address,
|
||||||
|
From: m.from,
|
||||||
|
Method: builtin0.MethodsInit.Exec,
|
||||||
|
Params: enc,
|
||||||
|
Value: initialAmount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message0) Propose(msig, to address.Address, amt abi.TokenAmount,
|
||||||
|
method abi.MethodNum, params []byte) (*types.Message, error) {
|
||||||
|
|
||||||
|
if msig == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("must provide a multisig address for proposal")
|
||||||
|
}
|
||||||
|
|
||||||
|
if to == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("must provide a target address for proposal")
|
||||||
|
}
|
||||||
|
|
||||||
|
if amt.Sign() == -1 {
|
||||||
|
return nil, xerrors.Errorf("must provide a non-negative amount for proposed send")
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.from == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("must provide source address")
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr := actors.SerializeParams(&multisig0.ProposeParams{
|
||||||
|
To: to,
|
||||||
|
Value: amt,
|
||||||
|
Method: method,
|
||||||
|
Params: params,
|
||||||
|
})
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to serialize parameters: %w", actErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: msig,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin0.MethodsMultisig.Propose,
|
||||||
|
Params: enc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message0) Approve(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
||||||
|
enc, err := txnParams(txID, hashData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: msig,
|
||||||
|
From: m.from,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
Method: builtin0.MethodsMultisig.Approve,
|
||||||
|
Params: enc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message0) Cancel(msig address.Address, txID uint64, hashData *ProposalHashData) (*types.Message, error) {
|
||||||
|
enc, err := txnParams(txID, hashData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: msig,
|
||||||
|
From: m.from,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
Method: builtin0.MethodsMultisig.Cancel,
|
||||||
|
Params: enc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package multisig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
|
||||||
|
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type message2 struct{ message0 }
|
||||||
|
|
||||||
|
func (m message2) Create(
|
||||||
|
signers []address.Address, threshold uint64,
|
||||||
|
unlockStart, unlockDuration abi.ChainEpoch,
|
||||||
|
initialAmount abi.TokenAmount,
|
||||||
|
) (*types.Message, error) {
|
||||||
|
|
||||||
|
lenAddrs := uint64(len(signers))
|
||||||
|
|
||||||
|
if lenAddrs < threshold {
|
||||||
|
return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
|
||||||
|
}
|
||||||
|
|
||||||
|
if threshold == 0 {
|
||||||
|
threshold = lenAddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.from == address.Undef {
|
||||||
|
return nil, xerrors.Errorf("must provide source address")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up constructor parameters for multisig
|
||||||
|
msigParams := &multisig2.ConstructorParams{
|
||||||
|
Signers: signers,
|
||||||
|
NumApprovalsThreshold: threshold,
|
||||||
|
UnlockDuration: unlockDuration,
|
||||||
|
StartEpoch: unlockStart,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr := actors.SerializeParams(msigParams)
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// new actors are created by invoking 'exec' on the init actor with the constructor params
|
||||||
|
execParams := &init2.ExecParams{
|
||||||
|
CodeCID: builtin2.MultisigActorCodeID,
|
||||||
|
ConstructorParams: enc,
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, actErr = actors.SerializeParams(execParams)
|
||||||
|
if actErr != nil {
|
||||||
|
return nil, actErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: init_.Address,
|
||||||
|
From: m.from,
|
||||||
|
Method: builtin2.MethodsInit.Exec,
|
||||||
|
Params: enc,
|
||||||
|
Value: initialAmount,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -1,28 +1,38 @@
|
|||||||
package multisig
|
package multisig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.MultisigActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.MultisigActorCodeID:
|
case builtin0.MultisigActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.MultisigActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -38,6 +48,10 @@ type State interface {
|
|||||||
Signers() ([]address.Address, error)
|
Signers() ([]address.Address, error)
|
||||||
|
|
||||||
ForEachPendingTxn(func(id int64, txn Transaction) error) 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
|
type Transaction = msig0.Transaction
|
||||||
@@ -1,19 +1,33 @@
|
|||||||
package multisig
|
package multisig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/ipfs/go-cid"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
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)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
msig0.State
|
msig0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
@@ -57,3 +71,24 @@ func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
|
|||||||
return cb(txid, (Transaction)(out))
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
msig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
msig2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||||
|
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) StartEpoch() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.StartEpoch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) UnlockDuration() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.UnlockDuration, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) InitialBalance() (abi.TokenAmount, error) {
|
||||||
|
return s.State.InitialBalance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) Threshold() (uint64, error) {
|
||||||
|
return s.State.NumApprovalsThreshold, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) Signers() ([]address.Address, error) {
|
||||||
|
return s.State.Signers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
||||||
|
arr, err := adt2.AsMap(s.store, s.State.PendingTxns)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var out msig2.Transaction
|
||||||
|
return arr.ForEach(&out, func(key string) error {
|
||||||
|
txid, n := binary.Varint([]byte(key))
|
||||||
|
if n <= 0 {
|
||||||
|
return xerrors.Errorf("invalid pending transaction key: %v", key)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package paych
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"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:
|
||||||
|
return message0{from}
|
||||||
|
case actors.Version2:
|
||||||
|
return message2{from}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unsupported actors version: %d", version))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageBuilder interface {
|
||||||
|
Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error)
|
||||||
|
Update(paych address.Address, voucher *SignedVoucher, secret []byte) (*types.Message, error)
|
||||||
|
Settle(paych address.Address) (*types.Message, error)
|
||||||
|
Collect(paych address.Address) (*types.Message, error)
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package paych
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||||
|
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type message0 struct{ from address.Address }
|
||||||
|
|
||||||
|
func (m message0) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
|
||||||
|
params, aerr := actors.SerializeParams(&paych0.ConstructorParams{From: m.from, To: to})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
enc, aerr := actors.SerializeParams(&init0.ExecParams{
|
||||||
|
CodeCID: builtin0.PaymentChannelActorCodeID,
|
||||||
|
ConstructorParams: params,
|
||||||
|
})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: init_.Address,
|
||||||
|
From: m.from,
|
||||||
|
Value: initialAmount,
|
||||||
|
Method: builtin0.MethodsInit.Exec,
|
||||||
|
Params: enc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message0) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
|
||||||
|
params, aerr := actors.SerializeParams(&paych0.UpdateChannelStateParams{
|
||||||
|
Sv: *sv,
|
||||||
|
Secret: secret,
|
||||||
|
})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin0.MethodsPaych.UpdateChannelState,
|
||||||
|
Params: params,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message0) Settle(paych address.Address) (*types.Message, error) {
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin0.MethodsPaych.Settle,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message0) Collect(paych address.Address) (*types.Message, error) {
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin0.MethodsPaych.Collect,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package paych
|
||||||
|
|
||||||
|
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"
|
||||||
|
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
|
||||||
|
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type message2 struct{ from address.Address }
|
||||||
|
|
||||||
|
func (m message2) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
|
||||||
|
params, aerr := actors.SerializeParams(&paych2.ConstructorParams{From: m.from, To: to})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
enc, aerr := actors.SerializeParams(&init2.ExecParams{
|
||||||
|
CodeCID: builtin2.PaymentChannelActorCodeID,
|
||||||
|
ConstructorParams: params,
|
||||||
|
})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: init_.Address,
|
||||||
|
From: m.from,
|
||||||
|
Value: initialAmount,
|
||||||
|
Method: builtin2.MethodsInit.Exec,
|
||||||
|
Params: enc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message2) Update(paych address.Address, sv *SignedVoucher, secret []byte) (*types.Message, error) {
|
||||||
|
params, aerr := actors.SerializeParams(&paych2.UpdateChannelStateParams{
|
||||||
|
Sv: *sv,
|
||||||
|
Secret: secret,
|
||||||
|
})
|
||||||
|
if aerr != nil {
|
||||||
|
return nil, aerr
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin2.MethodsPaych.UpdateChannelState,
|
||||||
|
Params: params,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message2) Settle(paych address.Address) (*types.Message, error) {
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin2.MethodsPaych.Settle,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m message2) Collect(paych address.Address) (*types.Message, error) {
|
||||||
|
return &types.Message{
|
||||||
|
To: paych,
|
||||||
|
From: m.from,
|
||||||
|
Value: abi.NewTokenAmount(0),
|
||||||
|
Method: builtin2.MethodsPaych.Collect,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -27,10 +27,9 @@ type mockLaneState struct {
|
|||||||
func NewMockPayChState(from address.Address,
|
func NewMockPayChState(from address.Address,
|
||||||
to address.Address,
|
to address.Address,
|
||||||
settlingAt abi.ChainEpoch,
|
settlingAt abi.ChainEpoch,
|
||||||
toSend abi.TokenAmount,
|
|
||||||
lanes map[uint64]paych.LaneState,
|
lanes map[uint64]paych.LaneState,
|
||||||
) paych.State {
|
) paych.State {
|
||||||
return &mockState{from, to, settlingAt, toSend, lanes}
|
return &mockState{from: from, to: to, settlingAt: settlingAt, toSend: big.NewInt(0), lanes: lanes}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMockLaneState constructs a state for a payment channel lane with the set fixed values
|
// NewMockLaneState constructs a state for a payment channel lane with the set fixed values
|
||||||
|
|||||||
@@ -1,29 +1,42 @@
|
|||||||
package paych
|
package paych
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
big "github.com/filecoin-project/go-state-types/big"
|
big "github.com/filecoin-project/go-state-types/big"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
ipldcbor "github.com/ipfs/go-ipld-cbor"
|
||||||
|
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.PaymentChannelActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.PaymentChannelActorCodeID:
|
case builtin0.PaymentChannelActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.PaymentChannelActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -58,3 +71,18 @@ type LaneState interface {
|
|||||||
|
|
||||||
type SignedVoucher = paych0.SignedVoucher
|
type SignedVoucher = paych0.SignedVoucher
|
||||||
type ModVerifyParams = paych0.ModVerifyParams
|
type ModVerifyParams = paych0.ModVerifyParams
|
||||||
|
|
||||||
|
// DecodeSignedVoucher decodes base64 encoded signed voucher.
|
||||||
|
func DecodeSignedVoucher(s string) (*SignedVoucher, error) {
|
||||||
|
data, err := base64.RawURLEncoding.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var sv SignedVoucher
|
||||||
|
if err := ipldcbor.DecodeInto(data, &sv); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sv, nil
|
||||||
|
}
|
||||||
@@ -1,18 +1,31 @@
|
|||||||
package paych
|
package paych
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
big "github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
|
||||||
|
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
paych.State
|
paych0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
lsAmt *adt0.Array
|
lsAmt *adt0.Array
|
||||||
}
|
}
|
||||||
@@ -72,14 +85,14 @@ func (s *state0) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error
|
|||||||
// Note: we use a map instead of an array to store laneStates because the
|
// Note: we use a map instead of an array to store laneStates because the
|
||||||
// client sets the lane ID (the index) and potentially they could use a
|
// client sets the lane ID (the index) and potentially they could use a
|
||||||
// very large index.
|
// very large index.
|
||||||
var ls paych.LaneState
|
var ls paych0.LaneState
|
||||||
return lsamt.ForEach(&ls, func(i int64) error {
|
return lsamt.ForEach(&ls, func(i int64) error {
|
||||||
return cb(uint64(i), &laneState0{ls})
|
return cb(uint64(i), &laneState0{ls})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type laneState0 struct {
|
type laneState0 struct {
|
||||||
paych.LaneState
|
paych0.LaneState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls *laneState0) Redeemed() (big.Int, error) {
|
func (ls *laneState0) Redeemed() (big.Int, error) {
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package paych
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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/big"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
paych2.State
|
||||||
|
store adt.Store
|
||||||
|
lsAmt *adt2.Array
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel owner, who has funded the actor
|
||||||
|
func (s *state2) From() (address.Address, error) {
|
||||||
|
return s.State.From, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recipient of payouts from channel
|
||||||
|
func (s *state2) To() (address.Address, error) {
|
||||||
|
return s.State.To, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Height at which the channel can be `Collected`
|
||||||
|
func (s *state2) SettlingAt() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.SettlingAt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||||
|
func (s *state2) ToSend() (abi.TokenAmount, error) {
|
||||||
|
return s.State.ToSend, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) getOrLoadLsAmt() (*adt2.Array, error) {
|
||||||
|
if s.lsAmt != nil {
|
||||||
|
return s.lsAmt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the lane state from the chain
|
||||||
|
lsamt, err := adt2.AsArray(s.store, s.State.LaneStates)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.lsAmt = lsamt
|
||||||
|
return lsamt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total number of lanes
|
||||||
|
func (s *state2) LaneCount() (uint64, error) {
|
||||||
|
lsamt, err := s.getOrLoadLsAmt()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return lsamt.Length(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate lane states
|
||||||
|
func (s *state2) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
|
||||||
|
// Get the lane state from the chain
|
||||||
|
lsamt, err := s.getOrLoadLsAmt()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: we use a map instead of an array to store laneStates because the
|
||||||
|
// client sets the lane ID (the index) and potentially they could use a
|
||||||
|
// very large index.
|
||||||
|
var ls paych2.LaneState
|
||||||
|
return lsamt.ForEach(&ls, func(i int64) error {
|
||||||
|
return cb(uint64(i), &laneState2{ls})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type laneState2 struct {
|
||||||
|
paych2.LaneState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls *laneState2) Redeemed() (big.Int, error) {
|
||||||
|
return ls.LaneState.Redeemed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls *laneState2) Nonce() (uint64, error) {
|
||||||
|
return ls.LaneState.Nonce, nil
|
||||||
|
}
|
||||||
@@ -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,28 +2,42 @@ package power
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"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"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
|
||||||
|
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Address = builtin0.StoragePowerActorAddr
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.StoragePowerActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Address = builtin2.StoragePowerActorAddr
|
||||||
|
Methods = builtin2.MethodsPower
|
||||||
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.StoragePowerActorCodeID:
|
case builtin0.StoragePowerActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.StoragePowerActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -42,6 +56,12 @@ type State interface {
|
|||||||
MinerPower(address.Address) (Claim, bool, error)
|
MinerPower(address.Address) (Claim, bool, error)
|
||||||
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
||||||
ListAllMiners() ([]address.Address, 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 {
|
type Claim struct {
|
||||||
@@ -51,3 +71,10 @@ type Claim struct {
|
|||||||
// Sum of quality adjusted power for a miner's sectors.
|
// Sum of quality adjusted power for a miner's sectors.
|
||||||
QualityAdjPower abi.StoragePower
|
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,15 +1,31 @@
|
|||||||
package power
|
package power
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"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"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
|
|
||||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
power0.State
|
power0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
@@ -35,7 +51,7 @@ func (s *state0) TotalCommitted() (Claim, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
|
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||||
claims, err := adt.AsMap(s.store, s.Claims)
|
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Claim{}, false, err
|
return Claim{}, false, err
|
||||||
}
|
}
|
||||||
@@ -63,7 +79,7 @@ func (s *state0) MinerCounts() (uint64, uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) ListAllMiners() ([]address.Address, error) {
|
func (s *state0) ListAllMiners() ([]address.Address, error) {
|
||||||
claims, err := adt.AsMap(s.store, s.Claims)
|
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -83,3 +99,47 @@ func (s *state0) ListAllMiners() ([]address.Address, error) {
|
|||||||
|
|
||||||
return miners, nil
|
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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power"
|
||||||
|
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
power2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) TotalLocked() (abi.TokenAmount, error) {
|
||||||
|
return s.TotalPledgeCollateral, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) TotalPower() (Claim, error) {
|
||||||
|
return Claim{
|
||||||
|
RawBytePower: s.TotalRawBytePower,
|
||||||
|
QualityAdjPower: s.TotalQualityAdjPower,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Committed power to the network. Includes miners below the minimum threshold.
|
||||||
|
func (s *state2) TotalCommitted() (Claim, error) {
|
||||||
|
return Claim{
|
||||||
|
RawBytePower: s.TotalBytesCommitted,
|
||||||
|
QualityAdjPower: s.TotalQABytesCommitted,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||||
|
claims, err := adt2.AsMap(s.store, s.Claims)
|
||||||
|
if err != nil {
|
||||||
|
return Claim{}, false, err
|
||||||
|
}
|
||||||
|
var claim power2.Claim
|
||||||
|
ok, err := claims.Get(abi.AddrKey(addr), &claim)
|
||||||
|
if err != nil {
|
||||||
|
return Claim{}, false, err
|
||||||
|
}
|
||||||
|
return Claim{
|
||||||
|
RawBytePower: claim.RawBytePower,
|
||||||
|
QualityAdjPower: claim.QualityAdjPower,
|
||||||
|
}, ok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
||||||
|
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
||||||
|
return builtin.FromV2FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) MinerCounts() (uint64, uint64, error) {
|
||||||
|
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ListAllMiners() ([]address.Address, error) {
|
||||||
|
claims, err := adt2.AsMap(s.store, s.Claims)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var miners []address.Address
|
||||||
|
err = claims.ForEach(nil, func(k string) error {
|
||||||
|
a, err := address.NewFromBytes([]byte(k))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
miners = append(miners, a)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,27 +3,38 @@ package reward
|
|||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "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/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Address = builtin0.RewardActorAddr
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.RewardActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Address = builtin2.RewardActorAddr
|
||||||
|
Methods = builtin2.MethodsReward
|
||||||
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.RewardActorCodeID:
|
case builtin0.RewardActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.RewardActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,29 @@ package reward
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
|
|
||||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
reward.State
|
reward0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +57,7 @@ func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) CumsumRealized() (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) {
|
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||||
@@ -54,7 +66,7 @@ func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTot
|
|||||||
s.State.ThisEpochBaselinePower,
|
s.State.ThisEpochBaselinePower,
|
||||||
networkTotalPledge,
|
networkTotalPledge,
|
||||||
s.State.ThisEpochRewardSmoothed,
|
s.State.ThisEpochRewardSmoothed,
|
||||||
&smoothing.FilterEstimate{
|
&smoothing0.FilterEstimate{
|
||||||
PositionEstimate: networkQAPower.PositionEstimate,
|
PositionEstimate: networkQAPower.PositionEstimate,
|
||||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||||
},
|
},
|
||||||
@@ -63,7 +75,7 @@ func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTot
|
|||||||
|
|
||||||
func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
||||||
return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
||||||
&smoothing.FilterEstimate{
|
&smoothing0.FilterEstimate{
|
||||||
PositionEstimate: networkQAPower.PositionEstimate,
|
PositionEstimate: networkQAPower.PositionEstimate,
|
||||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package reward
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
|
|
||||||
|
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||||
|
reward2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/reward"
|
||||||
|
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
reward2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ThisEpochReward() (abi.TokenAmount, error) {
|
||||||
|
return s.State.ThisEpochReward, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||||
|
return builtin.FilterEstimate{
|
||||||
|
PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
|
||||||
|
VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||||
|
return s.State.ThisEpochBaselinePower, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
||||||
|
return s.State.TotalStoragePowerReward, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) EffectiveBaselinePower() (abi.StoragePower, error) {
|
||||||
|
return s.State.EffectiveBaselinePower, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||||
|
return s.State.EffectiveNetworkTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) CumsumBaseline() (reward2.Spacetime, 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) {
|
||||||
|
return miner2.InitialPledgeForPower(
|
||||||
|
qaPower,
|
||||||
|
s.State.ThisEpochBaselinePower,
|
||||||
|
s.State.ThisEpochRewardSmoothed,
|
||||||
|
smoothing2.FilterEstimate{
|
||||||
|
PositionEstimate: networkQAPower.PositionEstimate,
|
||||||
|
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||||
|
},
|
||||||
|
circSupply,
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
||||||
|
return miner2.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
||||||
|
smoothing2.FilterEstimate{
|
||||||
|
PositionEstimate: networkQAPower.PositionEstimate,
|
||||||
|
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||||
|
},
|
||||||
|
sectorWeight), nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package verifreg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getDataCap(store adt.Store, ver actors.Version, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
|
if addr.Protocol() != address.ID {
|
||||||
|
return false, big.Zero(), xerrors.Errorf("can only look up ID addresses")
|
||||||
|
}
|
||||||
|
|
||||||
|
vh, err := adt.AsMap(store, root, ver)
|
||||||
|
if err != nil {
|
||||||
|
return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dcap abi.StoragePower
|
||||||
|
if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil {
|
||||||
|
return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err)
|
||||||
|
} else if !found {
|
||||||
|
return false, big.Zero(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, dcap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func forEachCap(store adt.Store, ver actors.Version, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
|
vh, err := adt.AsMap(store, root, ver)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("loading verified clients: %w", err)
|
||||||
|
}
|
||||||
|
var dcap abi.StoragePower
|
||||||
|
return vh.ForEach(&dcap, func(key string) error {
|
||||||
|
a, err := address.NewFromBytes([]byte(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cb(a, dcap)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -3,69 +3,46 @@ package verifreg
|
|||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
|
||||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ State = (*state0)(nil)
|
var _ State = (*state0)(nil)
|
||||||
|
|
||||||
|
func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state0{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type state0 struct {
|
type state0 struct {
|
||||||
verifreg0.State
|
verifreg0.State
|
||||||
store adt.Store
|
store adt.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDataCap(store adt.Store, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state0) RootKey() (address.Address, error) {
|
||||||
if addr.Protocol() != address.ID {
|
return s.State.RootKey, nil
|
||||||
return false, big.Zero(), xerrors.Errorf("can only look up ID addresses")
|
|
||||||
}
|
|
||||||
|
|
||||||
vh, err := adt0.AsMap(store, root)
|
|
||||||
if err != nil {
|
|
||||||
return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var dcap abi.StoragePower
|
|
||||||
if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil {
|
|
||||||
return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err)
|
|
||||||
} else if !found {
|
|
||||||
return false, big.Zero(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, dcap, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
return getDataCap(s.store, s.State.VerifiedClients, addr)
|
return getDataCap(s.store, actors.Version0, s.State.VerifiedClients, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
return getDataCap(s.store, s.State.Verifiers, addr)
|
return getDataCap(s.store, actors.Version0, s.State.Verifiers, addr)
|
||||||
}
|
|
||||||
|
|
||||||
func forEachCap(store adt.Store, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
|
||||||
vh, err := adt0.AsMap(store, root)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("loading verified clients: %w", err)
|
|
||||||
}
|
|
||||||
var dcap abi.StoragePower
|
|
||||||
return vh.ForEach(&dcap, func(key string) error {
|
|
||||||
a, err := address.NewFromBytes([]byte(key))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return cb(a, dcap)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, s.State.Verifiers, cb)
|
return forEachCap(s.store, actors.Version0, s.State.Verifiers, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
return forEachCap(s.store, s.State.VerifiedClients, cb)
|
return forEachCap(s.store, actors.Version0, s.State.VerifiedClients, cb)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package verifreg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
|
||||||
|
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ State = (*state2)(nil)
|
||||||
|
|
||||||
|
func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||||
|
out := state2{store: store}
|
||||||
|
err := store.Get(store.Context(), root, &out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type state2 struct {
|
||||||
|
verifreg2.State
|
||||||
|
store adt.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) RootKey() (address.Address, error) {
|
||||||
|
return s.State.RootKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
|
return getDataCap(s.store, actors.Version2, s.State.VerifiedClients, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||||
|
return getDataCap(s.store, actors.Version2, s.State.Verifiers, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
|
return forEachCap(s.store, actors.Version2, s.State.Verifiers, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state2) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||||
|
return forEachCap(s.store, actors.Version2, s.State.VerifiedClients, cb)
|
||||||
|
}
|
||||||
@@ -3,26 +3,38 @@ package verifreg
|
|||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/cbor"
|
"github.com/filecoin-project/go-state-types/cbor"
|
||||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
builtin0 "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/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Address = builtin0.VerifiedRegistryActorAddr
|
func init() {
|
||||||
|
builtin.RegisterActorState(builtin0.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load0(store, root)
|
||||||
|
})
|
||||||
|
builtin.RegisterActorState(builtin2.VerifiedRegistryActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||||
|
return load2(store, root)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Address = builtin2.VerifiedRegistryActorAddr
|
||||||
|
Methods = builtin2.MethodsVerifiedRegistry
|
||||||
|
)
|
||||||
|
|
||||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||||
switch act.Code {
|
switch act.Code {
|
||||||
case builtin0.VerifiedRegistryActorCodeID:
|
case builtin0.VerifiedRegistryActorCodeID:
|
||||||
out := state0{store: store}
|
return load0(store, act.Head)
|
||||||
err := store.Get(store.Context(), act.Head, &out)
|
case builtin2.VerifiedRegistryActorCodeID:
|
||||||
if err != nil {
|
return load2(store, act.Head)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &out, nil
|
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||||
}
|
}
|
||||||
@@ -30,6 +42,7 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
|
|||||||
type State interface {
|
type State interface {
|
||||||
cbor.Marshaler
|
cbor.Marshaler
|
||||||
|
|
||||||
|
RootKey() (address.Address, error)
|
||||||
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||||
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||||
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package actors
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/lotus/chain/actors/aerrors"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
)
|
)
|
||||||
@@ -11,7 +13,7 @@ func SerializeParams(i cbg.CBORMarshaler) ([]byte, aerrors.ActorError) {
|
|||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
if err := i.MarshalCBOR(buf); err != nil {
|
if err := i.MarshalCBOR(buf); err != nil {
|
||||||
// TODO: shouldnt this be a fatal error?
|
// 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
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
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"
|
||||||
|
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
|
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
|
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) {
|
||||||
|
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.PreCommitSealProofTypesV0[t] = struct{}{}
|
||||||
|
|
||||||
|
miner2.PreCommitSealProofTypesV7[t] = struct{}{}
|
||||||
|
miner2.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||||
|
|
||||||
|
miner2.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPreCommitChallengeDelay sets the pre-commit challenge delay across all
|
||||||
|
// actors versions. Use for testing.
|
||||||
|
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
|
||||||
|
// Set for all miner versions.
|
||||||
|
miner0.PreCommitChallengeDelay = delay
|
||||||
|
miner2.PreCommitChallengeDelay = delay
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
|
||||||
|
func GetPreCommitChallengeDelay() abi.ChainEpoch {
|
||||||
|
return miner0.PreCommitChallengeDelay
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
|
||||||
|
// meet for leader election, across all actor versions. This should only be used
|
||||||
|
// for testing.
|
||||||
|
func SetConsensusMinerMinPower(p abi.StoragePower) {
|
||||||
|
power0.ConsensusMinerMinPower = p
|
||||||
|
for _, policy := range builtin2.SealProofPolicies {
|
||||||
|
policy.ConsensusMinerMinPower = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
|
||||||
|
// only be used for testing.
|
||||||
|
func SetMinVerifiedDealSize(size abi.StoragePower) {
|
||||||
|
verifreg0.MinVerifiedDealSize = size
|
||||||
|
verifreg2.MinVerifiedDealSize = size
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch {
|
||||||
|
switch ver {
|
||||||
|
case actors.Version0:
|
||||||
|
return miner0.MaxSealDuration[t]
|
||||||
|
case actors.Version2:
|
||||||
|
return miner2.MaxProveCommitDuration[t]
|
||||||
|
default:
|
||||||
|
panic("unsupported actors version")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DealProviderCollateralBounds(
|
||||||
|
size abi.PaddedPieceSize, verified bool,
|
||||||
|
rawBytePower, qaPower, baselinePower abi.StoragePower,
|
||||||
|
circulatingFil abi.TokenAmount, nwVer network.Version,
|
||||||
|
) (min, max abi.TokenAmount) {
|
||||||
|
switch actors.VersionForNetwork(nwVer) {
|
||||||
|
case actors.Version0:
|
||||||
|
return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer)
|
||||||
|
case actors.Version2:
|
||||||
|
return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
|
||||||
|
default:
|
||||||
|
panic("unsupported network version")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the challenge window and scales the proving period to match (such that
|
||||||
|
// there are always 48 challenge windows in a proving period).
|
||||||
|
func SetWPoStChallengeWindow(period abi.ChainEpoch) {
|
||||||
|
miner0.WPoStChallengeWindow = period
|
||||||
|
miner0.WPoStProvingPeriod = period * abi.ChainEpoch(miner0.WPoStPeriodDeadlines)
|
||||||
|
|
||||||
|
miner2.WPoStChallengeWindow = period
|
||||||
|
miner2.WPoStProvingPeriod = period * abi.ChainEpoch(miner2.WPoStPeriodDeadlines)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
|
||||||
|
if nwVer <= network.Version3 {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package policy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSupportedProofTypes(t *testing.T) {
|
||||||
|
var oldTypes []abi.RegisteredSealProof
|
||||||
|
for t := range miner0.SupportedProofTypes {
|
||||||
|
oldTypes = append(oldTypes, t)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
SetSupportedProofTypes(oldTypes...)
|
||||||
|
})
|
||||||
|
|
||||||
|
SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||||
|
require.EqualValues(t,
|
||||||
|
miner0.SupportedProofTypes,
|
||||||
|
map[abi.RegisteredSealProof]struct{}{
|
||||||
|
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1)
|
||||||
|
require.EqualValues(t,
|
||||||
|
miner0.SupportedProofTypes,
|
||||||
|
map[abi.RegisteredSealProof]struct{}{
|
||||||
|
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||||
|
abi.RegisteredSealProof_StackedDrg8MiBV1: {},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests assumptions about policies being the same between actor versions.
|
||||||
|
func TestAssumptions(t *testing.T) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package actors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Version int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Version0 Version = 0
|
||||||
|
Version2 Version = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Converts a network version into an actors adt version.
|
||||||
|
func VersionForNetwork(version network.Version) Version {
|
||||||
|
switch version {
|
||||||
|
case network.Version0, network.Version1, network.Version2, network.Version3:
|
||||||
|
return Version0
|
||||||
|
case network.Version4, network.Version5, network.Version6, 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)
|
bts.badBlocks.Remove(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bts *BadBlockCache) Purge() {
|
||||||
|
bts.badBlocks.Purge()
|
||||||
|
}
|
||||||
|
|
||||||
func (bts *BadBlockCache) Has(c cid.Cid) (BadBlockReason, bool) {
|
func (bts *BadBlockCache) Has(c cid.Cid) (BadBlockReason, bool) {
|
||||||
rval, ok := bts.badBlocks.Get(c)
|
rval, ok := bts.badBlocks.Get(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ type DrandBeacon struct {
|
|||||||
localCache map[uint64]types.BeaconEntry
|
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) {
|
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) {
|
||||||
if genesisTs == 0 {
|
if genesisTs == 0 {
|
||||||
panic("what are you doing this cant be zero")
|
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 {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("could not create http drand client: %w", err)
|
return nil, xerrors.Errorf("could not create http drand client: %w", err)
|
||||||
}
|
}
|
||||||
|
hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.BuildVersion)
|
||||||
clients = append(clients, hc)
|
clients = append(clients, hc)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -92,7 +98,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
|
|||||||
dclient.WithChainInfo(drandChain),
|
dclient.WithChainInfo(drandChain),
|
||||||
dclient.WithCacheSize(1024),
|
dclient.WithCacheSize(1024),
|
||||||
dclient.WithLogger(dlogger),
|
dclient.WithLogger(dlogger),
|
||||||
dclient.WithAutoWatch(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ps != nil {
|
if ps != nil {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestPrintGroupInfo(t *testing.T) {
|
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)
|
c, err := hclient.New(server, nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
cg := c.(interface {
|
cg := c.(interface {
|
||||||
|
|||||||
+26
-15
@@ -20,8 +20,10 @@ import (
|
|||||||
var log = logging.Logger("events")
|
var log = logging.Logger("events")
|
||||||
|
|
||||||
// HeightHandler `curH`-`ts.Height` = `confidence`
|
// HeightHandler `curH`-`ts.Height` = `confidence`
|
||||||
type HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error
|
type (
|
||||||
type RevertHandler func(ctx context.Context, ts *types.TipSet) error
|
HeightHandler func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error
|
||||||
|
RevertHandler func(ctx context.Context, ts *types.TipSet) error
|
||||||
|
)
|
||||||
|
|
||||||
type heightHandler struct {
|
type heightHandler struct {
|
||||||
confidence int
|
confidence int
|
||||||
@@ -48,7 +50,7 @@ type Events struct {
|
|||||||
tsc *tipSetCache
|
tsc *tipSetCache
|
||||||
lk sync.Mutex
|
lk sync.Mutex
|
||||||
|
|
||||||
ready sync.WaitGroup
|
ready chan struct{}
|
||||||
readyOnce sync.Once
|
readyOnce sync.Once
|
||||||
|
|
||||||
heightEvents
|
heightEvents
|
||||||
@@ -76,15 +78,16 @@ func NewEvents(ctx context.Context, api eventAPI) *Events {
|
|||||||
},
|
},
|
||||||
|
|
||||||
hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
|
hcEvents: newHCEvents(ctx, api, tsc, uint64(gcConfidence)),
|
||||||
|
ready: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
e.ready.Add(1)
|
|
||||||
|
|
||||||
go e.listenHeadChanges(ctx)
|
go e.listenHeadChanges(ctx)
|
||||||
|
|
||||||
e.ready.Wait()
|
// Wait for the first tipset to be seen or bail if shutting down
|
||||||
|
select {
|
||||||
// TODO: cleanup/gc goroutine
|
case <-e.ready:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
@@ -111,13 +114,21 @@ func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
|
|||||||
|
|
||||||
notifs, err := e.api.ChainNotify(ctx)
|
notifs, err := e.api.ChainNotify(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: retry
|
// Retry is handled by caller
|
||||||
return xerrors.Errorf("listenHeadChanges ChainNotify call failed: %w", err)
|
return xerrors.Errorf("listenHeadChanges ChainNotify call failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cur, ok := <-notifs // TODO: timeout?
|
var cur []*api.HeadChange
|
||||||
if !ok {
|
var ok bool
|
||||||
return xerrors.Errorf("notification channel closed")
|
|
||||||
|
// 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 {
|
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 {
|
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.readyOnce.Do(func() {
|
||||||
e.lastTs = cur[0].Val
|
e.lastTs = cur[0].Val
|
||||||
|
// Signal that we have seen first tipset
|
||||||
e.ready.Done()
|
close(e.ready)
|
||||||
})
|
})
|
||||||
|
|
||||||
for notif := range notifs {
|
for notif := range notifs {
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ type messageEvents struct {
|
|||||||
hcAPI headChangeAPI
|
hcAPI headChangeAPI
|
||||||
|
|
||||||
lk sync.RWMutex
|
lk sync.RWMutex
|
||||||
matchers map[triggerID][]MsgMatchFunc
|
matchers map[triggerID]MsgMatchFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) messageEvents {
|
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,
|
ctx: ctx,
|
||||||
cs: cs,
|
cs: cs,
|
||||||
hcAPI: hcAPI,
|
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()
|
me.lk.RLock()
|
||||||
defer me.lk.RUnlock()
|
defer me.lk.RUnlock()
|
||||||
|
|
||||||
|
// For each message in the tipset
|
||||||
res := make(map[triggerID]eventData)
|
res := make(map[triggerID]eventData)
|
||||||
me.messagesForTs(pts, func(msg *types.Message) {
|
me.messagesForTs(pts, func(msg *types.Message) {
|
||||||
// TODO: provide receipts
|
// TODO: provide receipts
|
||||||
|
|
||||||
for tid, matchFns := range me.matchers {
|
// Run each trigger's matcher against the message
|
||||||
var matched bool
|
for tid, matchFn := range me.matchers {
|
||||||
var once bool
|
matched, err := matchFn(msg)
|
||||||
for _, matchFn := range matchFns {
|
if err != nil {
|
||||||
matchOne, ok, err := matchFn(msg)
|
log.Errorf("event matcher failed: %s", err)
|
||||||
if err != nil {
|
continue
|
||||||
log.Errorf("event matcher failed: %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
matched = ok
|
|
||||||
once = matchOne
|
|
||||||
|
|
||||||
if matched {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there was a match, include the message in the results for the
|
||||||
|
// trigger
|
||||||
if matched {
|
if matched {
|
||||||
res[tid] = msg
|
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`
|
// `curH`-`ts.Height` = `confidence`
|
||||||
type MsgHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error)
|
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 registers a callback which is triggered when a specified method is
|
||||||
// called on an actor, or a timeout is reached.
|
// 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()
|
me.lk.Lock()
|
||||||
defer me.lk.Unlock()
|
defer me.lk.Unlock()
|
||||||
me.matchers[id] = append(me.matchers[id], mf)
|
me.matchers[id] = mf
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence
|
|||||||
|
|
||||||
best, err := e.tsc.best()
|
best, err := e.tsc.best()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e.lk.Unlock()
|
||||||
return xerrors.Errorf("error getting best tipset: %w", err)
|
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()
|
e.lk.Lock()
|
||||||
best, err = e.tsc.best()
|
best, err = e.tsc.best()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e.lk.Unlock()
|
||||||
return xerrors.Errorf("error getting best tipset: %w", err)
|
return xerrors.Errorf("error getting best tipset: %w", err)
|
||||||
}
|
}
|
||||||
bestH = best.Height()
|
bestH = best.Height()
|
||||||
|
|||||||
@@ -572,9 +572,9 @@ func TestAtChainedConfidenceNull(t *testing.T) {
|
|||||||
require.Equal(t, false, reverted)
|
require.Equal(t, false, reverted)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (matchOnce bool, matched bool, err error) {
|
func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (matched bool, err error) {
|
||||||
return func(msg *types.Message) (matchOnce bool, matched bool, err error) {
|
return func(msg *types.Message) (matched bool, err error) {
|
||||||
return true, to == msg.To && m == msg.Method, nil
|
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
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"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/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
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/api/apibstore"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||||
@@ -419,179 +417,17 @@ type AddressPair struct {
|
|||||||
PK address.Address
|
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)
|
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 {
|
func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
|
||||||
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
|
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
|
||||||
addressChanges := &InitActorAddressChanges{
|
addressChanges, err := init_.DiffAddressMap(oldState, newState)
|
||||||
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
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
if len(addressChanges.Added)+len(addressChanges.Modified)+len(addressChanges.Removed) == 0 {
|
||||||
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 {
|
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, addressChanges, nil
|
return true, addressChanges, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,28 +4,26 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
test "github.com/filecoin-project/lotus/chain/events/state/mock"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbornode "github.com/ipfs/go-ipld-cbor"
|
cbornode "github.com/ipfs/go-ipld-cbor"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"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"
|
"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"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||||
)
|
)
|
||||||
@@ -36,60 +34,27 @@ func init() {
|
|||||||
dummyCid, _ = cid.Parse("bafkqaaa")
|
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) {
|
func TestMarketPredicates(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := bstore.NewTemporarySync()
|
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,
|
SectorStartEpoch: 1,
|
||||||
LastUpdatedEpoch: 2,
|
LastUpdatedEpoch: 2,
|
||||||
SlashEpoch: 0,
|
SlashEpoch: 0,
|
||||||
}
|
}
|
||||||
oldDeal2 := &market0.DealState{
|
oldDeal2 := &market2.DealState{
|
||||||
SectorStartEpoch: 4,
|
SectorStartEpoch: 4,
|
||||||
LastUpdatedEpoch: 5,
|
LastUpdatedEpoch: 5,
|
||||||
SlashEpoch: 0,
|
SlashEpoch: 0,
|
||||||
}
|
}
|
||||||
oldDeals := map[abi.DealID]*market0.DealState{
|
oldDeals := map[abi.DealID]*market2.DealState{
|
||||||
abi.DealID(1): oldDeal1,
|
abi.DealID(1): oldDeal1,
|
||||||
abi.DealID(2): oldDeal2,
|
abi.DealID(2): oldDeal2,
|
||||||
}
|
}
|
||||||
|
|
||||||
oldProp1 := &market0.DealProposal{
|
oldProp1 := &market2.DealProposal{
|
||||||
PieceCID: dummyCid,
|
PieceCID: dummyCid,
|
||||||
PieceSize: 0,
|
PieceSize: 0,
|
||||||
VerifiedDeal: false,
|
VerifiedDeal: false,
|
||||||
@@ -101,7 +66,7 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
ProviderCollateral: big.Zero(),
|
ProviderCollateral: big.Zero(),
|
||||||
ClientCollateral: big.Zero(),
|
ClientCollateral: big.Zero(),
|
||||||
}
|
}
|
||||||
oldProp2 := &market0.DealProposal{
|
oldProp2 := &market2.DealProposal{
|
||||||
PieceCID: dummyCid,
|
PieceCID: dummyCid,
|
||||||
PieceSize: 0,
|
PieceSize: 0,
|
||||||
VerifiedDeal: false,
|
VerifiedDeal: false,
|
||||||
@@ -113,7 +78,7 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
ProviderCollateral: big.Zero(),
|
ProviderCollateral: big.Zero(),
|
||||||
ClientCollateral: big.Zero(),
|
ClientCollateral: big.Zero(),
|
||||||
}
|
}
|
||||||
oldProps := map[abi.DealID]*market0.DealProposal{
|
oldProps := map[abi.DealID]*market2.DealProposal{
|
||||||
abi.DealID(1): oldProp1,
|
abi.DealID(1): oldProp1,
|
||||||
abi.DealID(2): oldProp2,
|
abi.DealID(2): oldProp2,
|
||||||
}
|
}
|
||||||
@@ -127,7 +92,7 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
|
|
||||||
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
|
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
|
||||||
|
|
||||||
newDeal1 := &market0.DealState{
|
newDeal1 := &market2.DealState{
|
||||||
SectorStartEpoch: 1,
|
SectorStartEpoch: 1,
|
||||||
LastUpdatedEpoch: 3,
|
LastUpdatedEpoch: 3,
|
||||||
SlashEpoch: 0,
|
SlashEpoch: 0,
|
||||||
@@ -136,19 +101,19 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
// deal 2 removed
|
// deal 2 removed
|
||||||
|
|
||||||
// added
|
// added
|
||||||
newDeal3 := &market0.DealState{
|
newDeal3 := &market2.DealState{
|
||||||
SectorStartEpoch: 1,
|
SectorStartEpoch: 1,
|
||||||
LastUpdatedEpoch: 2,
|
LastUpdatedEpoch: 2,
|
||||||
SlashEpoch: 3,
|
SlashEpoch: 3,
|
||||||
}
|
}
|
||||||
newDeals := map[abi.DealID]*market0.DealState{
|
newDeals := map[abi.DealID]*market2.DealState{
|
||||||
abi.DealID(1): newDeal1,
|
abi.DealID(1): newDeal1,
|
||||||
// deal 2 was removed
|
// deal 2 was removed
|
||||||
abi.DealID(3): newDeal3,
|
abi.DealID(3): newDeal3,
|
||||||
}
|
}
|
||||||
|
|
||||||
// added
|
// added
|
||||||
newProp3 := &market0.DealProposal{
|
newProp3 := &market2.DealProposal{
|
||||||
PieceCID: dummyCid,
|
PieceCID: dummyCid,
|
||||||
PieceSize: 0,
|
PieceSize: 0,
|
||||||
VerifiedDeal: false,
|
VerifiedDeal: false,
|
||||||
@@ -160,7 +125,7 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
ProviderCollateral: big.Zero(),
|
ProviderCollateral: big.Zero(),
|
||||||
ClientCollateral: big.Zero(),
|
ClientCollateral: big.Zero(),
|
||||||
}
|
}
|
||||||
newProps := map[abi.DealID]*market0.DealProposal{
|
newProps := map[abi.DealID]*market2.DealProposal{
|
||||||
abi.DealID(1): oldProp1, // 1 was persisted
|
abi.DealID(1): oldProp1, // 1 was persisted
|
||||||
// prop 2 was removed
|
// prop 2 was removed
|
||||||
abi.DealID(3): newProp3, // new
|
abi.DealID(3): newProp3, // new
|
||||||
@@ -177,14 +142,14 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
|
|
||||||
minerAddr, err := address.NewFromString("t00")
|
minerAddr, err := address.NewFromString("t00")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
oldState, err := mockTipset(minerAddr, 1)
|
oldState, err := test.MockTipset(minerAddr, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
newState, err := mockTipset(minerAddr, 2)
|
newState, err := test.MockTipset(minerAddr, 2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
api := newMockAPI(bs)
|
api := test.NewMockAPI(bs)
|
||||||
api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC})
|
api.SetActor(oldState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: oldStateC})
|
||||||
api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC})
|
api.SetActor(newState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: newStateC})
|
||||||
|
|
||||||
t.Run("deal ID predicate", func(t *testing.T) {
|
t.Run("deal ID predicate", func(t *testing.T) {
|
||||||
preds := NewStatePredicates(api)
|
preds := NewStatePredicates(api)
|
||||||
@@ -239,11 +204,11 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
t.Fatal("No state change so this should not be called")
|
t.Fatal("No state change so this should not be called")
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
})
|
})
|
||||||
marketState0 := createEmptyMarketState(t, store)
|
marketState0 := test.CreateEmptyMarketState(t, store)
|
||||||
marketCid, err := store.Put(ctx, marketState0)
|
marketCid, err := store.Put(ctx, marketState0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
marketState, err := market.Load(store, &types.Actor{
|
marketState, err := market.Load(store, &types.Actor{
|
||||||
Code: builtin0.StorageMarketActorCodeID,
|
Code: builtin2.StorageMarketActorCodeID,
|
||||||
Head: marketCid,
|
Head: marketCid,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -352,11 +317,11 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
t.Fatal("No state change so this should not be called")
|
t.Fatal("No state change so this should not be called")
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
})
|
})
|
||||||
marketState0 := createEmptyMarketState(t, store)
|
marketState0 := test.CreateEmptyMarketState(t, store)
|
||||||
marketCid, err := store.Put(ctx, marketState0)
|
marketCid, err := store.Put(ctx, marketState0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
marketState, err := market.Load(store, &types.Actor{
|
marketState, err := market.Load(store, &types.Actor{
|
||||||
Code: builtin0.StorageMarketActorCodeID,
|
Code: builtin2.StorageMarketActorCodeID,
|
||||||
Head: marketCid,
|
Head: marketCid,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -370,7 +335,7 @@ func TestMarketPredicates(t *testing.T) {
|
|||||||
func TestMinerSectorChange(t *testing.T) {
|
func TestMinerSectorChange(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
bs := bstore.NewTemporarySync()
|
bs := bstore.NewTemporarySync()
|
||||||
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||||
|
|
||||||
nextID := uint64(0)
|
nextID := uint64(0)
|
||||||
nextIDAddrF := func() address.Address {
|
nextIDAddrF := func() address.Address {
|
||||||
@@ -379,12 +344,12 @@ func TestMinerSectorChange(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
owner, worker := nextIDAddrF(), nextIDAddrF()
|
owner, worker := nextIDAddrF(), nextIDAddrF()
|
||||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner2.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))
|
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner2.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))
|
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})
|
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
|
// 0 delete
|
||||||
// 1 extend
|
// 1 extend
|
||||||
// 2 same
|
// 2 same
|
||||||
@@ -394,14 +359,14 @@ func TestMinerSectorChange(t *testing.T) {
|
|||||||
newMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si1Ext, si2, si3})
|
newMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si1Ext, si2, si3})
|
||||||
|
|
||||||
minerAddr := nextIDAddrF()
|
minerAddr := nextIDAddrF()
|
||||||
oldState, err := mockTipset(minerAddr, 1)
|
oldState, err := test.MockTipset(minerAddr, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
newState, err := mockTipset(minerAddr, 2)
|
newState, err := test.MockTipset(minerAddr, 2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
api := newMockAPI(bs)
|
api := test.NewMockAPI(bs)
|
||||||
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID})
|
api.SetActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin2.StorageMinerActorCodeID})
|
||||||
api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID})
|
api.SetActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin2.StorageMinerActorCodeID})
|
||||||
|
|
||||||
preds := NewStatePredicates(api)
|
preds := NewStatePredicates(api)
|
||||||
|
|
||||||
@@ -449,29 +414,16 @@ func TestMinerSectorChange(t *testing.T) {
|
|||||||
require.Equal(t, si1Ext, sectorChanges.Extended[0].From)
|
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 {
|
type balance struct {
|
||||||
available abi.TokenAmount
|
available abi.TokenAmount
|
||||||
locked 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 {
|
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 := createDealAMT(ctx, t, store, deals)
|
dealRootCid := test.CreateDealAMT(ctx, t, store, deals)
|
||||||
propRootCid := createProposalAMT(ctx, t, store, props)
|
propRootCid := createProposalAMT(ctx, t, store, props)
|
||||||
balancesCids := createBalanceTable(ctx, t, store, balances)
|
balancesCids := createBalanceTable(ctx, t, store, balances)
|
||||||
state := createEmptyMarketState(t, store)
|
state := test.CreateEmptyMarketState(t, store)
|
||||||
state.States = dealRootCid
|
state.States = dealRootCid
|
||||||
state.Proposals = propRootCid
|
state.Proposals = propRootCid
|
||||||
state.EscrowTable = balancesCids[0]
|
state.EscrowTable = balancesCids[0]
|
||||||
@@ -482,27 +434,8 @@ func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals
|
|||||||
return stateC
|
return stateC
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State {
|
func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, props map[abi.DealID]*market2.DealProposal) cid.Cid {
|
||||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
root := adt2.MakeEmptyArray(store)
|
||||||
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)
|
|
||||||
for dealID, prop := range props {
|
for dealID, prop := range props {
|
||||||
err := root.Set(uint64(dealID), prop)
|
err := root.Set(uint64(dealID), prop)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -512,16 +445,16 @@ func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props
|
|||||||
return rootCid
|
return rootCid
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, balances map[address.Address]balance) [2]cid.Cid {
|
func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, balances map[address.Address]balance) [2]cid.Cid {
|
||||||
escrowMapRoot := adt.MakeEmptyMap(store)
|
escrowMapRoot := adt2.MakeEmptyMap(store)
|
||||||
escrowMapRootCid, err := escrowMapRoot.Root()
|
escrowMapRootCid, err := escrowMapRoot.Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
escrowRoot, err := adt.AsBalanceTable(store, escrowMapRootCid)
|
escrowRoot, err := adt2.AsBalanceTable(store, escrowMapRootCid)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
lockedMapRoot := adt.MakeEmptyMap(store)
|
lockedMapRoot := adt2.MakeEmptyMap(store)
|
||||||
lockedMapRootCid, err := lockedMapRoot.Root()
|
lockedMapRootCid, err := lockedMapRoot.Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
lockedRoot, err := adt.AsBalanceTable(store, lockedMapRootCid)
|
lockedRoot, err := adt2.AsBalanceTable(store, lockedMapRootCid)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for addr, balance := range balances {
|
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}
|
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)
|
rootCid := createSectorsAMT(ctx, t, store, sectors)
|
||||||
|
|
||||||
state := createEmptyMinerState(ctx, t, store, owner, worker)
|
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
|
return stateC
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State {
|
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address) *miner2.State {
|
||||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
emptyArrayCid, err := adt2.MakeEmptyArray(store).Root()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
emptyMap, err := adt2.MakeEmptyMap(store).Root()
|
||||||
require.NoError(t, err)
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
emptyVestingFunds := miner0.ConstructVestingFunds()
|
emptyVestingFunds := miner2.ConstructVestingFunds()
|
||||||
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
|
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline)
|
emptyDeadlines := miner2.ConstructDeadlines(emptyDeadline)
|
||||||
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
|
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
|
||||||
require.NoError(t, err)
|
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)
|
emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
|
||||||
require.NoError(t, err)
|
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)
|
require.NoError(t, err)
|
||||||
return state
|
return state
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
func createSectorsAMT(ctx context.Context, t *testing.T, store adt2.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||||
root := adt.MakeEmptyArray(store)
|
root := adt2.MakeEmptyArray(store)
|
||||||
for _, sector := range sectors {
|
for _, sector := range sectors {
|
||||||
sector := 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)
|
err := root.Set(uint64(sector.SectorNumber), §or)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
@@ -614,8 +561,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
|
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
|
||||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner.SectorPreCommitInfo {
|
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner2.SectorPreCommitInfo {
|
||||||
return &miner.SectorPreCommitInfo{
|
return &miner2.SectorPreCommitInfo{
|
||||||
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
|
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||||
SectorNumber: sectorNo,
|
SectorNumber: sectorNo,
|
||||||
SealedCID: sealed,
|
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 &&
|
return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
|
||||||
expected.SectorStartEpoch == actual.SectorStartEpoch &&
|
expected.SectorStartEpoch == actual.SectorStartEpoch &&
|
||||||
expected.SlashEpoch == actual.SlashEpoch
|
expected.SlashEpoch == actual.SlashEpoch
|
||||||
|
|||||||
+24
-2
@@ -2,6 +2,7 @@ package events
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@@ -17,6 +18,8 @@ type tsCacheAPI interface {
|
|||||||
// tipSetCache implements a simple ring-buffer cache to keep track of recent
|
// tipSetCache implements a simple ring-buffer cache to keep track of recent
|
||||||
// tipsets
|
// tipsets
|
||||||
type tipSetCache struct {
|
type tipSetCache struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
|
||||||
cache []*types.TipSet
|
cache []*types.TipSet
|
||||||
start int
|
start int
|
||||||
len int
|
len int
|
||||||
@@ -35,6 +38,9 @@ func newTSCache(cap abi.ChainEpoch, storage tsCacheAPI) *tipSetCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tsc *tipSetCache) add(ts *types.TipSet) error {
|
func (tsc *tipSetCache) add(ts *types.TipSet) error {
|
||||||
|
tsc.mu.Lock()
|
||||||
|
defer tsc.mu.Unlock()
|
||||||
|
|
||||||
if tsc.len > 0 {
|
if tsc.len > 0 {
|
||||||
if tsc.cache[tsc.start].Height() >= ts.Height() {
|
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())
|
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 {
|
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 {
|
if tsc.len == 0 {
|
||||||
return nil // this can happen, and it's fine
|
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.start = normalModulo(tsc.start-1, len(tsc.cache))
|
||||||
tsc.len--
|
tsc.len--
|
||||||
|
|
||||||
_ = tsc.revert(nil) // revert null block gap
|
_ = tsc.revertUnlocked(nil) // revert null block gap
|
||||||
return nil
|
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) {
|
func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
|
||||||
|
tsc.mu.RLock()
|
||||||
|
|
||||||
if tsc.len == 0 {
|
if tsc.len == 0 {
|
||||||
|
tsc.mu.RUnlock()
|
||||||
log.Warnf("tipSetCache.get: cache is empty, requesting from storage (h=%d)", height)
|
log.Warnf("tipSetCache.get: cache is empty, requesting from storage (h=%d)", height)
|
||||||
return tsc.storage.ChainGetTipSetByHeight(context.TODO(), height, types.EmptyTSK)
|
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()
|
headH := tsc.cache[tsc.start].Height()
|
||||||
|
|
||||||
if height > headH {
|
if height > headH {
|
||||||
|
tsc.mu.RUnlock()
|
||||||
return nil, xerrors.Errorf("tipSetCache.get: requested tipset not in cache (req: %d, cache head: %d)", height, headH)
|
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() {
|
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())
|
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.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) {
|
func (tsc *tipSetCache) best() (*types.TipSet, error) {
|
||||||
|
tsc.mu.RLock()
|
||||||
best := tsc.cache[tsc.start]
|
best := tsc.cache[tsc.start]
|
||||||
|
tsc.mu.RUnlock()
|
||||||
if best == nil {
|
if best == nil {
|
||||||
return tsc.storage.ChainHead(context.TODO())
|
return tsc.storage.ChainHead(context.TODO())
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user