Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1401efb115 | ||
|
|
f417d39a08 | ||
|
|
11e35cf911 | ||
|
|
10d464a1eb | ||
|
|
d84f5dabab | ||
|
|
a6d9b302fa | ||
|
|
114a1aaffd | ||
|
|
83ba7ec8cc | ||
|
|
83dfc460d4 | ||
|
|
283fd054e8 | ||
|
|
09bff14d85 | ||
|
|
3cb1abba4f | ||
|
|
d4c92942e7 | ||
|
|
f773ab4b28 | ||
|
|
c0182f8301 | ||
|
|
c06f394b81 | ||
|
|
748d2e82a7 | ||
|
|
a5c78371fd | ||
|
|
d80e7eda93 | ||
|
|
9f9d5cb2a5 | ||
|
|
fdaa9c14ad | ||
|
|
9d8932d395 | ||
|
|
105aa40007 | ||
|
|
110f033c83 | ||
|
|
f87d325b6f | ||
|
|
ab8286fa38 | ||
|
|
feb4b3c8b4 | ||
|
|
7f7c9e978f | ||
|
|
200a95f824 | ||
|
|
d69e4c7cf2 | ||
|
|
b2834baa4b | ||
|
|
e9e27cbbb0 | ||
|
|
ef73b964fb | ||
|
|
7b1bec91ed | ||
|
|
b32d25c562 | ||
|
|
767611247c | ||
|
|
be09a8a00a | ||
|
|
2719adc1b1 | ||
|
|
f1b1d8cec6 | ||
|
|
8fa4c0a970 | ||
|
|
00a14de094 | ||
|
|
eec13ff8dc | ||
|
|
1ffdd7d5b3 | ||
|
|
e19cd9ed01 | ||
|
|
bacac245c7 | ||
|
|
e1792ffe4d | ||
|
|
9c35762966 | ||
|
|
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 | ||
|
|
4cd73f1560 | ||
|
|
8a175a7465 | ||
|
|
f7f229ae54 | ||
|
|
1323e07a2c | ||
|
|
2ad671649c | ||
|
|
d26ece10b8 | ||
|
|
4c8084dcb0 | ||
|
|
98d702fb5a | ||
|
|
17f61ac212 | ||
|
|
df67576b89 | ||
|
|
cdc2f86f5a | ||
|
|
67b3a55e30 | ||
|
|
3201e0eb8f | ||
|
|
8d2d74438b | ||
|
|
1f9446f91f | ||
|
|
4937ca1a96 | ||
|
|
264fe4edb9 | ||
|
|
cb7d99fcc7 | ||
|
|
7332a39f00 | ||
|
|
8f35a5c036 | ||
|
|
dea7042668 | ||
|
|
bd8f3f05be | ||
|
|
304d835739 | ||
|
|
cb8678e4c2 | ||
|
|
da34548a05 | ||
|
|
cd9af278b4 | ||
|
|
b1fe92f8ff | ||
|
|
8dd8892b81 | ||
|
|
79dba816c7 | ||
|
|
14bb4c9a0b | ||
|
|
f9f54819d4 | ||
|
|
d1555106a4 | ||
|
|
413c357361 | ||
|
|
d97eb10349 | ||
|
|
e8253d22c6 | ||
|
|
a4e954197c | ||
|
|
8f4911ac0d | ||
|
|
b0bea5f145 | ||
|
|
7c7e0d73d5 | ||
|
|
1fea550ce5 | ||
|
|
9b7b6146eb | ||
|
|
dab1107f5b | ||
|
|
fe912223bd | ||
|
|
12cd478e11 | ||
|
|
ae3691e0a2 | ||
|
|
e55b00f358 | ||
|
|
de3f4111f4 | ||
|
|
767c346cf8 | ||
|
|
6f4a762664 | ||
|
|
c02daca9e9 | ||
|
|
cca17f6078 | ||
|
|
c17fa4bc35 | ||
|
|
e803cf151f | ||
|
|
1268cfbfcd | ||
|
|
5ef929f130 | ||
|
|
5bd6a3cdad | ||
|
|
df4b068d0e | ||
|
|
0d34881a0c | ||
|
|
6eb49b717f | ||
|
|
099b982ea8 | ||
|
|
10c120bd3c | ||
|
|
7cd1330acd | ||
|
|
39bc816a79 | ||
|
|
81fb552e1d | ||
|
|
cfd126ee9f | ||
|
|
d6fa644974 | ||
|
|
d3dc560f53 | ||
|
|
25bc00eec8 | ||
|
|
3b12a9f425 | ||
|
|
b7c8f65af5 | ||
|
|
c6e0cb4ff2 | ||
|
|
f6eb530cba | ||
|
|
f4991e868e | ||
|
|
0ec2a10ebc | ||
|
|
be92dd9e63 | ||
|
|
e90ca96289 | ||
|
|
c23f1623a1 | ||
|
|
839d1121ce | ||
|
|
a98b0f18fc | ||
|
|
15670942c3 | ||
|
|
74016ab1cc | ||
|
|
bd474617ed | ||
|
|
087030fe37 | ||
|
|
2f70a91665 | ||
|
|
60ad339033 | ||
|
|
00187d4aa8 | ||
|
|
dfaabb4596 | ||
|
|
0edecbd043 | ||
|
|
4d6a0f7b8c | ||
|
|
5043247958 | ||
|
|
282c99bdbd | ||
|
|
9857e42206 | ||
|
|
6919ff3881 | ||
|
|
d9fad5fad0 | ||
|
|
757aa1039f | ||
|
|
b71b743420 | ||
|
|
8739b938db | ||
|
|
4a3081c77a | ||
|
|
b1818a1055 | ||
|
|
256be285ba | ||
|
|
4a6e9c920d | ||
|
|
d4cbd4fb55 | ||
|
|
15330396bb | ||
|
|
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 | ||
|
|
7c3f622fae | ||
|
|
140671599c | ||
|
|
ed03202c1d | ||
|
|
0162a485d8 | ||
|
|
97087fe576 | ||
|
|
e3269770d8 | ||
|
|
0fee5dab8a | ||
|
|
1fc23fb466 | ||
|
|
306dfaa11f | ||
|
|
8fe8da6f4c | ||
|
|
4631cee564 | ||
|
|
8292d60196 | ||
|
|
f6ccab1c6c | ||
|
|
6aba3e3b94 | ||
|
|
863a6ed38c | ||
|
|
f1e5e9fe72 | ||
|
|
a57288a4b9 | ||
|
|
c5de617af6 | ||
|
|
bd964b4c3e | ||
|
|
5e256be81e | ||
|
|
04db9ea72d | ||
|
|
6f33706025 | ||
|
|
44e352cd8e | ||
|
|
1319d7072e | ||
|
|
f147072284 | ||
|
|
43bd7cb055 | ||
|
|
a3a3df9b30 | ||
|
|
d3effe52a5 | ||
|
|
0591bac768 | ||
|
|
db91d22a8a | ||
|
|
fecc1ee0ef | ||
|
|
3bebdb3882 | ||
|
|
73b9fe36e3 | ||
|
|
2c1ef3708e | ||
|
|
53cc1f18d0 | ||
|
|
e848c13ff1 | ||
|
|
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 | ||
|
|
196bf39574 | ||
|
|
954d806367 | ||
|
|
7699f195f1 | ||
|
|
6981f776f4 | ||
|
|
1b7cdb9341 | ||
|
|
47a83b422e | ||
|
|
5e08d56630 | ||
|
|
9705b25bbd | ||
|
|
9d59635b42 | ||
|
|
42d5d8d784 | ||
|
|
486812e082 | ||
|
|
6825a485eb | ||
|
|
8091bb3117 | ||
|
|
8dcbd525da | ||
|
|
35e606d397 | ||
|
|
99fe63716b | ||
|
|
941c1947be | ||
|
|
feecee310d | ||
|
|
b01a1d457a | ||
|
|
2e9915ac28 | ||
|
|
be884e27be | ||
|
|
5253c0d959 | ||
|
|
4c60d7b5ce | ||
|
|
23b729a056 | ||
|
|
724306c110 | ||
|
|
4989b1cc90 | ||
|
|
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 | ||
|
|
be9d23b329 | ||
|
|
dd65e57d4b | ||
|
|
e658ab3287 | ||
|
|
c0e190344d | ||
|
|
1c03862854 | ||
|
|
2315db161b | ||
|
|
9344bc4e9b | ||
|
|
01272f850d | ||
|
|
b95b871943 | ||
|
|
a314cfd237 | ||
|
|
c0b316fd9c | ||
|
|
3e6323a503 | ||
|
|
d1000e38d7 | ||
|
|
044674487e | ||
|
|
0070d2716c | ||
|
|
9b403e26e5 | ||
|
|
4b3b35c9de | ||
|
|
c88d124954 | ||
|
|
233d8a9b72 | ||
|
|
52e064dabb | ||
|
|
1a7fb06dd9 | ||
|
|
6fcf57ed1f | ||
|
|
ca9448bc11 | ||
|
|
2049daa008 | ||
|
|
947d1e2902 | ||
|
|
5f3160cf5b | ||
|
|
64f24fd276 | ||
|
|
124bd0c765 | ||
|
|
4b61f1756e | ||
|
|
2633198e6c | ||
|
|
b84cc46c3d | ||
|
|
96f882860f | ||
|
|
cfe6f595b0 | ||
|
|
6b16d48bad | ||
|
|
9f6862a456 | ||
|
|
4c9717187f | ||
|
|
a0dffb44d3 | ||
|
|
8f3be78667 | ||
|
|
dfdcbd184d | ||
|
|
f05a40feed | ||
|
|
f809529699 | ||
|
|
a3145bae07 | ||
|
|
b14afba859 | ||
|
|
c33b3dfa55 | ||
|
|
c448d85cf5 | ||
|
|
bc495a5c8c | ||
|
|
18dac6d415 | ||
|
|
5a72662d26 | ||
|
|
b479988044 | ||
|
|
a2d24b5b33 | ||
|
|
9a355c4bc5 | ||
|
|
fe869c9c22 | ||
|
|
f5f23f7291 | ||
|
|
a712c109d8 | ||
|
|
e5c56da321 | ||
|
|
be5dc2c57f | ||
|
|
e4c1f090af | ||
|
|
7a14455ac8 | ||
|
|
04876c663e | ||
|
|
70071e273d | ||
|
|
fb3bcc4ce5 | ||
|
|
1483f1e59a | ||
|
|
10cdbadd82 | ||
|
|
8955b8d8a7 | ||
|
|
1c5cb50da3 | ||
|
|
bddd6dd8a8 | ||
|
|
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 | ||
|
|
80a7ed8116 | ||
|
|
13b38815c2 | ||
|
|
9dfce400a7 | ||
|
|
4ff38aa856 | ||
|
|
e5873d5dea | ||
|
|
8fbbebbaf1 | ||
|
|
89bfe84f36 | ||
|
|
585b8cc51d | ||
|
|
306c098d30 | ||
|
|
6db37b72a8 | ||
|
|
80ee3be4d0 | ||
|
|
e48c525053 | ||
|
|
cf9dfdb972 | ||
|
|
6ca5308c82 | ||
|
|
68663060dc | ||
|
|
87b48c94a6 | ||
|
|
45d8cb08ba | ||
|
|
130ae3ccb3 | ||
|
|
4eaa05db52 | ||
|
|
a19023fada | ||
|
|
85caa48814 | ||
|
|
cdda66a154 | ||
|
|
f8f335df55 | ||
|
|
28b46ad08c | ||
|
|
43323b2188 | ||
|
|
17a84c9a2c | ||
|
|
7eb9bec13f | ||
|
|
2867b31d2b | ||
|
|
3c524ac0e0 | ||
|
|
1a70dd4fb4 | ||
|
|
15eddf0c96 | ||
|
|
bbcad52ce0 | ||
|
|
ded3a30f55 | ||
|
|
38e256cece | ||
|
|
b4e03d1759 | ||
|
|
efd2dff0ca | ||
|
|
44748775ff | ||
|
|
f729c6b7f5 | ||
|
|
22fafc7054 | ||
|
|
32a699d6a3 | ||
|
|
46f5b62a76 | ||
|
|
e09d291e5d | ||
|
|
97a97fe992 | ||
|
|
f4f5ef6f83 | ||
|
|
a1281273bc | ||
|
|
42216184e1 | ||
|
|
2c945d33ee | ||
|
|
1c1d23d142 | ||
|
|
3fc791b0e8 | ||
|
|
7d39542522 | ||
|
|
6c5ed3f07f | ||
|
|
a2278e26af | ||
|
|
b28b8b9649 | ||
|
|
f1ab1af617 | ||
|
|
91a43c477c | ||
|
|
a4ade158f4 | ||
|
|
c46e1574dd | ||
|
|
a876a0ba44 | ||
|
|
819180f739 | ||
|
|
476e7992e8 | ||
|
|
e27fc03f55 | ||
|
|
ed4bf9b8fe | ||
|
|
773714792f | ||
|
|
dcf2735836 | ||
|
|
77f81fc49b | ||
|
|
46fb0e74cd | ||
|
|
2967c4ec10 | ||
|
|
88ada66280 | ||
|
|
3cf2fd595f | ||
|
|
3153ab9ae3 | ||
|
|
c91774be3b | ||
|
|
c66f087f4c | ||
|
|
441d7ff790 | ||
|
|
bc24fdbd14 | ||
|
|
ab070f2ebe | ||
|
|
5314ba8c6d | ||
|
|
f96698b54d | ||
|
|
fc15888697 | ||
|
|
9b91628d85 | ||
|
|
001ba17d37 | ||
|
|
1dc69e397e | ||
|
|
d56da1b014 | ||
|
|
d33dd4f7bc | ||
|
|
63f026f7c3 | ||
|
|
3f0106cfe5 | ||
|
|
4bab784e40 | ||
|
|
916421b247 | ||
|
|
a41bf74bad | ||
|
|
0ab2459fce | ||
|
|
f9a896f6f2 | ||
|
|
24ae9205fe | ||
|
|
4cf0c105eb | ||
|
|
025663118f | ||
|
|
f7934b083c | ||
|
|
46ed0142db | ||
|
|
ad3db0e83c | ||
|
|
29913f4c41 | ||
|
|
1096f8acc6 | ||
|
|
14588d1fd2 | ||
|
|
901f7d2b4c | ||
|
|
a5e7fd8f5c | ||
|
|
0b5e4a9612 | ||
|
|
5663b2d697 | ||
|
|
44b52941f7 | ||
|
|
58a85f378c | ||
|
|
d3ddd3bff9 | ||
|
|
d9f2b909ac | ||
|
|
a79291070e | ||
|
|
d9951cdff4 | ||
|
|
c1a9cf7edd | ||
|
|
dfaad08a8b | ||
|
|
d607ca6118 | ||
|
|
49a94b7cba | ||
|
|
ab53abf04e | ||
|
|
cfa041ca8a | ||
|
|
a307e4593a | ||
|
|
286fe04271 | ||
|
|
f135ec8468 | ||
|
|
b355eb75eb | ||
|
|
a95e34f742 | ||
|
|
ed285f1114 | ||
|
|
b25dd2a00d | ||
|
|
b3d0a5fb4a | ||
|
|
0d2c8196c6 | ||
|
|
c401d2ec4e | ||
|
|
6b40e1e30d | ||
|
|
7c3f638f68 | ||
|
|
e6bbc03ca8 | ||
|
|
e39036dd49 | ||
|
|
26de0db757 | ||
|
|
35bce5a5c6 | ||
|
|
1bf3b4989d | ||
|
|
c130806c37 | ||
|
|
f741ce6e30 | ||
|
|
4a7055c328 | ||
|
|
8285eda8e5 | ||
|
|
e60027c00a | ||
|
|
24df873498 | ||
|
|
8747c6083e | ||
|
|
6050401652 | ||
|
|
298efa221c | ||
|
|
fb2b25c297 | ||
|
|
7109e95f5e | ||
|
|
c3046f487c | ||
|
|
ccd0a67b01 | ||
|
|
eadc61c37a | ||
|
|
70faa36b7f | ||
|
|
9afdda4584 | ||
|
|
9e2df907f8 | ||
|
|
0dfd4f3e63 | ||
|
|
0cd45ab82b | ||
|
|
37108ebf8f | ||
|
|
694463ffbe | ||
|
|
3c72461969 | ||
|
|
fce423c743 | ||
|
|
37de154a7c | ||
|
|
daa441b989 | ||
|
|
8bd6791e58 | ||
|
|
f2a0779bb9 | ||
|
|
b2ee59024f | ||
|
|
ac7007d1d0 | ||
|
|
db2a20da6c | ||
|
|
5bcfee0042 | ||
|
|
dc58f71604 | ||
|
|
ae38970526 | ||
|
|
708aa368e1 | ||
|
|
18bc59b93b | ||
|
|
dfd28ab0c4 | ||
|
|
784399738a | ||
|
|
bc9232544c | ||
|
|
591e32af48 | ||
|
|
a4fd356fcb | ||
|
|
6849d18b03 | ||
|
|
14a4acec8c | ||
|
|
c40c1361f0 | ||
|
|
82b95e34b7 | ||
|
|
68e884ee44 | ||
|
|
6eda53565f | ||
|
|
6dfc40abc1 | ||
|
|
2946561dec | ||
|
|
d7948fcbcd | ||
|
|
fb605f6d7f | ||
|
|
2a428f09e6 | ||
|
|
8a4b629f40 | ||
|
|
b984e94a87 | ||
|
|
05a233f84d | ||
|
|
35f6e10646 | ||
|
|
61c0b8c3db | ||
|
|
e632643801 | ||
|
|
12e76bc1af | ||
|
|
31ff5230bb | ||
|
|
053cfc1cc7 | ||
|
|
7bf165c73a | ||
|
|
691bd9f442 | ||
|
|
e2295c372a | ||
|
|
b60614982e | ||
|
|
9e48dd211a | ||
|
|
b5ba7a0fad | ||
|
|
81004ea39e | ||
|
|
bf2e3baa8f | ||
|
|
d5af25b76c | ||
|
|
80b6994fe2 | ||
|
|
7115485b0a | ||
|
|
b530f25f09 | ||
|
|
ccce1a9715 | ||
|
|
ca956ca57e | ||
|
|
ed74091c20 | ||
|
|
72d19f369b | ||
|
|
90853e24cf | ||
|
|
b4ee519282 | ||
|
|
05c11531b1 | ||
|
|
6670d22fb5 | ||
|
|
454c382e7e | ||
|
|
2ca1d111c5 | ||
|
|
b20f558abb | ||
|
|
92471d41d6 | ||
|
|
c2148ba106 | ||
|
|
e53aee26a3 | ||
|
|
02bc5fab26 | ||
|
|
e1ba4eb5c4 | ||
|
|
4e01fad0d4 | ||
|
|
91e9573863 | ||
|
|
c64f983900 | ||
|
|
53384e83d7 | ||
|
|
4cd92d8576 | ||
|
|
6bf7976add | ||
|
|
00c6397ec9 | ||
|
|
9dad38c9a5 | ||
|
|
4419850195 | ||
|
|
4dabab5ce6 | ||
|
|
36f920bcd7 | ||
|
|
7fa6c1e8d0 | ||
|
|
cc4d5306eb | ||
|
|
02dcb5e182 | ||
|
|
2088335b9d | ||
|
|
fb3f710523 | ||
|
|
06ec571c20 | ||
|
|
683a58195e | ||
|
|
68097132fe | ||
|
|
38f87981c1 | ||
|
|
d3594835c4 | ||
|
|
c610bd818e | ||
|
|
5e445f5a48 | ||
|
|
e86a74156e | ||
|
|
64d150e215 | ||
|
|
780f6dba34 | ||
|
|
f90cfda2e6 | ||
|
|
bd0c6a4ccc | ||
|
|
af38c902f8 | ||
|
|
a153e1d586 | ||
|
|
fe52c47570 | ||
|
|
6b63fa379f | ||
|
|
485f13de12 | ||
|
|
7f3ba0e6eb | ||
|
|
f58e8bc9a3 | ||
|
|
cac848c106 | ||
|
|
e4daadbfcf |
@@ -13,3 +13,4 @@
|
||||
### Conformance testing.
|
||||
conformance/ @raulk
|
||||
extern/test-vectors @raulk
|
||||
cmd/tvx @raulk
|
||||
@@ -12,6 +12,7 @@
|
||||
/lotus-bench
|
||||
/lotus-gateway
|
||||
/lotus-pcr
|
||||
/lotus-wallet
|
||||
/bench.json
|
||||
/lotuspond/front/node_modules
|
||||
/lotuspond/front/build
|
||||
|
||||
+271
@@ -1,5 +1,276 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 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
|
||||
|
||||
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.
|
||||
|
||||
Additionally, this release introduces various improvements to the sync process, as well as changes to better the overall UX experience.
|
||||
|
||||
## Changes
|
||||
|
||||
#### Core Lotus
|
||||
|
||||
- Network upgrade support (https://github.com/filecoin-project/lotus/pull/3781)
|
||||
- Upgrade markets to `v0.6.2` (https://github.com/filecoin-project/lotus/pull/3974)
|
||||
- Validate chain sync response indices when fetching messages (https://github.com/filecoin-project/lotus/pull/3939)
|
||||
- Add height diff to sync wait (https://github.com/filecoin-project/lotus/pull/3926)
|
||||
- Replace Requires with Wants (https://github.com/filecoin-project/lotus/pull/3898)
|
||||
- Update state diffing for market actor (https://github.com/filecoin-project/lotus/pull/3889)
|
||||
- Parallel fetch for sync (https://github.com/filecoin-project/lotus/pull/3887)
|
||||
- Fix SectorState (https://github.com/filecoin-project/lotus/pull/3881)
|
||||
|
||||
#### User Experience
|
||||
|
||||
- Add basic deal stats api server for spacerace slingshot (https://github.com/filecoin-project/lotus/pull/3963)
|
||||
- When doing `sectors update-state`, show a list of existing states if user inputs an invalid one (https://github.com/filecoin-project/lotus/pull/3944)
|
||||
- Fix `lotus-miner storage find` error (https://github.com/filecoin-project/lotus/pull/3927)
|
||||
- Log shutdown method for lotus daemon and miner (https://github.com/filecoin-project/lotus/pull/3925)
|
||||
- Update build and setup instruction link (https://github.com/filecoin-project/lotus/pull/3919)
|
||||
- Add an option to hide removed sectors from `sectors list` output (https://github.com/filecoin-project/lotus/pull/3903)
|
||||
|
||||
#### Testing and validation
|
||||
|
||||
- Add init.State#Remove() for testing (https://github.com/filecoin-project/lotus/pull/3971)
|
||||
- lotus-shed: add consensus check command (https://github.com/filecoin-project/lotus/pull/3933)
|
||||
- Add keyinfo verify and jwt token command to lotus-shed (https://github.com/filecoin-project/lotus/pull/3914)
|
||||
- Fix conformance gen (https://github.com/filecoin-project/lotus/pull/3892)
|
||||
|
||||
# 0.7.1 / 2020-09-17
|
||||
|
||||
This optional release of Lotus introduces some critical fixes to the window PoSt process. It also upgrades some core dependencies, and introduces many improvements to the mining process, deal-making cycle, and overall User Experience.
|
||||
|
||||
@@ -186,6 +186,12 @@ lotus-health:
|
||||
.PHONY: lotus-health
|
||||
BINS+=lotus-health
|
||||
|
||||
lotus-wallet:
|
||||
rm -f lotus-wallet
|
||||
go build -o lotus-wallet ./cmd/lotus-wallet
|
||||
.PHONY: lotus-wallet
|
||||
BINS+=lotus-wallet
|
||||
|
||||
testground:
|
||||
go build -tags testground -o /dev/null ./cmd/lotus
|
||||
.PHONY: testground
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<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" />
|
||||
</a>
|
||||
</p>
|
||||
@@ -18,7 +18,7 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more
|
||||
|
||||
## Building & Documentation
|
||||
|
||||
For instructions on how to build lotus from source, please visit [https://lotu.sh](https://lotu.sh) 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
|
||||
|
||||
|
||||
+94
-52
@@ -5,9 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -20,12 +18,13 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
@@ -77,6 +76,9 @@ type FullNode interface {
|
||||
// blockstore and returns raw bytes.
|
||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||
|
||||
// ChainDeleteObj deletes node referenced by the given CID
|
||||
ChainDeleteObj(context.Context, cid.Cid) error
|
||||
|
||||
// ChainHasObj checks if a given CID exists in the chain blockstore.
|
||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
||||
|
||||
@@ -174,6 +176,9 @@ type FullNode interface {
|
||||
// the reason.
|
||||
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
|
||||
// The Mpool methods are for interacting with the message pool. The message pool
|
||||
// manages all incoming and outgoing 'messages' going over the network.
|
||||
@@ -187,6 +192,9 @@ type FullNode interface {
|
||||
// MpoolPush pushes a signed message to mempool.
|
||||
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
|
||||
// to mempool.
|
||||
// maxFee is only used when GasFeeCap/GasPremium fields aren't specified
|
||||
@@ -231,7 +239,7 @@ type FullNode interface {
|
||||
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
||||
// WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid.
|
||||
// The address does not have to be in the wallet.
|
||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) bool
|
||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error)
|
||||
// WalletDefaultAddress returns the address marked as default in the wallet.
|
||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||
// WalletSetDefault marks the given address as as the default one.
|
||||
@@ -242,6 +250,8 @@ type FullNode interface {
|
||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
||||
// WalletDelete deletes an address from the wallet.
|
||||
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
|
||||
|
||||
@@ -273,7 +283,7 @@ type FullNode interface {
|
||||
// of status updates.
|
||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
|
||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error)
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error)
|
||||
// ClientCalcCommP calculates the CommP for a specified file
|
||||
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
|
||||
// ClientGenCar generates a CAR file for the specified file.
|
||||
@@ -314,22 +324,20 @@ type FullNode interface {
|
||||
// StateNetworkName returns the name of the network the node is synced to
|
||||
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||
// StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included.
|
||||
// If the filterOut boolean is set to true, any sectors in the filter are excluded.
|
||||
// If false, only those sectors in the filter are included.
|
||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
||||
// StateMinerActiveSectors returns info about sectors that a given miner is actively proving.
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
|
||||
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
|
||||
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
|
||||
// and returns the deadline-related calculations.
|
||||
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
|
||||
// StateMinerPower returns the power of the indicated miner
|
||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||
// StateMinerInfo returns info about the indicated miner
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (MinerInfo, error)
|
||||
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error)
|
||||
// StateMinerDeadlines returns all the proving deadlines for the given miner
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error)
|
||||
// StateMinerPartitions loads miner partitions for the specified miner/deadline
|
||||
StateMinerPartitions(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error)
|
||||
StateMinerDeadlines(context.Context, address.Address, types.TipSetKey) ([]Deadline, error)
|
||||
// StateMinerPartitions returns all partitions in the specified deadline
|
||||
StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]Partition, error)
|
||||
// StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner
|
||||
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error)
|
||||
// StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset
|
||||
@@ -349,9 +357,9 @@ type FullNode interface {
|
||||
// expiration epoch
|
||||
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||
// StateSectorExpiration returns epoch at which given sector will expire
|
||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*SectorExpiration, error)
|
||||
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error)
|
||||
// StateSectorPartition finds deadline/partition with the specified sector
|
||||
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*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(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
|
||||
@@ -359,6 +367,10 @@ type FullNode interface {
|
||||
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
|
||||
// message arrives on chain, and gets to the indicated confidence depth.
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
// StateWaitMsgLimited looks back up to limit epochs in the chain for a message.
|
||||
// If not found, it blocks until the message arrives on chain, and gets to the
|
||||
// indicated confidence depth.
|
||||
StateWaitMsgLimited(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch) (*MsgLookup, error)
|
||||
// StateListMiners returns the addresses of every miner that has claimed power in the Power Actor
|
||||
StateListMiners(context.Context, types.TipSetKey) ([]address.Address, error)
|
||||
// StateListActors returns the addresses of every actor in the state
|
||||
@@ -385,16 +397,24 @@ type FullNode interface {
|
||||
// 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.
|
||||
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.
|
||||
// Returns nil if there is no entry in the data cap table for the
|
||||
// address.
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*verifreg.DataCap, 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
|
||||
// can issue. It takes the deal size and verified status as parameters.
|
||||
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
|
||||
|
||||
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
|
||||
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
|
||||
// StateNetworkVersion returns the network version at the given tipset
|
||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||
|
||||
// MethodGroup: Msig
|
||||
// The Msig methods are used to interact with multisig wallets on the
|
||||
@@ -402,6 +422,8 @@ type FullNode interface {
|
||||
|
||||
// MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
// MsigGetVestingSchedule returns the vesting details of a given multisig.
|
||||
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error)
|
||||
// MsigGetVested returns the amount of FIL that vested in a multisig in a certain period.
|
||||
// It takes the following params: <multisig address>, <start epoch>, <end epoch>
|
||||
MsigGetVested(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error)
|
||||
@@ -468,6 +490,12 @@ type FullNode interface {
|
||||
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
|
||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, 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 {
|
||||
@@ -476,21 +504,12 @@ type FileRef struct {
|
||||
}
|
||||
|
||||
type MinerSectors struct {
|
||||
Sectors uint64
|
||||
Active uint64
|
||||
}
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
||||
// removed if it doesn't recover
|
||||
Early abi.ChainEpoch
|
||||
}
|
||||
|
||||
type SectorLocation struct {
|
||||
Deadline uint64
|
||||
Partition uint64
|
||||
// Live sectors that should be proven.
|
||||
Live uint64
|
||||
// Sectors actively contributing to power.
|
||||
Active uint64
|
||||
// Sectors with failed proofs.
|
||||
Faulty uint64
|
||||
}
|
||||
|
||||
type ImportRes struct {
|
||||
@@ -523,6 +542,7 @@ type DealInfo struct {
|
||||
DealID abi.DealID
|
||||
|
||||
CreationTime time.Time
|
||||
Verified bool
|
||||
}
|
||||
|
||||
type MsgLookup struct {
|
||||
@@ -556,11 +576,6 @@ type Message struct {
|
||||
Message *types.Message
|
||||
}
|
||||
|
||||
type ChainSectorInfo struct {
|
||||
Info miner.SectorOnChainInfo
|
||||
ID abi.SectorNumber
|
||||
}
|
||||
|
||||
type ActorState struct {
|
||||
Balance types.BigInt
|
||||
State interface{}
|
||||
@@ -632,8 +647,9 @@ type VoucherCreateResult struct {
|
||||
}
|
||||
|
||||
type MinerPower struct {
|
||||
MinerPower power.Claim
|
||||
TotalPower power.Claim
|
||||
MinerPower power.Claim
|
||||
TotalPower power.Claim
|
||||
HasMinPower bool
|
||||
}
|
||||
|
||||
type QueryOffer struct {
|
||||
@@ -736,6 +752,8 @@ type ActiveSync struct {
|
||||
|
||||
type SyncState struct {
|
||||
ActiveSyncs []ActiveSync
|
||||
|
||||
VMApplied uint64
|
||||
}
|
||||
|
||||
type SyncStateStage int
|
||||
@@ -800,14 +818,14 @@ type CirculatingSupply struct {
|
||||
}
|
||||
|
||||
type MiningBaseInfo struct {
|
||||
MinerPower types.BigInt
|
||||
NetworkPower types.BigInt
|
||||
Sectors []proof.SectorInfo
|
||||
WorkerKey address.Address
|
||||
SectorSize abi.SectorSize
|
||||
PrevBeaconEntry types.BeaconEntry
|
||||
BeaconEntries []types.BeaconEntry
|
||||
HasMinPower bool
|
||||
MinerPower types.BigInt
|
||||
NetworkPower types.BigInt
|
||||
Sectors []builtin.SectorInfo
|
||||
WorkerKey address.Address
|
||||
SectorSize abi.SectorSize
|
||||
PrevBeaconEntry types.BeaconEntry
|
||||
BeaconEntries []types.BeaconEntry
|
||||
EligibleForMining bool
|
||||
}
|
||||
|
||||
type BlockTemplate struct {
|
||||
@@ -819,7 +837,7 @@ type BlockTemplate struct {
|
||||
Messages []*types.SignedMessage
|
||||
Epoch abi.ChainEpoch
|
||||
Timestamp uint64
|
||||
WinningPoStProof []proof.PoStProof
|
||||
WinningPoStProof []builtin.PoStProof
|
||||
}
|
||||
|
||||
type DataSize struct {
|
||||
@@ -843,7 +861,31 @@ const (
|
||||
MsigCancel
|
||||
)
|
||||
|
||||
type Deadline struct {
|
||||
PostSubmissions bitfield.BitField
|
||||
}
|
||||
|
||||
type Partition struct {
|
||||
AllSectors bitfield.BitField
|
||||
FaultySectors bitfield.BitField
|
||||
RecoveringSectors bitfield.BitField
|
||||
LiveSectors bitfield.BitField
|
||||
ActiveSectors bitfield.BitField
|
||||
}
|
||||
|
||||
type Fault struct {
|
||||
Miner address.Address
|
||||
Epoch abi.ChainEpoch
|
||||
}
|
||||
|
||||
var EmptyVesting = MsigVesting{
|
||||
InitialBalance: types.EmptyInt,
|
||||
StartEpoch: -1,
|
||||
UnlockDuration: -1,
|
||||
}
|
||||
|
||||
type MsigVesting struct {
|
||||
InitialBalance abi.TokenAmount
|
||||
StartEpoch abi.ChainEpoch
|
||||
UnlockDuration abi.ChainEpoch
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
type GatewayAPI interface {
|
||||
ChainHead(ctx context.Context) (*types.TipSet, error)
|
||||
ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, 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)
|
||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error)
|
||||
}
|
||||
+8
-2
@@ -71,7 +71,7 @@ type StorageMiner interface {
|
||||
stores.SectorIndex
|
||||
|
||||
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
|
||||
MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
MarketListDeals(ctx context.Context) ([]MarketDeal, error)
|
||||
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error)
|
||||
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error)
|
||||
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
|
||||
@@ -83,7 +83,7 @@ type StorageMiner interface {
|
||||
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
|
||||
|
||||
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
|
||||
DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error)
|
||||
DealsList(ctx context.Context) ([]MarketDeal, error)
|
||||
DealsConsiderOnlineStorageDeals(context.Context) (bool, error)
|
||||
DealsSetConsiderOnlineStorageDeals(context.Context, bool) error
|
||||
DealsConsiderOnlineRetrievalDeals(context.Context) (bool, error)
|
||||
@@ -101,6 +101,12 @@ type StorageMiner interface {
|
||||
PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error)
|
||||
PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, 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
|
||||
}
|
||||
|
||||
type SealRes struct {
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func goCmd() string {
|
||||
@@ -32,3 +36,68 @@ func TestDoesntDependOnFFI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReturnTypes(t *testing.T) {
|
||||
errType := reflect.TypeOf(new(error)).Elem()
|
||||
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
||||
jmarsh := reflect.TypeOf(new(json.Marshaler)).Elem()
|
||||
|
||||
tst := func(api interface{}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
ra := reflect.TypeOf(api).Elem()
|
||||
for i := 0; i < ra.NumMethod(); i++ {
|
||||
m := ra.Method(i)
|
||||
switch m.Type.NumOut() {
|
||||
case 1: // if 1 return value, it must be an error
|
||||
require.Equal(t, errType, m.Type.Out(0), m.Name)
|
||||
|
||||
case 2: // if 2 return values, first cant be an interface/function, second must be an error
|
||||
seen := map[reflect.Type]struct{}{}
|
||||
todo := []reflect.Type{m.Type.Out(0)}
|
||||
for len(todo) > 0 {
|
||||
typ := todo[len(todo)-1]
|
||||
todo = todo[:len(todo)-1]
|
||||
|
||||
if _, ok := seen[typ]; ok {
|
||||
continue
|
||||
}
|
||||
seen[typ] = struct{}{}
|
||||
|
||||
if typ.Kind() == reflect.Interface && typ != bareIface && !typ.Implements(jmarsh) {
|
||||
t.Error("methods can't return interfaces", m.Name)
|
||||
}
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Ptr:
|
||||
fallthrough
|
||||
case reflect.Array:
|
||||
fallthrough
|
||||
case reflect.Slice:
|
||||
fallthrough
|
||||
case reflect.Chan:
|
||||
todo = append(todo, typ.Elem())
|
||||
case reflect.Map:
|
||||
todo = append(todo, typ.Elem())
|
||||
todo = append(todo, typ.Key())
|
||||
case reflect.Struct:
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
todo = append(todo, typ.Field(i).Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require.NotEqual(t, reflect.Func.String(), m.Type.Out(0).Kind().String(), m.Name)
|
||||
require.Equal(t, errType, m.Type.Out(1), m.Name)
|
||||
|
||||
default:
|
||||
t.Error("methods can only have 1 or 2 return values", m.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("common", tst(new(Common)))
|
||||
t.Run("full", tst(new(FullNode)))
|
||||
t.Run("miner", tst(new(StorageMiner)))
|
||||
t.Run("worker", tst(new(WorkerAPI)))
|
||||
}
|
||||
|
||||
@@ -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, crypto.SigType) (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
|
||||
}
|
||||
@@ -36,3 +36,9 @@ func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI {
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
}
|
||||
|
||||
func PermissionedWalletAPI(a api.WalletAPI) api.WalletAPI {
|
||||
var out WalletStruct
|
||||
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||
return &out
|
||||
}
|
||||
|
||||
+203
-42
@@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
stnetwork "github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
metrics "github.com/libp2p/go-libp2p-core/metrics"
|
||||
@@ -23,18 +23,18 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
@@ -87,6 +87,7 @@ type FullNodeStruct struct {
|
||||
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||
ChainDeleteObj func(context.Context, cid.Cid) error `perm:"admin"`
|
||||
ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"`
|
||||
ChainStatObj func(context.Context, cid.Cid, cid.Cid) (api.ObjStat, error) `perm:"read"`
|
||||
ChainSetHead func(context.Context, types.TipSetKey) error `perm:"admin"`
|
||||
@@ -111,6 +112,7 @@ type FullNodeStruct struct {
|
||||
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncUnmarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
|
||||
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
|
||||
SyncValidateTipset func(ctx context.Context, tsk types.TipSetKey) (bool, error) `perm:"read"`
|
||||
|
||||
MpoolGetConfig func(context.Context) (*types.MpoolConfig, error) `perm:"read"`
|
||||
MpoolSetConfig func(context.Context, *types.MpoolConfig) error `perm:"write"`
|
||||
@@ -120,7 +122,9 @@ type FullNodeStruct struct {
|
||||
MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolClear func(context.Context, bool) error `perm:"write"`
|
||||
|
||||
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
MpoolPushUntrusted func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolPushMessage func(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"`
|
||||
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
|
||||
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
|
||||
@@ -128,18 +132,19 @@ type FullNodeStruct struct {
|
||||
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
|
||||
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
|
||||
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
|
||||
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) bool `perm:"read"`
|
||||
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
|
||||
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
|
||||
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
WalletDelete func(context.Context, address.Address) error `perm:"write"`
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
|
||||
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) `perm:"read"`
|
||||
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
|
||||
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
|
||||
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
WalletDelete func(context.Context, address.Address) error `perm:"write"`
|
||||
WalletValidateAddress func(context.Context, string) (address.Address, error) `perm:"read"`
|
||||
|
||||
ClientImport func(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) `perm:"admin"`
|
||||
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
|
||||
@@ -153,7 +158,7 @@ type FullNodeStruct struct {
|
||||
ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"`
|
||||
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
|
||||
ClientRetrieveWithEvents func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
|
||||
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
|
||||
ClientCalcCommP func(ctx context.Context, inpath string) (*api.CommPRet, error) `perm:"read"`
|
||||
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
|
||||
ClientDealSize func(ctx context.Context, root cid.Cid) (api.DataSize, error) `perm:"read"`
|
||||
@@ -162,13 +167,13 @@ type FullNodeStruct struct {
|
||||
ClientRetrieveTryRestartInsufficientFunds func(ctx context.Context, paymentChannel address.Address) error `perm:"write"`
|
||||
|
||||
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
|
||||
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) `perm:"read"`
|
||||
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
|
||||
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error) `perm:"read"`
|
||||
StateMinerPartitions func(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error) `perm:"read"`
|
||||
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"`
|
||||
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]api.Deadline, error) `perm:"read"`
|
||||
StateMinerPartitions func(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]api.Partition, error) `perm:"read"`
|
||||
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
StateAllMinerFaults func(context.Context, abi.ChainEpoch, types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
|
||||
StateMinerRecoveries func(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
@@ -177,14 +182,15 @@ type FullNodeStruct struct {
|
||||
StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
|
||||
StateSectorGetInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*api.SectorExpiration, error) `perm:"read"`
|
||||
StateSectorPartition func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*api.SectorLocation, error) `perm:"read"`
|
||||
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
|
||||
StateSectorPartition func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StateMsgGasCost func(context.Context, cid.Cid, types.TipSetKey) (*api.MsgGasCost, error) `perm:"read"`
|
||||
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateWaitMsgLimited func(context.Context, cid.Cid, uint64, abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateListActors func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
@@ -199,11 +205,15 @@ type FullNodeStruct struct {
|
||||
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*verifreg.DataCap, error) `perm:"read"`
|
||||
StateVerifierStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVerifiedRegistryRootKey func(ctx context.Context, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
||||
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"`
|
||||
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigGetVestingSchedule func(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error) `perm:"read"`
|
||||
MsigGetVested func(context.Context, address.Address, types.TipSetKey, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigCreate func(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MsigPropose func(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
@@ -235,6 +245,8 @@ type FullNodeStruct struct {
|
||||
PaychVoucherCreate func(context.Context, address.Address, big.Int, uint64) (*api.VoucherCreateResult, error) `perm:"sign"`
|
||||
PaychVoucherList func(context.Context, address.Address) ([]*paych.SignedVoucher, error) `perm:"write"`
|
||||
PaychVoucherSubmit func(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
CreateBackup func(ctx context.Context, fpath string) error `perm:"admin"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +264,7 @@ type StorageMinerStruct struct {
|
||||
MiningBase func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"`
|
||||
MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
MarketListDeals func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
|
||||
MarketListRetrievalDeals func(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"`
|
||||
MarketGetDealUpdates func(ctx context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"`
|
||||
MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
|
||||
@@ -297,7 +309,7 @@ type StorageMinerStruct struct {
|
||||
StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"`
|
||||
|
||||
DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
|
||||
DealsList func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
|
||||
DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
|
||||
DealsConsiderOnlineStorageDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
DealsSetConsiderOnlineStorageDeals func(context.Context, bool) error `perm:"admin"`
|
||||
DealsConsiderOnlineRetrievalDeals func(context.Context) (bool, error) `perm:"read"`
|
||||
@@ -315,6 +327,8 @@ type StorageMinerStruct struct {
|
||||
PiecesListCidInfos func(ctx context.Context) ([]cid.Cid, error) `perm:"read"`
|
||||
PiecesGetPieceInfo func(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error) `perm:"read"`
|
||||
PiecesGetCIDInfo func(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error) `perm:"read"`
|
||||
|
||||
CreateBackup func(ctx context.Context, fpath string) error `perm:"admin"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,6 +362,35 @@ type WorkerStruct struct {
|
||||
}
|
||||
}
|
||||
|
||||
type GatewayStruct struct {
|
||||
Internal struct {
|
||||
// TODO: does the gateway need perms?
|
||||
ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
|
||||
ChainHead func(ctx context.Context) (*types.TipSet, error)
|
||||
GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||
MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||
MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||
MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||
StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||
StateWaitMsg func(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
||||
}
|
||||
}
|
||||
|
||||
type WalletStruct struct {
|
||||
Internal struct {
|
||||
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
|
||||
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
|
||||
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"`
|
||||
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
WalletDelete func(context.Context, address.Address) error `perm:"write"`
|
||||
}
|
||||
}
|
||||
|
||||
// CommonStruct
|
||||
|
||||
func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) {
|
||||
@@ -482,7 +525,7 @@ func (c *FullNodeStruct) ClientRetrieveWithEvents(ctx context.Context, order api
|
||||
return c.Internal.ClientRetrieveWithEvents(ctx, order, ref)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) {
|
||||
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) {
|
||||
return c.Internal.ClientQueryAsk(ctx, p, miner)
|
||||
}
|
||||
func (c *FullNodeStruct) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) {
|
||||
@@ -549,6 +592,10 @@ func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessag
|
||||
return c.Internal.MpoolPush(ctx, smsg)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolPushUntrusted(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) {
|
||||
return c.Internal.MpoolPushUntrusted(ctx, smsg)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
|
||||
return c.Internal.MpoolPushMessage(ctx, msg, spec)
|
||||
}
|
||||
@@ -605,7 +652,7 @@ func (c *FullNodeStruct) WalletSignMessage(ctx context.Context, k address.Addres
|
||||
return c.Internal.WalletSignMessage(ctx, k, msg)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool {
|
||||
func (c *FullNodeStruct) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) {
|
||||
return c.Internal.WalletVerify(ctx, k, msg, sig)
|
||||
}
|
||||
|
||||
@@ -629,6 +676,10 @@ func (c *FullNodeStruct) WalletDelete(ctx context.Context, addr address.Address)
|
||||
return c.Internal.WalletDelete(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) WalletValidateAddress(ctx context.Context, str string) (address.Address, error) {
|
||||
return c.Internal.WalletValidateAddress(ctx, str)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) {
|
||||
return c.Internal.MpoolGetNonce(ctx, addr)
|
||||
}
|
||||
@@ -661,6 +712,10 @@ func (c *FullNodeStruct) ChainReadObj(ctx context.Context, obj cid.Cid) ([]byte,
|
||||
return c.Internal.ChainReadObj(ctx, obj)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainDeleteObj(ctx context.Context, obj cid.Cid) error {
|
||||
return c.Internal.ChainDeleteObj(ctx, obj)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) ChainHasObj(ctx context.Context, o cid.Cid) (bool, error) {
|
||||
return c.Internal.ChainHasObj(ctx, o)
|
||||
}
|
||||
@@ -729,15 +784,19 @@ func (c *FullNodeStruct) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string
|
||||
return c.Internal.SyncCheckBad(ctx, bcid)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error) {
|
||||
return c.Internal.SyncValidateTipset(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
|
||||
return c.Internal.StateNetworkName(ctx)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, filter *bitfield.BitField, filterOut bool, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
return c.Internal.StateMinerSectors(ctx, addr, filter, filterOut, tsk)
|
||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*miner.SectorOnChainInfo, error) {
|
||||
return c.Internal.StateMinerSectors(ctx, addr, sectorNos, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
|
||||
func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*miner.SectorOnChainInfo, error) {
|
||||
return c.Internal.StateMinerActiveSectors(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
@@ -749,15 +808,15 @@ func (c *FullNodeStruct) StateMinerPower(ctx context.Context, a address.Address,
|
||||
return c.Internal.StateMinerPower(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error) {
|
||||
func (c *FullNodeStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
|
||||
return c.Internal.StateMinerInfo(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerDeadlines(ctx context.Context, m address.Address, tsk types.TipSetKey) ([]*miner.Deadline, error) {
|
||||
return c.Internal.StateMinerDeadlines(ctx, m, tsk)
|
||||
func (c *FullNodeStruct) StateMinerDeadlines(ctx context.Context, actor address.Address, tsk types.TipSetKey) ([]api.Deadline, error) {
|
||||
return c.Internal.StateMinerDeadlines(ctx, actor, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]*miner.Partition, error) {
|
||||
func (c *FullNodeStruct) StateMinerPartitions(ctx context.Context, m address.Address, dlIdx uint64, tsk types.TipSetKey) ([]api.Partition, error) {
|
||||
return c.Internal.StateMinerPartitions(ctx, m, dlIdx, tsk)
|
||||
}
|
||||
|
||||
@@ -793,11 +852,11 @@ func (c *FullNodeStruct) StateSectorGetInfo(ctx context.Context, maddr address.A
|
||||
return c.Internal.StateSectorGetInfo(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSectorExpiration(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*api.SectorExpiration, error) {
|
||||
func (c *FullNodeStruct) StateSectorExpiration(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorExpiration, error) {
|
||||
return c.Internal.StateSectorExpiration(ctx, maddr, n, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*api.SectorLocation, error) {
|
||||
func (c *FullNodeStruct) StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) {
|
||||
return c.Internal.StateSectorPartition(ctx, maddr, sectorNumber, tok)
|
||||
}
|
||||
|
||||
@@ -825,6 +884,10 @@ func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confide
|
||||
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateWaitMsgLimited(ctx context.Context, msgc cid.Cid, confidence uint64, limit abi.ChainEpoch) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateWaitMsgLimited(ctx, msgc, confidence, limit)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateSearchMsg(ctx context.Context, msgc cid.Cid) (*api.MsgLookup, error) {
|
||||
return c.Internal.StateSearchMsg(ctx, msgc)
|
||||
}
|
||||
@@ -877,10 +940,18 @@ func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch
|
||||
return c.Internal.StateCompute(ctx, height, msgs, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*verifreg.DataCap, error) {
|
||||
func (c *FullNodeStruct) StateVerifierStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
|
||||
return c.Internal.StateVerifierStatus(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
|
||||
return c.Internal.StateVerifiedClientStatus(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateVerifiedRegistryRootKey(ctx context.Context, tsk types.TipSetKey) (address.Address, error) {
|
||||
return c.Internal.StateVerifiedRegistryRootKey(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) {
|
||||
return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
||||
}
|
||||
@@ -889,10 +960,18 @@ func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.T
|
||||
return c.Internal.StateCirculatingSupply(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
|
||||
return c.Internal.StateNetworkVersion(ctx, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetAvailableBalance(ctx context.Context, a address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetAvailableBalance(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetVestingSchedule(ctx context.Context, a address.Address, tsk types.TipSetKey) (api.MsigVesting, error) {
|
||||
return c.Internal.MsigGetVestingSchedule(ctx, a, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) MsigGetVested(ctx context.Context, a address.Address, sTsk types.TipSetKey, eTsk types.TipSetKey) (types.BigInt, error) {
|
||||
return c.Internal.MsigGetVested(ctx, a, sTsk, eTsk)
|
||||
}
|
||||
@@ -1005,6 +1084,10 @@ func (c *FullNodeStruct) PaychVoucherSubmit(ctx context.Context, ch address.Addr
|
||||
return c.Internal.PaychVoucherSubmit(ctx, ch, sv, secret, proof)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) CreateBackup(ctx context.Context, fpath string) error {
|
||||
return c.Internal.CreateBackup(ctx, fpath)
|
||||
}
|
||||
|
||||
// StorageMinerStruct
|
||||
|
||||
func (c *StorageMinerStruct) ActorAddress(ctx context.Context) (address.Address, error) {
|
||||
@@ -1137,7 +1220,7 @@ func (c *StorageMinerStruct) MarketImportDealData(ctx context.Context, propcid c
|
||||
return c.Internal.MarketImportDealData(ctx, propcid, path)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error) {
|
||||
func (c *StorageMinerStruct) MarketListDeals(ctx context.Context) ([]api.MarketDeal, error) {
|
||||
return c.Internal.MarketListDeals(ctx)
|
||||
}
|
||||
|
||||
@@ -1181,7 +1264,7 @@ func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid ci
|
||||
return c.Internal.DealsImportData(ctx, dealPropCid, file)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error) {
|
||||
func (c *StorageMinerStruct) DealsList(ctx context.Context) ([]api.MarketDeal, error) {
|
||||
return c.Internal.DealsList(ctx)
|
||||
}
|
||||
|
||||
@@ -1245,6 +1328,10 @@ func (c *StorageMinerStruct) PiecesGetCIDInfo(ctx context.Context, payloadCid ci
|
||||
return c.Internal.PiecesGetCIDInfo(ctx, payloadCid)
|
||||
}
|
||||
|
||||
func (c *StorageMinerStruct) CreateBackup(ctx context.Context, fpath string) error {
|
||||
return c.Internal.CreateBackup(ctx, fpath)
|
||||
}
|
||||
|
||||
// WorkerStruct
|
||||
|
||||
func (w *WorkerStruct) Version(ctx context.Context) (build.Version, error) {
|
||||
@@ -1319,7 +1406,81 @@ func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
|
||||
return w.Internal.Closing(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||
return g.Internal.ChainHead(ctx)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return g.Internal.ChainGetTipSet(ctx, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
|
||||
return g.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
|
||||
return g.Internal.GasEstimateMessageGas(ctx, msg, spec, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) {
|
||||
return g.Internal.MpoolPush(ctx, sm)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error) {
|
||||
return g.Internal.MsigGetAvailableBalance(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error) {
|
||||
return g.Internal.MsigGetVested(ctx, addr, start, end)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return g.Internal.StateAccountKey(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
|
||||
return g.Internal.StateGetActor(ctx, actor, ts)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
|
||||
return g.Internal.StateLookupID(ctx, addr, tsk)
|
||||
}
|
||||
|
||||
func (g GatewayStruct) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) {
|
||||
return g.Internal.StateWaitMsg(ctx, msg, confidence)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
|
||||
return c.Internal.WalletNew(ctx, typ)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletHas(ctx context.Context, addr address.Address) (bool, error) {
|
||||
return c.Internal.WalletHas(ctx, addr)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletList(ctx context.Context) ([]address.Address, error) {
|
||||
return c.Internal.WalletList(ctx)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletSign(ctx context.Context, k address.Address, msg []byte, meta api.MsgMeta) (*crypto.Signature, error) {
|
||||
return c.Internal.WalletSign(ctx, k, msg, meta)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) {
|
||||
return c.Internal.WalletExport(ctx, a)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletImport(ctx context.Context, ki *types.KeyInfo) (address.Address, error) {
|
||||
return c.Internal.WalletImport(ctx, ki)
|
||||
}
|
||||
|
||||
func (c *WalletStruct) WalletDelete(ctx context.Context, addr address.Address) error {
|
||||
return c.Internal.WalletDelete(ctx, addr)
|
||||
}
|
||||
|
||||
var _ api.Common = &CommonStruct{}
|
||||
var _ api.FullNode = &FullNodeStruct{}
|
||||
var _ api.StorageMiner = &StorageMinerStruct{}
|
||||
var _ api.WorkerAPI = &WorkerStruct{}
|
||||
var _ api.GatewayAPI = &GatewayStruct{}
|
||||
var _ api.WalletAPI = &WalletStruct{}
|
||||
|
||||
@@ -82,3 +82,29 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
// NewGatewayRPC creates a new http jsonrpc client for a gateway node.
|
||||
func NewGatewayRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.GatewayAPI, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.GatewayStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
opts...,
|
||||
)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WalletAPI, jsonrpc.ClientCloser, error) {
|
||||
var res apistruct.WalletStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ func init() {
|
||||
addExample(retrievalmarket.ClientEventDealAccepted)
|
||||
addExample(retrievalmarket.DealStatusNew)
|
||||
addExample(network.ReachabilityPublic)
|
||||
addExample(build.NewestNetworkVersion)
|
||||
addExample(&types.ExecutionTrace{
|
||||
Msg: exampleValue(reflect.TypeOf(&types.Message{}), nil).(*types.Message),
|
||||
MsgRct: exampleValue(reflect.TypeOf(&types.MessageReceipt{}), nil).(*types.MessageReceipt),
|
||||
|
||||
+32
-1
@@ -19,8 +19,22 @@ import (
|
||||
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()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, []FullNodeOpts{FullNodeWithUpgradeAt(upgradeHeight)}, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -85,6 +99,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
{
|
||||
exp, err := client.StateSectorExpiration(ctx, maddr, CC, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, exp)
|
||||
require.Greater(t, 50000, int(exp.OnTime))
|
||||
}
|
||||
{
|
||||
@@ -93,6 +108,22 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
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")
|
||||
atomic.AddInt64(&mine, -1)
|
||||
<-done
|
||||
|
||||
+8
-5
@@ -48,7 +48,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -85,7 +85,7 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -149,7 +149,7 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -204,7 +204,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -402,9 +402,12 @@ func testRetrieval(t *testing.T, ctx context.Context, client *impl.FullNodeAPI,
|
||||
IsCAR: carExport,
|
||||
}
|
||||
updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for update := range updates {
|
||||
if update.Err != "" {
|
||||
t.Fatalf("%v", err)
|
||||
t.Fatalf("retrieval failed: %s", update.Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ var log = logging.Logger("apitest")
|
||||
|
||||
func (ts *testSuite) testMining(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, sn := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
newHeads, err := api.ChainNotify(ctx)
|
||||
@@ -54,7 +54,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
|
||||
}()
|
||||
|
||||
ctx := context.Background()
|
||||
apis, sn := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
newHeads, err := api.ChainNotify(ctx)
|
||||
@@ -93,7 +93,7 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
|
||||
// test making a deal with a fresh miner, and see if it starts to mine
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, []StorageMiner{
|
||||
n, sn := b(t, OneFull, []StorageMiner{
|
||||
{Full: 0, Preseal: PresealGenesis},
|
||||
{Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node
|
||||
})
|
||||
|
||||
+68
-10
@@ -8,17 +8,21 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"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/apibstore"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -29,7 +33,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
_ = os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 2, OneMiner)
|
||||
n, sn := b(t, TwoFull, OneMiner)
|
||||
|
||||
paymentCreator := n[0]
|
||||
paymentReceiver := n[1]
|
||||
@@ -67,7 +71,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
channelAmt := int64(100000)
|
||||
channelAmt := int64(7000)
|
||||
channelInfo, err := paymentCreator.PaychGet(ctx, createrAddr, receiverAddr, abi.NewTokenAmount(channelAmt))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -133,17 +137,26 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
t.Fatal("Unable to settle payment channel")
|
||||
}
|
||||
|
||||
creatorStore := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(paymentCreator)))
|
||||
|
||||
// wait for the receiver to submit their vouchers
|
||||
ev := events.NewEvents(ctx, paymentCreator)
|
||||
preds := state.NewStatePredicates(paymentCreator)
|
||||
finished := make(chan struct{})
|
||||
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 {
|
||||
return false, false, err
|
||||
}
|
||||
state := act.State.(paych.State)
|
||||
if state.ToSend.GreaterThanEqual(abi.NewTokenAmount(6000)) {
|
||||
state, err := paych.Load(creatorStore, act)
|
||||
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 false, true, nil
|
||||
@@ -156,7 +169,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
return true, nil
|
||||
}, func(ctx context.Context, ts *types.TipSet) error {
|
||||
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())
|
||||
})
|
||||
if err != nil {
|
||||
@@ -169,8 +182,53 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
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
|
||||
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych.SettleDelay)
|
||||
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych0.SettleDelay)
|
||||
|
||||
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
|
||||
if err != nil {
|
||||
@@ -226,7 +284,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec
|
||||
|
||||
// Add a real block
|
||||
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
|
||||
To: builtin.BurntFundsActorAddr,
|
||||
To: builtin0.BurntFundsActorAddr,
|
||||
From: receiverAddr,
|
||||
Value: types.NewInt(0),
|
||||
}, nil)
|
||||
|
||||
+44
-4
@@ -4,14 +4,18 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
)
|
||||
|
||||
type TestNode struct {
|
||||
@@ -34,17 +38,27 @@ var PresealGenesis = -1
|
||||
|
||||
const GenesisPreseals = 2
|
||||
|
||||
// Options for setting up a mock storage miner
|
||||
type StorageMiner struct {
|
||||
Full int
|
||||
Preseal int
|
||||
}
|
||||
|
||||
type OptionGenerator func([]TestNode) node.Option
|
||||
|
||||
// Options for setting up a mock full node
|
||||
type FullNodeOpts struct {
|
||||
Lite bool // run node in "lite" mode
|
||||
Opts OptionGenerator // generate dependency injection options
|
||||
}
|
||||
|
||||
// APIBuilder is a function which is invoked in test suite to provide
|
||||
// test nodes and networks
|
||||
//
|
||||
// fullOpts array defines options for each full node
|
||||
// storage array defines storage nodes, numbers in the array specify full node
|
||||
// index the storage node 'belongs' to
|
||||
type APIBuilder func(t *testing.T, nFull int, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
||||
type APIBuilder func(t *testing.T, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
||||
type testSuite struct {
|
||||
makeNodes APIBuilder
|
||||
}
|
||||
@@ -62,13 +76,39 @@ func TestApis(t *testing.T, b APIBuilder) {
|
||||
t.Run("testMiningReal", ts.testMiningReal)
|
||||
}
|
||||
|
||||
func DefaultFullOpts(nFull int) []FullNodeOpts {
|
||||
full := make([]FullNodeOpts, nFull)
|
||||
for i := range full {
|
||||
full[i] = FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Options()
|
||||
},
|
||||
}
|
||||
}
|
||||
return full
|
||||
}
|
||||
|
||||
var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
|
||||
var OneFull = DefaultFullOpts(1)
|
||||
var TwoFull = DefaultFullOpts(2)
|
||||
|
||||
var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
return FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
Network: build.ActorUpgradeNetworkVersion,
|
||||
Height: upgradeHeight,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *testSuite) testVersion(t *testing.T) {
|
||||
build.RunningNodeType = build.NodeFull
|
||||
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
v, err := api.Version(ctx)
|
||||
@@ -80,7 +120,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
|
||||
|
||||
func (ts *testSuite) testID(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 1, OneMiner)
|
||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
id, err := api.ID(ctx)
|
||||
@@ -92,7 +132,7 @@ func (ts *testSuite) testID(t *testing.T) {
|
||||
|
||||
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, 2, OneMiner)
|
||||
apis, _ := ts.makeNodes(t, TwoFull, OneMiner)
|
||||
|
||||
p, err := apis[0].NetPeers(ctx)
|
||||
if err != nil {
|
||||
|
||||
+51
-31
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@@ -33,7 +32,7 @@ func init() {
|
||||
|
||||
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -115,8 +114,25 @@ func pledgeSectors(t *testing.T, ctx context.Context, miner TestStorageNode, n,
|
||||
}
|
||||
|
||||
func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, 1, OneMiner)
|
||||
for _, height := range []abi.ChainEpoch{
|
||||
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{FullNodeWithUpgradeAt(upgradeHeight)}, OneMiner)
|
||||
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
|
||||
@@ -130,17 +146,24 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
}
|
||||
build.Clock.Sleep(time.Second)
|
||||
|
||||
mine := true
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for mine {
|
||||
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
|
||||
}()
|
||||
|
||||
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
|
||||
|
||||
@@ -154,18 +177,16 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("Running one proving period\n")
|
||||
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
||||
|
||||
for {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||
break
|
||||
}
|
||||
|
||||
if head.Height()%100 == 0 {
|
||||
fmt.Printf("@%d\n", head.Height())
|
||||
}
|
||||
build.Clock.Sleep(blocktime)
|
||||
}
|
||||
|
||||
@@ -186,12 +207,13 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(parts), 0)
|
||||
|
||||
n, err := parts[0].Sectors.Count()
|
||||
secs := parts[0].AllSectors
|
||||
n, err := secs.Count()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), n)
|
||||
|
||||
// Drop the partition
|
||||
err = parts[0].Sectors.ForEach(func(sid uint64) error {
|
||||
err = secs.ForEach(func(sid uint64) error {
|
||||
return miner.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).MarkCorrupted(abi.SectorID{
|
||||
Miner: abi.ActorID(mid),
|
||||
Number: abi.SectorNumber(sid),
|
||||
@@ -208,15 +230,16 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(parts), 0)
|
||||
|
||||
n, err := parts[0].Sectors.Count()
|
||||
secs := parts[0].AllSectors
|
||||
n, err := secs.Count()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(2), n)
|
||||
|
||||
// Drop the sector
|
||||
sn, err := parts[0].Sectors.First()
|
||||
sn, err := secs.First()
|
||||
require.NoError(t, err)
|
||||
|
||||
all, err := parts[0].Sectors.All(2)
|
||||
all, err := secs.All(2)
|
||||
require.NoError(t, err)
|
||||
fmt.Println("the sectors", all)
|
||||
|
||||
@@ -233,18 +256,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
require.NoError(t, err)
|
||||
|
||||
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 {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
|
||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||
break
|
||||
}
|
||||
|
||||
if head.Height()%100 == 0 {
|
||||
fmt.Printf("@%d\n", head.Height())
|
||||
}
|
||||
build.Clock.Sleep(blocktime)
|
||||
}
|
||||
|
||||
@@ -264,17 +286,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
|
||||
|
||||
for {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > di.PeriodStart+(miner2.WPoStProvingPeriod)+2 {
|
||||
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
|
||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||
break
|
||||
}
|
||||
|
||||
if head.Height()%100 == 0 {
|
||||
fmt.Printf("@%d\n", head.Height())
|
||||
}
|
||||
build.Clock.Sleep(blocktime)
|
||||
}
|
||||
|
||||
@@ -291,18 +313,19 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
pledgeSectors(t, ctx, miner, 1, nSectors, nil)
|
||||
|
||||
{
|
||||
// wait a bit more
|
||||
|
||||
head, err := client.ChainHead(ctx)
|
||||
// Wait until proven.
|
||||
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
waitUntil := head.Height() + 10
|
||||
waitUntil := di.PeriodStart + di.WPoStProvingPeriod + 2
|
||||
fmt.Printf("End for head.Height > %d\n", waitUntil)
|
||||
|
||||
for {
|
||||
head, err := client.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
if head.Height() > waitUntil {
|
||||
fmt.Printf("Now head.Height = %d\n", head.Height())
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -315,7 +338,4 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
|
||||
|
||||
sectors = p.MinerPower.RawBytePower.Uint64() / uint64(ssz)
|
||||
require.Equal(t, nSectors+GenesisPreseals-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged
|
||||
|
||||
mine = false
|
||||
<-done
|
||||
}
|
||||
|
||||
@@ -4,11 +4,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -49,48 +47,6 @@ type PubsubScore struct {
|
||||
Score *pubsub.PeerScoreSnapshot
|
||||
}
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
}
|
||||
|
||||
func NewApiMinerInfo(info *miner.MinerInfo) MinerInfo {
|
||||
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,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi
|
||||
}
|
||||
|
||||
type MessageSendSpec struct {
|
||||
MaxFee abi.TokenAmount
|
||||
}
|
||||
|
||||
@@ -4,3 +4,9 @@
|
||||
/dns4/bootstrap-4.testnet.fildev.network/tcp/1347/p2p/12D3KooWPkL9LrKRQgHtq7kn9ecNhGU9QaziG8R5tX8v9v7t3h34
|
||||
/dns4/bootstrap-3.testnet.fildev.network/tcp/1347/p2p/12D3KooWKYSsbpgZ3HAjax5M1BXCwXLa6gVkUARciz7uN3FNtr7T
|
||||
/dns4/bootstrap-5.testnet.fildev.network/tcp/1347/p2p/12D3KooWQYzqnLASJAabyMpPb1GcWZvNSe7JDcRuhdRqonFoiK9W
|
||||
/dns4/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
|
||||
|
||||
+17
-8
@@ -3,28 +3,37 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
const UpgradeBreezeHeight = -1
|
||||
const BreezeGasTampingDuration = 0
|
||||
|
||||
const UpgradeSmokeHeight = -1
|
||||
const UpgradeIgnitionHeight = -2
|
||||
const UpgradeRefuelHeight = -3
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-4)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV2Height = math.MaxInt64
|
||||
UpgradeLiftoffHeight = 11
|
||||
}
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
||||
@@ -3,17 +3,19 @@ package build
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
func DefaultSectorSize() abi.SectorSize {
|
||||
szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes))
|
||||
for spt := range miner.SupportedProofTypes {
|
||||
szs := make([]abi.SectorSize, 0, len(miner0.SupportedProofTypes))
|
||||
for spt := range miner0.SupportedProofTypes {
|
||||
ss, err := spt.SectorSize()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -39,8 +41,12 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
|
||||
|
||||
func UseNewestNetwork() bool {
|
||||
// TODO: Put these in a container we can iterate over
|
||||
if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 {
|
||||
if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2Height <= 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func SetAddressNetwork(n address.Network) {
|
||||
address.CurrentNetwork = n
|
||||
}
|
||||
|
||||
+24
-11
@@ -4,12 +4,15 @@ package build
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"os"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
)
|
||||
|
||||
// /////
|
||||
@@ -22,7 +25,8 @@ const UnixfsLinksPerLevel = 1024
|
||||
// Consensus / Network
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version2
|
||||
const NewestNetworkVersion = network.Version4
|
||||
const ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
// Epochs
|
||||
const ForkLengthThreshold = Finality
|
||||
@@ -31,7 +35,7 @@ const ForkLengthThreshold = Finality
|
||||
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
|
||||
|
||||
// Epochs
|
||||
const Finality = miner.ChainFinality
|
||||
const Finality = policy.ChainFinality
|
||||
const MessageConfidence = uint64(5)
|
||||
|
||||
// constants for Weight calculation
|
||||
@@ -43,13 +47,8 @@ const WRatioDen = uint64(2)
|
||||
// Proofs
|
||||
|
||||
// Epochs
|
||||
const SealRandomnessLookback = Finality
|
||||
|
||||
// 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
|
||||
// TODO: unused
|
||||
const SealRandomnessLookback = policy.SealRandomnessLookback
|
||||
|
||||
// /////
|
||||
// Mining
|
||||
@@ -57,23 +56,37 @@ const MaxSealLookback = SealRandomnessLookbackLimit + 2000 // TODO: Get from spe
|
||||
// Epochs
|
||||
const TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||
|
||||
const WinningPoStSectorSetLookback = abi.ChainEpoch(10)
|
||||
// /////
|
||||
// Address
|
||||
|
||||
const AddressMainnetEnvVar = "_mainnet_"
|
||||
|
||||
// /////
|
||||
// Devnet settings
|
||||
|
||||
var Devnet = true
|
||||
|
||||
const FilBase = uint64(2_000_000_000)
|
||||
const FilAllocStorageMining = uint64(1_100_000_000)
|
||||
|
||||
const FilecoinPrecision = uint64(1_000_000_000_000_000_000)
|
||||
const FilReserved = uint64(300_000_000)
|
||||
|
||||
var InitialRewardBalance *big.Int
|
||||
var InitialFilReserved *big.Int
|
||||
|
||||
// TODO: Move other important consts here
|
||||
|
||||
func init() {
|
||||
InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining))
|
||||
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
|
||||
|
||||
@@ -13,7 +13,8 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -32,7 +33,7 @@ var (
|
||||
|
||||
AllowableClockDriftSecs = uint64(1)
|
||||
|
||||
Finality = miner.ChainFinality
|
||||
Finality = policy.ChainFinality
|
||||
ForkLengthThreshold = Finality
|
||||
|
||||
SlashablePowerDelay = 20
|
||||
@@ -47,15 +48,13 @@ var (
|
||||
BlsSignatureCacheSize = 40000
|
||||
VerifSigCacheSize = 32000
|
||||
|
||||
SealRandomnessLookback = Finality
|
||||
SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
|
||||
MaxSealLookback = SealRandomnessLookbackLimit + 2000
|
||||
SealRandomnessLookback = policy.SealRandomnessLookback
|
||||
|
||||
TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||
WinningPoStSectorSetLookback = abi.ChainEpoch(10)
|
||||
TicketRandomnessLookback = abi.ChainEpoch(1)
|
||||
|
||||
FilBase uint64 = 2_000_000_000
|
||||
FilAllocStorageMining uint64 = 1_400_000_000
|
||||
FilReserved uint64 = 300_000_000
|
||||
|
||||
FilecoinPrecision uint64 = 1_000_000_000_000_000_000
|
||||
|
||||
@@ -64,6 +63,13 @@ var (
|
||||
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
||||
return v
|
||||
}()
|
||||
|
||||
InitialFilReserved = func() *big.Int {
|
||||
v := big.NewInt(int64(FilReserved))
|
||||
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
|
||||
return v
|
||||
}()
|
||||
|
||||
// Actor consts
|
||||
// TODO: Pull from actors when its made not private
|
||||
MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
|
||||
@@ -74,11 +80,18 @@ var (
|
||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
||||
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeActorsV2Height abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -4
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
NewestNetworkVersion = network.Version2
|
||||
NewestNetworkVersion = network.Version4
|
||||
ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
Devnet = true
|
||||
)
|
||||
|
||||
+32
-9
@@ -5,11 +5,14 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"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/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
@@ -22,14 +25,34 @@ const BreezeGasTampingDuration = 120
|
||||
|
||||
const UpgradeSmokeHeight = 51000
|
||||
|
||||
const UpgradeIgnitionHeight = 94000
|
||||
const UpgradeRefuelHeight = 130800
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(138720)
|
||||
|
||||
// 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
|
||||
|
||||
func init() {
|
||||
power.ConsensusMinerMinPower = big.NewInt(10 << 40)
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
)
|
||||
|
||||
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
||||
SetAddressNetwork(address.Mainnet)
|
||||
}
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV2Height = math.MaxInt64
|
||||
}
|
||||
|
||||
Devnet = false
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
|
||||
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds)
|
||||
|
||||
const PropagationDelaySecs = uint64(6)
|
||||
|
||||
+4
-4
@@ -29,7 +29,7 @@ func buildType() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "0.7.1"
|
||||
const BuildVersion = "0.9.1"
|
||||
|
||||
func UserVersion() string {
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
@@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
|
||||
|
||||
// semver versions of the rpc api exposed
|
||||
var (
|
||||
FullAPIVersion = newVer(0, 15, 0)
|
||||
MinerAPIVersion = newVer(0, 14, 0)
|
||||
WorkerAPIVersion = newVer(0, 14, 0)
|
||||
FullAPIVersion = newVer(0, 16, 0)
|
||||
MinerAPIVersion = newVer(0, 15, 0)
|
||||
WorkerAPIVersion = newVer(0, 15, 0)
|
||||
)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package adt
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
|
||||
)
|
||||
|
||||
type Map interface {
|
||||
Root() (cid.Cid, error)
|
||||
|
||||
Put(k abi.Keyer, v cbor.Marshaler) error
|
||||
Get(k abi.Keyer, v cbor.Unmarshaler) (bool, error)
|
||||
Delete(k abi.Keyer) error
|
||||
|
||||
ForEach(v cbor.Unmarshaler, fn func(key string) error) error
|
||||
}
|
||||
|
||||
func AsMap(store Store, root cid.Cid, version actors.Version) (Map, error) {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
return adt0.AsMap(store, root)
|
||||
case actors.Version2:
|
||||
return adt2.AsMap(store, root)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
func NewMap(store Store, version actors.Version) (Map, error) {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
return adt0.MakeEmptyMap(store), nil
|
||||
case actors.Version2:
|
||||
return adt2.MakeEmptyMap(store), nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
type Array interface {
|
||||
Root() (cid.Cid, error)
|
||||
|
||||
Set(idx uint64, v cbor.Marshaler) error
|
||||
Get(idx uint64, v cbor.Unmarshaler) (bool, error)
|
||||
Delete(idx uint64) error
|
||||
Length() uint64
|
||||
|
||||
ForEach(v cbor.Unmarshaler, fn func(idx int64) error) error
|
||||
}
|
||||
|
||||
func AsArray(store Store, root cid.Cid, version network.Version) (Array, error) {
|
||||
switch actors.VersionForNetwork(version) {
|
||||
case actors.Version0:
|
||||
return adt0.AsArray(store, root)
|
||||
case actors.Version2:
|
||||
return adt2.AsArray(store, root)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
|
||||
func NewArray(store Store, version actors.Version) (Array, error) {
|
||||
switch version {
|
||||
case actors.Version0:
|
||||
return adt0.MakeEmptyArray(store), nil
|
||||
case actors.Version2:
|
||||
return adt2.MakeEmptyArray(store), nil
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown network version: %d", version)
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package state
|
||||
package adt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
@@ -27,7 +26,8 @@ type AdtArrayDiff interface {
|
||||
// - All values that exist in curArr nnd not in prevArr are passed to adtArrayDiff.Add()
|
||||
// - All values that exist in preArr and in curArr are passed to AdtArrayDiff.Modify()
|
||||
// - It is the responsibility of AdtArrayDiff.Modify() to determine if the values it was passed have been modified.
|
||||
func DiffAdtArray(preArr, curArr *adt.Array, out AdtArrayDiff) error {
|
||||
func DiffAdtArray(preArr, curArr Array, out AdtArrayDiff) error {
|
||||
notNew := make(map[int64]struct{}, curArr.Length())
|
||||
prevVal := new(typegen.Deferred)
|
||||
if err := preArr.ForEach(prevVal, func(i int64) error {
|
||||
curVal := new(typegen.Deferred)
|
||||
@@ -48,14 +48,17 @@ func DiffAdtArray(preArr, curArr *adt.Array, out AdtArrayDiff) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return curArr.Delete(uint64(i))
|
||||
notNew[i] = struct{}{}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curVal := new(typegen.Deferred)
|
||||
return curArr.ForEach(curVal, func(i int64) error {
|
||||
if _, ok := notNew[i]; ok {
|
||||
return nil
|
||||
}
|
||||
return out.Add(uint64(i), curVal)
|
||||
})
|
||||
}
|
||||
@@ -76,7 +79,8 @@ type AdtMapDiff interface {
|
||||
Remove(key string, val *typegen.Deferred) error
|
||||
}
|
||||
|
||||
func DiffAdtMap(preMap, curMap *adt.Map, out AdtMapDiff) error {
|
||||
func DiffAdtMap(preMap, curMap Map, out AdtMapDiff) error {
|
||||
notNew := make(map[string]struct{})
|
||||
prevVal := new(typegen.Deferred)
|
||||
if err := preMap.ForEach(prevVal, func(key string) error {
|
||||
curVal := new(typegen.Deferred)
|
||||
@@ -102,14 +106,17 @@ func DiffAdtMap(preMap, curMap *adt.Map, out AdtMapDiff) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return curMap.Delete(k)
|
||||
notNew[key] = struct{}{}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curVal := new(typegen.Deferred)
|
||||
return curMap.ForEach(curVal, func(key string) error {
|
||||
if _, ok := notNew[key]; ok {
|
||||
return nil
|
||||
}
|
||||
return out.Add(key, curVal)
|
||||
})
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package state
|
||||
package adt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||
)
|
||||
@@ -22,8 +22,8 @@ func TestDiffAdtArray(t *testing.T) {
|
||||
ctxstoreA := newContextStore()
|
||||
ctxstoreB := newContextStore()
|
||||
|
||||
arrA := adt.MakeEmptyArray(ctxstoreA)
|
||||
arrB := adt.MakeEmptyArray(ctxstoreB)
|
||||
arrA := adt0.MakeEmptyArray(ctxstoreA)
|
||||
arrB := adt0.MakeEmptyArray(ctxstoreB)
|
||||
|
||||
require.NoError(t, arrA.Set(0, runtime.CBORBytes([]byte{0}))) // delete
|
||||
|
||||
@@ -76,8 +76,8 @@ func TestDiffAdtMap(t *testing.T) {
|
||||
ctxstoreA := newContextStore()
|
||||
ctxstoreB := newContextStore()
|
||||
|
||||
mapA := adt.MakeEmptyMap(ctxstoreA)
|
||||
mapB := adt.MakeEmptyMap(ctxstoreB)
|
||||
mapA := adt0.MakeEmptyMap(ctxstoreA)
|
||||
mapB := adt0.MakeEmptyMap(ctxstoreB)
|
||||
|
||||
require.NoError(t, mapA.Put(abi.UIntKey(0), runtime.CBORBytes([]byte{0}))) // delete
|
||||
|
||||
@@ -292,12 +292,9 @@ func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newContextStore() *contextStore {
|
||||
func newContextStore() Store {
|
||||
ctx := context.Background()
|
||||
bs := bstore.NewTemporarySync()
|
||||
store := cbornode.NewCborStore(bs)
|
||||
return &contextStore{
|
||||
ctx: ctx,
|
||||
cst: store,
|
||||
}
|
||||
return WrapStore(ctx, store)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package adt
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
adt "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
Context() context.Context
|
||||
cbor.IpldStore
|
||||
}
|
||||
|
||||
func WrapStore(ctx context.Context, store cbor.IpldStore) Store {
|
||||
return adt.WrapStore(ctx, store)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
# Actors
|
||||
|
||||
This package contains shims for abstracting over different actor versions.
|
||||
|
||||
## Design
|
||||
|
||||
Shims in this package follow a few common design principles.
|
||||
|
||||
### Structure Agnostic
|
||||
|
||||
Shims interfaces defined in this package should (ideally) not change even if the
|
||||
structure of the underlying data changes. For example:
|
||||
|
||||
* All shims store an internal "store" object. That way, state can be moved into
|
||||
a separate object without needing to add a store to the function signature.
|
||||
* All functions must return an error, even if unused for now.
|
||||
|
||||
### Minimal
|
||||
|
||||
These interfaces should be expanded only as necessary to reduce maintenance burden.
|
||||
|
||||
### Queries, not field assessors.
|
||||
|
||||
When possible, functions should query the state instead of simply acting as
|
||||
field assessors. These queries are more likely to remain stable across
|
||||
specs-actor upgrades than specific state fields.
|
||||
|
||||
Note: there is a trade-off here. Avoid implementing _complicated_ query logic
|
||||
inside these shims, as it will need to be replicated in every shim.
|
||||
@@ -0,0 +1,41 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"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/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)
|
||||
})
|
||||
}
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.AccountActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.AccountActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
PubkeyAddress() (address.Address, error)
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
)
|
||||
|
||||
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 {
|
||||
account0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||
)
|
||||
|
||||
var SystemActorAddr = builtin0.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
// TODO: Why does actors have 2 different versions of this?
|
||||
type SectorInfo = proof0.SectorInfo
|
||||
type PoStProof = proof0.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
return (FilterEstimate)(v0)
|
||||
}
|
||||
|
||||
// Doesn't change between actors v0 and v1
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
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,57 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"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/types"
|
||||
"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"
|
||||
)
|
||||
|
||||
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 = builtin0.InitActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.InitActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.InitActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ResolveAddress(address address.Address) (address.Address, bool, error)
|
||||
MapAddressToNewID(address address.Address) (address.Address, error)
|
||||
NetworkName() (dtypes.NetworkName, error)
|
||||
|
||||
ForEachActor(func(id abi.ActorID, address address.Address) error) error
|
||||
|
||||
// Remove exists to support tooling that manipulates state for testing.
|
||||
// It should not be used in production code, as init actor entries are
|
||||
// immutable.
|
||||
Remove(addrs ...address.Address) error
|
||||
|
||||
// Sets the network's name. This should only be used on upgrade/fork.
|
||||
SetNetworkName(name string) error
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
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"
|
||||
|
||||
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
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 {
|
||||
init0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) ResolveAddress(address address.Address) (address.Address, bool, error) {
|
||||
return s.State.ResolveAddress(s.store, address)
|
||||
}
|
||||
|
||||
func (s *state0) MapAddressToNewID(address address.Address) (address.Address, error) {
|
||||
return s.State.MapAddressToNewID(s.store, address)
|
||||
}
|
||||
|
||||
func (s *state0) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
|
||||
addrs, err := adt0.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 *state0) NetworkName() (dtypes.NetworkName, error) {
|
||||
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) {
|
||||
m, err := adt0.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
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func DiffDealProposals(pre, cur DealProposals) (*DealProposalChanges, error) {
|
||||
results := new(DealProposalChanges)
|
||||
if err := adt.DiffAdtArray(pre.array(), cur.array(), &marketProposalsDiffer{results, pre, cur}); err != nil {
|
||||
return nil, fmt.Errorf("diffing deal states: %w", err)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type marketProposalsDiffer struct {
|
||||
Results *DealProposalChanges
|
||||
pre, cur DealProposals
|
||||
}
|
||||
|
||||
func (d *marketProposalsDiffer) Add(key uint64, val *cbg.Deferred) error {
|
||||
dp, err := d.cur.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Added = append(d.Results.Added, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketProposalsDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
||||
// short circuit, DealProposals are static
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketProposalsDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
||||
dp, err := d.pre.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Removed = append(d.Results.Removed, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
func DiffDealStates(pre, cur DealStates) (*DealStateChanges, error) {
|
||||
results := new(DealStateChanges)
|
||||
if err := adt.DiffAdtArray(pre.array(), cur.array(), &marketStatesDiffer{results, pre, cur}); err != nil {
|
||||
return nil, fmt.Errorf("diffing deal states: %w", err)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type marketStatesDiffer struct {
|
||||
Results *DealStateChanges
|
||||
pre, cur DealStates
|
||||
}
|
||||
|
||||
func (d *marketStatesDiffer) Add(key uint64, val *cbg.Deferred) error {
|
||||
ds, err := d.cur.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Added = append(d.Results.Added, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketStatesDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
||||
dsFrom, err := d.pre.decode(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dsTo, err := d.cur.decode(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if *dsFrom != *dsTo {
|
||||
d.Results.Modified = append(d.Results.Modified, DealStateChange{abi.DealID(key), dsFrom, dsTo})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *marketStatesDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
||||
ds, err := d.pre.decode(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Results.Removed = append(d.Results.Removed, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
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/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
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 = builtin0.StorageMarketActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StorageMarketActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.StorageMarketActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
BalancesChanged(State) (bool, error)
|
||||
EscrowTable() (BalanceTable, error)
|
||||
LockedTable() (BalanceTable, error)
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
StatesChanged(State) (bool, error)
|
||||
States() (DealStates, error)
|
||||
ProposalsChanged(State) (bool, error)
|
||||
Proposals() (DealProposals, error)
|
||||
VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error)
|
||||
}
|
||||
|
||||
type BalanceTable interface {
|
||||
ForEach(cb func(address.Address, abi.TokenAmount) error) error
|
||||
Get(key address.Address) (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type DealStates interface {
|
||||
ForEach(cb func(id abi.DealID, ds DealState) error) error
|
||||
Get(id abi.DealID) (*DealState, bool, error)
|
||||
|
||||
array() adt.Array
|
||||
decode(*cbg.Deferred) (*DealState, error)
|
||||
}
|
||||
|
||||
type DealProposals interface {
|
||||
ForEach(cb func(id abi.DealID, dp DealProposal) error) error
|
||||
Get(id abi.DealID) (*DealProposal, bool, error)
|
||||
|
||||
array() adt.Array
|
||||
decode(*cbg.Deferred) (*DealProposal, error)
|
||||
}
|
||||
|
||||
type PublishStorageDealsParams = market0.PublishStorageDealsParams
|
||||
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
|
||||
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
|
||||
|
||||
type ClientDealProposal = market0.ClientDealProposal
|
||||
|
||||
type DealState struct {
|
||||
SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector
|
||||
LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated
|
||||
SlashEpoch abi.ChainEpoch // -1 if deal never slashed
|
||||
}
|
||||
|
||||
type DealProposal struct {
|
||||
PieceCID cid.Cid
|
||||
PieceSize abi.PaddedPieceSize
|
||||
VerifiedDeal bool
|
||||
Client address.Address
|
||||
Provider address.Address
|
||||
Label string
|
||||
StartEpoch abi.ChainEpoch
|
||||
EndEpoch abi.ChainEpoch
|
||||
StoragePricePerEpoch abi.TokenAmount
|
||||
ProviderCollateral abi.TokenAmount
|
||||
ClientCollateral abi.TokenAmount
|
||||
}
|
||||
|
||||
type DealStateChanges struct {
|
||||
Added []DealIDState
|
||||
Modified []DealStateChange
|
||||
Removed []DealIDState
|
||||
}
|
||||
|
||||
type DealIDState struct {
|
||||
ID abi.DealID
|
||||
Deal DealState
|
||||
}
|
||||
|
||||
// DealStateChange is a change in deal state from -> to
|
||||
type DealStateChange struct {
|
||||
ID abi.DealID
|
||||
From *DealState
|
||||
To *DealState
|
||||
}
|
||||
|
||||
type DealProposalChanges struct {
|
||||
Added []ProposalIDState
|
||||
Removed []ProposalIDState
|
||||
}
|
||||
|
||||
type ProposalIDState struct {
|
||||
ID abi.DealID
|
||||
Proposal DealProposal
|
||||
}
|
||||
|
||||
func EmptyDealState() *DealState {
|
||||
return &DealState{
|
||||
SectorStartEpoch: -1,
|
||||
SlashEpoch: -1,
|
||||
LastUpdatedEpoch: -1,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
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"
|
||||
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
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 {
|
||||
market0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) TotalLocked() (abi.TokenAmount, error) {
|
||||
fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
|
||||
fml = types.BigAdd(fml, s.TotalClientStorageFee)
|
||||
return fml, nil
|
||||
}
|
||||
|
||||
func (s *state0) BalancesChanged(otherState State) (bool, error) {
|
||||
otherState0, ok := otherState.(*state0)
|
||||
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(otherState0.State.EscrowTable) || !s.State.LockedTable.Equals(otherState0.State.LockedTable), nil
|
||||
}
|
||||
|
||||
func (s *state0) StatesChanged(otherState State) (bool, error) {
|
||||
otherState0, ok := otherState.(*state0)
|
||||
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(otherState0.State.States), nil
|
||||
}
|
||||
|
||||
func (s *state0) States() (DealStates, error) {
|
||||
stateArray, err := adt0.AsArray(s.store, s.State.States)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dealStates0{stateArray}, nil
|
||||
}
|
||||
|
||||
func (s *state0) ProposalsChanged(otherState State) (bool, error) {
|
||||
otherState0, ok := otherState.(*state0)
|
||||
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(otherState0.State.Proposals), nil
|
||||
}
|
||||
|
||||
func (s *state0) Proposals() (DealProposals, error) {
|
||||
proposalArray, err := adt0.AsArray(s.store, s.State.Proposals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dealProposals0{proposalArray}, nil
|
||||
}
|
||||
|
||||
func (s *state0) EscrowTable() (BalanceTable, error) {
|
||||
bt, err := adt0.AsBalanceTable(s.store, s.State.EscrowTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &balanceTable0{bt}, nil
|
||||
}
|
||||
|
||||
func (s *state0) LockedTable() (BalanceTable, error) {
|
||||
bt, err := adt0.AsBalanceTable(s.store, s.State.LockedTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &balanceTable0{bt}, nil
|
||||
}
|
||||
|
||||
func (s *state0) VerifyDealsForActivation(
|
||||
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
|
||||
) (weight, verifiedWeight abi.DealWeight, err error) {
|
||||
return market0.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
|
||||
}
|
||||
|
||||
type balanceTable0 struct {
|
||||
*adt0.BalanceTable
|
||||
}
|
||||
|
||||
func (bt *balanceTable0) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
|
||||
asMap := (*adt0.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 dealStates0 struct {
|
||||
adt.Array
|
||||
}
|
||||
|
||||
func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
|
||||
var deal0 market0.DealState
|
||||
found, err := s.Array.Get(uint64(dealID), &deal0)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
deal := fromV0DealState(deal0)
|
||||
return &deal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
|
||||
var ds0 market0.DealState
|
||||
return s.Array.ForEach(&ds0, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV0DealState(ds0))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) {
|
||||
var ds0 market0.DealState
|
||||
if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ds := fromV0DealState(ds0)
|
||||
return &ds, nil
|
||||
}
|
||||
|
||||
func (s *dealStates0) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV0DealState(v0 market0.DealState) DealState {
|
||||
return (DealState)(v0)
|
||||
}
|
||||
|
||||
type dealProposals0 struct {
|
||||
adt.Array
|
||||
}
|
||||
|
||||
func (s *dealProposals0) Get(dealID abi.DealID) (*DealProposal, bool, error) {
|
||||
var proposal0 market0.DealProposal
|
||||
found, err := s.Array.Get(uint64(dealID), &proposal0)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if !found {
|
||||
return nil, false, nil
|
||||
}
|
||||
proposal := fromV0DealProposal(proposal0)
|
||||
return &proposal, true, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals0) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
|
||||
var dp0 market0.DealProposal
|
||||
return s.Array.ForEach(&dp0, func(idx int64) error {
|
||||
return cb(abi.DealID(idx), fromV0DealProposal(dp0))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *dealProposals0) decode(val *cbg.Deferred) (*DealProposal, error) {
|
||||
var dp0 market0.DealProposal
|
||||
if err := dp0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dp := fromV0DealProposal(dp0)
|
||||
return &dp, nil
|
||||
}
|
||||
|
||||
func (s *dealProposals0) array() adt.Array {
|
||||
return s.Array
|
||||
}
|
||||
|
||||
func fromV0DealProposal(v0 market0.DealProposal) DealProposal {
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
)
|
||||
|
||||
func DiffPreCommits(pre, cur State) (*PreCommitChanges, error) {
|
||||
results := new(PreCommitChanges)
|
||||
|
||||
prep, err := pre.precommits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curp, err := cur.precommits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = adt.DiffAdtMap(prep, curp, &preCommitDiffer{results, pre, cur})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type preCommitDiffer struct {
|
||||
Results *PreCommitChanges
|
||||
pre, after State
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) AsKey(key string) (abi.Keyer, error) {
|
||||
sector, err := abi.ParseUIntKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return abi.UIntKey(sector), nil
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) Add(key string, val *cbg.Deferred) error {
|
||||
sp, err := m.after.decodeSectorPreCommitOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Added = append(m.Results.Added, sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) Modify(key string, from, to *cbg.Deferred) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *preCommitDiffer) Remove(key string, val *cbg.Deferred) error {
|
||||
sp, err := m.pre.decodeSectorPreCommitOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Removed = append(m.Results.Removed, sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func DiffSectors(pre, cur State) (*SectorChanges, error) {
|
||||
results := new(SectorChanges)
|
||||
|
||||
pres, err := pre.sectors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curs, err := cur.sectors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = adt.DiffAdtArray(pres, curs, §orDiffer{results, pre, cur})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type sectorDiffer struct {
|
||||
Results *SectorChanges
|
||||
pre, after State
|
||||
}
|
||||
|
||||
func (m *sectorDiffer) Add(key uint64, val *cbg.Deferred) error {
|
||||
si, err := m.after.decodeSectorOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Added = append(m.Results.Added, si)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *sectorDiffer) Modify(key uint64, from, to *cbg.Deferred) error {
|
||||
siFrom, err := m.pre.decodeSectorOnChainInfo(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
siTo, err := m.after.decodeSectorOnChainInfo(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if siFrom.Expiration != siTo.Expiration {
|
||||
m.Results.Extended = append(m.Results.Extended, SectorExtensions{
|
||||
From: siFrom,
|
||||
To: siTo,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *sectorDiffer) Remove(key uint64, val *cbg.Deferred) error {
|
||||
si, err := m.pre.decodeSectorOnChainInfo(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Results.Removed = append(m.Results.Removed, si)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
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
|
||||
}
|
||||
|
||||
numDl, err := pre.NumDeadlines()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dlDiff := make(DeadlinesDiff, numDl)
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"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/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"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"
|
||||
)
|
||||
|
||||
func init() {
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
// Unchanged between v0 and v2 actors
|
||||
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
|
||||
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
|
||||
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
|
||||
var WPoStChallengeLookback = miner0.WPoStChallengeLookback
|
||||
var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
|
||||
|
||||
const MinSectorExpiration = miner0.MinSectorExpiration
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StorageMinerActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.StorageMinerActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
// Total available balance to spend.
|
||||
AvailableBalance(abi.TokenAmount) (abi.TokenAmount, error)
|
||||
// Funds that will vest by the given epoch.
|
||||
VestedFunds(abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
// Funds locked for various reasons.
|
||||
LockedFunds() (LockedFunds, error)
|
||||
FeeDebt() (abi.TokenAmount, error)
|
||||
|
||||
GetSector(abi.SectorNumber) (*SectorOnChainInfo, error)
|
||||
FindSector(abi.SectorNumber) (*SectorLocation, error)
|
||||
GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error)
|
||||
GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error)
|
||||
LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error)
|
||||
NumLiveSectors() (uint64, error)
|
||||
IsAllocated(abi.SectorNumber) (bool, error)
|
||||
|
||||
LoadDeadline(idx uint64) (Deadline, error)
|
||||
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
|
||||
NumDeadlines() (uint64, error)
|
||||
DeadlinesChanged(State) (bool, error)
|
||||
|
||||
Info() (MinerInfo, error)
|
||||
|
||||
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
|
||||
|
||||
// Diff helpers. Used by Diff* functions internally.
|
||||
sectors() (adt.Array, error)
|
||||
decodeSectorOnChainInfo(*cbg.Deferred) (SectorOnChainInfo, error)
|
||||
precommits() (adt.Map, error)
|
||||
decodeSectorPreCommitOnChainInfo(*cbg.Deferred) (SectorPreCommitOnChainInfo, error)
|
||||
}
|
||||
|
||||
type Deadline interface {
|
||||
LoadPartition(idx uint64) (Partition, error)
|
||||
ForEachPartition(cb func(idx uint64, part Partition) error) error
|
||||
PostSubmissions() (bitfield.BitField, error)
|
||||
|
||||
PartitionsChanged(Deadline) (bool, error)
|
||||
}
|
||||
|
||||
type Partition interface {
|
||||
AllSectors() (bitfield.BitField, error)
|
||||
FaultySectors() (bitfield.BitField, error)
|
||||
RecoveringSectors() (bitfield.BitField, error)
|
||||
LiveSectors() (bitfield.BitField, error)
|
||||
ActiveSectors() (bitfield.BitField, error)
|
||||
}
|
||||
|
||||
type SectorOnChainInfo struct {
|
||||
SectorNumber abi.SectorNumber
|
||||
SealProof abi.RegisteredSealProof
|
||||
SealedCID cid.Cid
|
||||
DealIDs []abi.DealID
|
||||
Activation abi.ChainEpoch
|
||||
Expiration abi.ChainEpoch
|
||||
DealWeight abi.DealWeight
|
||||
VerifiedDealWeight abi.DealWeight
|
||||
InitialPledge abi.TokenAmount
|
||||
ExpectedDayReward abi.TokenAmount
|
||||
ExpectedStoragePledge abi.TokenAmount
|
||||
}
|
||||
|
||||
type SectorPreCommitInfo = miner0.SectorPreCommitInfo
|
||||
|
||||
type SectorPreCommitOnChainInfo struct {
|
||||
Info SectorPreCommitInfo
|
||||
PreCommitDeposit abi.TokenAmount
|
||||
PreCommitEpoch abi.ChainEpoch
|
||||
DealWeight abi.DealWeight
|
||||
VerifiedDealWeight abi.DealWeight
|
||||
}
|
||||
|
||||
type PoStPartition = miner0.PoStPartition
|
||||
type RecoveryDeclaration = miner0.RecoveryDeclaration
|
||||
type FaultDeclaration = miner0.FaultDeclaration
|
||||
|
||||
// Params
|
||||
type DeclareFaultsParams = miner0.DeclareFaultsParams
|
||||
type DeclareFaultsRecoveredParams = miner0.DeclareFaultsRecoveredParams
|
||||
type SubmitWindowedPoStParams = miner0.SubmitWindowedPoStParams
|
||||
type ProveCommitSectorParams = miner0.ProveCommitSectorParams
|
||||
|
||||
type MinerInfo struct {
|
||||
Owner address.Address // Must be an ID-address.
|
||||
Worker address.Address // Must be an ID-address.
|
||||
NewWorker address.Address // Must be an ID-address.
|
||||
ControlAddresses []address.Address // Must be an ID-addresses.
|
||||
WorkerChangeEpoch abi.ChainEpoch
|
||||
PeerId *peer.ID
|
||||
Multiaddrs []abi.Multiaddrs
|
||||
SealProofType abi.RegisteredSealProof
|
||||
SectorSize abi.SectorSize
|
||||
WindowPoStPartitionSectors uint64
|
||||
ConsensusFaultElapsed abi.ChainEpoch
|
||||
}
|
||||
|
||||
type SectorExpiration struct {
|
||||
OnTime abi.ChainEpoch
|
||||
|
||||
// non-zero if sector is faulty, epoch at which it will be permanently
|
||||
// removed if it doesn't recover
|
||||
Early abi.ChainEpoch
|
||||
}
|
||||
|
||||
type SectorLocation struct {
|
||||
Deadline uint64
|
||||
Partition uint64
|
||||
}
|
||||
|
||||
type SectorChanges struct {
|
||||
Added []SectorOnChainInfo
|
||||
Extended []SectorExtensions
|
||||
Removed []SectorOnChainInfo
|
||||
}
|
||||
|
||||
type SectorExtensions struct {
|
||||
From SectorOnChainInfo
|
||||
To SectorOnChainInfo
|
||||
}
|
||||
|
||||
type PreCommitChanges struct {
|
||||
Added []SectorPreCommitOnChainInfo
|
||||
Removed []SectorPreCommitOnChainInfo
|
||||
}
|
||||
|
||||
type LockedFunds struct {
|
||||
VestingFunds abi.TokenAmount
|
||||
InitialPledgeRequirement abi.TokenAmount
|
||||
PreCommitDeposits abi.TokenAmount
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
)
|
||||
|
||||
func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) (bitfield.BitField, error) {
|
||||
var parts []bitfield.BitField
|
||||
|
||||
err := mas.ForEachDeadline(func(dlidx uint64, dl Deadline) error {
|
||||
return dl.ForEachPartition(func(partidx uint64, part Partition) error {
|
||||
s, err := sget(part)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("getting sector list (dl: %d, part %d): %w", dlidx, partidx, err)
|
||||
}
|
||||
|
||||
parts = append(parts, s)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return bitfield.BitField{}, err
|
||||
}
|
||||
|
||||
return bitfield.MultiMerge(parts...)
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
package miner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"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"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
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 {
|
||||
miner0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type deadline0 struct {
|
||||
miner0.Deadline
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
type partition0 struct {
|
||||
miner0.Partition
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return s.GetAvailableBalance(bal), nil
|
||||
}
|
||||
|
||||
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return s.CheckVestedFunds(s.store, epoch)
|
||||
}
|
||||
|
||||
func (s *state0) LockedFunds() (LockedFunds, error) {
|
||||
return LockedFunds{
|
||||
VestingFunds: s.State.LockedFunds,
|
||||
InitialPledgeRequirement: s.State.InitialPledgeRequirement,
|
||||
PreCommitDeposits: s.State.PreCommitDeposits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state0) FeeDebt() (abi.TokenAmount, error) {
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialPledge() (abi.TokenAmount, error) {
|
||||
return s.State.InitialPledgeRequirement, nil
|
||||
}
|
||||
|
||||
func (s *state0) PreCommitDeposits() (abi.TokenAmount, error) {
|
||||
return s.State.PreCommitDeposits, nil
|
||||
}
|
||||
|
||||
func (s *state0) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
|
||||
info, ok, err := s.State.GetSector(s.store, num)
|
||||
if !ok || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := fromV0SectorOnChainInfo(*info)
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (s *state0) 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 *state0) 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 *miner0.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 *state0) 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 *miner0.Deadline) error {
|
||||
partitions, err := dl.PartitionsArray(s.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
quant := s.State.QuantSpecForDeadline(dlIdx)
|
||||
var part miner0.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 := miner0.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var exp miner0.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 *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
|
||||
info, ok, err := s.State.GetPrecommittedSector(s.store, num)
|
||||
if !ok || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := fromV0SectorPreCommitOnChainInfo(*info)
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (s *state0) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
|
||||
sectors, err := miner0.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 info0 miner0.SectorOnChainInfo
|
||||
if err := sectors.ForEach(&info0, func(_ int64) error {
|
||||
info := fromV0SectorOnChainInfo(info0)
|
||||
infos = append(infos, &info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
// Otherwise, load selected.
|
||||
infos0, err := sectors.Load(*snos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos := make([]*SectorOnChainInfo, len(infos0))
|
||||
for i, info0 := range infos0 {
|
||||
info := fromV0SectorOnChainInfo(*info0)
|
||||
infos[i] = &info
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
func (s *state0) 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 *state0) 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 &deadline0{*dl, s.store}, nil
|
||||
}
|
||||
|
||||
func (s *state0) 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 *miner0.Deadline) error {
|
||||
return cb(i, &deadline0{*dl, s.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *state0) NumDeadlines() (uint64, error) {
|
||||
return miner0.WPoStPeriodDeadlines, nil
|
||||
}
|
||||
|
||||
func (s *state0) DeadlinesChanged(other State) (bool, error) {
|
||||
other0, ok := other.(*state0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return s.State.Deadlines.Equals(other0.Deadlines), nil
|
||||
}
|
||||
|
||||
func (s *state0) 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: -1,
|
||||
}
|
||||
|
||||
if info.PendingWorkerKey != nil {
|
||||
mi.NewWorker = info.PendingWorkerKey.NewWorker
|
||||
mi.WorkerChangeEpoch = info.PendingWorkerKey.EffectiveAt
|
||||
}
|
||||
|
||||
return mi, nil
|
||||
}
|
||||
|
||||
func (s *state0) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
|
||||
return s.State.DeadlineInfo(epoch), nil
|
||||
}
|
||||
|
||||
func (s *state0) sectors() (adt.Array, error) {
|
||||
return adt0.AsArray(s.store, s.Sectors)
|
||||
}
|
||||
|
||||
func (s *state0) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
|
||||
var si miner0.SectorOnChainInfo
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return SectorOnChainInfo{}, err
|
||||
}
|
||||
|
||||
return fromV0SectorOnChainInfo(si), nil
|
||||
}
|
||||
|
||||
func (s *state0) precommits() (adt.Map, error) {
|
||||
return adt0.AsMap(s.store, s.PreCommittedSectors)
|
||||
}
|
||||
|
||||
func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
|
||||
var sp miner0.SectorPreCommitOnChainInfo
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return SectorPreCommitOnChainInfo{}, err
|
||||
}
|
||||
|
||||
return fromV0SectorPreCommitOnChainInfo(sp), nil
|
||||
}
|
||||
|
||||
func (d *deadline0) LoadPartition(idx uint64) (Partition, error) {
|
||||
p, err := d.Deadline.LoadPartition(d.store, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &partition0{*p, d.store}, nil
|
||||
}
|
||||
|
||||
func (d *deadline0) ForEachPartition(cb func(uint64, Partition) error) error {
|
||||
ps, err := d.Deadline.PartitionsArray(d.store)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var part miner0.Partition
|
||||
return ps.ForEach(&part, func(i int64) error {
|
||||
return cb(uint64(i), &partition0{part, d.store})
|
||||
})
|
||||
}
|
||||
|
||||
func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
|
||||
other0, ok := other.(*deadline0)
|
||||
if !ok {
|
||||
// treat an upgrade as a change, always
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
|
||||
}
|
||||
|
||||
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
|
||||
return d.Deadline.PostSubmissions, nil
|
||||
}
|
||||
|
||||
func (p *partition0) AllSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Sectors, nil
|
||||
}
|
||||
|
||||
func (p *partition0) FaultySectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Faults, nil
|
||||
}
|
||||
|
||||
func (p *partition0) RecoveringSectors() (bitfield.BitField, error) {
|
||||
return p.Partition.Recoveries, nil
|
||||
}
|
||||
|
||||
func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo {
|
||||
return (SectorOnChainInfo)(v0)
|
||||
}
|
||||
|
||||
func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
|
||||
return (SectorPreCommitOnChainInfo)(v0)
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
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) (abi.TokenAmount, error) {
|
||||
return s.GetAvailableBalance(bal)
|
||||
}
|
||||
|
||||
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) 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,70 @@
|
||||
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"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
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/builtin"
|
||||
"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) {
|
||||
switch act.Code {
|
||||
case builtin0.MultisigActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.MultisigActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
|
||||
StartEpoch() (abi.ChainEpoch, error)
|
||||
UnlockDuration() (abi.ChainEpoch, error)
|
||||
InitialBalance() (abi.TokenAmount, error)
|
||||
Threshold() (uint64, error)
|
||||
Signers() ([]address.Address, error)
|
||||
|
||||
ForEachPendingTxn(func(id int64, txn Transaction) error) error
|
||||
}
|
||||
|
||||
type Transaction = msig0.Transaction
|
||||
@@ -0,0 +1,70 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
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 {
|
||||
msig0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
|
||||
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
|
||||
}
|
||||
|
||||
func (s *state0) StartEpoch() (abi.ChainEpoch, error) {
|
||||
return s.State.StartEpoch, nil
|
||||
}
|
||||
|
||||
func (s *state0) UnlockDuration() (abi.ChainEpoch, error) {
|
||||
return s.State.UnlockDuration, nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialBalance() (abi.TokenAmount, error) {
|
||||
return s.State.InitialBalance, nil
|
||||
}
|
||||
|
||||
func (s *state0) Threshold() (uint64, error) {
|
||||
return s.State.NumApprovalsThreshold, nil
|
||||
}
|
||||
|
||||
func (s *state0) Signers() ([]address.Address, error) {
|
||||
return s.State.Signers, nil
|
||||
}
|
||||
|
||||
func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
|
||||
arr, err := adt0.AsMap(s.store, s.State.PendingTxns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var out msig0.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))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package multisig
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
"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))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"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/builtin/paych"
|
||||
)
|
||||
|
||||
type mockState struct {
|
||||
from address.Address
|
||||
to address.Address
|
||||
settlingAt abi.ChainEpoch
|
||||
toSend abi.TokenAmount
|
||||
lanes map[uint64]paych.LaneState
|
||||
}
|
||||
|
||||
type mockLaneState struct {
|
||||
redeemed big.Int
|
||||
nonce uint64
|
||||
}
|
||||
|
||||
// NewMockPayChState constructs a state for a payment channel with the set fixed values
|
||||
// that satisfies the paych.State interface.
|
||||
func NewMockPayChState(from address.Address,
|
||||
to address.Address,
|
||||
settlingAt abi.ChainEpoch,
|
||||
lanes map[uint64]paych.LaneState,
|
||||
) paych.State {
|
||||
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
|
||||
// that satisfies the paych.LaneState interface. Useful for populating lanes when
|
||||
// calling NewMockPayChState
|
||||
func NewMockLaneState(redeemed big.Int, nonce uint64) paych.LaneState {
|
||||
return &mockLaneState{redeemed, nonce}
|
||||
}
|
||||
|
||||
func (ms *mockState) MarshalCBOR(io.Writer) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// Channel owner, who has funded the actor
|
||||
func (ms *mockState) From() (address.Address, error) {
|
||||
return ms.from, nil
|
||||
}
|
||||
|
||||
// Recipient of payouts from channel
|
||||
func (ms *mockState) To() (address.Address, error) {
|
||||
return ms.to, nil
|
||||
}
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
func (ms *mockState) SettlingAt() (abi.ChainEpoch, error) {
|
||||
return ms.settlingAt, nil
|
||||
}
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
func (ms *mockState) ToSend() (abi.TokenAmount, error) {
|
||||
return ms.toSend, nil
|
||||
}
|
||||
|
||||
// Get total number of lanes
|
||||
func (ms *mockState) LaneCount() (uint64, error) {
|
||||
return uint64(len(ms.lanes)), nil
|
||||
}
|
||||
|
||||
// Iterate lane states
|
||||
func (ms *mockState) ForEachLaneState(cb func(idx uint64, dl paych.LaneState) error) error {
|
||||
var lastErr error
|
||||
for lane, state := range ms.lanes {
|
||||
if err := cb(lane, state); err != nil {
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func (mls *mockLaneState) Redeemed() (big.Int, error) {
|
||||
return mls.redeemed, nil
|
||||
}
|
||||
|
||||
func (mls *mockLaneState) Nonce() (uint64, error) {
|
||||
return mls.nonce, nil
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package paych
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
big "github.com/filecoin-project/go-state-types/big"
|
||||
"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"
|
||||
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/builtin"
|
||||
"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
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.PaymentChannelActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.PaymentChannelActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
// State is an abstract version of payment channel state that works across
|
||||
// versions
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
// Channel owner, who has funded the actor
|
||||
From() (address.Address, error)
|
||||
// Recipient of payouts from channel
|
||||
To() (address.Address, error)
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
SettlingAt() (abi.ChainEpoch, error)
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
ToSend() (abi.TokenAmount, error)
|
||||
|
||||
// Get total number of lanes
|
||||
LaneCount() (uint64, error)
|
||||
|
||||
// Iterate lane states
|
||||
ForEachLaneState(cb func(idx uint64, dl LaneState) error) error
|
||||
}
|
||||
|
||||
// LaneState is an abstract copy of the state of a single lane
|
||||
type LaneState interface {
|
||||
Redeemed() (big.Int, error)
|
||||
Nonce() (uint64, error)
|
||||
}
|
||||
|
||||
type SignedVoucher = paych0.SignedVoucher
|
||||
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
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
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 {
|
||||
paych0.State
|
||||
store adt.Store
|
||||
lsAmt *adt0.Array
|
||||
}
|
||||
|
||||
// Channel owner, who has funded the actor
|
||||
func (s *state0) From() (address.Address, error) {
|
||||
return s.State.From, nil
|
||||
}
|
||||
|
||||
// Recipient of payouts from channel
|
||||
func (s *state0) To() (address.Address, error) {
|
||||
return s.State.To, nil
|
||||
}
|
||||
|
||||
// Height at which the channel can be `Collected`
|
||||
func (s *state0) SettlingAt() (abi.ChainEpoch, error) {
|
||||
return s.State.SettlingAt, nil
|
||||
}
|
||||
|
||||
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
|
||||
func (s *state0) ToSend() (abi.TokenAmount, error) {
|
||||
return s.State.ToSend, nil
|
||||
}
|
||||
|
||||
func (s *state0) getOrLoadLsAmt() (*adt0.Array, error) {
|
||||
if s.lsAmt != nil {
|
||||
return s.lsAmt, nil
|
||||
}
|
||||
|
||||
// Get the lane state from the chain
|
||||
lsamt, err := adt0.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 *state0) LaneCount() (uint64, error) {
|
||||
lsamt, err := s.getOrLoadLsAmt()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return lsamt.Length(), nil
|
||||
}
|
||||
|
||||
// Iterate lane states
|
||||
func (s *state0) 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 paych0.LaneState
|
||||
return lsamt.ForEach(&ls, func(i int64) error {
|
||||
return cb(uint64(i), &laneState0{ls})
|
||||
})
|
||||
}
|
||||
|
||||
type laneState0 struct {
|
||||
paych0.LaneState
|
||||
}
|
||||
|
||||
func (ls *laneState0) Redeemed() (big.Int, error) {
|
||||
return ls.LaneState.Redeemed, nil
|
||||
}
|
||||
|
||||
func (ls *laneState0) Nonce() (uint64, error) {
|
||||
return ls.LaneState.Nonce, nil
|
||||
}
|
||||
@@ -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,62 @@
|
||||
package power
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"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/actors/builtin"
|
||||
"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.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 = builtin0.StoragePowerActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.StoragePowerActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.StoragePowerActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
TotalLocked() (abi.TokenAmount, error)
|
||||
TotalPower() (Claim, error)
|
||||
TotalCommitted() (Claim, error)
|
||||
TotalPowerSmoothed() (builtin.FilterEstimate, error)
|
||||
|
||||
// MinerCounts returns the number of miners. Participating is the number
|
||||
// with power above the minimum miner threshold.
|
||||
MinerCounts() (participating, total uint64, err error)
|
||||
MinerPower(address.Address) (Claim, bool, error)
|
||||
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
|
||||
ListAllMiners() ([]address.Address, error)
|
||||
}
|
||||
|
||||
type Claim struct {
|
||||
// Sum of raw byte power for a miner's sectors.
|
||||
RawBytePower abi.StoragePower
|
||||
|
||||
// Sum of quality adjusted power for a miner's sectors.
|
||||
QualityAdjPower abi.StoragePower
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package power
|
||||
|
||||
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/adt"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
)
|
||||
|
||||
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 {
|
||||
power0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) TotalLocked() (abi.TokenAmount, error) {
|
||||
return s.TotalPledgeCollateral, nil
|
||||
}
|
||||
|
||||
func (s *state0) 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 *state0) TotalCommitted() (Claim, error) {
|
||||
return Claim{
|
||||
RawBytePower: s.TotalBytesCommitted,
|
||||
QualityAdjPower: s.TotalQABytesCommitted,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *state0) MinerPower(addr address.Address) (Claim, bool, error) {
|
||||
claims, err := adt0.AsMap(s.store, s.Claims)
|
||||
if err != nil {
|
||||
return Claim{}, false, err
|
||||
}
|
||||
var claim power0.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 *state0) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
|
||||
return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
|
||||
}
|
||||
|
||||
func (s *state0) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
|
||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochQAPowerSmoothed), nil
|
||||
}
|
||||
|
||||
func (s *state0) MinerCounts() (uint64, uint64, error) {
|
||||
return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
|
||||
}
|
||||
|
||||
func (s *state0) ListAllMiners() ([]address.Address, error) {
|
||||
claims, err := adt0.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
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package power
|
||||
|
||||
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/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
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
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/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
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 = builtin0.RewardActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (st State, err error) {
|
||||
switch act.Code {
|
||||
case builtin0.RewardActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.RewardActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
ThisEpochBaselinePower() (abi.StoragePower, error)
|
||||
ThisEpochReward() (abi.StoragePower, error)
|
||||
ThisEpochRewardSmoothed() (builtin.FilterEstimate, error)
|
||||
|
||||
EffectiveBaselinePower() (abi.StoragePower, error)
|
||||
EffectiveNetworkTime() (abi.ChainEpoch, error)
|
||||
|
||||
TotalStoragePowerReward() (abi.TokenAmount, error)
|
||||
|
||||
CumsumBaseline() (abi.StoragePower, error)
|
||||
CumsumRealized() (abi.StoragePower, error)
|
||||
|
||||
InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error)
|
||||
PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error)
|
||||
}
|
||||
|
||||
type AwardBlockRewardParams = reward0.AwardBlockRewardParams
|
||||
@@ -0,0 +1,83 @@
|
||||
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"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
)
|
||||
|
||||
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 {
|
||||
reward0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochReward() (abi.StoragePower, error) {
|
||||
return s.State.ThisEpochReward, nil
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
|
||||
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
|
||||
}
|
||||
|
||||
func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) {
|
||||
return s.State.ThisEpochBaselinePower, nil
|
||||
}
|
||||
|
||||
func (s *state0) TotalStoragePowerReward() (abi.TokenAmount, error) {
|
||||
return s.State.TotalMined, nil
|
||||
}
|
||||
|
||||
func (s *state0) EffectiveBaselinePower() (abi.StoragePower, error) {
|
||||
return s.State.EffectiveBaselinePower, nil
|
||||
}
|
||||
|
||||
func (s *state0) EffectiveNetworkTime() (abi.ChainEpoch, error) {
|
||||
return s.State.EffectiveNetworkTime, nil
|
||||
}
|
||||
|
||||
func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
|
||||
return s.State.CumsumRealized, nil
|
||||
}
|
||||
|
||||
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
|
||||
return miner0.InitialPledgeForPower(
|
||||
sectorWeight,
|
||||
s.State.ThisEpochBaselinePower,
|
||||
networkTotalPledge,
|
||||
s.State.ThisEpochRewardSmoothed,
|
||||
&smoothing0.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
circSupply), nil
|
||||
}
|
||||
|
||||
func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
|
||||
return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
|
||||
&smoothing0.FilterEstimate{
|
||||
PositionEstimate: networkQAPower.PositionEstimate,
|
||||
VelocityEstimate: networkQAPower.VelocityEstimate,
|
||||
},
|
||||
sectorWeight), nil
|
||||
}
|
||||
@@ -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.StoragePower, 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() (abi.StoragePower, error) {
|
||||
return s.State.CumsumBaseline, nil
|
||||
}
|
||||
|
||||
func (s *state2) CumsumRealized() (abi.StoragePower, 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)
|
||||
})
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
)
|
||||
|
||||
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 {
|
||||
verifreg0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) RootKey() (address.Address, error) {
|
||||
return s.State.RootKey, nil
|
||||
}
|
||||
|
||||
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||
return getDataCap(s.store, actors.Version0, s.State.VerifiedClients, addr)
|
||||
}
|
||||
|
||||
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
|
||||
return getDataCap(s.store, actors.Version0, s.State.Verifiers, addr)
|
||||
}
|
||||
|
||||
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
return forEachCap(s.store, actors.Version0, s.State.Verifiers, cb)
|
||||
}
|
||||
|
||||
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package verifreg
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
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/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
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 = builtin0.VerifiedRegistryActorAddr
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
case builtin0.VerifiedRegistryActorCodeID:
|
||||
return load0(store, act.Head)
|
||||
case builtin2.VerifiedRegistryActorCodeID:
|
||||
return load2(store, act.Head)
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
RootKey() (address.Address, error)
|
||||
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
|
||||
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"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"
|
||||
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
|
||||
)
|
||||
|
||||
const (
|
||||
ChainFinality = miner0.ChainFinality
|
||||
SealRandomnessLookback = ChainFinality
|
||||
)
|
||||
|
||||
// SetSupportedProofTypes sets supported proof types, across all actor versions.
|
||||
// This should only be used for testing.
|
||||
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
|
||||
newTypes := make(map[abi.RegisteredSealProof]struct{}, len(types))
|
||||
for _, t := range types {
|
||||
newTypes[t] = struct{}{}
|
||||
}
|
||||
// Set for all miner versions.
|
||||
miner0.SupportedProofTypes = newTypes
|
||||
miner2.SupportedProofTypes = newTypes
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// Set for all miner versions.
|
||||
miner0.SupportedProofTypes[t] = struct{}{}
|
||||
miner2.SupportedProofTypes[t] = 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
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
|
||||
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.SupportedProofTypes)
|
||||
require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay)
|
||||
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.True(t, verifreg0.MinVerifiedDealSize.Equals(verifreg2.MinVerifiedDealSize))
|
||||
}
|
||||
@@ -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:
|
||||
return Version2
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported network version %d", version))
|
||||
}
|
||||
}
|
||||
+168
-358
@@ -4,20 +4,19 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"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/specs-actors/actors/builtin"
|
||||
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
typegen "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/apibstore"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@@ -49,7 +48,7 @@ func NewStatePredicates(api ChainAPI) *StatePredicates {
|
||||
// - err
|
||||
type DiffTipSetKeyFunc func(ctx context.Context, oldState, newState types.TipSetKey) (changed bool, user UserData, err error)
|
||||
|
||||
type DiffActorStateFunc func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error)
|
||||
type DiffActorStateFunc func(ctx context.Context, oldActorState *types.Actor, newActorState *types.Actor) (changed bool, user UserData, err error)
|
||||
|
||||
// OnActorStateChanged calls diffStateFunc when the state changes for the given actor
|
||||
func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFunc DiffActorStateFunc) DiffTipSetKeyFunc {
|
||||
@@ -66,30 +65,30 @@ func (sp *StatePredicates) OnActorStateChanged(addr address.Address, diffStateFu
|
||||
if oldActor.Head.Equals(newActor.Head) {
|
||||
return false, nil, nil
|
||||
}
|
||||
return diffStateFunc(ctx, oldActor.Head, newActor.Head)
|
||||
return diffStateFunc(ctx, oldActor, newActor)
|
||||
}
|
||||
}
|
||||
|
||||
type DiffStorageMarketStateFunc func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error)
|
||||
type DiffStorageMarketStateFunc func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error)
|
||||
|
||||
// OnStorageMarketActorChanged calls diffStorageMarketState when the state changes for the market actor
|
||||
func (sp *StatePredicates) OnStorageMarketActorChanged(diffStorageMarketState DiffStorageMarketStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(builtin.StorageMarketActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState market.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(market.Address, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := market.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState market.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := market.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffStorageMarketState(ctx, &oldState, &newState)
|
||||
return diffStorageMarketState(ctx, oldState, newState)
|
||||
})
|
||||
}
|
||||
|
||||
type BalanceTables struct {
|
||||
EscrowTable *adt.BalanceTable
|
||||
LockedTable *adt.BalanceTable
|
||||
EscrowTable market.BalanceTable
|
||||
LockedTable market.BalanceTable
|
||||
}
|
||||
|
||||
// DiffBalanceTablesFunc compares two balance tables
|
||||
@@ -97,32 +96,32 @@ type DiffBalanceTablesFunc func(ctx context.Context, oldBalanceTable, newBalance
|
||||
|
||||
// OnBalanceChanged runs when the escrow table for available balances changes
|
||||
func (sp *StatePredicates) OnBalanceChanged(diffBalances DiffBalanceTablesFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) {
|
||||
if oldState.EscrowTable.Equals(newState.EscrowTable) && oldState.LockedTable.Equals(newState.LockedTable) {
|
||||
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
|
||||
bc, err := oldState.BalancesChanged(newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if !bc {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
oldEscrowRoot, err := adt.AsBalanceTable(ctxStore, oldState.EscrowTable)
|
||||
oldEscrowRoot, err := oldState.EscrowTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
oldLockedRoot, err := adt.AsBalanceTable(ctxStore, oldState.LockedTable)
|
||||
oldLockedRoot, err := oldState.LockedTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newEscrowRoot, err := adt.AsBalanceTable(ctxStore, newState.EscrowTable)
|
||||
newEscrowRoot, err := newState.EscrowTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newLockedRoot, err := adt.AsBalanceTable(ctxStore, newState.LockedTable)
|
||||
newLockedRoot, err := newState.LockedTable()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@@ -131,25 +130,27 @@ func (sp *StatePredicates) OnBalanceChanged(diffBalances DiffBalanceTablesFunc)
|
||||
}
|
||||
}
|
||||
|
||||
type DiffAdtArraysFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot *adt.Array) (changed bool, user UserData, err error)
|
||||
type DiffDealStatesFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot market.DealStates) (changed bool, user UserData, err error)
|
||||
type DiffDealProposalsFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot market.DealProposals) (changed bool, user UserData, err error)
|
||||
type DiffAdtArraysFunc func(ctx context.Context, oldDealStateRoot, newDealStateRoot adt.Array) (changed bool, user UserData, err error)
|
||||
|
||||
// OnDealStateChanged calls diffDealStates when the market deal state changes
|
||||
func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffAdtArraysFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) {
|
||||
if oldState.States.Equals(newState.States) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
oldRoot, err := adt.AsArray(ctxStore, oldState.States)
|
||||
func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
|
||||
sc, err := oldState.StatesChanged(newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := adt.AsArray(ctxStore, newState.States)
|
||||
|
||||
if !sc {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldRoot, err := oldState.States()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := newState.States()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@@ -159,22 +160,22 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffAdtArraysFunc)
|
||||
}
|
||||
|
||||
// OnDealProposalChanged calls diffDealProps when the market proposal state changes
|
||||
func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffAdtArraysFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState *market.State, newState *market.State) (changed bool, user UserData, err error) {
|
||||
if oldState.Proposals.Equals(newState.Proposals) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
oldRoot, err := adt.AsArray(ctxStore, oldState.Proposals)
|
||||
func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffDealProposalsFunc) DiffStorageMarketStateFunc {
|
||||
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
|
||||
pc, err := oldState.ProposalsChanged(newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := adt.AsArray(ctxStore, newState.Proposals)
|
||||
|
||||
if !pc {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldRoot, err := oldState.Proposals()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
newRoot, err := newState.Proposals()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@@ -183,51 +184,14 @@ func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffAdtArraysFunc
|
||||
}
|
||||
}
|
||||
|
||||
var _ AdtArrayDiff = &MarketDealProposalChanges{}
|
||||
|
||||
type MarketDealProposalChanges struct {
|
||||
Added []ProposalIDState
|
||||
Removed []ProposalIDState
|
||||
}
|
||||
|
||||
type ProposalIDState struct {
|
||||
ID abi.DealID
|
||||
Proposal market.DealProposal
|
||||
}
|
||||
|
||||
func (m *MarketDealProposalChanges) Add(key uint64, val *typegen.Deferred) error {
|
||||
dp := new(market.DealProposal)
|
||||
err := dp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealProposalChanges) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
// short circuit, DealProposals are static
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealProposalChanges) Remove(key uint64, val *typegen.Deferred) error {
|
||||
dp := new(market.DealProposal)
|
||||
err := dp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, ProposalIDState{abi.DealID(key), *dp})
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnDealProposalAmtChanged detects changes in the deal proposal AMT for all deal proposals and returns a MarketProposalsChanges structure containing:
|
||||
// - Added Proposals
|
||||
// - Modified Proposals
|
||||
// - Removed Proposals
|
||||
func (sp *StatePredicates) OnDealProposalAmtChanged() DiffAdtArraysFunc {
|
||||
return func(ctx context.Context, oldDealProps, newDealProps *adt.Array) (changed bool, user UserData, err error) {
|
||||
proposalChanges := new(MarketDealProposalChanges)
|
||||
if err := DiffAdtArray(oldDealProps, newDealProps, proposalChanges); err != nil {
|
||||
func (sp *StatePredicates) OnDealProposalAmtChanged() DiffDealProposalsFunc {
|
||||
return func(ctx context.Context, oldDealProps, newDealProps market.DealProposals) (changed bool, user UserData, err error) {
|
||||
proposalChanges, err := market.DiffDealProposals(oldDealProps, newDealProps)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
@@ -239,64 +203,14 @@ func (sp *StatePredicates) OnDealProposalAmtChanged() DiffAdtArraysFunc {
|
||||
}
|
||||
}
|
||||
|
||||
var _ AdtArrayDiff = &MarketDealStateChanges{}
|
||||
|
||||
type MarketDealStateChanges struct {
|
||||
Added []DealIDState
|
||||
Modified []DealStateChange
|
||||
Removed []DealIDState
|
||||
}
|
||||
|
||||
type DealIDState struct {
|
||||
ID abi.DealID
|
||||
Deal market.DealState
|
||||
}
|
||||
|
||||
func (m *MarketDealStateChanges) Add(key uint64, val *typegen.Deferred) error {
|
||||
ds := new(market.DealState)
|
||||
err := ds.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealStateChanges) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
dsFrom := new(market.DealState)
|
||||
if err := dsFrom.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dsTo := new(market.DealState)
|
||||
if err := dsTo.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if *dsFrom != *dsTo {
|
||||
m.Modified = append(m.Modified, DealStateChange{abi.DealID(key), dsFrom, dsTo})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MarketDealStateChanges) Remove(key uint64, val *typegen.Deferred) error {
|
||||
ds := new(market.DealState)
|
||||
err := ds.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, DealIDState{abi.DealID(key), *ds})
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnDealStateAmtChanged detects changes in the deal state AMT for all deal states and returns a MarketDealStateChanges structure containing:
|
||||
// - Added Deals
|
||||
// - Modified Deals
|
||||
// - Removed Deals
|
||||
func (sp *StatePredicates) OnDealStateAmtChanged() DiffAdtArraysFunc {
|
||||
return func(ctx context.Context, oldDealStates, newDealStates *adt.Array) (changed bool, user UserData, err error) {
|
||||
dealStateChanges := new(MarketDealStateChanges)
|
||||
if err := DiffAdtArray(oldDealStates, newDealStates, dealStateChanges); err != nil {
|
||||
func (sp *StatePredicates) OnDealStateAmtChanged() DiffDealStatesFunc {
|
||||
return func(ctx context.Context, oldDealStates, newDealStates market.DealStates) (changed bool, user UserData, err error) {
|
||||
dealStateChanges, err := market.DiffDealStates(oldDealStates, newDealStates)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
@@ -309,42 +223,29 @@ func (sp *StatePredicates) OnDealStateAmtChanged() DiffAdtArraysFunc {
|
||||
}
|
||||
|
||||
// ChangedDeals is a set of changes to deal state
|
||||
type ChangedDeals map[abi.DealID]DealStateChange
|
||||
|
||||
// DealStateChange is a change in deal state from -> to
|
||||
type DealStateChange struct {
|
||||
ID abi.DealID
|
||||
From *market.DealState
|
||||
To *market.DealState
|
||||
}
|
||||
type ChangedDeals map[abi.DealID]market.DealStateChange
|
||||
|
||||
// DealStateChangedForIDs detects changes in the deal state AMT for the given deal IDs
|
||||
func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffAdtArraysFunc {
|
||||
return func(ctx context.Context, oldDealStateArray, newDealStateArray *adt.Array) (changed bool, user UserData, err error) {
|
||||
func (sp *StatePredicates) DealStateChangedForIDs(dealIds []abi.DealID) DiffDealStatesFunc {
|
||||
return func(ctx context.Context, oldDealStates, newDealStates market.DealStates) (changed bool, user UserData, err error) {
|
||||
changedDeals := make(ChangedDeals)
|
||||
for _, dealID := range dealIds {
|
||||
var oldDealPtr, newDealPtr *market.DealState
|
||||
var oldDeal, newDeal market.DealState
|
||||
|
||||
// If the deal has been removed, we just set it to nil
|
||||
found, err := oldDealStateArray.Get(uint64(dealID), &oldDeal)
|
||||
oldDeal, oldFound, err := oldDealStates.Get(dealID)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if found {
|
||||
oldDealPtr = &oldDeal
|
||||
}
|
||||
|
||||
found, err = newDealStateArray.Get(uint64(dealID), &newDeal)
|
||||
newDeal, newFound, err := newDealStates.Get(dealID)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if found {
|
||||
newDealPtr = &newDeal
|
||||
}
|
||||
|
||||
if oldDeal != newDeal {
|
||||
changedDeals[dealID] = DealStateChange{dealID, oldDealPtr, newDealPtr}
|
||||
existenceChanged := oldFound != newFound
|
||||
valueChanged := (oldFound && newFound) && *oldDeal != *newDeal
|
||||
if existenceChanged || valueChanged {
|
||||
changedDeals[dealID] = market.DealStateChange{ID: dealID, From: oldDeal, To: newDeal}
|
||||
}
|
||||
}
|
||||
if len(changedDeals) > 0 {
|
||||
@@ -405,124 +306,43 @@ func (sp *StatePredicates) AvailableBalanceChangedForAddresses(getAddrs func() [
|
||||
}
|
||||
}
|
||||
|
||||
type DiffMinerActorStateFunc func(ctx context.Context, oldState *miner.State, newState *miner.State) (changed bool, user UserData, err error)
|
||||
type DiffMinerActorStateFunc func(ctx context.Context, oldState miner.State, newState miner.State) (changed bool, user UserData, err error)
|
||||
|
||||
func (sp *StatePredicates) OnInitActorChange(diffInitActorState DiffInitActorStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(builtin.InitActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState init_.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(init_.Address, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := init_.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState init_.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := init_.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffInitActorState(ctx, &oldState, &newState)
|
||||
return diffInitActorState(ctx, oldState, newState)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnMinerActorChange(minerAddr address.Address, diffMinerActorState DiffMinerActorStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(minerAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState miner.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(minerAddr, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := miner.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState miner.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := miner.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffMinerActorState(ctx, &oldState, &newState)
|
||||
return diffMinerActorState(ctx, oldState, newState)
|
||||
})
|
||||
}
|
||||
|
||||
type MinerSectorChanges struct {
|
||||
Added []miner.SectorOnChainInfo
|
||||
Extended []SectorExtensions
|
||||
Removed []miner.SectorOnChainInfo
|
||||
}
|
||||
|
||||
var _ AdtArrayDiff = &MinerSectorChanges{}
|
||||
|
||||
type SectorExtensions struct {
|
||||
From miner.SectorOnChainInfo
|
||||
To miner.SectorOnChainInfo
|
||||
}
|
||||
|
||||
func (m *MinerSectorChanges) Add(key uint64, val *typegen.Deferred) error {
|
||||
si := new(miner.SectorOnChainInfo)
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, *si)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerSectorChanges) Modify(key uint64, from, to *typegen.Deferred) error {
|
||||
siFrom := new(miner.SectorOnChainInfo)
|
||||
err := siFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
siTo := new(miner.SectorOnChainInfo)
|
||||
err = siTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if siFrom.Expiration != siTo.Expiration {
|
||||
m.Extended = append(m.Extended, SectorExtensions{
|
||||
From: *siFrom,
|
||||
To: *siTo,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerSectorChanges) Remove(key uint64, val *typegen.Deferred) error {
|
||||
si := new(miner.SectorOnChainInfo)
|
||||
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, *si)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnMinerSectorChange() DiffMinerActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState *miner.State) (changed bool, user UserData, err error) {
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
sectorChanges := &MinerSectorChanges{
|
||||
Added: []miner.SectorOnChainInfo{},
|
||||
Extended: []SectorExtensions{},
|
||||
Removed: []miner.SectorOnChainInfo{},
|
||||
}
|
||||
|
||||
// no sector changes
|
||||
if oldState.Sectors.Equals(newState.Sectors) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldSectors, err := adt.AsArray(ctxStore, oldState.Sectors)
|
||||
return func(ctx context.Context, oldState, newState miner.State) (changed bool, user UserData, err error) {
|
||||
sectorChanges, err := miner.DiffSectors(oldState, newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newSectors, err := adt.AsArray(ctxStore, newState.Sectors)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if err := DiffAdtArray(oldSectors, newSectors, sectorChanges); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
// nothing changed
|
||||
if len(sectorChanges.Added)+len(sectorChanges.Extended)+len(sectorChanges.Removed) == 0 {
|
||||
return false, nil, nil
|
||||
@@ -532,73 +352,13 @@ func (sp *StatePredicates) OnMinerSectorChange() DiffMinerActorStateFunc {
|
||||
}
|
||||
}
|
||||
|
||||
type MinerPreCommitChanges struct {
|
||||
Added []miner.SectorPreCommitOnChainInfo
|
||||
Removed []miner.SectorPreCommitOnChainInfo
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) AsKey(key string) (abi.Keyer, error) {
|
||||
sector, err := abi.ParseUIntKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return miner.SectorKey(abi.SectorNumber(sector)), nil
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) Add(key string, val *typegen.Deferred) error {
|
||||
sp := new(miner.SectorPreCommitOnChainInfo)
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Added = append(m.Added, *sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) Modify(key string, from, to *typegen.Deferred) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MinerPreCommitChanges) Remove(key string, val *typegen.Deferred) error {
|
||||
sp := new(miner.SectorPreCommitOnChainInfo)
|
||||
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Removed = append(m.Removed, *sp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnMinerPreCommitChange() DiffMinerActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState *miner.State) (changed bool, user UserData, err error) {
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
precommitChanges := &MinerPreCommitChanges{
|
||||
Added: []miner.SectorPreCommitOnChainInfo{},
|
||||
Removed: []miner.SectorPreCommitOnChainInfo{},
|
||||
}
|
||||
|
||||
if oldState.PreCommittedSectors.Equals(newState.PreCommittedSectors) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
oldPrecommits, err := adt.AsMap(ctxStore, oldState.PreCommittedSectors)
|
||||
return func(ctx context.Context, oldState, newState miner.State) (changed bool, user UserData, err error) {
|
||||
precommitChanges, err := miner.DiffPreCommits(oldState, newState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newPrecommits, err := adt.AsMap(ctxStore, newState.PreCommittedSectors)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if err := DiffAdtMap(oldPrecommits, newPrecommits, precommitChanges); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if len(precommitChanges.Added)+len(precommitChanges.Removed) == 0 {
|
||||
return false, nil, nil
|
||||
}
|
||||
@@ -608,20 +368,20 @@ func (sp *StatePredicates) OnMinerPreCommitChange() DiffMinerActorStateFunc {
|
||||
}
|
||||
|
||||
// DiffPaymentChannelStateFunc is function that compares two states for the payment channel
|
||||
type DiffPaymentChannelStateFunc func(ctx context.Context, oldState *paych.State, newState *paych.State) (changed bool, user UserData, err error)
|
||||
type DiffPaymentChannelStateFunc func(ctx context.Context, oldState paych.State, newState paych.State) (changed bool, user UserData, err error)
|
||||
|
||||
// OnPaymentChannelActorChanged calls diffPaymentChannelState when the state changes for the the payment channel actor
|
||||
func (sp *StatePredicates) OnPaymentChannelActorChanged(paychAddr address.Address, diffPaymentChannelState DiffPaymentChannelStateFunc) DiffTipSetKeyFunc {
|
||||
return sp.OnActorStateChanged(paychAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
|
||||
var oldState paych.State
|
||||
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
|
||||
return sp.OnActorStateChanged(paychAddr, func(ctx context.Context, oldActorState, newActorState *types.Actor) (changed bool, user UserData, err error) {
|
||||
oldState, err := paych.Load(adt.WrapStore(ctx, sp.cst), oldActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
var newState paych.State
|
||||
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
|
||||
newState, err := paych.Load(adt.WrapStore(ctx, sp.cst), newActorState)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return diffPaymentChannelState(ctx, &oldState, &newState)
|
||||
return diffPaymentChannelState(ctx, oldState, newState)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -633,13 +393,23 @@ type PayChToSendChange struct {
|
||||
|
||||
// OnToSendAmountChanges monitors changes on the total amount to send from one party to the other on a payment channel
|
||||
func (sp *StatePredicates) OnToSendAmountChanges() DiffPaymentChannelStateFunc {
|
||||
return func(ctx context.Context, oldState *paych.State, newState *paych.State) (changed bool, user UserData, err error) {
|
||||
if oldState.ToSend.Equals(newState.ToSend) {
|
||||
return func(ctx context.Context, oldState paych.State, newState paych.State) (changed bool, user UserData, err error) {
|
||||
ots, err := oldState.ToSend()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
nts, err := newState.ToSend()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
if ots.Equals(nts) {
|
||||
return false, nil, nil
|
||||
}
|
||||
return true, &PayChToSendChange{
|
||||
OldToSend: oldState.ToSend,
|
||||
NewToSend: newState.ToSend,
|
||||
OldToSend: ots,
|
||||
NewToSend: nts,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@@ -660,7 +430,7 @@ type AddressChange struct {
|
||||
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))
|
||||
@@ -748,33 +518,73 @@ func (i *InitActorAddressChanges) Remove(key string, val *typegen.Deferred) erro
|
||||
}
|
||||
|
||||
func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
|
||||
return func(ctx context.Context, oldState, newState *init_.State) (changed bool, user UserData, err error) {
|
||||
ctxStore := &contextStore{
|
||||
ctx: ctx,
|
||||
cst: sp.cst,
|
||||
}
|
||||
|
||||
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
|
||||
addressChanges := &InitActorAddressChanges{
|
||||
Added: []AddressPair{},
|
||||
Modified: []AddressChange{},
|
||||
Removed: []AddressPair{},
|
||||
}
|
||||
|
||||
if oldState.AddressMap.Equals(newState.AddressMap) {
|
||||
return false, nil, nil
|
||||
}
|
||||
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
|
||||
})
|
||||
|
||||
oldAddrs, err := adt.AsMap(ctxStore, oldState.AddressMap)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
newAddrs, err := adt.AsMap(ctxStore, newState.AddressMap)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
err = newState.ForEachActor(func(newId abi.ActorID, newAddress address.Address) error {
|
||||
newIdAddress, err := address.NewIDAddress(uint64(newId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := DiffAdtMap(oldAddrs, newAddrs, addressChanges); err != nil {
|
||||
_, 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
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -16,8 +18,11 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"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"
|
||||
|
||||
@@ -69,22 +74,22 @@ func TestMarketPredicates(t *testing.T) {
|
||||
bs := bstore.NewTemporarySync()
|
||||
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
|
||||
|
||||
oldDeal1 := &market.DealState{
|
||||
oldDeal1 := &market0.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 2,
|
||||
SlashEpoch: 0,
|
||||
}
|
||||
oldDeal2 := &market.DealState{
|
||||
oldDeal2 := &market0.DealState{
|
||||
SectorStartEpoch: 4,
|
||||
LastUpdatedEpoch: 5,
|
||||
SlashEpoch: 0,
|
||||
}
|
||||
oldDeals := map[abi.DealID]*market.DealState{
|
||||
oldDeals := map[abi.DealID]*market0.DealState{
|
||||
abi.DealID(1): oldDeal1,
|
||||
abi.DealID(2): oldDeal2,
|
||||
}
|
||||
|
||||
oldProp1 := &market.DealProposal{
|
||||
oldProp1 := &market0.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@@ -96,7 +101,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
oldProp2 := &market.DealProposal{
|
||||
oldProp2 := &market0.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@@ -108,7 +113,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
oldProps := map[abi.DealID]*market.DealProposal{
|
||||
oldProps := map[abi.DealID]*market0.DealProposal{
|
||||
abi.DealID(1): oldProp1,
|
||||
abi.DealID(2): oldProp2,
|
||||
}
|
||||
@@ -122,7 +127,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
|
||||
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
|
||||
|
||||
newDeal1 := &market.DealState{
|
||||
newDeal1 := &market0.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 3,
|
||||
SlashEpoch: 0,
|
||||
@@ -131,19 +136,19 @@ func TestMarketPredicates(t *testing.T) {
|
||||
// deal 2 removed
|
||||
|
||||
// added
|
||||
newDeal3 := &market.DealState{
|
||||
newDeal3 := &market0.DealState{
|
||||
SectorStartEpoch: 1,
|
||||
LastUpdatedEpoch: 2,
|
||||
SlashEpoch: 3,
|
||||
}
|
||||
newDeals := map[abi.DealID]*market.DealState{
|
||||
newDeals := map[abi.DealID]*market0.DealState{
|
||||
abi.DealID(1): newDeal1,
|
||||
// deal 2 was removed
|
||||
abi.DealID(3): newDeal3,
|
||||
}
|
||||
|
||||
// added
|
||||
newProp3 := &market.DealProposal{
|
||||
newProp3 := &market0.DealProposal{
|
||||
PieceCID: dummyCid,
|
||||
PieceSize: 0,
|
||||
VerifiedDeal: false,
|
||||
@@ -155,7 +160,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
ProviderCollateral: big.Zero(),
|
||||
ClientCollateral: big.Zero(),
|
||||
}
|
||||
newProps := map[abi.DealID]*market.DealProposal{
|
||||
newProps := map[abi.DealID]*market0.DealProposal{
|
||||
abi.DealID(1): oldProp1, // 1 was persisted
|
||||
// prop 2 was removed
|
||||
abi.DealID(3): newProp3, // new
|
||||
@@ -178,8 +183,8 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
api := newMockAPI(bs)
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldStateC})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newStateC})
|
||||
api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC})
|
||||
api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC})
|
||||
|
||||
t.Run("deal ID predicate", func(t *testing.T) {
|
||||
preds := NewStatePredicates(api)
|
||||
@@ -221,7 +226,7 @@ func TestMarketPredicates(t *testing.T) {
|
||||
// Test that OnActorStateChanged does not call the callback if the state has not changed
|
||||
mockAddr, err := address.NewFromString("t01")
|
||||
require.NoError(t, err)
|
||||
actorDiffFn := preds.OnActorStateChanged(mockAddr, func(context.Context, cid.Cid, cid.Cid) (bool, UserData, error) {
|
||||
actorDiffFn := preds.OnActorStateChanged(mockAddr, func(context.Context, *types.Actor, *types.Actor) (bool, UserData, error) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
@@ -230,11 +235,18 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.False(t, changed)
|
||||
|
||||
// Test that OnDealStateChanged does not call the callback if the state has not changed
|
||||
diffDealStateFn := preds.OnDealStateChanged(func(context.Context, *adt.Array, *adt.Array) (bool, UserData, error) {
|
||||
diffDealStateFn := preds.OnDealStateChanged(func(context.Context, market.DealStates, market.DealStates) (bool, UserData, error) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
marketState := createEmptyMarketState(t, store)
|
||||
marketState0 := createEmptyMarketState(t, store)
|
||||
marketCid, err := store.Put(ctx, marketState0)
|
||||
require.NoError(t, err)
|
||||
marketState, err := market.Load(store, &types.Actor{
|
||||
Code: builtin0.StorageMarketActorCodeID,
|
||||
Head: marketCid,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
changed, _, err = diffDealStateFn(ctx, marketState, marketState)
|
||||
require.NoError(t, err)
|
||||
require.False(t, changed)
|
||||
@@ -252,18 +264,18 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.True(t, changed)
|
||||
|
||||
changedDeals, ok := valArr.(*MarketDealStateChanges)
|
||||
changedDeals, ok := valArr.(*market.DealStateChanges)
|
||||
require.True(t, ok)
|
||||
require.Len(t, changedDeals.Added, 1)
|
||||
require.Equal(t, abi.DealID(3), changedDeals.Added[0].ID)
|
||||
require.Equal(t, *newDeal3, changedDeals.Added[0].Deal)
|
||||
require.True(t, dealEquality(*newDeal3, changedDeals.Added[0].Deal))
|
||||
|
||||
require.Len(t, changedDeals.Removed, 1)
|
||||
|
||||
require.Len(t, changedDeals.Modified, 1)
|
||||
require.Equal(t, abi.DealID(1), changedDeals.Modified[0].ID)
|
||||
require.Equal(t, newDeal1, changedDeals.Modified[0].To)
|
||||
require.Equal(t, oldDeal1, changedDeals.Modified[0].From)
|
||||
require.True(t, dealEquality(*newDeal1, *changedDeals.Modified[0].To))
|
||||
require.True(t, dealEquality(*oldDeal1, *changedDeals.Modified[0].From))
|
||||
|
||||
require.Equal(t, abi.DealID(2), changedDeals.Removed[0].ID)
|
||||
})
|
||||
@@ -279,17 +291,15 @@ func TestMarketPredicates(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.True(t, changed)
|
||||
|
||||
changedProps, ok := valArr.(*MarketDealProposalChanges)
|
||||
changedProps, ok := valArr.(*market.DealProposalChanges)
|
||||
require.True(t, ok)
|
||||
require.Len(t, changedProps.Added, 1)
|
||||
require.Equal(t, abi.DealID(3), changedProps.Added[0].ID)
|
||||
require.Equal(t, *newProp3, changedProps.Added[0].Proposal)
|
||||
|
||||
// proposals cannot be modified -- no modified testing
|
||||
|
||||
require.Len(t, changedProps.Removed, 1)
|
||||
require.Equal(t, abi.DealID(2), changedProps.Removed[0].ID)
|
||||
require.Equal(t, *oldProp2, changedProps.Removed[0].Proposal)
|
||||
})
|
||||
|
||||
t.Run("balances predicate", func(t *testing.T) {
|
||||
@@ -342,7 +352,14 @@ func TestMarketPredicates(t *testing.T) {
|
||||
t.Fatal("No state change so this should not be called")
|
||||
return false, nil, nil
|
||||
})
|
||||
marketState := createEmptyMarketState(t, store)
|
||||
marketState0 := createEmptyMarketState(t, store)
|
||||
marketCid, err := store.Put(ctx, marketState0)
|
||||
require.NoError(t, err)
|
||||
marketState, err := market.Load(store, &types.Actor{
|
||||
Code: builtin0.StorageMarketActorCodeID,
|
||||
Head: marketCid,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
changed, _, err = diffDealBalancesFn(ctx, marketState, marketState)
|
||||
require.NoError(t, err)
|
||||
require.False(t, changed)
|
||||
@@ -362,12 +379,12 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
}
|
||||
|
||||
owner, worker := nextIDAddrF(), nextIDAddrF()
|
||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
||||
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
|
||||
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
|
||||
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
|
||||
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner0.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
|
||||
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner0.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
|
||||
oldMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si0, si1, si2})
|
||||
|
||||
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
|
||||
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner0.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
|
||||
// 0 delete
|
||||
// 1 extend
|
||||
// 2 same
|
||||
@@ -383,8 +400,8 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
api := newMockAPI(bs)
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newMinerC})
|
||||
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID})
|
||||
api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID})
|
||||
|
||||
preds := NewStatePredicates(api)
|
||||
|
||||
@@ -394,7 +411,7 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.True(t, change)
|
||||
require.NotNil(t, val)
|
||||
|
||||
sectorChanges, ok := val.(*MinerSectorChanges)
|
||||
sectorChanges, ok := val.(*miner.SectorChanges)
|
||||
require.True(t, ok)
|
||||
|
||||
require.Equal(t, len(sectorChanges.Added), 1)
|
||||
@@ -418,7 +435,7 @@ func TestMinerSectorChange(t *testing.T) {
|
||||
require.True(t, change)
|
||||
require.NotNil(t, val)
|
||||
|
||||
sectorChanges, ok = val.(*MinerSectorChanges)
|
||||
sectorChanges, ok = val.(*miner.SectorChanges)
|
||||
require.True(t, ok)
|
||||
|
||||
require.Equal(t, 1, len(sectorChanges.Added))
|
||||
@@ -450,7 +467,7 @@ type balance struct {
|
||||
locked abi.TokenAmount
|
||||
}
|
||||
|
||||
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState, props map[abi.DealID]*market.DealProposal, balances map[address.Address]balance) cid.Cid {
|
||||
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState, props map[abi.DealID]*market0.DealProposal, balances map[address.Address]balance) cid.Cid {
|
||||
dealRootCid := createDealAMT(ctx, t, store, deals)
|
||||
propRootCid := createProposalAMT(ctx, t, store, props)
|
||||
balancesCids := createBalanceTable(ctx, t, store, balances)
|
||||
@@ -465,15 +482,15 @@ func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals
|
||||
return stateC
|
||||
}
|
||||
|
||||
func createEmptyMarketState(t *testing.T, store adt.Store) *market.State {
|
||||
func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
return market.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||
return market0.ConstructState(emptyArrayCid, emptyMap, emptyMap)
|
||||
}
|
||||
|
||||
func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState) cid.Cid {
|
||||
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)
|
||||
@@ -484,7 +501,7 @@ func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map
|
||||
return rootCid
|
||||
}
|
||||
|
||||
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market.DealProposal) cid.Cid {
|
||||
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 {
|
||||
err := root.Set(uint64(dealID), prop)
|
||||
@@ -532,20 +549,20 @@ func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner,
|
||||
return stateC
|
||||
}
|
||||
|
||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner.State {
|
||||
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State {
|
||||
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
|
||||
require.NoError(t, err)
|
||||
emptyMap, err := adt.MakeEmptyMap(store).Root()
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyDeadline, err := store.Put(store.Context(), miner.ConstructDeadline(emptyArrayCid))
|
||||
emptyDeadline, err := store.Put(store.Context(), miner0.ConstructDeadline(emptyArrayCid))
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyVestingFunds := miner.ConstructVestingFunds()
|
||||
emptyVestingFunds := miner0.ConstructVestingFunds()
|
||||
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
|
||||
require.NoError(t, err)
|
||||
|
||||
emptyDeadlines := miner.ConstructDeadlines(emptyDeadline)
|
||||
emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline)
|
||||
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -555,7 +572,7 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
|
||||
emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, err := miner.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
|
||||
state, err := miner0.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
|
||||
require.NoError(t, err)
|
||||
return state
|
||||
|
||||
@@ -564,7 +581,7 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
|
||||
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
|
||||
root := adt.MakeEmptyArray(store)
|
||||
for _, sector := range sectors {
|
||||
sector := sector
|
||||
sector := (miner0.SectorOnChainInfo)(sector)
|
||||
err := root.Set(uint64(sector.SectorNumber), §or)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -597,8 +614,8 @@ const (
|
||||
)
|
||||
|
||||
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
|
||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner.SectorPreCommitInfo {
|
||||
return &miner.SectorPreCommitInfo{
|
||||
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner0.SectorPreCommitInfo {
|
||||
return &miner0.SectorPreCommitInfo{
|
||||
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
SectorNumber: sectorNo,
|
||||
SealedCID: sealed,
|
||||
@@ -607,3 +624,9 @@ func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiratio
|
||||
Expiration: expiration,
|
||||
}
|
||||
}
|
||||
|
||||
func dealEquality(expected market0.DealState, actual market.DealState) bool {
|
||||
return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
|
||||
expected.SectorStartEpoch == actual.SectorStartEpoch &&
|
||||
expected.SlashEpoch == actual.SlashEpoch
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.Status (blocksync.status) (uint64)
|
||||
// t.Status (exchange.status) (uint64)
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Status)); err != nil {
|
||||
return err
|
||||
@@ -164,7 +164,7 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.Chain ([]*blocksync.BSTipSet) (slice)
|
||||
// t.Chain ([]*exchange.BSTipSet) (slice)
|
||||
if len(t.Chain) > cbg.MaxLength {
|
||||
return xerrors.Errorf("Slice value in field t.Chain was too long")
|
||||
}
|
||||
@@ -198,7 +198,7 @@ func (t *Response) UnmarshalCBOR(r io.Reader) error {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.Status (blocksync.status) (uint64)
|
||||
// t.Status (exchange.status) (uint64)
|
||||
|
||||
{
|
||||
|
||||
@@ -222,7 +222,7 @@ func (t *Response) UnmarshalCBOR(r io.Reader) error {
|
||||
|
||||
t.ErrorMessage = string(sval)
|
||||
}
|
||||
// t.Chain ([]*blocksync.BSTipSet) (slice)
|
||||
// t.Chain ([]*exchange.BSTipSet) (slice)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
@@ -567,7 +567,7 @@ func (t *BSTipSet) MarshalCBOR(w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// t.Messages (blocksync.CompactedMessages) (struct)
|
||||
// t.Messages (exchange.CompactedMessages) (struct)
|
||||
if err := t.Messages.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -621,7 +621,7 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
|
||||
t.Blocks[i] = &v
|
||||
}
|
||||
|
||||
// t.Messages (blocksync.CompactedMessages) (struct)
|
||||
// t.Messages (exchange.CompactedMessages) (struct)
|
||||
|
||||
{
|
||||
|
||||
|
||||
+93
-32
@@ -7,6 +7,7 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
@@ -64,7 +65,15 @@ func NewClient(lc fx.Lifecycle, host host.Host, pmgr peermgr.MaybePeerMgr) Clien
|
||||
// request options without disrupting external calls. In the future the
|
||||
// consumers should be forced to use a more standardized service and
|
||||
// adhere to a single API derived from this function.
|
||||
func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.ID) (*validatedResponse, error) {
|
||||
func (c *client) doRequest(
|
||||
ctx context.Context,
|
||||
req *Request,
|
||||
singlePeer *peer.ID,
|
||||
// In the `GetChainMessages` case, we won't request the headers but we still
|
||||
// need them to check the integrity of the `CompactedMessages` in the response
|
||||
// so the tipset blocks need to be provided by the caller.
|
||||
tipsets []*types.TipSet,
|
||||
) (*validatedResponse, error) {
|
||||
// Validate request.
|
||||
if req.Length == 0 {
|
||||
return nil, xerrors.Errorf("invalid request of length 0")
|
||||
@@ -108,14 +117,14 @@ func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.I
|
||||
res, err := c.sendRequestToPeer(ctx, peer, req)
|
||||
if err != nil {
|
||||
if !xerrors.Is(err, network.ErrNoConn) {
|
||||
log.Warnf("could not connect to peer %s: %s",
|
||||
log.Warnf("could not send request to peer %s: %s",
|
||||
peer.String(), err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Process and validate response.
|
||||
validRes, err := c.processResponse(req, res)
|
||||
validRes, err := c.processResponse(req, res, tipsets)
|
||||
if err != nil {
|
||||
log.Warnf("processing peer %s response failed: %s",
|
||||
peer.String(), err)
|
||||
@@ -143,7 +152,7 @@ func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.I
|
||||
// errors. Peer penalization should happen here then, before returning, so
|
||||
// we can apply the correct penalties depending on the cause of the error.
|
||||
// FIXME: Add the `peer` as argument once we implement penalties.
|
||||
func (c *client) processResponse(req *Request, res *Response) (*validatedResponse, error) {
|
||||
func (c *client) processResponse(req *Request, res *Response, tipsets []*types.TipSet) (*validatedResponse, error) {
|
||||
err := res.statusToError()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("status error: %s", err)
|
||||
@@ -175,6 +184,16 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
|
||||
// Check for valid block sets and extract them into `TipSet`s.
|
||||
validRes.tipsets = make([]*types.TipSet, resLength)
|
||||
for i := 0; i < resLength; i++ {
|
||||
if res.Chain[i] == nil {
|
||||
return nil, xerrors.Errorf("response with nil tipset in pos %d", i)
|
||||
}
|
||||
for blockIdx, block := range res.Chain[i].Blocks {
|
||||
if block == nil {
|
||||
return nil, xerrors.Errorf("tipset with nil block in pos %d", blockIdx)
|
||||
// FIXME: Maybe we should move this check to `NewTipSet`.
|
||||
}
|
||||
}
|
||||
|
||||
validRes.tipsets[i], err = types.NewTipSet(res.Chain[i].Blocks)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("invalid tipset blocks at height (head - %d): %w", i, err)
|
||||
@@ -209,31 +228,28 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
|
||||
// If the headers were also returned check that the compression
|
||||
// indexes are valid before `toFullTipSets()` is called by the
|
||||
// consumer.
|
||||
for tipsetIdx := 0; tipsetIdx < resLength; tipsetIdx++ {
|
||||
msgs := res.Chain[tipsetIdx].Messages
|
||||
blocksNum := len(res.Chain[tipsetIdx].Blocks)
|
||||
if len(msgs.BlsIncludes) != blocksNum {
|
||||
return nil, xerrors.Errorf("BlsIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.BlsIncludes), blocksNum)
|
||||
}
|
||||
if len(msgs.SecpkIncludes) != blocksNum {
|
||||
return nil, xerrors.Errorf("SecpkIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.SecpkIncludes), blocksNum)
|
||||
}
|
||||
for blockIdx := 0; blockIdx < blocksNum; blockIdx++ {
|
||||
for _, mi := range msgs.BlsIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Bls) {
|
||||
return nil, xerrors.Errorf("index in BlsIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Bls))
|
||||
}
|
||||
}
|
||||
for _, mi := range msgs.SecpkIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Secpk) {
|
||||
return nil, xerrors.Errorf("index in SecpkIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Secpk))
|
||||
}
|
||||
}
|
||||
err := c.validateCompressedIndices(res.Chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// If we didn't request the headers they should have been provided
|
||||
// by the caller.
|
||||
if len(tipsets) < len(res.Chain) {
|
||||
return nil, xerrors.Errorf("not enought tipsets provided for message response validation, needed %d, have %d", len(res.Chain), len(tipsets))
|
||||
}
|
||||
chain := make([]*BSTipSet, 0, resLength)
|
||||
for i, resChain := range res.Chain {
|
||||
next := &BSTipSet{
|
||||
Blocks: tipsets[i].Blocks(),
|
||||
Messages: resChain.Messages,
|
||||
}
|
||||
chain = append(chain, next)
|
||||
}
|
||||
|
||||
err := c.validateCompressedIndices(chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,6 +257,42 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
|
||||
return validRes, nil
|
||||
}
|
||||
|
||||
func (c *client) validateCompressedIndices(chain []*BSTipSet) error {
|
||||
resLength := len(chain)
|
||||
for tipsetIdx := 0; tipsetIdx < resLength; tipsetIdx++ {
|
||||
msgs := chain[tipsetIdx].Messages
|
||||
blocksNum := len(chain[tipsetIdx].Blocks)
|
||||
|
||||
if len(msgs.BlsIncludes) != blocksNum {
|
||||
return xerrors.Errorf("BlsIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.BlsIncludes), blocksNum)
|
||||
}
|
||||
|
||||
if len(msgs.SecpkIncludes) != blocksNum {
|
||||
return xerrors.Errorf("SecpkIncludes (%d) does not match number of blocks (%d)",
|
||||
len(msgs.SecpkIncludes), blocksNum)
|
||||
}
|
||||
|
||||
for blockIdx := 0; blockIdx < blocksNum; blockIdx++ {
|
||||
for _, mi := range msgs.BlsIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Bls) {
|
||||
return xerrors.Errorf("index in BlsIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Bls))
|
||||
}
|
||||
}
|
||||
|
||||
for _, mi := range msgs.SecpkIncludes[blockIdx] {
|
||||
if int(mi) >= len(msgs.Secpk) {
|
||||
return xerrors.Errorf("index in SecpkIncludes (%d) exceeds number of messages (%d)",
|
||||
mi, len(msgs.Secpk))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlocks implements Client.GetBlocks(). Refer to the godocs there.
|
||||
func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks")
|
||||
@@ -258,7 +310,7 @@ func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int)
|
||||
Options: Headers,
|
||||
}
|
||||
|
||||
validRes, err := c.doRequest(ctx, req, nil)
|
||||
validRes, err := c.doRequest(ctx, req, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -276,7 +328,7 @@ func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipS
|
||||
Options: Headers | Messages,
|
||||
}
|
||||
|
||||
validRes, err := c.doRequest(ctx, req, &peer)
|
||||
validRes, err := c.doRequest(ctx, req, &peer, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -287,7 +339,10 @@ func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipS
|
||||
}
|
||||
|
||||
// GetChainMessages implements Client.GetChainMessages(). Refer to the godocs there.
|
||||
func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error) {
|
||||
func (c *client) GetChainMessages(ctx context.Context, tipsets []*types.TipSet) ([]*CompactedMessages, error) {
|
||||
head := tipsets[0]
|
||||
length := uint64(len(tipsets))
|
||||
|
||||
ctx, span := trace.StartSpan(ctx, "GetChainMessages")
|
||||
if span.IsRecordingEvents() {
|
||||
span.AddAttributes(
|
||||
@@ -303,7 +358,7 @@ func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, lengt
|
||||
Options: Messages,
|
||||
}
|
||||
|
||||
validRes, err := c.doRequest(ctx, req, nil)
|
||||
validRes, err := c.doRequest(ctx, req, nil, tipsets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -357,6 +412,12 @@ func (c *client) sendRequestToPeer(ctx context.Context, peer peer.ID, req *Reque
|
||||
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
go helpers.FullClose(stream) //nolint:errcheck
|
||||
}()
|
||||
|
||||
// Write request.
|
||||
_ = stream.SetWriteDeadline(time.Now().Add(WriteReqDeadline))
|
||||
if err := cborutil.WriteCborRPC(stream, req); err != nil {
|
||||
|
||||
@@ -32,10 +32,9 @@ type Client interface {
|
||||
// or less.
|
||||
GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error)
|
||||
|
||||
// GetChainMessages fetches messages from the network, from the provided
|
||||
// tipset *backwards*, returning the messages from as many tipsets as the
|
||||
// count parameter, or less.
|
||||
GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error)
|
||||
// GetChainMessages fetches messages from the network, starting from the first provided tipset
|
||||
// and returning messages from as many tipsets as requested or less.
|
||||
GetChainMessages(ctx context.Context, tipsets []*types.TipSet) ([]*CompactedMessages, error)
|
||||
|
||||
// GetFullTipSet fetches a full tipset from a given peer. If successful,
|
||||
// the fetched object contains block headers and all messages in full form.
|
||||
|
||||
@@ -40,7 +40,7 @@ const (
|
||||
WriteReqDeadline = 5 * time.Second
|
||||
ReadResDeadline = WriteReqDeadline
|
||||
ReadResMinSpeed = 50 << 10
|
||||
ShufflePeersPrefix = 5
|
||||
ShufflePeersPrefix = 16
|
||||
WriteResDeadline = 60 * time.Second
|
||||
)
|
||||
|
||||
@@ -139,6 +139,8 @@ func (res *Response) statusToError() error {
|
||||
|
||||
// FIXME: Rename.
|
||||
type BSTipSet struct {
|
||||
// List of blocks belonging to a single tipset to which the
|
||||
// `CompactedMessages` are linked.
|
||||
Blocks []*types.BlockHeader
|
||||
Messages *CompactedMessages
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/helpers"
|
||||
inet "github.com/libp2p/go-libp2p-core/network"
|
||||
)
|
||||
|
||||
@@ -39,7 +40,9 @@ func (s *server) HandleStream(stream inet.Stream) {
|
||||
ctx, span := trace.StartSpan(context.Background(), "chainxchg.HandleStream")
|
||||
defer span.End()
|
||||
|
||||
defer stream.Close() //nolint:errcheck
|
||||
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
|
||||
// go-libp2p-core 0.7.0
|
||||
defer helpers.FullClose(stream) //nolint:errcheck
|
||||
|
||||
var req Request
|
||||
if err := cborutil.ReadCborRPC(bufio.NewReader(stream), &req); err != nil {
|
||||
|
||||
+35
-20
@@ -9,12 +9,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
block "github.com/ipfs/go-block-format"
|
||||
"github.com/ipfs/go-blockservice"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
"github.com/filecoin-project/lotus/chain/beacon"
|
||||
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
@@ -38,6 +39,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
||||
"github.com/filecoin-project/lotus/lib/sigs"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
@@ -70,7 +72,7 @@ type ChainGen struct {
|
||||
|
||||
GetMessages func(*ChainGen) ([]*types.SignedMessage, error)
|
||||
|
||||
w *wallet.Wallet
|
||||
w *wallet.LocalWallet
|
||||
|
||||
eppProvs map[address.Address]WinningPoStProver
|
||||
Miners []address.Address
|
||||
@@ -121,9 +123,9 @@ var DefaultRemainderAccountActor = genesis.Actor{
|
||||
}
|
||||
|
||||
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
j := journal.NilJournal()
|
||||
// TODO: we really shouldn't modify a global variable here.
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
|
||||
mr := repo.NewMemory(nil)
|
||||
lr, err := mr.Lock(repo.StorageMiner)
|
||||
@@ -153,14 +155,14 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
|
||||
}
|
||||
|
||||
banker, err := w.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
banker, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate banker key: %w", err)
|
||||
}
|
||||
|
||||
receievers := make([]address.Address, msgsPerBlock)
|
||||
for r := range receievers {
|
||||
receievers[r], err = w.GenerateKey(crypto.SigTypeBLS)
|
||||
receievers[r], err = w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate receiver key: %w", err)
|
||||
}
|
||||
@@ -190,11 +192,11 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mk1, err := w.Import(k1)
|
||||
mk1, err := w.WalletImport(context.Background(), k1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mk2, err := w.Import(k2)
|
||||
mk2, err := w.WalletImport(context.Background(), k2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -225,16 +227,16 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
||||
},
|
||||
VerifregRootKey: DefaultVerifregRootkeyActor,
|
||||
RemainderAccount: DefaultRemainderAccountActor,
|
||||
NetworkName: "",
|
||||
NetworkName: uuid.New().String(),
|
||||
Timestamp: uint64(build.Clock.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()),
|
||||
}
|
||||
|
||||
genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl)
|
||||
genb, err := genesis2.MakeGenesisBlock(context.TODO(), j, bs, sys, tpl)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("make genesis block failed: %w", err)
|
||||
}
|
||||
|
||||
cs := store.NewChainStore(bs, ds, sys)
|
||||
cs := store.NewChainStore(bs, ds, sys, j)
|
||||
|
||||
genfb := &types.FullBlock{Header: genb.Genesis}
|
||||
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
|
||||
@@ -374,7 +376,13 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
return nil, nil, nil, xerrors.Errorf("get miner worker: %w", err)
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, ticketRand)
|
||||
sf := func(ctx context.Context, a address.Address, i []byte) (*crypto.Signature, error) {
|
||||
return cg.w.WalletSign(ctx, a, i, api.MsgMeta{
|
||||
Type: api.MTUnknown,
|
||||
})
|
||||
}
|
||||
|
||||
vrfout, err := ComputeVRF(ctx, sf, worker, ticketRand)
|
||||
if err != nil {
|
||||
return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err)
|
||||
}
|
||||
@@ -489,13 +497,16 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke
|
||||
// ResyncBankerNonce is used for dealing with messages made when
|
||||
// simulating forks
|
||||
func (cg *ChainGen) ResyncBankerNonce(ts *types.TipSet) error {
|
||||
var act types.Actor
|
||||
err := cg.sm.WithParentState(ts, cg.sm.WithActor(cg.banker, stmgr.GetActor(&act)))
|
||||
st, err := cg.sm.ParentState(ts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
act, err := st.GetActor(cg.banker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cg.bankerNonce = act.Nonce
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -503,7 +514,7 @@ func (cg *ChainGen) Banker() address.Address {
|
||||
return cg.banker
|
||||
}
|
||||
|
||||
func (cg *ChainGen) Wallet() *wallet.Wallet {
|
||||
func (cg *ChainGen) Wallet() *wallet.LocalWallet {
|
||||
return cg.w
|
||||
}
|
||||
|
||||
@@ -525,7 +536,9 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) {
|
||||
GasPremium: types.NewInt(0),
|
||||
}
|
||||
|
||||
sig, err := cg.w.Sign(context.TODO(), cg.banker, msg.Cid().Bytes())
|
||||
sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes(), api.MsgMeta{
|
||||
Type: api.MTUnknown, // testing
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -556,7 +569,7 @@ type MiningCheckAPI interface {
|
||||
}
|
||||
|
||||
type mca struct {
|
||||
w *wallet.Wallet
|
||||
w *wallet.LocalWallet
|
||||
sm *stmgr.StateManager
|
||||
pv ffiwrapper.Verifier
|
||||
bcn beacon.Schedule
|
||||
@@ -585,7 +598,9 @@ func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoc
|
||||
}
|
||||
|
||||
func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) {
|
||||
return mca.w.Sign(ctx, a, v)
|
||||
return mca.w.WalletSign(ctx, a, v, api.MsgMeta{
|
||||
Type: api.MTUnknown,
|
||||
})
|
||||
}
|
||||
|
||||
type WinningPoStProver interface {
|
||||
|
||||
@@ -4,21 +4,16 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
|
||||
}
|
||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||
verifreg.MinVerifiedDealSize = big.NewInt(256)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
}
|
||||
|
||||
func testGeneration(t testing.TB, n int, msgs int, sectors int) {
|
||||
|
||||
@@ -6,7 +6,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
@@ -19,11 +20,11 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
|
||||
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
@@ -116,7 +117,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, xerrors.Errorf("putting empty object: %w", err)
|
||||
}
|
||||
|
||||
state, err := state.NewStateTree(cst)
|
||||
state, err := state.NewStateTree(cst, types.StateTreeVersion0)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("making new state tree: %w", err)
|
||||
}
|
||||
@@ -127,7 +128,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.SystemActorAddr, sysact); err != nil {
|
||||
if err := state.SetActor(builtin0.SystemActorAddr, sysact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set init actor: %w", err)
|
||||
}
|
||||
|
||||
@@ -137,7 +138,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.InitActorAddr, initact); err != nil {
|
||||
if err := state.SetActor(builtin0.InitActorAddr, initact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set init actor: %w", err)
|
||||
}
|
||||
|
||||
@@ -148,7 +149,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
|
||||
}
|
||||
|
||||
err = state.SetActor(builtin.RewardActorAddr, rewact)
|
||||
err = state.SetActor(builtin0.RewardActorAddr, rewact)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("set network account actor: %w", err)
|
||||
}
|
||||
@@ -158,7 +159,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup cron actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.CronActorAddr, cronact); err != nil {
|
||||
if err := state.SetActor(builtin0.CronActorAddr, cronact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set cron actor: %w", err)
|
||||
}
|
||||
|
||||
@@ -167,7 +168,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.StoragePowerActorAddr, spact); err != nil {
|
||||
if err := state.SetActor(builtin0.StoragePowerActorAddr, spact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set storage market actor: %w", err)
|
||||
}
|
||||
|
||||
@@ -176,7 +177,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.StorageMarketActorAddr, marketact); err != nil {
|
||||
if err := state.SetActor(builtin0.StorageMarketActorAddr, marketact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set market actor: %w", err)
|
||||
}
|
||||
|
||||
@@ -185,20 +186,20 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("setup storage market actor: %w", err)
|
||||
}
|
||||
if err := state.SetActor(builtin.VerifiedRegistryActorAddr, verifact); err != nil {
|
||||
if err := state.SetActor(builtin0.VerifiedRegistryActorAddr, verifact); err != nil {
|
||||
return nil, nil, xerrors.Errorf("set market actor: %w", err)
|
||||
}
|
||||
|
||||
burntRoot, err := cst.Put(ctx, &account.State{
|
||||
Address: builtin.BurntFundsActorAddr,
|
||||
burntRoot, err := cst.Put(ctx, &account0.State{
|
||||
Address: builtin0.BurntFundsActorAddr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("failed to setup burnt funds actor state: %w", err)
|
||||
}
|
||||
|
||||
// Setup burnt-funds
|
||||
err = state.SetActor(builtin.BurntFundsActorAddr, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
err = state.SetActor(builtin0.BurntFundsActorAddr, &types.Actor{
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: burntRoot,
|
||||
})
|
||||
@@ -263,13 +264,13 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
verifierState, err := cst.Put(ctx, &account.State{Address: verifierAd})
|
||||
verifierState, err := cst.Put(ctx, &account0.State{Address: verifierAd})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = state.SetActor(verifierId, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: verifierState,
|
||||
})
|
||||
@@ -297,14 +298,9 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
|
||||
return nil, nil, xerrors.Errorf("somehow overallocated filecoin (allocated = %s)", types.FIL(totalFilAllocated))
|
||||
}
|
||||
|
||||
remAccKey, err := address.NewIDAddress(90)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
template.RemainderAccount.Balance = remainingFil
|
||||
|
||||
if err := createMultisigAccount(ctx, bs, cst, state, remAccKey, template.RemainderAccount, keyIDs); err != nil {
|
||||
if err := createMultisigAccount(ctx, bs, cst, state, builtin.ReserveAddress, template.RemainderAccount, keyIDs); err != nil {
|
||||
return nil, nil, xerrors.Errorf("failed to set up remainder account: %w", err)
|
||||
}
|
||||
|
||||
@@ -316,7 +312,7 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St
|
||||
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
|
||||
return xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
st, err := cst.Put(ctx, &account.State{Address: ainfo.Owner})
|
||||
st, err := cst.Put(ctx, &account0.State{Address: ainfo.Owner})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -327,7 +323,7 @@ func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.St
|
||||
}
|
||||
|
||||
err = state.SetActor(ida, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: info.Balance,
|
||||
Head: st,
|
||||
})
|
||||
@@ -345,7 +341,7 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
|
||||
return xerrors.Errorf("unmarshaling account meta: %w", err)
|
||||
}
|
||||
pending, err := adt.MakeEmptyMap(adt.WrapStore(ctx, cst)).Root()
|
||||
pending, err := adt0.MakeEmptyMap(adt0.WrapStore(ctx, cst)).Root()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to create empty map: %v", err)
|
||||
}
|
||||
@@ -365,12 +361,12 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
continue
|
||||
}
|
||||
|
||||
st, err := cst.Put(ctx, &account.State{Address: e})
|
||||
st, err := cst.Put(ctx, &account0.State{Address: e})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = state.SetActor(idAddress, &types.Actor{
|
||||
Code: builtin.AccountActorCodeID,
|
||||
Code: builtin0.AccountActorCodeID,
|
||||
Balance: types.NewInt(0),
|
||||
Head: st,
|
||||
})
|
||||
@@ -380,7 +376,7 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
signers = append(signers, idAddress)
|
||||
}
|
||||
|
||||
st, err := cst.Put(ctx, &multisig.State{
|
||||
st, err := cst.Put(ctx, &multisig0.State{
|
||||
Signers: signers,
|
||||
NumApprovalsThreshold: uint64(ainfo.Threshold),
|
||||
StartEpoch: abi.ChainEpoch(ainfo.VestingStart),
|
||||
@@ -392,7 +388,7 @@ func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.I
|
||||
return err
|
||||
}
|
||||
err = state.SetActor(ida, &types.Actor{
|
||||
Code: builtin.MultisigActorCodeID,
|
||||
Code: builtin0.MultisigActorCodeID,
|
||||
Balance: info.Balance,
|
||||
Head: st,
|
||||
})
|
||||
@@ -406,10 +402,6 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
|
||||
var sum abi.PaddedPieceSize
|
||||
|
||||
nwv := func(context.Context, abi.ChainEpoch) network.Version {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
vmopt := vm.VMOpts{
|
||||
StateBase: stateroot,
|
||||
Epoch: 0,
|
||||
@@ -417,10 +409,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
Bstore: cs.Blockstore(),
|
||||
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
|
||||
CircSupplyCalc: nil,
|
||||
NtwkVersion: nwv,
|
||||
NtwkVersion: genesisNetworkVersion,
|
||||
BaseFee: types.NewInt(0),
|
||||
}
|
||||
vm, err := vm.NewVM(&vmopt)
|
||||
vm, err := vm.NewVM(ctx, &vmopt)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
@@ -447,7 +439,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
_, err = doExecValue(ctx, vm, builtin.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg.AddVerifierParams{
|
||||
_, err = doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifregRoot, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifier, mustEnc(&verifreg0.AddVerifierParams{
|
||||
|
||||
Address: verifier,
|
||||
Allowance: abi.NewStoragePower(int64(sum)), // eh, close enough
|
||||
@@ -458,7 +450,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
}
|
||||
|
||||
for c, amt := range verifNeeds {
|
||||
_, err := doExecValue(ctx, vm, builtin.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg.AddVerifiedClientParams{
|
||||
_, err := doExecValue(ctx, vm, builtin0.VerifiedRegistryActorAddr, verifier, types.NewInt(0), builtin0.MethodsVerifiedRegistry.AddVerifiedClient, mustEnc(&verifreg0.AddVerifiedClientParams{
|
||||
Address: c,
|
||||
Allowance: abi.NewStoragePower(int64(amt)),
|
||||
}))
|
||||
@@ -475,7 +467,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallBuilder, template genesis.Template) (*GenesisBootstrap, error) {
|
||||
func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blockstore, sys vm.SyscallBuilder, template genesis.Template) (*GenesisBootstrap, error) {
|
||||
if j == nil {
|
||||
j = journal.NilJournal()
|
||||
}
|
||||
st, keyIDs, err := MakeInitialStateTree(ctx, bs, template)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("make initial state tree failed: %w", err)
|
||||
@@ -487,7 +482,7 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
||||
}
|
||||
|
||||
// temp chainstore
|
||||
cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys)
|
||||
cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys, j)
|
||||
|
||||
// Verify PreSealed Data
|
||||
stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs)
|
||||
@@ -500,8 +495,8 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
||||
return nil, xerrors.Errorf("setup miners failed: %w", err)
|
||||
}
|
||||
|
||||
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||
emptyroot, err := adt.MakeEmptyArray(store).Root()
|
||||
store := adt0.WrapStore(ctx, cbor.NewCborStore(bs))
|
||||
emptyroot, err := adt0.MakeEmptyArray(store).Root()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("amt build failed: %w", err)
|
||||
}
|
||||
@@ -549,7 +544,7 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
||||
}
|
||||
|
||||
b := &types.BlockHeader{
|
||||
Miner: builtin.SystemActorAddr,
|
||||
Miner: builtin0.SystemActorAddr,
|
||||
Ticket: genesisticket,
|
||||
Parents: []cid.Cid{filecoinGenesisCid},
|
||||
Height: 0,
|
||||
|
||||
+41
-42
@@ -6,11 +6,13 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
@@ -23,12 +25,12 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/runtime"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
@@ -65,10 +67,6 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return big.Zero(), nil
|
||||
}
|
||||
|
||||
nwv := func(context.Context, abi.ChainEpoch) network.Version {
|
||||
return build.NewestNetworkVersion
|
||||
}
|
||||
|
||||
vmopt := &vm.VMOpts{
|
||||
StateBase: sroot,
|
||||
Epoch: 0,
|
||||
@@ -76,11 +74,11 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
Bstore: cs.Blockstore(),
|
||||
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
|
||||
CircSupplyCalc: csc,
|
||||
NtwkVersion: nwv,
|
||||
NtwkVersion: genesisNetworkVersion,
|
||||
BaseFee: types.NewInt(0),
|
||||
}
|
||||
|
||||
vm, err := vm.NewVM(vmopt)
|
||||
vm, err := vm.NewVM(ctx, vmopt)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||
}
|
||||
@@ -108,7 +106,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
{
|
||||
constructorParams := &power.CreateMinerParams{
|
||||
constructorParams := &power0.CreateMinerParams{
|
||||
Owner: m.Worker,
|
||||
Worker: m.Worker,
|
||||
Peer: []byte(m.PeerId),
|
||||
@@ -116,12 +114,12 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
params := mustEnc(constructorParams)
|
||||
rval, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
|
||||
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
||||
}
|
||||
|
||||
var ma power.CreateMinerReturn
|
||||
var ma power0.CreateMinerReturn
|
||||
if err := ma.UnmarshalCBOR(bytes.NewReader(rval)); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("unmarshaling CreateMinerReturn: %w", err)
|
||||
}
|
||||
@@ -132,9 +130,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
minerInfos[i].maddr = ma.IDAddress
|
||||
|
||||
err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner.State) error {
|
||||
maxPeriods := miner.MaxSectorExpirationExtension / miner.WPoStProvingPeriod
|
||||
minerInfos[i].presealExp = (maxPeriods-1)*miner.WPoStProvingPeriod + st.ProvingPeriodStart - 1
|
||||
// TODO: ActorUpgrade
|
||||
err = vm.MutateState(ctx, minerInfos[i].maddr, func(cst cbor.IpldStore, st *miner0.State) error {
|
||||
maxPeriods := miner0.MaxSectorExpirationExtension / miner0.WPoStProvingPeriod
|
||||
minerInfos[i].presealExp = (maxPeriods-1)*miner0.WPoStProvingPeriod + st.ProvingPeriodStart - 1
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -147,7 +146,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
|
||||
if m.MarketBalance.GreaterThan(big.Zero()) {
|
||||
params := mustEnc(&minerInfos[i].maddr)
|
||||
_, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
|
||||
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err)
|
||||
}
|
||||
@@ -159,7 +158,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
publish := func(params *market.PublishStorageDealsParams) error {
|
||||
fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker)
|
||||
|
||||
ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
|
||||
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
|
||||
}
|
||||
@@ -210,13 +209,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("getting deal weight: %w", err)
|
||||
}
|
||||
|
||||
sectorWeight := miner.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
|
||||
qaPow = types.BigAdd(qaPow, sectorWeight)
|
||||
}
|
||||
}
|
||||
|
||||
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
|
||||
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
|
||||
st.TotalQualityAdjPower = qaPow
|
||||
st.TotalRawBytePower = rawPow
|
||||
|
||||
@@ -228,8 +227,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("mutating state: %w", err)
|
||||
}
|
||||
|
||||
err = vm.MutateState(ctx, builtin.RewardActorAddr, func(sct cbor.IpldStore, st *reward.State) error {
|
||||
*st = *reward.ConstructState(qaPow)
|
||||
err = vm.MutateState(ctx, reward.Address, func(sct cbor.IpldStore, st *reward0.State) error {
|
||||
*st = *reward0.ConstructState(qaPow)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -255,10 +254,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("getting deal weight: %w", err)
|
||||
}
|
||||
|
||||
sectorWeight := miner.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
|
||||
|
||||
// we've added fake power for this sector above, remove it now
|
||||
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
|
||||
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
|
||||
st.TotalQualityAdjPower = types.BigSub(st.TotalQualityAdjPower, sectorWeight) //nolint:scopelint
|
||||
st.TotalRawBytePower = types.BigSub(st.TotalRawBytePower, types.NewInt(uint64(m.SectorSize)))
|
||||
return nil
|
||||
@@ -277,9 +276,9 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
return cid.Undef, xerrors.Errorf("getting current total power: %w", err)
|
||||
}
|
||||
|
||||
pcd := miner.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight)
|
||||
pcd := miner0.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight)
|
||||
|
||||
pledge := miner.InitialPledgeForPower(
|
||||
pledge := miner0.InitialPledgeForPower(
|
||||
sectorWeight,
|
||||
epochReward.ThisEpochBaselinePower,
|
||||
tpow.PledgeCollateral,
|
||||
@@ -301,7 +300,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
Sectors: []abi.SectorNumber{preseal.SectorID},
|
||||
}
|
||||
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, builtin.StoragePowerActorAddr, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
|
||||
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
|
||||
}
|
||||
@@ -310,7 +309,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
||||
}
|
||||
|
||||
// Sanity-check total network power
|
||||
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power.State) error {
|
||||
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
|
||||
if !st.TotalRawBytePower.Equals(rawPow) {
|
||||
return xerrors.Errorf("st.TotalRawBytePower doesn't match previously calculated rawPow")
|
||||
}
|
||||
@@ -349,12 +348,12 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power.CurrentTotalPowerReturn, error) {
|
||||
pwret, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
|
||||
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
|
||||
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pwr power.CurrentTotalPowerReturn
|
||||
var pwr power0.CurrentTotalPowerReturn
|
||||
if err := pwr.UnmarshalCBOR(bytes.NewReader(pwret)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -362,38 +361,38 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*
|
||||
return &pwr, nil
|
||||
}
|
||||
|
||||
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market.VerifyDealsForActivationReturn, error) {
|
||||
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market0.VerifyDealsForActivationReturn, error) {
|
||||
params := &market.VerifyDealsForActivationParams{
|
||||
DealIDs: dealIDs,
|
||||
SectorStart: sectorStart,
|
||||
SectorExpiry: sectorExpiry,
|
||||
}
|
||||
|
||||
var dealWeights market.VerifyDealsForActivationReturn
|
||||
var dealWeights market0.VerifyDealsForActivationReturn
|
||||
ret, err := doExecValue(ctx, vm,
|
||||
builtin.StorageMarketActorAddr,
|
||||
market.Address,
|
||||
maddr,
|
||||
abi.NewTokenAmount(0),
|
||||
builtin.MethodsMarket.VerifyDealsForActivation,
|
||||
mustEnc(params),
|
||||
)
|
||||
if err != nil {
|
||||
return market.VerifyDealsForActivationReturn{}, err
|
||||
return market0.VerifyDealsForActivationReturn{}, err
|
||||
}
|
||||
if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
|
||||
return market.VerifyDealsForActivationReturn{}, err
|
||||
return market0.VerifyDealsForActivationReturn{}, err
|
||||
}
|
||||
|
||||
return dealWeights, nil
|
||||
}
|
||||
|
||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward.ThisEpochRewardReturn, error) {
|
||||
rwret, err := doExecValue(ctx, vm, builtin.RewardActorAddr, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
|
||||
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) {
|
||||
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var epochReward reward.ThisEpochRewardReturn
|
||||
var epochReward reward0.ThisEpochRewardReturn
|
||||
if err := epochReward.UnmarshalCBOR(bytes.NewReader(rwret)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
func SetupRewardActor(bs bstore.Blockstore, qaPower big.Int) (*types.Actor, error) {
|
||||
cst := cbor.NewCborStore(bs)
|
||||
|
||||
st := reward.ConstructState(qaPower)
|
||||
st := reward0.ConstructState(qaPower)
|
||||
|
||||
hcid, err := cst.Put(context.TODO(), st)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -30,7 +30,7 @@ func SetupStoragePowerActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sms := power.ConstructState(emptyMap, emptyMultiMap)
|
||||
sms := power0.ConstructState(emptyMap, emptyMultiMap)
|
||||
|
||||
stcid, err := store.Put(store.Context(), sms)
|
||||
if err != nil {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -34,7 +34,7 @@ func SetupVerifiedRegistryActor(bs bstore.Blockstore) (*types.Actor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sms := verifreg.ConstructState(h, RootVerifierID)
|
||||
sms := verifreg0.ConstructState(h, RootVerifierID)
|
||||
|
||||
stcid, err := store.Put(store.Context(), sms)
|
||||
if err != nil {
|
||||
|
||||
@@ -3,6 +3,9 @@ package genesis
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -46,3 +49,14 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
|
||||
|
||||
return ret.Return, nil
|
||||
}
|
||||
|
||||
var GenesisNetworkVersion = func() network.Version { // TODO: Get from build/
|
||||
if build.UseNewestNetwork() { // TODO: Get from build/
|
||||
return build.NewestNetworkVersion // TODO: Get from build/
|
||||
} // TODO: Get from build/
|
||||
return network.Version1 // TODO: Get from build/
|
||||
}() // TODO: Get from build/
|
||||
|
||||
func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/
|
||||
return GenesisNetworkVersion // TODO: Get from build/
|
||||
} // TODO: Get from build/
|
||||
|
||||
+4
-3
@@ -15,11 +15,10 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/vm"
|
||||
"github.com/filecoin-project/lotus/chain/wallet"
|
||||
"github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||
)
|
||||
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletAPI, bt *api.BlockTemplate) (*types.FullBlock, error) {
|
||||
|
||||
pts, err := sm.ChainStore().LoadTipSet(bt.Parents)
|
||||
if err != nil {
|
||||
@@ -131,7 +130,9 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
||||
return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err)
|
||||
}
|
||||
|
||||
sig, err := w.Sign(ctx, waddr, nosigbytes)
|
||||
sig, err := w.WalletSign(ctx, waddr, nosigbytes, api.MsgMeta{
|
||||
Type: api.MTBlock,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to sign new block: %w", err)
|
||||
}
|
||||
|
||||
@@ -105,6 +105,10 @@ func checkFault(t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType str
|
||||
return err
|
||||
}
|
||||
|
||||
if other == bh.Cid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return xerrors.Errorf("produced block would trigger '%s' consensus fault; miner: %s; bh: %s, other: %s", faultType, bh.Miner, bh.Cid(), other)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/events"
|
||||
"github.com/filecoin-project/lotus/chain/events/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -119,9 +120,10 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
|
||||
return cid.Undef, err
|
||||
}
|
||||
fm.lk.Lock()
|
||||
defer fm.lk.Unlock()
|
||||
|
||||
bal, err := fm.api.StateMarketBalance(ctx, addr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
fm.lk.Unlock()
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
@@ -137,7 +139,6 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
|
||||
toAdd = types.NewInt(0)
|
||||
}
|
||||
fm.available[idAddr] = big.Add(avail, toAdd)
|
||||
fm.lk.Unlock()
|
||||
|
||||
log.Infof("Funds operation w/ Expected Balance: %s, In State: %s, Requested: %s, Adding: %s", avail.String(), stateAvail.String(), amt.String(), toAdd.String())
|
||||
|
||||
@@ -147,17 +148,19 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
|
||||
|
||||
params, err := actors.SerializeParams(&addr)
|
||||
if err != nil {
|
||||
fm.available[idAddr] = avail
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
smsg, err := fm.api.MpoolPushMessage(ctx, &types.Message{
|
||||
To: builtin.StorageMarketActorAddr,
|
||||
To: market.Address,
|
||||
From: wallet,
|
||||
Value: toAdd,
|
||||
Method: builtin.MethodsMarket.AddBalance,
|
||||
Params: params,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
fm.available[idAddr] = avail
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@@ -47,7 +48,7 @@ func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, s
|
||||
func addFundsMsg(toAdd abi.TokenAmount, addr address.Address, wallet address.Address) *types.Message {
|
||||
params, _ := actors.SerializeParams(&addr)
|
||||
return &types.Message{
|
||||
To: builtin.StorageMarketActorAddr,
|
||||
To: market.Address,
|
||||
From: wallet,
|
||||
Value: toAdd,
|
||||
Method: builtin.MethodsMarket.AddBalance,
|
||||
@@ -56,9 +57,10 @@ func addFundsMsg(toAdd abi.TokenAmount, addr address.Address, wallet address.Add
|
||||
}
|
||||
|
||||
type expectedResult struct {
|
||||
addAmt abi.TokenAmount
|
||||
shouldAdd bool
|
||||
err error
|
||||
addAmt abi.TokenAmount
|
||||
shouldAdd bool
|
||||
err error
|
||||
cachedAvailable abi.TokenAmount
|
||||
}
|
||||
|
||||
func TestAddFunds(t *testing.T) {
|
||||
@@ -87,8 +89,9 @@ func TestAddFunds(t *testing.T) {
|
||||
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
|
||||
expectedResults: []expectedResult{
|
||||
{
|
||||
shouldAdd: false,
|
||||
err: nil,
|
||||
shouldAdd: false,
|
||||
err: nil,
|
||||
cachedAvailable: abi.NewTokenAmount(100),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -101,18 +104,21 @@ func TestAddFunds(t *testing.T) {
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
addAmt: abi.NewTokenAmount(100),
|
||||
shouldAdd: true,
|
||||
err: nil,
|
||||
addAmt: abi.NewTokenAmount(100),
|
||||
shouldAdd: true,
|
||||
err: nil,
|
||||
cachedAvailable: abi.NewTokenAmount(200),
|
||||
},
|
||||
{
|
||||
addAmt: abi.NewTokenAmount(50),
|
||||
shouldAdd: true,
|
||||
err: nil,
|
||||
addAmt: abi.NewTokenAmount(50),
|
||||
shouldAdd: true,
|
||||
err: nil,
|
||||
cachedAvailable: abi.NewTokenAmount(250),
|
||||
},
|
||||
{
|
||||
shouldAdd: false,
|
||||
err: nil,
|
||||
shouldAdd: false,
|
||||
err: nil,
|
||||
cachedAvailable: abi.NewTokenAmount(250),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -131,7 +137,8 @@ func TestAddFunds(t *testing.T) {
|
||||
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
|
||||
expectedResults: []expectedResult{
|
||||
{
|
||||
err: errors.New("something went wrong"),
|
||||
err: errors.New("something went wrong"),
|
||||
cachedAvailable: abi.NewTokenAmount(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -182,6 +189,10 @@ func TestAddFunds(t *testing.T) {
|
||||
} else {
|
||||
require.EqualError(t, err, expected.err.Error())
|
||||
}
|
||||
|
||||
if !expected.cachedAvailable.Nil() {
|
||||
require.Equal(t, expected.cachedAvailable, fundMgr.available[addr])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"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"
|
||||
)
|
||||
|
||||
type ActorLookup func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error)
|
||||
@@ -27,19 +29,33 @@ type CostKey struct {
|
||||
}
|
||||
|
||||
var Costs = map[CostKey]int64{
|
||||
{builtin.InitActorCodeID, 2}: 8916753,
|
||||
{builtin.StorageMarketActorCodeID, 2}: 6955002,
|
||||
{builtin.StorageMarketActorCodeID, 4}: 245436108,
|
||||
{builtin.StorageMinerActorCodeID, 4}: 2315133,
|
||||
{builtin.StorageMinerActorCodeID, 5}: 1600271356,
|
||||
{builtin.StorageMinerActorCodeID, 6}: 22864493,
|
||||
{builtin.StorageMinerActorCodeID, 7}: 142002419,
|
||||
{builtin.StorageMinerActorCodeID, 10}: 23008274,
|
||||
{builtin.StorageMinerActorCodeID, 11}: 19303178,
|
||||
{builtin.StorageMinerActorCodeID, 14}: 566356835,
|
||||
{builtin.StorageMinerActorCodeID, 16}: 5325185,
|
||||
{builtin.StorageMinerActorCodeID, 18}: 2328637,
|
||||
{builtin.StoragePowerActorCodeID, 2}: 23600956,
|
||||
{builtin0.InitActorCodeID, 2}: 8916753,
|
||||
{builtin0.StorageMarketActorCodeID, 2}: 6955002,
|
||||
{builtin0.StorageMarketActorCodeID, 4}: 245436108,
|
||||
{builtin0.StorageMinerActorCodeID, 4}: 2315133,
|
||||
{builtin0.StorageMinerActorCodeID, 5}: 1600271356,
|
||||
{builtin0.StorageMinerActorCodeID, 6}: 22864493,
|
||||
{builtin0.StorageMinerActorCodeID, 7}: 142002419,
|
||||
{builtin0.StorageMinerActorCodeID, 10}: 23008274,
|
||||
{builtin0.StorageMinerActorCodeID, 11}: 19303178,
|
||||
{builtin0.StorageMinerActorCodeID, 14}: 566356835,
|
||||
{builtin0.StorageMinerActorCodeID, 16}: 5325185,
|
||||
{builtin0.StorageMinerActorCodeID, 18}: 2328637,
|
||||
{builtin0.StoragePowerActorCodeID, 2}: 23600956,
|
||||
// TODO: Just reuse v0 values for now, this isn't actually used
|
||||
{builtin2.InitActorCodeID, 2}: 8916753,
|
||||
{builtin2.StorageMarketActorCodeID, 2}: 6955002,
|
||||
{builtin2.StorageMarketActorCodeID, 4}: 245436108,
|
||||
{builtin2.StorageMinerActorCodeID, 4}: 2315133,
|
||||
{builtin2.StorageMinerActorCodeID, 5}: 1600271356,
|
||||
{builtin2.StorageMinerActorCodeID, 6}: 22864493,
|
||||
{builtin2.StorageMinerActorCodeID, 7}: 142002419,
|
||||
{builtin2.StorageMinerActorCodeID, 10}: 23008274,
|
||||
{builtin2.StorageMinerActorCodeID, 11}: 19303178,
|
||||
{builtin2.StorageMinerActorCodeID, 14}: 566356835,
|
||||
{builtin2.StorageMinerActorCodeID, 16}: 5325185,
|
||||
{builtin2.StorageMinerActorCodeID, 18}: 2328637,
|
||||
{builtin2.StoragePowerActorCodeID, 2}: 23600956,
|
||||
}
|
||||
|
||||
func failedGuess(msg *types.SignedMessage) int64 {
|
||||
@@ -51,7 +67,8 @@ func failedGuess(msg *types.SignedMessage) int64 {
|
||||
}
|
||||
|
||||
func GuessGasUsed(ctx context.Context, tsk types.TipSetKey, msg *types.SignedMessage, al ActorLookup) (int64, error) {
|
||||
if msg.Message.Method == builtin.MethodSend {
|
||||
// MethodSend is the same in all versions.
|
||||
if msg.Message.Method == builtin0.MethodSend {
|
||||
switch msg.Message.From.Protocol() {
|
||||
case address.BLS:
|
||||
return 1298450, nil
|
||||
|
||||
@@ -55,6 +55,7 @@ var baseFeeLowerBoundFactor = types.NewInt(10)
|
||||
var baseFeeLowerBoundFactorConservative = types.NewInt(100)
|
||||
|
||||
var MaxActorPendingMessages = 1000
|
||||
var MaxUntrustedActorPendingMessages = 10
|
||||
|
||||
var MaxNonceGap = uint64(4)
|
||||
|
||||
@@ -75,8 +76,6 @@ var (
|
||||
ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium")
|
||||
ErrTooManyPendingMessages = errors.New("too many pending messages for actor")
|
||||
ErrNonceGap = errors.New("unfulfilled nonce gap")
|
||||
|
||||
ErrTryAgain = errors.New("state inconsistency while pushing message; please try again")
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -160,6 +159,7 @@ type MessagePool struct {
|
||||
sigValCache *lru.TwoQueueCache
|
||||
|
||||
evtTypes [3]journal.EventType
|
||||
journal journal.Journal
|
||||
}
|
||||
|
||||
type msgSet struct {
|
||||
@@ -197,9 +197,17 @@ func CapGasFee(msg *types.Message, maxFee abi.TokenAmount) {
|
||||
msg.GasPremium = big.Min(msg.GasFeeCap, msg.GasPremium) // cap premium at FeeCap
|
||||
}
|
||||
|
||||
func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (bool, error) {
|
||||
func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict, untrusted bool) (bool, error) {
|
||||
nextNonce := ms.nextNonce
|
||||
nonceGap := false
|
||||
|
||||
maxNonceGap := MaxNonceGap
|
||||
maxActorPendingMessages := MaxActorPendingMessages
|
||||
if untrusted {
|
||||
maxNonceGap = 0
|
||||
maxActorPendingMessages = MaxUntrustedActorPendingMessages
|
||||
}
|
||||
|
||||
switch {
|
||||
case m.Message.Nonce == nextNonce:
|
||||
nextNonce++
|
||||
@@ -208,7 +216,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (boo
|
||||
nextNonce++
|
||||
}
|
||||
|
||||
case strict && m.Message.Nonce > nextNonce+MaxNonceGap:
|
||||
case strict && m.Message.Nonce > nextNonce+maxNonceGap:
|
||||
return false, xerrors.Errorf("message nonce has too big a gap from expected nonce (Nonce: %d, nextNonce: %d): %w", m.Message.Nonce, nextNonce, ErrNonceGap)
|
||||
|
||||
case m.Message.Nonce > nextNonce:
|
||||
@@ -244,7 +252,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (boo
|
||||
//ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.Value.Int)
|
||||
}
|
||||
|
||||
if !has && strict && len(ms.msgs) > MaxActorPendingMessages {
|
||||
if !has && strict && len(ms.msgs) >= maxActorPendingMessages {
|
||||
log.Errorf("too many pending messages from actor %s", m.Message.From)
|
||||
return false, ErrTooManyPendingMessages
|
||||
}
|
||||
@@ -309,7 +317,7 @@ func (ms *msgSet) getRequiredFunds(nonce uint64) types.BigInt {
|
||||
return types.BigInt{Int: requiredFunds}
|
||||
}
|
||||
|
||||
func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*MessagePool, error) {
|
||||
func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName, j journal.Journal) (*MessagePool, error) {
|
||||
cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
|
||||
verifcache, _ := lru.New2Q(build.VerifSigCacheSize)
|
||||
|
||||
@@ -318,6 +326,10 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
|
||||
return nil, xerrors.Errorf("error loading mpool config: %w", err)
|
||||
}
|
||||
|
||||
if j == nil {
|
||||
j = journal.NilJournal()
|
||||
}
|
||||
|
||||
mp := &MessagePool{
|
||||
ds: ds,
|
||||
addSema: make(chan struct{}, 1),
|
||||
@@ -337,10 +349,11 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
|
||||
netName: netName,
|
||||
cfg: cfg,
|
||||
evtTypes: [...]journal.EventType{
|
||||
evtTypeMpoolAdd: journal.J.RegisterEventType("mpool", "add"),
|
||||
evtTypeMpoolRemove: journal.J.RegisterEventType("mpool", "remove"),
|
||||
evtTypeMpoolRepub: journal.J.RegisterEventType("mpool", "repub"),
|
||||
evtTypeMpoolAdd: j.RegisterEventType("mpool", "add"),
|
||||
evtTypeMpoolRemove: j.RegisterEventType("mpool", "remove"),
|
||||
evtTypeMpoolRepub: j.RegisterEventType("mpool", "repub"),
|
||||
},
|
||||
journal: j,
|
||||
}
|
||||
|
||||
// enable initial prunes
|
||||
@@ -486,7 +499,7 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
|
||||
}
|
||||
|
||||
mp.curTsLk.Lock()
|
||||
publish, err := mp.addTs(m, mp.curTs, true)
|
||||
publish, err := mp.addTs(m, mp.curTs, true, false)
|
||||
if err != nil {
|
||||
mp.curTsLk.Unlock()
|
||||
return cid.Undef, err
|
||||
@@ -553,7 +566,7 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
|
||||
mp.curTsLk.Lock()
|
||||
defer mp.curTsLk.Unlock()
|
||||
|
||||
_, err = mp.addTs(m, mp.curTs, false)
|
||||
_, err = mp.addTs(m, mp.curTs, false, false)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -621,7 +634,7 @@ func (mp *MessagePool) checkBalance(m *types.SignedMessage, curTs *types.TipSet)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local bool) (bool, error) {
|
||||
func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local, untrusted bool) (bool, error) {
|
||||
snonce, err := mp.getStateNonce(m.Message.From, curTs)
|
||||
if err != nil {
|
||||
return false, xerrors.Errorf("failed to look up actor state nonce: %s: %w", err, ErrSoftValidationFailure)
|
||||
@@ -643,7 +656,7 @@ func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local
|
||||
return false, err
|
||||
}
|
||||
|
||||
return publish, mp.addLocked(m, !local)
|
||||
return publish, mp.addLocked(m, !local, untrusted)
|
||||
}
|
||||
|
||||
func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
|
||||
@@ -678,17 +691,17 @@ func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return mp.addLocked(m, false)
|
||||
return mp.addLocked(m, false, false)
|
||||
}
|
||||
|
||||
func (mp *MessagePool) addSkipChecks(m *types.SignedMessage) error {
|
||||
mp.lk.Lock()
|
||||
defer mp.lk.Unlock()
|
||||
|
||||
return mp.addLocked(m, false)
|
||||
return mp.addLocked(m, false, false)
|
||||
}
|
||||
|
||||
func (mp *MessagePool) addLocked(m *types.SignedMessage, strict bool) error {
|
||||
func (mp *MessagePool) addLocked(m *types.SignedMessage, strict, untrusted bool) error {
|
||||
log.Debugf("mpooladd: %s %d", m.Message.From, m.Message.Nonce)
|
||||
if m.Signature.Type == crypto.SigTypeBLS {
|
||||
mp.blsSigCache.Add(m.Cid(), m.Signature)
|
||||
@@ -715,7 +728,7 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage, strict bool) error {
|
||||
mp.pending[m.Message.From] = mset
|
||||
}
|
||||
|
||||
incr, err := mset.add(m, mp, strict)
|
||||
incr, err := mset.add(m, mp, strict, untrusted)
|
||||
if err != nil {
|
||||
log.Debug(err)
|
||||
return err
|
||||
@@ -737,7 +750,7 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage, strict bool) error {
|
||||
Message: m,
|
||||
}, localUpdates)
|
||||
|
||||
journal.J.RecordEvent(mp.evtTypes[evtTypeMpoolAdd], func() interface{} {
|
||||
mp.journal.RecordEvent(mp.evtTypes[evtTypeMpoolAdd], func() interface{} {
|
||||
return MessagePoolEvt{
|
||||
Action: "add",
|
||||
Messages: []MessagePoolEvtMessage{{Message: m.Message, CID: m.Cid()}},
|
||||
@@ -795,96 +808,48 @@ func (mp *MessagePool) getStateBalance(addr address.Address, ts *types.TipSet) (
|
||||
return act.Balance, nil
|
||||
}
|
||||
|
||||
func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address, cb func(address.Address, uint64) (*types.SignedMessage, error)) (*types.SignedMessage, error) {
|
||||
// this method is provided for the gateway to push messages.
|
||||
// differences from Push:
|
||||
// - strict checks are enabled
|
||||
// - extra strict add checks are used when adding the messages to the msgSet
|
||||
// that means: no nonce gaps, at most 10 pending messages for the actor
|
||||
func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) {
|
||||
err := mp.checkMessage(m)
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
// serialize push access to reduce lock contention
|
||||
mp.addSema <- struct{}{}
|
||||
defer func() {
|
||||
<-mp.addSema
|
||||
}()
|
||||
|
||||
mp.curTsLk.Lock()
|
||||
mp.lk.Lock()
|
||||
|
||||
curTs := mp.curTs
|
||||
|
||||
fromKey := addr
|
||||
if fromKey.Protocol() == address.ID {
|
||||
var err error
|
||||
fromKey, err = mp.api.StateAccountKey(ctx, fromKey, mp.curTs)
|
||||
if err != nil {
|
||||
mp.lk.Unlock()
|
||||
mp.curTsLk.Unlock()
|
||||
return nil, xerrors.Errorf("resolving sender key: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
nonce, err := mp.getNonceLocked(fromKey, mp.curTs)
|
||||
msgb, err := m.Serialize()
|
||||
if err != nil {
|
||||
mp.lk.Unlock()
|
||||
mp.curTsLk.Unlock()
|
||||
return nil, xerrors.Errorf("get nonce locked failed: %w", err)
|
||||
return cid.Undef, err
|
||||
}
|
||||
|
||||
// release the locks for signing
|
||||
mp.lk.Unlock()
|
||||
mp.curTsLk.Lock()
|
||||
publish, err := mp.addTs(m, mp.curTs, false, true)
|
||||
if err != nil {
|
||||
mp.curTsLk.Unlock()
|
||||
return cid.Undef, err
|
||||
}
|
||||
mp.curTsLk.Unlock()
|
||||
|
||||
msg, err := cb(fromKey, nonce)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = mp.checkMessage(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgb, err := msg.Serialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// reacquire the locks and check state for consistency
|
||||
mp.curTsLk.Lock()
|
||||
defer mp.curTsLk.Unlock()
|
||||
|
||||
if mp.curTs != curTs {
|
||||
return nil, ErrTryAgain
|
||||
}
|
||||
|
||||
mp.lk.Lock()
|
||||
defer mp.lk.Unlock()
|
||||
|
||||
nonce2, err := mp.getNonceLocked(fromKey, mp.curTs)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get nonce locked failed: %w", err)
|
||||
}
|
||||
|
||||
if nonce2 != nonce {
|
||||
return nil, ErrTryAgain
|
||||
}
|
||||
|
||||
publish, err := mp.verifyMsgBeforeAdd(msg, curTs, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := mp.checkBalance(msg, curTs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := mp.addLocked(msg, false); err != nil {
|
||||
return nil, xerrors.Errorf("add locked failed: %w", err)
|
||||
}
|
||||
if err := mp.addLocal(msg, msgb); err != nil {
|
||||
log.Errorf("addLocal failed: %+v", err)
|
||||
if err := mp.addLocal(m, msgb); err != nil {
|
||||
mp.lk.Unlock()
|
||||
return cid.Undef, err
|
||||
}
|
||||
mp.lk.Unlock()
|
||||
|
||||
if publish {
|
||||
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
|
||||
}
|
||||
|
||||
return msg, err
|
||||
return m.Cid(), err
|
||||
}
|
||||
|
||||
func (mp *MessagePool) Remove(from address.Address, nonce uint64, applied bool) {
|
||||
@@ -906,7 +871,7 @@ func (mp *MessagePool) remove(from address.Address, nonce uint64, applied bool)
|
||||
Message: m,
|
||||
}, localUpdates)
|
||||
|
||||
journal.J.RecordEvent(mp.evtTypes[evtTypeMpoolRemove], func() interface{} {
|
||||
mp.journal.RecordEvent(mp.evtTypes[evtTypeMpoolRemove], func() interface{} {
|
||||
return MessagePoolEvt{
|
||||
Action: "remove",
|
||||
Messages: []MessagePoolEvtMessage{{Message: m.Message, CID: m.Cid()}}}
|
||||
|
||||
@@ -225,14 +225,14 @@ func TestMessagePool(t *testing.T) {
|
||||
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a := tma.nextBlock()
|
||||
|
||||
sender, err := w.GenerateKey(crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -266,14 +266,14 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
|
||||
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a := tma.nextBlock()
|
||||
|
||||
sender, err := w.GenerateKey(crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -315,7 +315,7 @@ func TestRevertMessages(t *testing.T) {
|
||||
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -323,7 +323,7 @@ func TestRevertMessages(t *testing.T) {
|
||||
a := tma.nextBlock()
|
||||
b := tma.nextBlock()
|
||||
|
||||
sender, err := w.GenerateKey(crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -378,7 +378,7 @@ func TestPruningSimple(t *testing.T) {
|
||||
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -386,7 +386,7 @@ func TestPruningSimple(t *testing.T) {
|
||||
a := tma.nextBlock()
|
||||
tma.applyBlock(t, a)
|
||||
|
||||
sender, err := w.GenerateKey(crypto.SigTypeBLS)
|
||||
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -422,7 +422,7 @@ func TestLoadLocal(t *testing.T) {
|
||||
tma := newTestMpoolAPI()
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -433,7 +433,7 @@ func TestLoadLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -443,7 +443,7 @@ func TestLoadLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -465,7 +465,7 @@ func TestLoadLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mp, err = New(tma, ds, "mptest")
|
||||
mp, err = New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -494,7 +494,7 @@ func TestClearAll(t *testing.T) {
|
||||
tma := newTestMpoolAPI()
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -505,7 +505,7 @@ func TestClearAll(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -515,7 +515,7 @@ func TestClearAll(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -548,7 +548,7 @@ func TestClearNonLocal(t *testing.T) {
|
||||
tma := newTestMpoolAPI()
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -559,7 +559,7 @@ func TestClearNonLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -569,7 +569,7 @@ func TestClearNonLocal(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -609,7 +609,7 @@ func TestUpdates(t *testing.T) {
|
||||
tma := newTestMpoolAPI()
|
||||
ds := datastore.NewMapDatastore()
|
||||
|
||||
mp, err := New(tma, ds, "mptest")
|
||||
mp, err := New(tma, ds, "mptest", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -620,7 +620,7 @@ func TestUpdates(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -630,7 +630,7 @@ func TestUpdates(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
|
||||
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -47,13 +47,15 @@ func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||
var act types.Actor
|
||||
stcid, _, err := mpp.sm.TipSetState(context.TODO(), ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("computing tipset state for GetActor: %w", err)
|
||||
}
|
||||
|
||||
return &act, mpp.sm.WithStateTree(stcid, mpp.sm.WithActor(addr, stmgr.GetActor(&act)))
|
||||
st, err := mpp.sm.StateTree(stcid)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to load state tree: %w", err)
|
||||
}
|
||||
return st.GetActor(addr)
|
||||
}
|
||||
|
||||
func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/journal"
|
||||
"github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
@@ -148,14 +147,14 @@ loop:
|
||||
}
|
||||
|
||||
if len(msgs) > 0 {
|
||||
journal.J.RecordEvent(mp.evtTypes[evtTypeMpoolRepub], func() interface{} {
|
||||
msgs := make([]MessagePoolEvtMessage, 0, len(msgs))
|
||||
mp.journal.RecordEvent(mp.evtTypes[evtTypeMpoolRepub], func() interface{} {
|
||||
msgsEv := make([]MessagePoolEvtMessage, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
msgs = append(msgs, MessagePoolEvtMessage{Message: m.Message, CID: m.Cid()})
|
||||
msgsEv = append(msgsEv, MessagePoolEvtMessage{Message: m.Message, CID: m.Cid()})
|
||||
}
|
||||
return MessagePoolEvt{
|
||||
Action: "repub",
|
||||
Messages: msgs,
|
||||
Messages: msgsEv,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user