Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48e8f54c6a | ||
|
|
776c216072 | ||
|
|
c60959ea9f | ||
|
|
62044c34b1 | ||
|
|
c8d328d386 | ||
|
|
fd879e0426 | ||
|
|
27f3170022 | ||
|
|
5b1241d213 | ||
|
|
eaee1578dd | ||
|
|
9e5c5b624b | ||
|
|
640d69f5cb | ||
|
|
36876c2601 | ||
|
|
39c1594505 | ||
|
|
86e1c854fa | ||
|
|
1af89236da | ||
|
|
9741867426 | ||
|
|
b7b98f94a6 | ||
|
|
fb50d68c32 | ||
|
|
692961e019 | ||
|
|
312cc94e6d | ||
|
|
ea71e4de60 | ||
|
|
4ed9cd152c | ||
|
|
0dbb1940f0 | ||
|
|
1452a361a9 | ||
|
|
503c08f999 | ||
|
|
6bee14d6fa | ||
|
|
839abdf910 | ||
|
|
6057f2e6d9 | ||
|
|
213dbc6bc8 | ||
|
|
fc77705229 | ||
|
|
12d7db4efb | ||
|
|
d7827da5bb | ||
|
|
b2ff2edd0c | ||
|
|
13e845ae51 | ||
|
|
0c90868929 | ||
|
|
44496afc66 | ||
|
|
8becd922cf | ||
|
|
16be5b5478 | ||
|
|
1e7095995b | ||
|
|
ffb995035f | ||
|
|
ffe7185443 | ||
|
|
44036d9a4a | ||
|
|
b6a7a8c987 | ||
|
|
905592a3dc | ||
|
|
1c30d07d68 | ||
|
|
d8431da9b9 | ||
|
|
9724248a49 | ||
|
|
fd9f5dc83c | ||
|
|
ed058ae193 | ||
|
|
ca5a2eaa74 | ||
|
|
35b39063ac | ||
|
|
1d9dcef878 | ||
|
|
25cd577d06 | ||
|
|
e003203bea | ||
|
|
33c347956c | ||
|
|
f07a370711 | ||
|
|
a03c5ac3d2 | ||
|
|
a259ee307f | ||
|
|
46b78406b1 | ||
|
|
ab2f159d54 | ||
|
|
d023026cb0 | ||
|
|
b2f8b4011a | ||
|
|
3e9ec01d04 | ||
|
|
a48a6a168a | ||
|
|
ac03c01e4a | ||
|
|
bdaa73a413 | ||
|
|
cf81c897df | ||
|
|
81d614a607 | ||
|
|
5e5b4b7191 | ||
|
|
dd0f4dea81 | ||
|
|
c738d1f7ef | ||
|
|
5a23f64b3b | ||
|
|
44d01712c8 | ||
|
|
3f3a12b75c | ||
|
|
023146803d | ||
|
|
3d77ae1f4d | ||
|
|
6f126c80bf | ||
|
|
ff093fae00 | ||
|
|
669b47cfc9 | ||
|
|
818b8de182 | ||
|
|
c93328b036 | ||
|
|
35180b4761 | ||
|
|
dc81c0e6a2 | ||
|
|
f0c9e4e8f2 | ||
|
|
71ddbdaf10 | ||
|
|
856cbb2ca0 | ||
|
|
a37ababc20 | ||
|
|
677c193e6c | ||
|
|
dd09666399 | ||
|
|
583a8a13d9 | ||
|
|
837322ea59 | ||
|
|
0678b3fa05 | ||
|
|
7526a074d9 | ||
|
|
2af02af1c1 | ||
|
|
c37401a1a3 | ||
|
|
6efd2e7335 | ||
|
|
af399529ec | ||
|
|
257423e917 | ||
|
|
04abd190ab | ||
|
|
60212c86cb | ||
|
|
759594d01c | ||
|
|
5c3e79e8d0 | ||
|
|
92ec239202 | ||
|
|
4433c3cd7c | ||
|
|
7728d6bfc3 | ||
|
|
83f2368507 | ||
|
|
4bc9fa04ba | ||
|
|
056136ef5a | ||
|
|
a423c46f2a | ||
|
|
d89ddb9315 | ||
|
|
16784aa2cc | ||
|
|
88ac2ebc0c | ||
|
|
13dcfec8fe | ||
|
|
20582037c5 | ||
|
|
e983d90a28 | ||
|
|
ea9ad8c5a8 | ||
|
|
93d929a10a | ||
|
|
df9670c58d | ||
|
|
0c5e336ff1 | ||
|
|
f7f5fd4809 | ||
|
|
dff097a992 | ||
|
|
870a47f55d | ||
|
|
f5ae10e3d1 | ||
|
|
41290383e2 | ||
|
|
b9a5ea8f7b | ||
|
|
c0a1cfffa1 | ||
|
|
18161fee38 | ||
|
|
095d7427ba | ||
|
|
da0feb3fa4 | ||
|
|
acc4c374ef | ||
|
|
872843e491 | ||
|
|
565faff754 | ||
|
|
4f89d260b0 | ||
|
|
de5e21bf1a | ||
|
|
909f7039d4 | ||
|
|
abdf4a161a | ||
|
|
77a1a8a23f | ||
|
|
dbc721af3a | ||
|
|
b6611125b6 | ||
|
|
60dd97c7fc | ||
|
|
44e81424f2 | ||
|
|
ed0cc0b56d | ||
|
|
10825e3a95 | ||
|
|
8f7bf1df86 | ||
|
|
79b0bfb272 | ||
|
|
c0537848b3 | ||
|
|
fa30ac8c5d | ||
|
|
616fcb974c | ||
|
|
00d7772f57 | ||
|
|
e258e7c353 | ||
|
|
5cf1e09e81 | ||
|
|
9aa4f3b3b2 | ||
|
|
4dd59b566c | ||
|
|
140a2e0200 | ||
|
|
e6eacbdd56 | ||
|
|
48f13a43b7 | ||
|
|
f5c45bd517 | ||
|
|
9bdea91a70 | ||
|
|
4f808367f8 | ||
|
|
fee50b13a2 | ||
|
|
c6421f8a75 | ||
|
|
d0e87a7487 | ||
|
|
2dc27d6ab4 | ||
|
|
ee97aa0a8a | ||
|
|
c7bb326c78 | ||
|
|
8f5c0c60f5 | ||
|
|
82efe01c70 | ||
|
|
bb466ede66 | ||
|
|
aec2ba2c82 | ||
|
|
ec586a852a | ||
|
|
451ddf50ab | ||
|
|
9dbb2e0abd | ||
|
|
49896afe9f | ||
|
|
1fe08f5973 | ||
|
|
6b014f57e5 | ||
|
|
caa366bc6a | ||
|
|
42ae876711 | ||
|
|
a5ba556fff | ||
|
|
44d088be1e | ||
|
|
dcfbb1998f | ||
|
|
b40985a57c | ||
|
|
f8d32f5328 | ||
|
|
83c30dc4c0 | ||
|
|
6cc2112749 | ||
|
|
05dbbe9681 | ||
|
|
ba236fe258 | ||
|
|
2b5164c956 | ||
|
|
ca2d441b6d | ||
|
|
90da6227b3 | ||
|
|
0e2af11f6a | ||
|
|
88c578bc54 | ||
|
|
f268068457 | ||
|
|
251214dfd9 | ||
|
|
a8ca7baa93 | ||
|
|
9977a6d1d7 | ||
|
|
9d6d1f5715 | ||
|
|
566a9d5541 | ||
|
|
9f83da836d | ||
|
|
2a7af38538 | ||
|
|
7a78527fde | ||
|
|
b572c2b7bc | ||
|
|
10dc90f7fe | ||
|
|
898687ea2e | ||
|
|
8cf3accc53 | ||
|
|
604be5fc82 | ||
|
|
51696bb35d | ||
|
|
f2f4af669d | ||
|
|
ff2772a58c | ||
|
|
9839d5701b | ||
|
|
c1c25868cc | ||
|
|
fdff1bebc9 | ||
|
|
5c514504f7 | ||
|
|
dc8139a1d2 | ||
|
|
8697edc8b7 | ||
|
|
bed4c03a50 | ||
|
|
e041fe130b | ||
|
|
c4ae3e0c3d | ||
|
|
169ab262f5 | ||
|
|
55a9e0ccd1 | ||
|
|
bf7aeb3167 | ||
|
|
0659235e21 | ||
|
|
a07a0935fe | ||
|
|
525a2c71dd | ||
|
|
c6ad8fdaed | ||
|
|
2cbd3faf5a | ||
|
|
51ab891d5c | ||
|
|
bd436ab9de | ||
|
|
e859942fa4 | ||
|
|
3477d265c6 | ||
|
|
97207df705 | ||
|
|
73d07999bf | ||
|
|
af8cf712be | ||
|
|
17c0b9be44 | ||
|
|
d76cbf805a | ||
|
|
5e5de9b41b | ||
|
|
a56b6fea99 | ||
|
|
5a099b7d05 | ||
|
|
59639a0788 | ||
|
|
5a87f04e71 | ||
|
|
fa195bede2 | ||
|
|
4be0a7a215 | ||
|
|
a544fa0f97 | ||
|
|
add113f585 | ||
|
|
59936ef468 | ||
|
|
44985722d2 | ||
|
|
0b7153be86 | ||
|
|
d8b8d75e0f | ||
|
|
d7709deb2b | ||
|
|
3ec834b2e3 | ||
|
|
918a7ec749 | ||
|
|
2ea2abc07d | ||
|
|
839f7bd2b5 | ||
|
|
c81ae5fc20 | ||
|
|
4c41f52828 | ||
|
|
3597192d58 | ||
|
|
1726eb993c | ||
|
|
8ecdc929b4 | ||
|
|
db53859e7a | ||
|
|
b08e0b7102 | ||
|
|
94efae419e | ||
|
|
f33d4e79aa | ||
|
|
40c271cda1 | ||
|
|
13d612f72f | ||
|
|
f124389b66 | ||
|
|
4d286da593 | ||
|
|
680af8eb09 | ||
|
|
1f02428225 | ||
|
|
2c7a89a1db | ||
|
|
028a5c4942 | ||
|
|
8e56fffb33 | ||
|
|
95c3aaec9a | ||
|
|
190cb18ab0 | ||
|
|
19d1b1f532 | ||
|
|
0a1d7b3732 | ||
|
|
08cad30be2 | ||
|
|
eafffc1634 | ||
|
|
36f93649ef | ||
|
|
6fa2cd232d | ||
|
|
5f7ae1f489 | ||
|
|
1f2b604c07 | ||
|
|
d476a3db2c | ||
|
|
68a83500bc | ||
|
|
00fcf6dd72 | ||
|
|
642f0e4740 | ||
|
|
c5cf8e226b | ||
|
|
d79e4da7aa | ||
|
|
6f58fdcb22 | ||
|
|
2b03316cd9 | ||
|
|
184d3802b6 | ||
|
|
228a435ba7 | ||
|
|
9d6cabd18a | ||
|
|
8157f889ce | ||
|
|
736d6a3c19 | ||
|
|
39723bbe60 | ||
|
|
5834231e58 | ||
|
|
e4bb4be855 | ||
|
|
68bc5d2291 | ||
|
|
b87295db93 | ||
|
|
637fbf6c5b | ||
|
|
9d6bcd7705 | ||
|
|
484dfaebce | ||
|
|
1d41e1544a | ||
|
|
da00fc66ee | ||
|
|
4071488ef2 | ||
|
|
bd92c230da | ||
|
|
a98a062347 | ||
|
|
13a674330f | ||
|
|
982867317e | ||
|
|
4de0cd9fcb | ||
|
|
b3ddaa5f02 | ||
|
|
2faa4aa993 | ||
|
|
aeaa59d4b5 | ||
|
|
3e8e9273ca | ||
|
|
d0bfe421b5 | ||
|
|
7f473f56eb | ||
|
|
a29947d47c | ||
|
|
be6cc2c3e6 | ||
|
|
e472cacb3e | ||
|
|
6a3cbea790 | ||
|
|
f97535d87e | ||
|
|
90dc274113 | ||
|
|
40f42db7fa | ||
|
|
09efed50fd | ||
|
|
7de0771883 | ||
|
|
e29b64c5de | ||
|
|
4bed3161f0 | ||
|
|
7307eb54dc | ||
|
|
57e25ae1cd | ||
|
|
b2b13bbe89 | ||
|
|
0b315e97c8 | ||
|
|
dec61fa333 | ||
|
|
7ebef6d838 | ||
|
|
40ff5bf164 | ||
|
|
9fda61abec | ||
|
|
4a71c68e06 | ||
|
|
31497f4bd3 | ||
|
|
6af3a23dd4 | ||
|
|
65ccc99e79 | ||
|
|
cb665d07e0 | ||
|
|
649b7dd162 | ||
|
|
50ebaf25aa | ||
|
|
375a1790e7 | ||
|
|
b187b5c301 | ||
|
|
a53c4e1597 | ||
|
|
fce7b8dc9b | ||
|
|
fc247e4223 | ||
|
|
0390285c4e | ||
|
|
30dbe4978b | ||
|
|
a21f55919b | ||
|
|
79d21489df | ||
|
|
a25ac80777 | ||
|
|
a178c1fb93 | ||
|
|
c4d95de987 | ||
|
|
b7897595eb | ||
|
|
933c786421 | ||
|
|
66f1630f14 | ||
|
|
bb17608ae0 | ||
|
|
421f05eab9 | ||
|
|
9b6448518c | ||
|
|
3fe4261f12 | ||
|
|
7b02673620 | ||
|
|
997f2c098b | ||
|
|
7c814cd2e3 | ||
|
|
41573f1fb2 | ||
|
|
fa6481401d | ||
|
|
fda291b876 | ||
|
|
d33a44e67f | ||
|
|
bdb97d6186 | ||
|
|
7cf75e667d | ||
|
|
e9f531b4aa | ||
|
|
b2b7eb2ded | ||
|
|
3a9b7c592d | ||
|
|
d7ceef104e | ||
|
|
e3cbeec6ee | ||
|
|
04f2e102a1 | ||
|
|
5cca29d1db | ||
|
|
4d3c73f4ca | ||
|
|
a577bf340e | ||
|
|
5c643d6141 | ||
|
|
069fd0a244 | ||
|
|
de13b6edc5 | ||
|
|
303d5d6ff6 | ||
|
|
40b30d1fb1 | ||
|
|
dae6c757b5 | ||
|
|
31ecce3a72 | ||
|
|
13d4563c25 | ||
|
|
e2f48b21ab | ||
|
|
8a94ab676e | ||
|
|
bcb839a7d3 | ||
|
|
30efcf21f0 | ||
|
|
ca40234031 | ||
|
|
592b8c4f4a | ||
|
|
35c0e3cf8c | ||
|
|
60ecbdee8f | ||
|
|
adba1a792a | ||
|
|
e9d0a25436 | ||
|
|
ab6e01e379 | ||
|
|
724f728f60 | ||
|
|
8dbae00847 | ||
|
|
287e06995a | ||
|
|
9e85492b85 | ||
|
|
96245c3cfa | ||
|
|
4194c7fa24 | ||
|
|
71e1577a62 | ||
|
|
df53b97fe4 | ||
|
|
fe3ad4fd60 | ||
|
|
20c8250872 | ||
|
|
1869de7662 | ||
|
|
7c2c8b2a95 | ||
|
|
c094aa82ec | ||
|
|
98a4be475c | ||
|
|
88bb9f422e | ||
|
|
73e58f7af1 | ||
|
|
d02a2a2cfa | ||
|
|
3091e2a771 | ||
|
|
3aa6d03cc1 | ||
|
|
6a5b94ca3b | ||
|
|
229d5e5c80 | ||
|
|
2dad06d59f | ||
|
|
f45340461d | ||
|
|
19a536d869 | ||
|
|
4f0a96c9c7 | ||
|
|
9ec7cd7239 | ||
|
|
ed2d7964ad | ||
|
|
b0b070ffe7 | ||
|
|
3dd3476bfd | ||
|
|
a4342f3997 | ||
|
|
022d4b548a | ||
|
|
49de60d33b | ||
|
|
7b1b082381 | ||
|
|
7d4887b1f1 | ||
|
|
df86efbd43 | ||
|
|
73704c92ba | ||
|
|
5c3d67a811 | ||
|
|
07487b6d20 | ||
|
|
b8866f1d16 | ||
|
|
ba7e730d24 | ||
|
|
49a709a123 | ||
|
|
c1303f1eac | ||
|
|
69e0dff56c | ||
|
|
e9dd3e8650 | ||
|
|
37c5dd5afc | ||
|
|
cefd140e45 | ||
|
|
ed5cd3a6df | ||
|
|
ec69ac0b2c | ||
|
|
39979c07f5 | ||
|
|
c10d99e3fd | ||
|
|
3f3336340f | ||
|
|
4e7d17e889 | ||
|
|
1c025e49c4 | ||
|
|
cb4d7cb9e7 | ||
|
|
0517ef260b | ||
|
|
ebd746cdec | ||
|
|
f113430f07 | ||
|
|
3cea8b5e26 | ||
|
|
2e5e2f4e0e | ||
|
|
84dbcb63d2 | ||
|
|
04b25e09ea | ||
|
|
c3480dc0e8 | ||
|
|
64e05ac57c | ||
|
|
7c07dc9ed1 | ||
|
|
764fa9dae6 | ||
|
|
b3a6dbb5d7 | ||
|
|
28f2f96b65 | ||
|
|
7779d446ce | ||
|
|
f5fad636cf | ||
|
|
1411cff69e | ||
|
|
efaa7b0d76 | ||
|
|
64567d7f32 | ||
|
|
559f7f0cc3 | ||
|
|
a290982ca0 | ||
|
|
1c196e7e68 | ||
|
|
85f2fcf2c6 | ||
|
|
63626e1d0a | ||
|
|
cb8149e047 | ||
|
|
6a48fbbc11 | ||
|
|
58f348cb7f | ||
|
|
9521c0b773 | ||
|
|
fa4bcc6054 | ||
|
|
ae38dfe3b9 | ||
|
|
a1e57d35f9 | ||
|
|
0e4cd3c599 | ||
|
|
643b35c0c9 | ||
|
|
9b3188d110 | ||
|
|
779626ceec | ||
|
|
ef8f35510d | ||
|
|
f4d0db83d8 | ||
|
|
616e5688fc | ||
|
|
f4341409a1 | ||
|
|
2c605e08f1 | ||
|
|
0c31676bf8 | ||
|
|
6017715fd7 | ||
|
|
211751f8b8 | ||
|
|
f1ed13d1ef | ||
|
|
fa2be42eb0 | ||
|
|
a8d5ae5213 | ||
|
|
4217ec5308 | ||
|
|
8adfdfb0fb | ||
|
|
21b51328f9 | ||
|
|
99646d209e | ||
|
|
7fb93d4585 | ||
|
|
51a4657ef7 | ||
|
|
d98eca7260 | ||
|
|
03261771e2 | ||
|
|
cd9f6724a5 | ||
|
|
2dd498297f | ||
|
|
93f7cbe587 | ||
|
|
4af59e0188 | ||
|
|
6ca2a14819 | ||
|
|
32b986503d | ||
|
|
63e2caae81 | ||
|
|
87c306fd47 | ||
|
|
0b06de2bd3 | ||
|
|
da96414bf8 | ||
|
|
b74ad796ce | ||
|
|
c6c202d7d4 | ||
|
|
539f8c1f61 | ||
|
|
ec6c394de7 | ||
|
|
07fad6a201 | ||
|
|
51e51d1b90 | ||
|
|
9e4875f210 | ||
|
|
bf82b96fd8 | ||
|
|
2e9e1c2330 | ||
|
|
120dd14979 | ||
|
|
9b2efd5ace | ||
|
|
fc7feffaad | ||
|
|
098eb6bfff | ||
|
|
71a7270c98 | ||
|
|
2a58f830c0 | ||
|
|
aa584475cc | ||
|
|
218c9199f3 | ||
|
|
4f2d8b0a85 | ||
|
|
a828b15fbe | ||
|
|
9567807144 | ||
|
|
da789939b1 | ||
|
|
e656aad298 | ||
|
|
b0d1668ab9 | ||
|
|
00618672f5 | ||
|
|
5e10d53ca8 | ||
|
|
6720463799 | ||
|
|
bb032b526c | ||
|
|
0e2d06fc39 | ||
|
|
502e104e6a | ||
|
|
e438ef99f8 | ||
|
|
e69335b35f | ||
|
|
4fcd0b7aca | ||
|
|
6e1cf6fdc9 | ||
|
|
b7a5e3cd0f | ||
|
|
c0a8a9f5b5 | ||
|
|
684cce198f | ||
|
|
59eab2df25 | ||
|
|
83839362c5 | ||
|
|
b6147fb27f | ||
|
|
f3b6f8de1a | ||
|
|
b7c36bc02c | ||
|
|
c532b1b819 | ||
|
|
80eba1069a | ||
|
|
b5f9148748 | ||
|
|
ffb63a93ff | ||
|
|
c22e10c4a4 | ||
|
|
132b49728c | ||
|
|
70929a99e6 | ||
|
|
00fa3878d4 | ||
|
|
0879ac496f | ||
|
|
83ee345b1c | ||
|
|
d6abcff63c | ||
|
|
fa2b247f75 | ||
|
|
b37a66c7c9 | ||
|
|
d1b291de5e | ||
|
|
ae65e6595d | ||
|
|
7ee184e965 | ||
|
|
a641a03908 | ||
|
|
e1c2567136 | ||
|
|
b01189467a | ||
|
|
fd15080ead | ||
|
|
c11a32cf69 | ||
|
|
65844761b6 | ||
|
|
69a8a6bc0e | ||
|
|
2fdf49e7da | ||
|
|
eb0a15faf0 | ||
|
|
b30b5dd629 | ||
|
|
eb2b706156 | ||
|
|
2aedd82c72 | ||
|
|
bc2698a988 | ||
|
|
a26cd5a809 | ||
|
|
f0d0b40bd3 | ||
|
|
ce29a0ac17 | ||
|
|
28e6fa5923 | ||
|
|
ec5fab09a1 | ||
|
|
e41f0842b0 | ||
|
|
af33d69357 | ||
|
|
885062f712 | ||
|
|
73ae1924bc | ||
|
|
22267eb45d | ||
|
|
5d7b7ce5c1 | ||
|
|
95cf577447 | ||
|
|
8fffaa5c47 | ||
|
|
63178ce982 | ||
|
|
0af7dcdedb | ||
|
|
f9d2a23132 | ||
|
|
ec3f969e9a | ||
|
|
f6043a0250 | ||
|
|
52261fb814 | ||
|
|
8a215df46b | ||
|
|
7dd58efb84 | ||
|
|
2721279e87 | ||
|
|
985994cc0f | ||
|
|
707b3bf08a | ||
|
|
d551f2b4bd | ||
|
|
1df5445ed2 | ||
|
|
fbaffe86da | ||
|
|
500fae6a52 | ||
|
|
ab59474c4c | ||
|
|
3d3c26fa0c | ||
|
|
68593ce995 | ||
|
|
ca9eadd7c7 | ||
|
|
16449007ab | ||
|
|
8d734d81d9 | ||
|
|
783dc5a33d | ||
|
|
be713ec04a | ||
|
|
c18ca60d28 | ||
|
|
977bf1cad9 | ||
|
|
7a8bfd8725 | ||
|
|
a3f64e0768 | ||
|
|
5766002370 | ||
|
|
4a80c83533 | ||
|
|
936659d087 | ||
|
|
dcdb0abe27 | ||
|
|
2b77c17546 | ||
|
|
1802ae31a6 | ||
|
|
868231adc7 | ||
|
|
2b4f865665 | ||
|
|
e7b1e09ade | ||
|
|
86e459f585 | ||
|
|
0075abea5e | ||
|
|
88af350774 | ||
|
|
747b3d3e57 | ||
|
|
ba65a1ba9b | ||
|
|
e097ba8640 | ||
|
|
4578e0dd8d | ||
|
|
77f0fee58e | ||
|
|
bb4753ffbf | ||
|
|
4f0b9eefc1 | ||
|
|
8410b0f79f | ||
|
|
c5dc67ccd8 | ||
|
|
ccdd660f0d | ||
|
|
5f6733fe44 | ||
|
|
0faacbe154 | ||
|
|
a57c509e1e | ||
|
|
f9ebe3017d | ||
|
|
0725019bdb | ||
|
|
dfdafa3c15 | ||
|
|
5b31ae39ea | ||
|
|
82019ce474 | ||
|
|
2e4f526375 | ||
|
|
0ccf716989 | ||
|
|
7925b69573 | ||
|
|
2f7d7aed31 | ||
|
|
b7bfc06ebe | ||
|
|
be9e30e39d | ||
|
|
8000decac6 | ||
|
|
e2f5c494b0 | ||
|
|
8a418bf982 | ||
|
|
a7d8d15c13 | ||
|
|
a8bf7e7bad | ||
|
|
83de21e464 | ||
|
|
718babd33a | ||
|
|
9604be6d2f | ||
|
|
3d8eb374bd | ||
|
|
e7fa8589da | ||
|
|
3ae42d4648 | ||
|
|
7c329d43f2 | ||
|
|
2c2c37a138 | ||
|
|
5548541e1a | ||
|
|
577b730415 | ||
|
|
4c2cc8e5f7 | ||
|
|
e85af3cba7 | ||
|
|
085cabcda8 | ||
|
|
738ac926d1 | ||
|
|
32327c7d43 | ||
|
|
89df3cc207 | ||
|
|
5516f3492e | ||
|
|
572277caf7 | ||
|
|
2548c224c7 | ||
|
|
21848054d7 | ||
|
|
c4e0ac21a0 | ||
|
|
7f00a6e59c | ||
|
|
e56a171ab6 | ||
|
|
00372e144d | ||
|
|
715176698f | ||
|
|
d35fcd926f | ||
|
|
7f744b2760 | ||
|
|
6e8cf9061a | ||
|
|
86baa11937 | ||
|
|
87f2a41052 | ||
|
|
7c6736b3ef | ||
|
|
7f247bf553 | ||
|
|
0a5a7cf45d | ||
|
|
b0128bd99e | ||
|
|
097baeb9b0 | ||
|
|
5c8498b603 | ||
|
|
bc27602bea | ||
|
|
9436be5ff0 | ||
|
|
6562a23666 | ||
|
|
338bd042b9 | ||
|
|
7a9769b807 | ||
|
|
3de6beabe3 | ||
|
|
e9325fecc5 | ||
|
|
6567887e6e | ||
|
|
44de67cf7d | ||
|
|
8f608dff45 | ||
|
|
9002fcbe47 | ||
|
|
d250a59576 | ||
|
|
71785f9099 | ||
|
|
d6dc081cfe | ||
|
|
c41ccde73d | ||
|
|
f6fb41fce5 | ||
|
|
526674cefa | ||
|
|
653b1d8231 | ||
|
|
514107a75b | ||
|
|
9c7db6d305 | ||
|
|
35f76f58df | ||
|
|
ae26e50682 | ||
|
|
f1bf080e04 | ||
|
|
2c30ac394d | ||
|
|
b9f864ba9e | ||
|
|
9ab9e2a970 | ||
|
|
55d5c11b03 | ||
|
|
36bc96a6bc | ||
|
|
c198e7aa9a | ||
|
|
ef3ef85960 | ||
|
|
4007806068 | ||
|
|
429419f210 | ||
|
|
3acd846dcd | ||
|
|
8ed753a712 | ||
|
|
a3015ca9c2 | ||
|
|
d2ff0cd88e | ||
|
|
d45bb14015 | ||
|
|
30148477a7 | ||
|
|
7640ae47de | ||
|
|
4ea73b4088 | ||
|
|
ca4ca8cbcf | ||
|
|
8b2d74bb2c | ||
|
|
305e3245b6 | ||
|
|
fea5afd615 | ||
|
|
06cb3cf132 | ||
|
|
1d768a823f | ||
|
|
1f914053b4 | ||
|
|
a0894a866d | ||
|
|
f0a8a85928 | ||
|
|
719bb988c9 | ||
|
|
4bd2587e47 | ||
|
|
c1529714e6 | ||
|
|
9cb7964a77 | ||
|
|
0319ccbc4d | ||
|
|
81b412399e | ||
|
|
74db586fdf | ||
|
|
520a0091f5 | ||
|
|
d8e5359388 | ||
|
|
bee548face | ||
|
|
4efc3f8db0 | ||
|
|
21ba7408dd | ||
|
|
2b7e809efe | ||
|
|
9dc67abee6 | ||
|
|
041bf9990e | ||
|
|
45b063648d | ||
|
|
ad8b6baa03 | ||
|
|
c7c593c74e | ||
|
|
6b0aed9317 | ||
|
|
265afd696e | ||
|
|
9ae780902a | ||
|
|
cd903bec5e | ||
|
|
d763dcf48b | ||
|
|
20c4fe9bba | ||
|
|
cd53942525 | ||
|
|
323c78ef44 | ||
|
|
2267d15a0f | ||
|
|
090a16316c | ||
|
|
5ce482b817 | ||
|
|
c5b7e48cd1 | ||
|
|
16cad0e01a | ||
|
|
2d5b798763 | ||
|
|
4cd0964ab1 | ||
|
|
803a3df6b4 | ||
|
|
c27f3deadd | ||
|
|
0bb5fffd88 | ||
|
|
fdd3a85033 | ||
|
|
a79e6cb8c5 | ||
|
|
9d7f94bc67 | ||
|
|
ad6ddcb590 | ||
|
|
bffa716248 | ||
|
|
18b13f6f58 | ||
|
|
ae2b089a5c | ||
|
|
f9596dd730 | ||
|
|
dae8be0881 | ||
|
|
8a7dba11bd | ||
|
|
6fb31a34b3 | ||
|
|
471c365f36 | ||
|
|
b00cbcaf5e | ||
|
|
88c49998a8 | ||
|
|
5008914846 | ||
|
|
4d1fccd290 | ||
|
|
4da30931c9 | ||
|
|
40efafb7cd | ||
|
|
d3594a014b | ||
|
|
ff43d29bbd | ||
|
|
eb5a263d74 | ||
|
|
d2c35db0c9 | ||
|
|
7b00b1828b | ||
|
|
86cca7303d | ||
|
|
6f2c2c04b0 | ||
|
|
0514f38dc4 | ||
|
|
932f3ce1d1 | ||
|
|
0403fc416c | ||
|
|
38dc0eee32 | ||
|
|
d94a19ff65 | ||
|
|
c0feb36e70 | ||
|
|
31e6fb154e | ||
|
|
4419205b0e | ||
|
|
bed2bc73a3 | ||
|
|
3d086dfb43 | ||
|
|
ac67e466ec | ||
|
|
f1ec0d6094 | ||
|
|
958b6b54a8 | ||
|
|
183814a826 | ||
|
|
f392c1295c | ||
|
|
e84b8ab3a0 | ||
|
|
7f8718d805 | ||
|
|
534badad2a | ||
|
|
ea9bed2746 | ||
|
|
733240a2bb | ||
|
|
94be3a973a | ||
|
|
05d9b5ce0f | ||
|
|
ec06f086ef | ||
|
|
fed5afa704 | ||
|
|
8b037e2da3 | ||
|
|
dcd6fc239b | ||
|
|
4f2aaa54d2 | ||
|
|
329970934a | ||
|
|
adaf78961f | ||
|
|
06195bc8e1 | ||
|
|
cf0150e057 | ||
|
|
c27fdc263c | ||
|
|
0d69c03a8d | ||
|
|
0303a0297d | ||
|
|
019394b9e5 | ||
|
|
d3fc6833a5 | ||
|
|
bcbbd73d65 | ||
|
|
6f80d9f3c2 | ||
|
|
f0f78cce97 | ||
|
|
8f426b49ec | ||
|
|
3a1ad50da5 | ||
|
|
cdca6d09ea | ||
|
|
83c465ca0f | ||
|
|
c4c71802f2 | ||
|
|
fa440a1ca6 | ||
|
|
edf646d19c | ||
|
|
0379adc9f1 | ||
|
|
55b77a3c99 | ||
|
|
95ad74a156 | ||
|
|
fd783a6862 | ||
|
|
39c19a0fe5 | ||
|
|
8ea7398d38 | ||
|
|
6d46be53bd | ||
|
|
8b9ae8414a | ||
|
|
c4a86ba684 | ||
|
|
a64a059780 | ||
|
|
3766980331 | ||
|
|
126d5cdfb8 | ||
|
|
52199c9af3 | ||
|
|
bb4eee41d0 | ||
|
|
567d5cf587 | ||
|
|
6e4eae69ac | ||
|
|
29ebdc07c9 | ||
|
|
626d482990 | ||
|
|
3d09f468fe | ||
|
|
18043810c0 | ||
|
|
0cd0faa6fb | ||
|
|
f0a2e97cb5 | ||
|
|
dede1b4758 | ||
|
|
69ec16f634 | ||
|
|
f75922fd3d | ||
|
|
d09924d5ce | ||
|
|
b0c9dd49f0 | ||
|
|
81b3c6e2ab | ||
|
|
7df3f3755d | ||
|
|
dbb4e9fcc5 | ||
|
|
b746dc2af1 | ||
|
|
beb5bffaf6 | ||
|
|
a0f1662a1b | ||
|
|
92bb874327 | ||
|
|
4c87818de1 | ||
|
|
d1f749a808 | ||
|
|
9eecbb1b20 | ||
|
|
a44e91df4b | ||
|
|
4bff4f25ad | ||
|
|
71909c5642 | ||
|
|
ba27d45214 | ||
|
|
227932f9ee | ||
|
|
39bab148b8 | ||
|
|
9ab84bdc0a | ||
|
|
78171055e7 | ||
|
|
30ba9a2751 | ||
|
|
4c605c349f | ||
|
|
3f5f96dcbd | ||
|
|
4dd093b160 | ||
|
|
c0607a0e2a | ||
|
|
9f3ec82cc1 | ||
|
|
c98b6f6408 | ||
|
|
3c205a46bb | ||
|
|
d9ef2f3432 | ||
|
|
631fdaa217 | ||
|
|
4e9bb16532 | ||
|
|
212d0fc264 | ||
|
|
e4e60d7af4 | ||
|
|
16166504f4 | ||
|
|
b13169f071 | ||
|
|
40ea660cdd | ||
|
|
cd6f91ba6f | ||
|
|
a274fcc533 | ||
|
|
db1a61852d | ||
|
|
29d7561dd1 | ||
|
|
4aecb83932 | ||
|
|
5ef5680b98 | ||
|
|
0519c77c24 | ||
|
|
e1242a20ee | ||
|
|
f9acd07987 | ||
|
|
abf9bd0c4d | ||
|
|
fadc79a487 | ||
|
|
8625da3479 | ||
|
|
7124cd5149 | ||
|
|
0117584728 | ||
|
|
ddd9bf610e | ||
|
|
1a90d3bbb5 | ||
|
|
21e6b50294 | ||
|
|
de646a5b93 | ||
|
|
b0cb0c1a4a | ||
|
|
1c26b7220e | ||
|
|
7b5a9a3b9c | ||
|
|
042ac8240f | ||
|
|
8d9cef17af | ||
|
|
2a134887c3 | ||
|
|
ec6a49693f | ||
|
|
207f0d901a | ||
|
|
73f7825fbb | ||
|
|
3b792a32c3 | ||
|
|
22f36483cb | ||
|
|
acfa3d7370 | ||
|
|
ad4b182bfe | ||
|
|
35a0dbfa8c | ||
|
|
4efaa8d688 | ||
|
|
0d88800eb9 | ||
|
|
77b5e8d045 | ||
|
|
6879ae9e6a | ||
|
|
74372d3e81 | ||
|
|
759d8f090b | ||
|
|
db5c88196d | ||
|
|
c853350bdf | ||
|
|
65eb610ec3 | ||
|
|
670835fca0 | ||
|
|
c7c029ea91 | ||
|
|
becc2465a5 | ||
|
|
e4588aed5c | ||
|
|
02b35bf978 | ||
|
|
e61ff4153f | ||
|
|
25080956a7 | ||
|
|
52380fe7fc | ||
|
|
3921ea6916 | ||
|
|
10632d0131 | ||
|
|
8b06f51fb4 | ||
|
|
c12318f413 | ||
|
|
39f3384e7c | ||
|
|
b8deee048e | ||
|
|
52b90e4c9d | ||
|
|
91c87b7069 | ||
|
|
ba654285f0 | ||
|
|
35a466f4c4 | ||
|
|
ed4748e8ac | ||
|
|
182da9d4ef | ||
|
|
8733cea902 | ||
|
|
0244dfd76c | ||
|
|
393b60fb7d | ||
|
|
42ec5928e3 | ||
|
|
8286c6bd17 | ||
|
|
a7746961fb | ||
|
|
ded5341da0 | ||
|
|
ed634bc3a4 | ||
|
|
c4d10bc44e | ||
|
|
6f125cc129 | ||
|
|
d9a7348ae1 | ||
|
|
71cd268502 | ||
|
|
8bd09e39ca | ||
|
|
c877166b4a | ||
|
|
7f234809fc | ||
|
|
88756f3ebf | ||
|
|
86ab3926c5 | ||
|
|
303ef15a83 | ||
|
|
05ba3de5cc | ||
|
|
4dde67750c | ||
|
|
0fba816846 | ||
|
|
e89e0679b5 | ||
|
|
96e67b80c3 | ||
|
|
c66d66dfcb | ||
|
|
a41a1cbd93 | ||
|
|
8b2b488d17 | ||
|
|
eafcc14f0b | ||
|
|
92fdbd80d9 | ||
|
|
c5797482b2 | ||
|
|
565bb4f589 | ||
|
|
fd2d2d3ff4 | ||
|
|
78c128f6a3 | ||
|
|
bf468762b6 | ||
|
|
65651099b6 | ||
|
|
9d3410d374 | ||
|
|
43453bb633 | ||
|
|
4a321c6da2 | ||
|
|
cd4505dd63 | ||
|
|
1f10600f13 | ||
|
|
d5002d7395 | ||
|
|
55193bf36d | ||
|
|
6854cc5944 | ||
|
|
40cc29d723 | ||
|
|
08b7ab90c1 | ||
|
|
e1dc7ad6eb | ||
|
|
55f65702b2 | ||
|
|
6d9779ecae | ||
|
|
d77d3df698 | ||
|
|
f296385141 | ||
|
|
6ead83b605 | ||
|
|
f1ebf320b5 | ||
|
|
cba5c34aef | ||
|
|
6d7e0a57e4 | ||
|
|
3ae817d549 | ||
|
|
ff82a4e9ec | ||
|
|
e13dea7da8 | ||
|
|
16db46e6b9 | ||
|
|
a7f7350c51 | ||
|
|
2cf3674089 | ||
|
|
56ce8fb293 | ||
|
|
07b025a54f | ||
|
|
ae90d7c3b5 | ||
|
|
07102ec686 | ||
|
|
f6963523f8 | ||
|
|
1bc8c928b7 | ||
|
|
93a2530803 | ||
|
|
f30b2dab66 | ||
|
|
2a787dd4a3 | ||
|
|
cf18709100 | ||
|
|
964435a78c | ||
|
|
aad13bae08 | ||
|
|
f00cf70df0 | ||
|
|
06dbca24b4 | ||
|
|
133459756b | ||
|
|
2f0a9f6c40 | ||
|
|
ee21351aa0 | ||
|
|
a676da8a7e | ||
|
|
dc642d0b7b | ||
|
|
fa8beeac2b | ||
|
|
39f2246ae6 | ||
|
|
8b84e499c5 | ||
|
|
b6b56320bf | ||
|
|
c8cef1cb7e | ||
|
|
66c1554670 | ||
|
|
5c5b8866c7 | ||
|
|
8072573292 | ||
|
|
49fce48c3e | ||
|
|
6e92c43dd5 | ||
|
|
8997ed508b | ||
|
|
d69032b2f0 | ||
|
|
5a7f97210f | ||
|
|
5a9e6c8142 | ||
|
|
482e1110c2 | ||
|
|
5c3ebd424c | ||
|
|
cb4eb487f4 | ||
|
|
cd0a1c97fa | ||
|
|
084b0e7f60 | ||
|
|
9fcb564bef | ||
|
|
0a79f49dc5 | ||
|
|
e4136b0d42 | ||
|
|
9cfc275b3d | ||
|
|
b149eb8d02 | ||
|
|
fcfc214ed1 | ||
|
|
85873f6057 | ||
|
|
2ab24b358d | ||
|
|
ee508120d9 | ||
|
|
621e4eab0d | ||
|
|
9ceee6028b | ||
|
|
183c12db25 | ||
|
|
ed93d0725f | ||
|
|
1f03a618f9 | ||
|
|
8d991283f4 | ||
|
|
ac2887c01b | ||
|
|
3671f2a6ff | ||
|
|
4bf03b485f | ||
|
|
ffa47659a1 | ||
|
|
c3e8eddb9b | ||
|
|
9fd3c8c9af | ||
|
|
d9aa1fad75 | ||
|
|
2782ea31d3 | ||
|
|
e8825287d2 | ||
|
|
92f544d96c | ||
|
|
d86c8195dd | ||
|
|
2a1b35e694 | ||
|
|
5349789a19 | ||
|
|
61554cf3e0 | ||
|
|
2d6a159dcc | ||
|
|
7fca1c1ee7 | ||
|
|
20d1523c81 | ||
|
|
0413022196 | ||
|
|
8003a8a2d0 | ||
|
|
53477c2eea | ||
|
|
b6d5b88e9f | ||
|
|
c3a7b59bd1 | ||
|
|
039b88740d | ||
|
|
937366f04a | ||
|
|
d7b2f8c0b7 | ||
|
|
7d1ae7daf5 | ||
|
|
1e72d8f14c | ||
|
|
47608c1937 | ||
|
|
cc90b61dfc | ||
|
|
d195a12565 | ||
|
|
be3a8bd320 | ||
|
|
670913261c | ||
|
|
f3bf773152 | ||
|
|
6e1919c67f | ||
|
|
9475079b97 | ||
|
|
c8d603557b | ||
|
|
3ea39f76e1 | ||
|
|
5445b05d0d | ||
|
|
2b08e9f3a6 | ||
|
|
fba5c65ffd | ||
|
|
dd79c2c41a | ||
|
|
54e4cf564c | ||
|
|
3fbe2b320d | ||
|
|
9e73e43272 | ||
|
|
9c2467b17c | ||
|
|
19b6dc8d1e | ||
|
|
10b931312b | ||
|
|
cb59daf3c1 | ||
|
|
46a368d2b9 | ||
|
|
1e4456138e | ||
|
|
6267832504 | ||
|
|
83976cfd2d | ||
|
|
c311520968 | ||
|
|
d04e7d98ce | ||
|
|
d9e86afa24 | ||
|
|
21b4741e30 | ||
|
|
3cdd06b719 | ||
|
|
e24f24bc71 | ||
|
|
1ad2c4dab0 | ||
|
|
7714537239 | ||
|
|
9979de24db | ||
|
|
d7e36b9610 | ||
|
|
43c62f4406 | ||
|
|
409f96d716 | ||
|
|
2b93bcde72 | ||
|
|
930f2b4049 | ||
|
|
fc76a09b19 | ||
|
|
d50b59b4c7 | ||
|
|
e6b631078f | ||
|
|
cf574ca9a1 | ||
|
|
2bcedcf55f | ||
|
|
4c6c9a0edb | ||
|
|
10927daa53 | ||
|
|
ef6db7de07 | ||
|
|
d42eda4336 | ||
|
|
7bd0fcbb24 | ||
|
|
04658e1cae | ||
|
|
d90ab2b81f | ||
|
|
f5409845b5 | ||
|
|
c2e5a837e6 | ||
|
|
273368ed6a | ||
|
|
995efe4584 | ||
|
|
216fa5c965 | ||
|
|
391d6eca49 | ||
|
|
1b5c1f0588 | ||
|
|
05082e262a | ||
|
|
0f3ff9e06a | ||
|
|
ac443cd758 | ||
|
|
78255eac54 | ||
|
|
559c76a214 | ||
|
|
f6a7f21def | ||
|
|
57dab5b71c | ||
|
|
75c88d0385 | ||
|
|
d8d48953d9 | ||
|
|
188688c9ce | ||
|
|
c3f45cc836 | ||
|
|
2337248aa5 | ||
|
|
627248d610 | ||
|
|
de454b8e26 | ||
|
|
3a74ab8f82 | ||
|
|
dc6dbc9a11 | ||
|
|
888c63b79c | ||
|
|
5b77dbd06f | ||
|
|
f08c792686 | ||
|
|
416340d227 | ||
|
|
0f83515a4a | ||
|
|
714702f278 | ||
|
|
63f929541f | ||
|
|
58203559e7 | ||
|
|
bf36891972 | ||
|
|
2e9b0f0895 | ||
|
|
50e023edd3 | ||
|
|
2c9f5922b5 | ||
|
|
8ff5bce7a3 | ||
|
|
aed7017ab2 | ||
|
|
308d1e9b7c | ||
|
|
b56568d720 | ||
|
|
20dfe220f3 | ||
|
|
fb29f782df | ||
|
|
536d7c4275 | ||
|
|
40642b2cad | ||
|
|
85f2ac8789 | ||
|
|
2e279b2ba8 | ||
|
|
807c670184 | ||
|
|
78a0458ada | ||
|
|
00a1e2c05b | ||
|
|
c17300dc1f | ||
|
|
50d7acfa0c | ||
|
|
bd9959070e | ||
|
|
9b34494501 | ||
|
|
31a5f68dfa | ||
|
|
ec85a973b1 | ||
|
|
8c4c26ca4c | ||
|
|
dd9c9fd4fd | ||
|
|
c58048d16a | ||
|
|
d33d426692 | ||
|
|
73613ee883 | ||
|
|
2a40c802ea | ||
|
|
2d4eaf08c4 | ||
|
|
5f2e163bbb | ||
|
|
9ddeb5344f | ||
|
|
885564fe24 | ||
|
|
e3255a06ea | ||
|
|
13ff6ed462 | ||
|
|
f3fda4ae7f | ||
|
|
d71334cc24 | ||
|
|
25daa0c8e4 | ||
|
|
e21d4d7a7e | ||
|
|
8d3d3c88d4 | ||
|
|
9a7b0b657e | ||
|
|
1902c4c687 | ||
|
|
19bd5beb96 | ||
|
|
1a9b5760a7 | ||
|
|
90928991b3 | ||
|
|
4693c61305 | ||
|
|
76bb424de0 | ||
|
|
06b8ee5b95 | ||
|
|
cb603c62d9 | ||
|
|
c12d802811 | ||
|
|
2562f2e9a6 | ||
|
|
2aad7b6979 | ||
|
|
bb889a5976 | ||
|
|
678812f35b | ||
|
|
7edffcd37b | ||
|
|
44bf9bf903 | ||
|
|
6f55031faa | ||
|
|
e0a520cb65 | ||
|
|
706fdcbb80 | ||
|
|
3a99f95f8e | ||
|
|
51139361c7 | ||
|
|
e088c71b9a | ||
|
|
ac4f3ab684 | ||
|
|
2a70ff96bf | ||
|
|
6f4349064a | ||
|
|
5d34c8b7da | ||
|
|
2a71c47397 | ||
|
|
0cfef0fdbb | ||
|
|
41d0818347 | ||
|
|
c46d4ae529 | ||
|
|
625b18771d | ||
|
|
20a0d32e50 | ||
|
|
996feda1f7 | ||
|
|
2a1b359ede | ||
|
|
a5677d1b7a | ||
|
|
eafaf6d236 | ||
|
|
2a0c0e379b | ||
|
|
88c6642330 | ||
|
|
1295c924e1 | ||
|
|
83e55dc09e | ||
|
|
55401116bb | ||
|
|
e275b54f55 | ||
|
|
87ed228fd3 | ||
|
|
a989f60e27 | ||
|
|
081a2ed89a | ||
|
|
fc7ea8dfa3 | ||
|
|
9837fe27d7 | ||
|
|
5112b9fe2b | ||
|
|
dd393b470f | ||
|
|
0419c64a06 | ||
|
|
e400bdf87a | ||
|
|
9690bc882c | ||
|
|
1946d2ffd4 | ||
|
|
f66b9c5663 | ||
|
|
d92c5e1001 | ||
|
|
81b5d8c671 | ||
|
|
c7ba083fa4 | ||
|
|
56145201db | ||
|
|
c544f4ce44 | ||
|
|
7512748b56 | ||
|
|
6b3e04b9b1 | ||
|
|
74bad49068 | ||
|
|
fe9311e435 | ||
|
|
e56960f245 | ||
|
|
357c0868b7 | ||
|
|
febf7cf28f | ||
|
|
d3ad897fe9 | ||
|
|
6e57c819e0 | ||
|
|
9954577389 | ||
|
|
ba2032c642 | ||
|
|
2afe725933 | ||
|
|
987b9888d5 | ||
|
|
578bef4f83 | ||
|
|
6278bdc69a | ||
|
|
8f42f375cf | ||
|
|
71bd005594 | ||
|
|
5f8c80533a | ||
|
|
9a6e601754 | ||
|
|
867c52b8ed | ||
|
|
6db2faea2c | ||
|
|
50360e68ae | ||
|
|
c77f8fb382 | ||
|
|
72fc16e8a7 | ||
|
|
5611770639 | ||
|
|
eccdff459e | ||
|
|
9912212949 | ||
|
|
28efa9357c | ||
|
|
0f4270126f | ||
|
|
89dfb0ba19 | ||
|
|
0187aa6d9c | ||
|
|
2d7f4b1c61 | ||
|
|
314be51e1b | ||
|
|
9ffd4ada29 | ||
|
|
b8eb2bec12 | ||
|
|
3910d7cb4a | ||
|
|
b4b38788ef | ||
|
|
624f5969b3 | ||
|
|
7ce1312fc2 | ||
|
|
c7d50fe195 | ||
|
|
1d6941b0eb | ||
|
|
5daacc0f07 | ||
|
|
df7631df77 | ||
|
|
9fb4bea9ab | ||
|
|
60dca635f4 | ||
|
|
8d86dec653 | ||
|
|
3b7a5c70c3 | ||
|
|
506f39b294 | ||
|
|
eb13c74dce | ||
|
|
e07438417c | ||
|
|
d54ed1b0c6 | ||
|
|
0019187a4f | ||
|
|
f7fbaef361 | ||
|
|
6f71eab8ce | ||
|
|
b19d6cde11 | ||
|
|
bf10b051ff | ||
|
|
8465a97c4b | ||
|
|
5f821cc733 | ||
|
|
c95206cde1 | ||
|
|
60446b46c8 | ||
|
|
cd2b959a88 | ||
|
|
a80259d986 | ||
|
|
94d3c8bed7 | ||
|
|
c6cebb448f | ||
|
|
715b3dccec | ||
|
|
1a84bd5842 | ||
|
|
0db070779f | ||
|
|
9977cb2604 | ||
|
|
b5da2655dc | ||
|
|
63189cd81d | ||
|
|
e5587119fe | ||
|
|
18cbdcfc81 | ||
|
|
d777680449 | ||
|
|
61dbd443b8 | ||
|
|
cbfb4770fd | ||
|
|
5f638b4193 | ||
|
|
8d75da1629 | ||
|
|
3d8f641310 | ||
|
|
7535c5bb53 | ||
|
|
87df73a455 | ||
|
|
e2d0047a2a | ||
|
|
86e90dc6f1 | ||
|
|
d782250aba | ||
|
|
91e774063e | ||
|
|
ed61642b3a | ||
|
|
e3948c851f | ||
|
|
fac9994c02 | ||
|
|
25b4ffd09b | ||
|
|
838369229c | ||
|
|
026cd103c2 | ||
|
|
d7cd8bae2c | ||
|
|
00ee0b1bbb | ||
|
|
5351db9da7 | ||
|
|
e648b72d8d | ||
|
|
e1185dd5b5 | ||
|
|
312ad4abdc | ||
|
|
de60229957 | ||
|
|
b1db3fee78 | ||
|
|
72134ff458 | ||
|
|
c17a340f2e | ||
|
|
5b1fab8ffa | ||
|
|
b14c467fb4 | ||
|
|
f6360c34dd | ||
|
|
c074031fa1 | ||
|
|
2a90de30bd | ||
|
|
edc6a63e93 | ||
|
|
4193235b59 | ||
|
|
0d253c3e64 | ||
|
|
5cc94dcdf9 | ||
|
|
cad781c8ee | ||
|
|
dc475c2720 | ||
|
|
19ced50d81 | ||
|
|
e855b80b01 | ||
|
|
3574ec3d9d | ||
|
|
04c71b2c6b | ||
|
|
ab811e2e19 | ||
|
|
eb10918470 | ||
|
|
4db800473f | ||
|
|
462a44902e | ||
|
|
a55168aa86 | ||
|
|
ed08366cac | ||
|
|
7e4d906f06 | ||
|
|
483478d511 | ||
|
|
51ca7aa79a | ||
|
|
e6779b0b6f | ||
|
|
a590fb6a12 | ||
|
|
ac77c51d5e | ||
|
|
12867a567b | ||
|
|
9b87566dbf | ||
|
|
84d7565cee | ||
|
|
dd2b44351c | ||
|
|
c548bb3c4c | ||
|
|
f983fa8cd5 | ||
|
|
002eb4e812 | ||
|
|
05dbe5cbbe | ||
|
|
492b026031 | ||
|
|
f036abdff7 | ||
|
|
8929f767ff | ||
|
|
2857f6c0ed | ||
|
|
c7d74ef16e | ||
|
|
4867425685 | ||
|
|
a456f394ac | ||
|
|
4b04cac219 | ||
|
|
83ec2b53ee | ||
|
|
f353a794cb | ||
|
|
d794b49df3 | ||
|
|
63db9e1633 | ||
|
|
b23837a7d6 | ||
|
|
bcfad6b2bb | ||
|
|
701682c98a | ||
|
|
895e968ff9 | ||
|
|
77eefcd6d8 | ||
|
|
c8fcab5d22 | ||
|
|
8f309b214b | ||
|
|
0ad51f8a14 | ||
|
|
69da6a2a29 | ||
|
|
5769a45380 | ||
|
|
bc8d6a1d87 | ||
|
|
4688da5178 | ||
|
|
0304bebf20 | ||
|
|
48feb52cbf | ||
|
|
6daaf6ac2e | ||
|
|
a9e4a0d22b | ||
|
|
7e25a811c3 | ||
|
|
26d14a6262 | ||
|
|
2cb3c89570 | ||
|
|
b9cd364535 | ||
|
|
c915170b58 | ||
|
|
cba911ab5e | ||
|
|
8972152eb1 | ||
|
|
34aa267100 | ||
|
|
0bc94b554c | ||
|
|
ff48a70ed9 | ||
|
|
b6949aa4ba | ||
|
|
536d267cbb | ||
|
|
55aebd199b | ||
|
|
e6045bba85 | ||
|
|
640d6fa474 | ||
|
|
b8dff22a40 | ||
|
|
b79be2a2c2 | ||
|
|
7fddbb528d | ||
|
|
ef08bd48b5 | ||
|
|
4395f27143 | ||
|
|
526cd739f6 | ||
|
|
74a9dfc99f |
+272
-100
@@ -7,7 +7,7 @@ orbs:
|
||||
executors:
|
||||
golang:
|
||||
docker:
|
||||
- image: circleci/golang:1.15.5
|
||||
- image: circleci/golang:1.16.4
|
||||
resource_class: 2xlarge
|
||||
ubuntu:
|
||||
docker:
|
||||
@@ -112,7 +112,7 @@ jobs:
|
||||
- run:
|
||||
command: make debug
|
||||
|
||||
test: &test
|
||||
test:
|
||||
description: |
|
||||
Run tests with gotestsum.
|
||||
parameters: &test-params
|
||||
@@ -123,23 +123,20 @@ jobs:
|
||||
type: string
|
||||
default: "-timeout 30m"
|
||||
description: Flags passed to go test.
|
||||
packages:
|
||||
target:
|
||||
type: string
|
||||
default: "./..."
|
||||
description: Import paths of packages to be tested.
|
||||
winpost-test:
|
||||
proofs-log-test:
|
||||
type: string
|
||||
default: "0"
|
||||
deadline-test:
|
||||
type: string
|
||||
default: "0"
|
||||
test-suite-name:
|
||||
suite:
|
||||
type: string
|
||||
default: unit
|
||||
description: Test suite name to report to CircleCI.
|
||||
gotestsum-format:
|
||||
type: string
|
||||
default: pkgname-and-test-fails
|
||||
default: standard-verbose
|
||||
description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
|
||||
coverage:
|
||||
type: string
|
||||
@@ -147,7 +144,7 @@ jobs:
|
||||
description: Coverage flag. Set to the empty string to disable.
|
||||
codecov-upload:
|
||||
type: boolean
|
||||
default: false
|
||||
default: true
|
||||
description: |
|
||||
Upload coverage report to https://codecov.io/. Requires the codecov API token to be
|
||||
set as an environment variable for private projects.
|
||||
@@ -165,25 +162,24 @@ jobs:
|
||||
- run:
|
||||
name: go test
|
||||
environment:
|
||||
LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >>
|
||||
LOTUS_TEST_DEADLINE_TOGGLING: << parameters.deadline-test >>
|
||||
TEST_RUSTPROOFS_LOGS: << parameters.proofs-log-test >>
|
||||
SKIP_CONFORMANCE: "1"
|
||||
command: |
|
||||
mkdir -p /tmp/test-reports/<< parameters.test-suite-name >>
|
||||
mkdir -p /tmp/test-reports/<< parameters.suite >>
|
||||
mkdir -p /tmp/test-artifacts
|
||||
gotestsum \
|
||||
--format << parameters.gotestsum-format >> \
|
||||
--junitfile /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml \
|
||||
--jsonfile /tmp/test-artifacts/<< parameters.test-suite-name >>.json \
|
||||
--junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \
|
||||
--jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \
|
||||
-- \
|
||||
<< parameters.coverage >> \
|
||||
<< parameters.go-test-flags >> \
|
||||
<< parameters.packages >>
|
||||
<< parameters.target >>
|
||||
no_output_timeout: 30m
|
||||
- store_test_results:
|
||||
path: /tmp/test-reports
|
||||
- store_artifacts:
|
||||
path: /tmp/test-artifacts/<< parameters.test-suite-name >>.json
|
||||
path: /tmp/test-artifacts/<< parameters.suite >>.json
|
||||
- when:
|
||||
condition: << parameters.codecov-upload >>
|
||||
steps:
|
||||
@@ -194,24 +190,6 @@ jobs:
|
||||
command: |
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
test-chain:
|
||||
<<: *test
|
||||
test-node:
|
||||
<<: *test
|
||||
test-storage:
|
||||
<<: *test
|
||||
test-cli:
|
||||
<<: *test
|
||||
test-short:
|
||||
<<: *test
|
||||
test-window-post:
|
||||
<<: *test
|
||||
test-window-post-dispute:
|
||||
<<: *test
|
||||
test-deadline-toggling:
|
||||
<<: *test
|
||||
test-terminate:
|
||||
<<: *test
|
||||
test-conformance:
|
||||
description: |
|
||||
Run tests using a corpus of interoperable test vectors for Filecoin
|
||||
@@ -331,7 +309,7 @@ jobs:
|
||||
- run: cd extern/filecoin-ffi && make
|
||||
- run:
|
||||
name: "go get lotus@master"
|
||||
command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../..
|
||||
command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. && go mod tidy
|
||||
- run:
|
||||
name: "build lotus-soup testplan"
|
||||
command: pushd testplans/lotus-soup && go build -tags=testground .
|
||||
@@ -379,8 +357,8 @@ jobs:
|
||||
- run:
|
||||
name: Install go
|
||||
command: |
|
||||
curl -O https://dl.google.com/go/go1.15.5.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.15.5.darwin-amd64.pkg -target /
|
||||
curl -O https://dl.google.com/go/go1.16.4.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.16.4.darwin-amd64.pkg -target /
|
||||
- run:
|
||||
name: Install pkg-config
|
||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config
|
||||
@@ -428,6 +406,41 @@ jobs:
|
||||
- "~/.rustup"
|
||||
- "~/.cargo"
|
||||
|
||||
build-appimage:
|
||||
machine:
|
||||
image: ubuntu-2004:202104-01
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- run:
|
||||
name: install appimage-builder
|
||||
command: |
|
||||
# docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html
|
||||
sudo apt update
|
||||
sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace
|
||||
sudo curl -Lo /usr/local/bin/appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
sudo chmod +x /usr/local/bin/appimagetool
|
||||
sudo pip3 install appimage-builder
|
||||
- run:
|
||||
name: install lotus dependencies
|
||||
command: sudo apt install ocl-icd-opencl-dev libhwloc-dev
|
||||
- run:
|
||||
name: build appimage
|
||||
command: |
|
||||
sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml
|
||||
make appimage
|
||||
- run:
|
||||
name: prepare workspace
|
||||
command: |
|
||||
mkdir appimage
|
||||
mv Lotus-*.AppImage appimage
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- appimage
|
||||
|
||||
|
||||
gofmt:
|
||||
executor: golang
|
||||
steps:
|
||||
@@ -436,7 +449,7 @@ jobs:
|
||||
- run:
|
||||
command: "! go fmt ./... 2>&1 | read"
|
||||
|
||||
cbor-gen-check:
|
||||
gen-check:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
@@ -444,7 +457,10 @@ jobs:
|
||||
- run: make deps
|
||||
- run: go install golang.org/x/tools/cmd/goimports
|
||||
- run: go install github.com/hannahhoward/cbor-gen-for
|
||||
- run: make type-gen
|
||||
- run: make gen
|
||||
- run: git --no-pager diff
|
||||
- run: git --no-pager diff --quiet
|
||||
- run: make docsgen-cli
|
||||
- run: git --no-pager diff
|
||||
- run: git --no-pager diff --quiet
|
||||
|
||||
@@ -527,6 +543,33 @@ jobs:
|
||||
name: Publish release
|
||||
command: ./scripts/publish-release.sh
|
||||
|
||||
publish-snapcraft:
|
||||
description: build and push snapcraft
|
||||
machine:
|
||||
image: ubuntu-2004:202104-01
|
||||
resource_class: 2xlarge
|
||||
parameters:
|
||||
channel:
|
||||
type: string
|
||||
default: "edge"
|
||||
description: snapcraft channel
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: install snapcraft
|
||||
command: sudo snap install snapcraft --classic
|
||||
- run:
|
||||
name: create snapcraft config file
|
||||
command: |
|
||||
mkdir -p ~/.config/snapcraft
|
||||
echo "$SNAPCRAFT_LOGIN_FILE" | base64 -d > ~/.config/snapcraft/snapcraft.cfg
|
||||
- run:
|
||||
name: build snap
|
||||
command: snapcraft --use-lxd
|
||||
- run:
|
||||
name: publish snap
|
||||
command: snapcraft push *.snap --release << parameters.channel >>
|
||||
|
||||
build-and-push-image:
|
||||
description: build and push docker images to public AWS ECR registry
|
||||
executor: aws-cli/default
|
||||
@@ -701,61 +744,168 @@ workflows:
|
||||
concurrency: "16" # expend all docker 2xlarge CPUs.
|
||||
- mod-tidy-check
|
||||
- gofmt
|
||||
- cbor-gen-check
|
||||
- gen-check
|
||||
- docs-check
|
||||
- test:
|
||||
codecov-upload: true
|
||||
test-suite-name: full
|
||||
- test-chain:
|
||||
codecov-upload: true
|
||||
test-suite-name: chain
|
||||
packages: "./chain/..."
|
||||
- test-node:
|
||||
codecov-upload: true
|
||||
test-suite-name: node
|
||||
packages: "./node/..."
|
||||
- test-storage:
|
||||
codecov-upload: true
|
||||
test-suite-name: storage
|
||||
packages: "./storage/... ./extern/..."
|
||||
- test-cli:
|
||||
codecov-upload: true
|
||||
test-suite-name: cli
|
||||
packages: "./cli/... ./cmd/... ./api/..."
|
||||
- test-window-post:
|
||||
codecov-upload: true
|
||||
go-test-flags: "-run=TestWindowedPost"
|
||||
winpost-test: "1"
|
||||
test-suite-name: window-post
|
||||
- test-window-post-dispute:
|
||||
codecov-upload: true
|
||||
go-test-flags: "-run=TestWindowPostDispute"
|
||||
winpost-test: "1"
|
||||
test-suite-name: window-post-dispute
|
||||
- test-terminate:
|
||||
codecov-upload: true
|
||||
go-test-flags: "-run=TestTerminate"
|
||||
winpost-test: "1"
|
||||
test-suite-name: terminate
|
||||
- test-deadline-toggling:
|
||||
codecov-upload: true
|
||||
go-test-flags: "-run=TestDeadlineToggling"
|
||||
deadline-test: "1"
|
||||
test-suite-name: deadline-toggling
|
||||
- test-short:
|
||||
go-test-flags: "--timeout 10m --short"
|
||||
test-suite-name: short
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
name: test-itest-api
|
||||
suite: itest-api
|
||||
target: "./itests/api_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-batch_deal
|
||||
suite: itest-batch_deal
|
||||
target: "./itests/batch_deal_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-ccupgrade
|
||||
suite: itest-ccupgrade
|
||||
target: "./itests/ccupgrade_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-cli
|
||||
suite: itest-cli
|
||||
target: "./itests/cli_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deadlines
|
||||
suite: itest-deadlines
|
||||
target: "./itests/deadlines_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deals_concurrent
|
||||
suite: itest-deals_concurrent
|
||||
target: "./itests/deals_concurrent_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deals_offline
|
||||
suite: itest-deals_offline
|
||||
target: "./itests/deals_offline_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deals_power
|
||||
suite: itest-deals_power
|
||||
target: "./itests/deals_power_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deals_pricing
|
||||
suite: itest-deals_pricing
|
||||
target: "./itests/deals_pricing_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deals_publish
|
||||
suite: itest-deals_publish
|
||||
target: "./itests/deals_publish_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-deals
|
||||
suite: itest-deals
|
||||
target: "./itests/deals_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-gateway
|
||||
suite: itest-gateway
|
||||
target: "./itests/gateway_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-get_messages_in_ts
|
||||
suite: itest-get_messages_in_ts
|
||||
target: "./itests/get_messages_in_ts_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-multisig
|
||||
suite: itest-multisig
|
||||
target: "./itests/multisig_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-nonce
|
||||
suite: itest-nonce
|
||||
target: "./itests/nonce_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-paych_api
|
||||
suite: itest-paych_api
|
||||
target: "./itests/paych_api_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-paych_cli
|
||||
suite: itest-paych_cli
|
||||
target: "./itests/paych_cli_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-sdr_upgrade
|
||||
suite: itest-sdr_upgrade
|
||||
target: "./itests/sdr_upgrade_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-sector_finalize_early
|
||||
suite: itest-sector_finalize_early
|
||||
target: "./itests/sector_finalize_early_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-sector_miner_collateral
|
||||
suite: itest-sector_miner_collateral
|
||||
target: "./itests/sector_miner_collateral_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-sector_pledge
|
||||
suite: itest-sector_pledge
|
||||
target: "./itests/sector_pledge_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-sector_terminate
|
||||
suite: itest-sector_terminate
|
||||
target: "./itests/sector_terminate_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-tape
|
||||
suite: itest-tape
|
||||
target: "./itests/tape_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-verifreg
|
||||
suite: itest-verifreg
|
||||
target: "./itests/verifreg_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-wdpost_dispute
|
||||
suite: itest-wdpost_dispute
|
||||
target: "./itests/wdpost_dispute_test.go"
|
||||
|
||||
- test:
|
||||
name: test-itest-wdpost
|
||||
suite: itest-wdpost
|
||||
target: "./itests/wdpost_test.go"
|
||||
|
||||
- test:
|
||||
name: test-unit-cli
|
||||
suite: utest-unit-cli
|
||||
target: "./cli/... ./cmd/... ./api/..."
|
||||
- test:
|
||||
name: test-unit-node
|
||||
suite: utest-unit-node
|
||||
target: "./node/..."
|
||||
- test:
|
||||
name: test-unit-rest
|
||||
suite: utest-unit-rest
|
||||
target: "./api/... ./blockstore/... ./build/... ./chain/... ./cli/... ./cmd/... ./conformance/... ./extern/... ./gateway/... ./journal/... ./lib/... ./markets/... ./node/... ./paychmgr/... ./storage/... ./tools/..."
|
||||
- test:
|
||||
name: test-unit-storage
|
||||
suite: utest-unit-storage
|
||||
target: "./storage/... ./extern/..."
|
||||
- test:
|
||||
go-test-flags: "-run=TestMulticoreSDR"
|
||||
suite: multicore-sdr-check
|
||||
target: "./extern/sector-storage/ffiwrapper"
|
||||
proofs-log-test: "1"
|
||||
- test-conformance:
|
||||
test-suite-name: conformance
|
||||
packages: "./conformance"
|
||||
suite: conformance
|
||||
codecov-upload: false
|
||||
target: "./conformance"
|
||||
- test-conformance:
|
||||
name: test-conformance-bleeding-edge
|
||||
test-suite-name: conformance-bleeding-edge
|
||||
packages: "./conformance"
|
||||
codecov-upload: false
|
||||
suite: conformance-bleeding-edge
|
||||
target: "./conformance"
|
||||
vectors-branch: master
|
||||
- trigger-testplans:
|
||||
filters:
|
||||
@@ -764,37 +914,35 @@ workflows:
|
||||
- master
|
||||
- build-debug
|
||||
- build-all:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-ntwk-calibration:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-ntwk-butterfly:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-ntwk-nerpa:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-lotus-soup
|
||||
- build-macos:
|
||||
requires:
|
||||
- test-short
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-appimage:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
@@ -806,6 +954,7 @@ workflows:
|
||||
requires:
|
||||
- build-all
|
||||
- build-macos
|
||||
- build-appimage
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
@@ -858,3 +1007,26 @@ workflows:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- publish-snapcraft:
|
||||
name: publish-snapcraft-stable
|
||||
channel: stable
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
|
||||
nightly:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 0 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
jobs:
|
||||
- publish-snapcraft:
|
||||
name: publish-snapcraft-nightly
|
||||
channel: edge
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
//go:generate go run ./gen.go ..
|
||||
|
||||
//go:embed template.yml
|
||||
var templateFile embed.FS
|
||||
|
||||
type (
|
||||
dirs = []string
|
||||
suite = string
|
||||
)
|
||||
|
||||
// groupedUnitTests maps suite names to top-level directories that should be
|
||||
// included in that suite. The program adds an implicit group "rest" that
|
||||
// includes all other top-level directories.
|
||||
var groupedUnitTests = map[suite]dirs{
|
||||
"unit-node": {"node"},
|
||||
"unit-storage": {"storage", "extern"},
|
||||
"unit-cli": {"cli", "cmd", "api"},
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
panic("expected path to repo as argument")
|
||||
}
|
||||
|
||||
repo := os.Args[1]
|
||||
|
||||
tmpl := template.New("template.yml")
|
||||
tmpl.Delims("[[", "]]")
|
||||
tmpl.Funcs(template.FuncMap{
|
||||
"stripSuffix": func(in string) string {
|
||||
return strings.TrimSuffix(in, "_test.go")
|
||||
},
|
||||
})
|
||||
tmpl = template.Must(tmpl.ParseFS(templateFile, "*"))
|
||||
|
||||
// list all itests.
|
||||
itests, err := filepath.Glob(filepath.Join(repo, "./itests/*_test.go"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// strip the dir from all entries.
|
||||
for i, f := range itests {
|
||||
itests[i] = filepath.Base(f)
|
||||
}
|
||||
|
||||
// calculate the exclusion set of unit test directories to exclude because
|
||||
// they are already included in a grouped suite.
|
||||
var excluded = map[string]struct{}{}
|
||||
for _, ss := range groupedUnitTests {
|
||||
for _, s := range ss {
|
||||
e, err := filepath.Abs(filepath.Join(repo, s))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
excluded[e] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// all unit tests top-level dirs that are not itests, nor included in other suites.
|
||||
var rest = map[string]struct{}{}
|
||||
err = filepath.Walk(repo, func(path string, f os.FileInfo, err error) error {
|
||||
// include all tests that aren't in the itests directory.
|
||||
if strings.Contains(path, "itests") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
// exclude all tests included in other suites
|
||||
if f.IsDir() {
|
||||
if _, ok := excluded[path]; ok {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
if strings.HasSuffix(path, "_test.go") {
|
||||
rel, err := filepath.Rel(repo, path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// take the first directory
|
||||
rest[strings.Split(rel, string(os.PathSeparator))[0]] = struct{}{}
|
||||
}
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// add other directories to a 'rest' suite.
|
||||
for k := range rest {
|
||||
groupedUnitTests["unit-rest"] = append(groupedUnitTests["unit-rest"], k)
|
||||
}
|
||||
|
||||
// map iteration guarantees no order, so sort the array in-place.
|
||||
sort.Strings(groupedUnitTests["unit-rest"])
|
||||
|
||||
// form the input data.
|
||||
type data struct {
|
||||
ItestFiles []string
|
||||
UnitSuites map[string]string
|
||||
}
|
||||
in := data{
|
||||
ItestFiles: itests,
|
||||
UnitSuites: func() map[string]string {
|
||||
ret := make(map[string]string)
|
||||
for name, dirs := range groupedUnitTests {
|
||||
for i, d := range dirs {
|
||||
dirs[i] = fmt.Sprintf("./%s/...", d) // turn into package
|
||||
}
|
||||
ret[name] = strings.Join(dirs, " ")
|
||||
}
|
||||
return ret
|
||||
}(),
|
||||
}
|
||||
|
||||
out, err := os.Create("./config.yml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// execute the template.
|
||||
if err := tmpl.Execute(out, in); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,902 @@
|
||||
version: 2.1
|
||||
orbs:
|
||||
go: gotest/tools@0.0.13
|
||||
aws-cli: circleci/aws-cli@1.3.2
|
||||
packer: salaxander/packer@0.0.3
|
||||
|
||||
executors:
|
||||
golang:
|
||||
docker:
|
||||
- image: circleci/golang:1.16.4
|
||||
resource_class: 2xlarge
|
||||
ubuntu:
|
||||
docker:
|
||||
- image: ubuntu:20.04
|
||||
|
||||
commands:
|
||||
install-deps:
|
||||
steps:
|
||||
- go/install-ssh
|
||||
- go/install: {package: git}
|
||||
prepare:
|
||||
parameters:
|
||||
linux:
|
||||
default: true
|
||||
description: is a linux build environment?
|
||||
type: boolean
|
||||
darwin:
|
||||
default: false
|
||||
description: is a darwin build environment?
|
||||
type: boolean
|
||||
steps:
|
||||
- checkout
|
||||
- git_fetch_all_tags
|
||||
- checkout
|
||||
- when:
|
||||
condition: << parameters.linux >>
|
||||
steps:
|
||||
- run: sudo apt-get update
|
||||
- run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev
|
||||
- run: git submodule sync
|
||||
- run: git submodule update --init
|
||||
download-params:
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore parameters cache
|
||||
keys:
|
||||
- 'v25-2k-lotus-params'
|
||||
paths:
|
||||
- /var/tmp/filecoin-proof-parameters/
|
||||
- run: ./lotus fetch-params 2048
|
||||
- save_cache:
|
||||
name: Save parameters cache
|
||||
key: 'v25-2k-lotus-params'
|
||||
paths:
|
||||
- /var/tmp/filecoin-proof-parameters/
|
||||
install_ipfs:
|
||||
steps:
|
||||
- run: |
|
||||
apt update
|
||||
apt install -y wget
|
||||
wget https://github.com/ipfs/go-ipfs/releases/download/v0.4.22/go-ipfs_v0.4.22_linux-amd64.tar.gz
|
||||
wget https://github.com/ipfs/go-ipfs/releases/download/v0.4.22/go-ipfs_v0.4.22_linux-amd64.tar.gz.sha512
|
||||
if [ "$(sha512sum go-ipfs_v0.4.22_linux-amd64.tar.gz)" != "$(cat go-ipfs_v0.4.22_linux-amd64.tar.gz.sha512)" ]
|
||||
then
|
||||
echo "ipfs failed checksum check"
|
||||
exit 1
|
||||
fi
|
||||
tar -xf go-ipfs_v0.4.22_linux-amd64.tar.gz
|
||||
mv go-ipfs/ipfs /usr/local/bin/ipfs
|
||||
chmod +x /usr/local/bin/ipfs
|
||||
git_fetch_all_tags:
|
||||
steps:
|
||||
- run:
|
||||
name: fetch all tags
|
||||
command: |
|
||||
git fetch --all
|
||||
|
||||
jobs:
|
||||
mod-tidy-check:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- go/mod-tidy-check
|
||||
|
||||
build-all:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: sudo apt-get update
|
||||
- run: sudo apt-get install npm
|
||||
- run:
|
||||
command: make buildall
|
||||
- store_artifacts:
|
||||
path: lotus
|
||||
- store_artifacts:
|
||||
path: lotus-miner
|
||||
- store_artifacts:
|
||||
path: lotus-worker
|
||||
- run: mkdir linux && mv lotus lotus-miner lotus-worker linux/
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- linux
|
||||
|
||||
build-debug:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
command: make debug
|
||||
|
||||
test:
|
||||
description: |
|
||||
Run tests with gotestsum.
|
||||
parameters: &test-params
|
||||
executor:
|
||||
type: executor
|
||||
default: golang
|
||||
go-test-flags:
|
||||
type: string
|
||||
default: "-timeout 30m"
|
||||
description: Flags passed to go test.
|
||||
target:
|
||||
type: string
|
||||
default: "./..."
|
||||
description: Import paths of packages to be tested.
|
||||
proofs-log-test:
|
||||
type: string
|
||||
default: "0"
|
||||
suite:
|
||||
type: string
|
||||
default: unit
|
||||
description: Test suite name to report to CircleCI.
|
||||
gotestsum-format:
|
||||
type: string
|
||||
default: standard-verbose
|
||||
description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
|
||||
coverage:
|
||||
type: string
|
||||
default: -coverprofile=coverage.txt -coverpkg=github.com/filecoin-project/lotus/...
|
||||
description: Coverage flag. Set to the empty string to disable.
|
||||
codecov-upload:
|
||||
type: boolean
|
||||
default: true
|
||||
description: |
|
||||
Upload coverage report to https://codecov.io/. Requires the codecov API token to be
|
||||
set as an environment variable for private projects.
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
command: make deps lotus
|
||||
no_output_timeout: 30m
|
||||
- download-params
|
||||
- go/install-gotestsum:
|
||||
gobin: $HOME/.local/bin
|
||||
version: 0.5.2
|
||||
- run:
|
||||
name: go test
|
||||
environment:
|
||||
TEST_RUSTPROOFS_LOGS: << parameters.proofs-log-test >>
|
||||
SKIP_CONFORMANCE: "1"
|
||||
command: |
|
||||
mkdir -p /tmp/test-reports/<< parameters.suite >>
|
||||
mkdir -p /tmp/test-artifacts
|
||||
gotestsum \
|
||||
--format << parameters.gotestsum-format >> \
|
||||
--junitfile /tmp/test-reports/<< parameters.suite >>/junit.xml \
|
||||
--jsonfile /tmp/test-artifacts/<< parameters.suite >>.json \
|
||||
-- \
|
||||
<< parameters.coverage >> \
|
||||
<< parameters.go-test-flags >> \
|
||||
<< parameters.target >>
|
||||
no_output_timeout: 30m
|
||||
- store_test_results:
|
||||
path: /tmp/test-reports
|
||||
- store_artifacts:
|
||||
path: /tmp/test-artifacts/<< parameters.suite >>.json
|
||||
- when:
|
||||
condition: << parameters.codecov-upload >>
|
||||
steps:
|
||||
- go/install: {package: bash}
|
||||
- go/install: {package: curl}
|
||||
- run:
|
||||
shell: /bin/bash -eo pipefail
|
||||
command: |
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
test-conformance:
|
||||
description: |
|
||||
Run tests using a corpus of interoperable test vectors for Filecoin
|
||||
implementations to test their correctness and compliance with the Filecoin
|
||||
specifications.
|
||||
parameters:
|
||||
<<: *test-params
|
||||
vectors-branch:
|
||||
type: string
|
||||
default: ""
|
||||
description: |
|
||||
Branch on github.com/filecoin-project/test-vectors to checkout and
|
||||
test with. If empty (the default) the commit defined by the git
|
||||
submodule is used.
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
command: make deps lotus
|
||||
no_output_timeout: 30m
|
||||
- download-params
|
||||
- when:
|
||||
condition:
|
||||
not:
|
||||
equal: [ "", << parameters.vectors-branch >> ]
|
||||
steps:
|
||||
- run:
|
||||
name: checkout vectors branch
|
||||
command: |
|
||||
cd extern/test-vectors
|
||||
git fetch
|
||||
git checkout origin/<< parameters.vectors-branch >>
|
||||
- go/install-gotestsum:
|
||||
gobin: $HOME/.local/bin
|
||||
version: 0.5.2
|
||||
- run:
|
||||
name: install statediff globally
|
||||
command: |
|
||||
## statediff is optional; we succeed even if compilation fails.
|
||||
mkdir -p /tmp/statediff
|
||||
git clone https://github.com/filecoin-project/statediff.git /tmp/statediff
|
||||
cd /tmp/statediff
|
||||
go install ./cmd/statediff || exit 0
|
||||
- run:
|
||||
name: go test
|
||||
environment:
|
||||
SKIP_CONFORMANCE: "0"
|
||||
command: |
|
||||
mkdir -p /tmp/test-reports
|
||||
mkdir -p /tmp/test-artifacts
|
||||
gotestsum \
|
||||
--format pkgname-and-test-fails \
|
||||
--junitfile /tmp/test-reports/junit.xml \
|
||||
-- \
|
||||
-v -coverpkg ./chain/vm/,github.com/filecoin-project/specs-actors/... -coverprofile=/tmp/conformance.out ./conformance/
|
||||
go tool cover -html=/tmp/conformance.out -o /tmp/test-artifacts/conformance-coverage.html
|
||||
no_output_timeout: 30m
|
||||
- store_test_results:
|
||||
path: /tmp/test-reports
|
||||
- store_artifacts:
|
||||
path: /tmp/test-artifacts/conformance-coverage.html
|
||||
build-ntwk-calibration:
|
||||
description: |
|
||||
Compile lotus binaries for the calibration network
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: make calibnet
|
||||
- run: mkdir linux-calibrationnet && mv lotus lotus-miner lotus-worker linux-calibrationnet
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- linux-calibrationnet
|
||||
build-ntwk-butterfly:
|
||||
description: |
|
||||
Compile lotus binaries for the butterfly network
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: make butterflynet
|
||||
- run: mkdir linux-butterflynet && mv lotus lotus-miner lotus-worker linux-butterflynet
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- linux-butterflynet
|
||||
build-ntwk-nerpa:
|
||||
description: |
|
||||
Compile lotus binaries for the nerpa network
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: make nerpanet
|
||||
- run: mkdir linux-nerpanet && mv lotus lotus-miner lotus-worker linux-nerpanet
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- linux-nerpanet
|
||||
build-lotus-soup:
|
||||
description: |
|
||||
Compile `lotus-soup` Testground test plan
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: cd extern/filecoin-ffi && make
|
||||
- run:
|
||||
name: "go get lotus@master"
|
||||
command: cd testplans/lotus-soup && go mod edit -replace=github.com/filecoin-project/lotus=../.. && go mod tidy
|
||||
- run:
|
||||
name: "build lotus-soup testplan"
|
||||
command: pushd testplans/lotus-soup && go build -tags=testground .
|
||||
trigger-testplans:
|
||||
description: |
|
||||
Trigger `lotus-soup` test cases on TaaS
|
||||
parameters:
|
||||
<<: *test-params
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
name: "download testground"
|
||||
command: wget https://gist.github.com/nonsense/5fbf3167cac79945f658771aed32fc44/raw/2e17eb0debf7ec6bdf027c1bdafc2c92dd97273b/testground-d3e9603 -O ~/testground-cli && chmod +x ~/testground-cli
|
||||
- run:
|
||||
name: "prepare .env.toml"
|
||||
command: pushd testplans/lotus-soup && mkdir -p $HOME/testground && cp env-ci.toml $HOME/testground/.env.toml && echo 'endpoint="https://ci.testground.ipfs.team"' >> $HOME/testground/.env.toml && echo 'user="circleci"' >> $HOME/testground/.env.toml
|
||||
- run:
|
||||
name: "prepare testground home dir and link test plans"
|
||||
command: mkdir -p $HOME/testground/plans && ln -s $(pwd)/testplans/lotus-soup $HOME/testground/plans/lotus-soup && ln -s $(pwd)/testplans/graphsync $HOME/testground/plans/graphsync
|
||||
- run:
|
||||
name: "go get lotus@master"
|
||||
command: cd testplans/lotus-soup && go get github.com/filecoin-project/lotus@master
|
||||
- run:
|
||||
name: "trigger deals baseline testplan on taas"
|
||||
command: ~/testground-cli run composition -f $HOME/testground/plans/lotus-soup/_compositions/baseline-k8s-3-1.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH
|
||||
- run:
|
||||
name: "trigger payment channel stress testplan on taas"
|
||||
command: ~/testground-cli run composition -f $HOME/testground/plans/lotus-soup/_compositions/paych-stress-k8s.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH
|
||||
- run:
|
||||
name: "trigger graphsync testplan on taas"
|
||||
command: ~/testground-cli run composition -f $HOME/testground/plans/graphsync/_compositions/stress-k8s.toml --metadata-commit=$CIRCLE_SHA1 --metadata-repo=filecoin-project/lotus --metadata-branch=$CIRCLE_BRANCH
|
||||
|
||||
|
||||
build-macos:
|
||||
description: build darwin lotus binary
|
||||
macos:
|
||||
xcode: "10.0.0"
|
||||
working_directory: ~/go/src/github.com/filecoin-project/lotus
|
||||
steps:
|
||||
- prepare:
|
||||
linux: false
|
||||
darwin: true
|
||||
- run:
|
||||
name: Install go
|
||||
command: |
|
||||
curl -O https://dl.google.com/go/go1.16.4.darwin-amd64.pkg && \
|
||||
sudo installer -pkg go1.16.4.darwin-amd64.pkg -target /
|
||||
- run:
|
||||
name: Install pkg-config
|
||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config
|
||||
- run: go version
|
||||
- run:
|
||||
name: Install Rust
|
||||
command: |
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
- run:
|
||||
name: Install jq
|
||||
command: |
|
||||
curl --location https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64 --output /usr/local/bin/jq
|
||||
chmod +x /usr/local/bin/jq
|
||||
- run:
|
||||
name: Install hwloc
|
||||
command: |
|
||||
mkdir ~/hwloc
|
||||
curl --location https://download.open-mpi.org/release/hwloc/v2.4/hwloc-2.4.1.tar.gz --output ~/hwloc/hwloc-2.4.1.tar.gz
|
||||
cd ~/hwloc
|
||||
tar -xvzpf hwloc-2.4.1.tar.gz
|
||||
cd hwloc-2.4.1
|
||||
./configure && make && sudo make install
|
||||
- restore_cache:
|
||||
name: restore cargo cache
|
||||
key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
|
||||
- install-deps
|
||||
- run:
|
||||
command: make build
|
||||
no_output_timeout: 30m
|
||||
- store_artifacts:
|
||||
path: lotus
|
||||
- store_artifacts:
|
||||
path: lotus-miner
|
||||
- store_artifacts:
|
||||
path: lotus-worker
|
||||
- run: mkdir darwin && mv lotus lotus-miner lotus-worker darwin/
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- darwin
|
||||
- save_cache:
|
||||
name: save cargo cache
|
||||
key: v3-go-deps-{{ arch }}-{{ checksum "~/go/src/github.com/filecoin-project/lotus/go.sum" }}
|
||||
paths:
|
||||
- "~/.rustup"
|
||||
- "~/.cargo"
|
||||
|
||||
build-appimage:
|
||||
machine:
|
||||
image: ubuntu-2004:202104-01
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- run:
|
||||
name: install appimage-builder
|
||||
command: |
|
||||
# docs: https://appimage-builder.readthedocs.io/en/latest/intro/install.html
|
||||
sudo apt update
|
||||
sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace
|
||||
sudo curl -Lo /usr/local/bin/appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
sudo chmod +x /usr/local/bin/appimagetool
|
||||
sudo pip3 install appimage-builder
|
||||
- run:
|
||||
name: install lotus dependencies
|
||||
command: sudo apt install ocl-icd-opencl-dev libhwloc-dev
|
||||
- run:
|
||||
name: build appimage
|
||||
command: |
|
||||
sed -i "s/version: latest/version: ${CIRCLE_TAG:-latest}/" AppImageBuilder.yml
|
||||
make appimage
|
||||
- run:
|
||||
name: prepare workspace
|
||||
command: |
|
||||
mkdir appimage
|
||||
mv Lotus-*.AppImage appimage
|
||||
- persist_to_workspace:
|
||||
root: "."
|
||||
paths:
|
||||
- appimage
|
||||
|
||||
|
||||
gofmt:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
command: "! go fmt ./... 2>&1 | read"
|
||||
|
||||
gen-check:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: make deps
|
||||
- run: go install golang.org/x/tools/cmd/goimports
|
||||
- run: go install github.com/hannahhoward/cbor-gen-for
|
||||
- run: make gen
|
||||
- run: git --no-pager diff
|
||||
- run: git --no-pager diff --quiet
|
||||
- run: make docsgen-cli
|
||||
- run: git --no-pager diff
|
||||
- run: git --no-pager diff --quiet
|
||||
|
||||
docs-check:
|
||||
executor: golang
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run: go install golang.org/x/tools/cmd/goimports
|
||||
- run: zcat build/openrpc/full.json.gz | jq > ../pre-openrpc-full
|
||||
- run: zcat build/openrpc/miner.json.gz | jq > ../pre-openrpc-miner
|
||||
- run: zcat build/openrpc/worker.json.gz | jq > ../pre-openrpc-worker
|
||||
- run: make deps
|
||||
- run: make docsgen
|
||||
- run: zcat build/openrpc/full.json.gz | jq > ../post-openrpc-full
|
||||
- run: zcat build/openrpc/miner.json.gz | jq > ../post-openrpc-miner
|
||||
- run: zcat build/openrpc/worker.json.gz | jq > ../post-openrpc-worker
|
||||
- run: git --no-pager diff
|
||||
- run: diff ../pre-openrpc-full ../post-openrpc-full
|
||||
- run: diff ../pre-openrpc-miner ../post-openrpc-miner
|
||||
- run: diff ../pre-openrpc-worker ../post-openrpc-worker
|
||||
- run: git --no-pager diff --quiet
|
||||
|
||||
lint: &lint
|
||||
description: |
|
||||
Run golangci-lint.
|
||||
parameters:
|
||||
executor:
|
||||
type: executor
|
||||
default: golang
|
||||
golangci-lint-version:
|
||||
type: string
|
||||
default: 1.27.0
|
||||
concurrency:
|
||||
type: string
|
||||
default: '2'
|
||||
description: |
|
||||
Concurrency used to run linters. Defaults to 2 because NumCPU is not
|
||||
aware of container CPU limits.
|
||||
args:
|
||||
type: string
|
||||
default: ''
|
||||
description: |
|
||||
Arguments to pass to golangci-lint
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- install-deps
|
||||
- prepare
|
||||
- run:
|
||||
command: make deps
|
||||
no_output_timeout: 30m
|
||||
- go/install-golangci-lint:
|
||||
gobin: $HOME/.local/bin
|
||||
version: << parameters.golangci-lint-version >>
|
||||
- run:
|
||||
name: Lint
|
||||
command: |
|
||||
$HOME/.local/bin/golangci-lint run -v --timeout 2m \
|
||||
--concurrency << parameters.concurrency >> << parameters.args >>
|
||||
lint-all:
|
||||
<<: *lint
|
||||
|
||||
publish:
|
||||
description: publish binary artifacts
|
||||
executor: ubuntu
|
||||
steps:
|
||||
- run:
|
||||
name: Install git jq curl
|
||||
command: apt update && apt install -y git jq curl
|
||||
- checkout
|
||||
- git_fetch_all_tags
|
||||
- checkout
|
||||
- install_ipfs
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- run:
|
||||
name: Create bundles
|
||||
command: ./scripts/build-bundle.sh
|
||||
- run:
|
||||
name: Publish release
|
||||
command: ./scripts/publish-release.sh
|
||||
|
||||
publish-snapcraft:
|
||||
description: build and push snapcraft
|
||||
machine:
|
||||
image: ubuntu-2004:202104-01
|
||||
resource_class: 2xlarge
|
||||
parameters:
|
||||
channel:
|
||||
type: string
|
||||
default: "edge"
|
||||
description: snapcraft channel
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: install snapcraft
|
||||
command: sudo snap install snapcraft --classic
|
||||
- run:
|
||||
name: create snapcraft config file
|
||||
command: |
|
||||
mkdir -p ~/.config/snapcraft
|
||||
echo "$SNAPCRAFT_LOGIN_FILE" | base64 -d > ~/.config/snapcraft/snapcraft.cfg
|
||||
- run:
|
||||
name: build snap
|
||||
command: snapcraft --use-lxd
|
||||
- run:
|
||||
name: publish snap
|
||||
command: snapcraft push *.snap --release << parameters.channel >>
|
||||
|
||||
build-and-push-image:
|
||||
description: build and push docker images to public AWS ECR registry
|
||||
executor: aws-cli/default
|
||||
parameters:
|
||||
profile-name:
|
||||
type: string
|
||||
default: "default"
|
||||
description: AWS profile name to be configured.
|
||||
|
||||
aws-access-key-id:
|
||||
type: env_var_name
|
||||
default: AWS_ACCESS_KEY_ID
|
||||
description: >
|
||||
AWS access key id for IAM role. Set this to the name of
|
||||
the environment variable you will set to hold this
|
||||
value, i.e. AWS_ACCESS_KEY.
|
||||
|
||||
aws-secret-access-key:
|
||||
type: env_var_name
|
||||
default: AWS_SECRET_ACCESS_KEY
|
||||
description: >
|
||||
AWS secret key for IAM role. Set this to the name of
|
||||
the environment variable you will set to hold this
|
||||
value, i.e. AWS_SECRET_ACCESS_KEY.
|
||||
|
||||
region:
|
||||
type: env_var_name
|
||||
default: AWS_REGION
|
||||
description: >
|
||||
Name of env var storing your AWS region information,
|
||||
defaults to AWS_REGION
|
||||
|
||||
account-url:
|
||||
type: env_var_name
|
||||
default: AWS_ECR_ACCOUNT_URL
|
||||
description: >
|
||||
Env var storing Amazon ECR account URL that maps to an AWS account,
|
||||
e.g. {awsAccountNum}.dkr.ecr.us-west-2.amazonaws.com
|
||||
defaults to AWS_ECR_ACCOUNT_URL
|
||||
|
||||
dockerfile:
|
||||
type: string
|
||||
default: Dockerfile
|
||||
description: Name of dockerfile to use. Defaults to Dockerfile.
|
||||
|
||||
path:
|
||||
type: string
|
||||
default: .
|
||||
description: Path to the directory containing your Dockerfile and build context. Defaults to . (working directory).
|
||||
|
||||
extra-build-args:
|
||||
type: string
|
||||
default: ""
|
||||
description: >
|
||||
Extra flags to pass to docker build. For examples, see
|
||||
https://docs.docker.com/engine/reference/commandline/build
|
||||
|
||||
repo:
|
||||
type: string
|
||||
description: Name of an Amazon ECR repository
|
||||
|
||||
tag:
|
||||
type: string
|
||||
default: "latest"
|
||||
description: A comma-separated string containing docker image tags to build and push (default = latest)
|
||||
|
||||
steps:
|
||||
- run:
|
||||
name: Confirm that environment variables are set
|
||||
command: |
|
||||
if [ -z "$AWS_ACCESS_KEY_ID" ]; then
|
||||
echo "No AWS_ACCESS_KEY_ID is set. Skipping build-and-push job ..."
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
- aws-cli/setup:
|
||||
profile-name: <<parameters.profile-name>>
|
||||
aws-access-key-id: <<parameters.aws-access-key-id>>
|
||||
aws-secret-access-key: <<parameters.aws-secret-access-key>>
|
||||
aws-region: <<parameters.region>>
|
||||
|
||||
- run:
|
||||
name: Log into Amazon ECR
|
||||
command: |
|
||||
aws ecr-public get-login-password --region $<<parameters.region>> --profile <<parameters.profile-name>> | docker login --username AWS --password-stdin $<<parameters.account-url>>
|
||||
|
||||
- checkout
|
||||
|
||||
- setup_remote_docker:
|
||||
version: 19.03.13
|
||||
docker_layer_caching: false
|
||||
|
||||
- run:
|
||||
name: Build docker image
|
||||
command: |
|
||||
registry_id=$(echo $<<parameters.account-url>> | sed "s;\..*;;g")
|
||||
|
||||
docker_tag_args=""
|
||||
IFS="," read -ra DOCKER_TAGS \<<< "<< parameters.tag >>"
|
||||
for tag in "${DOCKER_TAGS[@]}"; do
|
||||
docker_tag_args="$docker_tag_args -t $<<parameters.account-url>>/<<parameters.repo>>:$tag"
|
||||
done
|
||||
|
||||
docker build \
|
||||
<<#parameters.extra-build-args>><<parameters.extra-build-args>><</parameters.extra-build-args>> \
|
||||
-f <<parameters.path>>/<<parameters.dockerfile>> \
|
||||
$docker_tag_args \
|
||||
<<parameters.path>>
|
||||
|
||||
- run:
|
||||
name: Push image to Amazon ECR
|
||||
command: |
|
||||
IFS="," read -ra DOCKER_TAGS \<<< "<< parameters.tag >>"
|
||||
for tag in "${DOCKER_TAGS[@]}"; do
|
||||
docker push $<<parameters.account-url>>/<<parameters.repo>>:${tag}
|
||||
done
|
||||
|
||||
publish-packer-mainnet:
|
||||
description: build and push AWS IAM and DigitalOcean droplet.
|
||||
executor:
|
||||
name: packer/default
|
||||
packer-version: 1.6.6
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- packer/build:
|
||||
template: tools/packer/lotus.pkr.hcl
|
||||
args: "-var ci_workspace_bins=./linux -var lotus_network=mainnet -var git_tag=$CIRCLE_TAG"
|
||||
publish-packer-calibrationnet:
|
||||
description: build and push AWS IAM and DigitalOcean droplet.
|
||||
executor:
|
||||
name: packer/default
|
||||
packer-version: 1.6.6
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- packer/build:
|
||||
template: tools/packer/lotus.pkr.hcl
|
||||
args: "-var ci_workspace_bins=./linux-calibrationnet -var lotus_network=calibrationnet -var git_tag=$CIRCLE_TAG"
|
||||
publish-packer-butterflynet:
|
||||
description: build and push AWS IAM and DigitalOcean droplet.
|
||||
executor:
|
||||
name: packer/default
|
||||
packer-version: 1.6.6
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- packer/build:
|
||||
template: tools/packer/lotus.pkr.hcl
|
||||
args: "-var ci_workspace_bins=./linux-butterflynet -var lotus_network=butterflynet -var git_tag=$CIRCLE_TAG"
|
||||
publish-packer-nerpanet:
|
||||
description: build and push AWS IAM and DigitalOcean droplet.
|
||||
executor:
|
||||
name: packer/default
|
||||
packer-version: 1.6.6
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: "."
|
||||
- packer/build:
|
||||
template: tools/packer/lotus.pkr.hcl
|
||||
args: "-var ci_workspace_bins=./linux-nerpanet -var lotus_network=nerpanet -var git_tag=$CIRCLE_TAG"
|
||||
|
||||
workflows:
|
||||
version: 2.1
|
||||
ci:
|
||||
jobs:
|
||||
- lint-all:
|
||||
concurrency: "16" # expend all docker 2xlarge CPUs.
|
||||
- mod-tidy-check
|
||||
- gofmt
|
||||
- gen-check
|
||||
- docs-check
|
||||
|
||||
[[- range $file := .ItestFiles -]]
|
||||
[[ with $name := $file | stripSuffix ]]
|
||||
- test:
|
||||
name: test-itest-[[ $name ]]
|
||||
suite: itest-[[ $name ]]
|
||||
target: "./itests/[[ $file ]]"
|
||||
[[ end ]]
|
||||
[[- end -]]
|
||||
|
||||
[[range $suite, $pkgs := .UnitSuites]]
|
||||
- test:
|
||||
name: test-[[ $suite ]]
|
||||
suite: utest-[[ $suite ]]
|
||||
target: "[[ $pkgs ]]"
|
||||
[[- end]]
|
||||
- test:
|
||||
go-test-flags: "-run=TestMulticoreSDR"
|
||||
suite: multicore-sdr-check
|
||||
target: "./extern/sector-storage/ffiwrapper"
|
||||
proofs-log-test: "1"
|
||||
- test-conformance:
|
||||
suite: conformance
|
||||
codecov-upload: false
|
||||
target: "./conformance"
|
||||
- test-conformance:
|
||||
name: test-conformance-bleeding-edge
|
||||
codecov-upload: false
|
||||
suite: conformance-bleeding-edge
|
||||
target: "./conformance"
|
||||
vectors-branch: master
|
||||
- trigger-testplans:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- build-debug
|
||||
- build-all:
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-ntwk-calibration:
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-ntwk-butterfly:
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-ntwk-nerpa:
|
||||
filters:
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-lotus-soup
|
||||
- build-macos:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-appimage:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- publish:
|
||||
requires:
|
||||
- build-all
|
||||
- build-macos
|
||||
- build-appimage
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- build-and-push-image:
|
||||
dockerfile: Dockerfile.lotus
|
||||
path: .
|
||||
repo: lotus-dev
|
||||
tag: '${CIRCLE_SHA1:0:8}'
|
||||
- publish-packer-mainnet:
|
||||
requires:
|
||||
- build-all
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- publish-packer-calibrationnet:
|
||||
requires:
|
||||
- build-ntwk-calibration
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- publish-packer-butterflynet:
|
||||
requires:
|
||||
- build-ntwk-butterfly
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- publish-packer-nerpanet:
|
||||
requires:
|
||||
- build-ntwk-nerpa
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
- publish-snapcraft:
|
||||
name: publish-snapcraft-stable
|
||||
channel: stable
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- /.*/
|
||||
tags:
|
||||
only:
|
||||
- /^v\d+\.\d+\.\d+(-rc\d+)?$/
|
||||
|
||||
nightly:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 0 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
jobs:
|
||||
- publish-snapcraft:
|
||||
name: publish-snapcraft-nightly
|
||||
channel: edge
|
||||
+5
-15
@@ -1,16 +1,6 @@
|
||||
## filecoin-project/lotus CODEOWNERS
|
||||
## Refer to https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners.
|
||||
##
|
||||
## These users or groups will be automatically assigned as reviewers every time
|
||||
## a PR is submitted that modifies code in the specified locations.
|
||||
##
|
||||
## The Lotus repo configuration requires that at least ONE codeowner approves
|
||||
## the PR before merging.
|
||||
# Reference
|
||||
# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners
|
||||
|
||||
### Global owners.
|
||||
* @magik6k @arajasek
|
||||
|
||||
### Conformance testing.
|
||||
conformance/ @ZenGround0
|
||||
extern/test-vectors @ZenGround0
|
||||
cmd/tvx @ZenGround0
|
||||
# Global owners
|
||||
# Ensure maintainers team is a requested reviewer for non-draft PRs
|
||||
* @filecoin-project/lotus-maintainers
|
||||
|
||||
@@ -35,6 +35,10 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: '1.16.4'
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Close and mark stale issue
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 24 hours.'
|
||||
close-issue-message: 'This issue was closed because it is missing author input.'
|
||||
stale-issue-label: 'kind/stale'
|
||||
any-of-labels: 'hint/needs-author-input'
|
||||
days-before-issue-stale: 5
|
||||
days-before-issue-close: 1
|
||||
enable-statistics: true
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: Testground PR Checker
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
testground:
|
||||
runs-on: ubuntu-latest
|
||||
name: ${{ matrix.composition_file }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- backend_addr: ci.testground.ipfs.team
|
||||
backend_proto: https
|
||||
plan_directory: testplans/lotus-soup
|
||||
composition_file: testplans/lotus-soup/_compositions/baseline-k8s-3-1.toml
|
||||
- backend_addr: ci.testground.ipfs.team
|
||||
backend_proto: https
|
||||
plan_directory: testplans/lotus-soup
|
||||
composition_file: testplans/lotus-soup/_compositions/paych-stress-k8s.toml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: testground run
|
||||
uses: coryschwartz/testground-github-action@v1.1
|
||||
with:
|
||||
backend_addr: ${{ matrix.backend_addr }}
|
||||
backend_proto: ${{ matrix.backend_proto }}
|
||||
plan_directory: ${{ matrix.plan_directory }}
|
||||
composition_file: ${{ matrix.composition_file }}
|
||||
@@ -1,3 +1,6 @@
|
||||
/AppDir
|
||||
/appimage-builder-cache
|
||||
*.AppImage
|
||||
/lotus
|
||||
/lotus-miner
|
||||
/lotus-worker
|
||||
@@ -5,6 +8,7 @@
|
||||
/lotus-health
|
||||
/lotus-chainwatch
|
||||
/lotus-shed
|
||||
/lotus-sim
|
||||
/lotus-pond
|
||||
/lotus-townhall
|
||||
/lotus-fountain
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 0 127 127" xml:space="preserve" enable-background="new 0 0 127 127"><style type="text/css">.st0{fill:#00d2d6}.st1{fill:#fff}</style><g><path class="st0" d="M63.5,127C28.5,127.1-0.2,98.4,0,63.2C0.2,28.3,28.6-0.2,63.9,0c34.8,0.2,63.3,28.7,63.1,64 C126.7,98.7,98.5,127.1,63.5,127z M71.4,57.6c5.5,0.8,11,1.5,16.5,2.3c0.5-1.7,0.9-3.1,1.3-4.7c-5.7-0.8-11.2-1.7-17.1-2.5 c2-7,3.7-13.7,5.8-20.2c0.7-2.2,2.3-4.2,3.9-5.9c2.1-2.2,5-1.7,6.8,0.7c0.7,1,1.4,2.1,2.3,2.9c1.1,1.1,2.8,1.6,4,0.6 c0.8-0.7,0.7-2.4,0.8-3.6c0-0.5-0.6-1.1-1-1.6c-2-2.3-4.7-3.1-7.5-3.2c-6.3-0.3-10.9,3-14.5,7.8c-3.5,4.8-5.1,10.5-6.8,16.2 c-0.5,1.6-0.9,3.3-1.4,5.1c-6.2-0.9-12.1-1.7-18.2-2.6c-0.2,1.6-0.4,3.2-0.6,4.8c6,0.9,11.8,1.8,17.8,2.7c-0.8,3.4-1.5,6.5-2.3,9.7 c-5.8-0.8-11.4-1.6-17-2.4c-0.2,1.8-0.4,3.2-0.6,4.8c5.6,0.9,11,1.7,16.5,2.5c0,0.6,0.1,1,0,1.3c-1.7,7.4-3.4,14.8-5.3,22.2 c-0.9,3.5-2.4,6.9-5.3,9.3c-2.4,2-5,1.7-6.8-0.8c-0.8-1.1-1.5-2.5-2.6-3.3c-0.8-0.6-2.5-0.9-3.1-0.5c-0.9,0.7-1.5,2.2-1.4,3.3 c0.1,1,1,2.2,1.9,2.8c3,2.3,6.5,2.6,10,1.9c5.9-1.2,10.1-4.9,12.7-10.1c2-4.1,3.6-8.5,5-12.9c1.3-4,2.2-8,3.3-12.2 c5.8,0.8,11.5,1.7,17.3,2.5c0.5-1.7,0.9-3.2,1.4-4.8c-6.1-0.9-11.9-1.7-17.7-2.6C70.1,64,70.7,60.9,71.4,57.6z"/><path class="st1" d="M71.4,57.6c-0.7,3.3-1.3,6.4-2,9.8c5.9,0.9,11.7,1.7,17.7,2.6c-0.5,1.6-0.9,3.1-1.4,4.8 c-5.8-0.8-11.5-1.7-17.3-2.5c-1.1,4.2-2,8.3-3.3,12.2c-1.4,4.4-3,8.7-5,12.9c-2.6,5.2-6.8,8.9-12.7,10.1c-3.5,0.7-7,0.4-10-1.9 c-0.9-0.7-1.8-1.8-1.9-2.8c-0.1-1.1,0.5-2.7,1.4-3.3c0.6-0.5,2.3-0.1,3.1,0.5c1.1,0.8,1.8,2.1,2.6,3.3c1.8,2.5,4.4,2.9,6.8,0.8 c2.9-2.5,4.4-5.8,5.3-9.3c1.9-7.3,3.6-14.8,5.3-22.2c0.1-0.3,0-0.7,0-1.3c-5.4-0.8-10.8-1.7-16.5-2.5c0.2-1.6,0.4-3,0.6-4.8 c5.6,0.8,11.1,1.6,17,2.4c0.8-3.2,1.5-6.4,2.3-9.7c-6-0.9-11.7-1.8-17.8-2.7c0.2-1.6,0.4-3.2,0.6-4.8c6.1,0.9,12,1.7,18.2,2.6 c0.5-1.8,0.9-3.5,1.4-5.1c1.7-5.6,3.2-11.3,6.8-16.2c3.6-4.9,8.1-8.1,14.5-7.8c2.8,0.1,5.5,0.9,7.5,3.2c0.4,0.5,1,1.1,1,1.6 c-0.1,1.2,0,2.9-0.8,3.6c-1.1,1.1-2.8,0.5-4-0.6c-0.9-0.9-1.6-1.9-2.3-2.9c-1.8-2.4-4.7-2.9-6.8-0.7c-1.6,1.7-3.2,3.7-3.9,5.9 C75.7,39.4,74,46,72,53c5.9,0.9,11.4,1.7,17.1,2.5c-0.5,1.6-0.9,3.1-1.3,4.7C82.3,59.1,76.9,58.3,71.4,57.6z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,73 @@
|
||||
version: 1
|
||||
AppDir:
|
||||
path: ./AppDir
|
||||
app_info:
|
||||
id: io.filecoin.lotus
|
||||
name: Lotus
|
||||
icon: icon
|
||||
version: latest
|
||||
exec: usr/bin/lotus
|
||||
exec_args: $@
|
||||
apt:
|
||||
arch: amd64
|
||||
allow_unauthenticated: true
|
||||
sources:
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal main restricted
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal universe
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates universe
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal multiverse
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates multiverse
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted
|
||||
universe multiverse
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu focal-security main restricted
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu focal-security universe
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu focal-security multiverse
|
||||
- sourceline: deb https://cli-assets.heroku.com/apt ./
|
||||
- sourceline: deb http://ppa.launchpad.net/openjdk-r/ppa/ubuntu focal main
|
||||
- sourceline: deb http://ppa.launchpad.net/git-core/ppa/ubuntu focal main
|
||||
- sourceline: deb http://archive.canonical.com/ubuntu focal partner
|
||||
include:
|
||||
- ocl-icd-libopencl1
|
||||
- libhwloc15
|
||||
exclude: []
|
||||
files:
|
||||
include:
|
||||
- /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
|
||||
- /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libm-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libdl-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libc-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libudev.so.1.6.17
|
||||
exclude:
|
||||
- usr/share/man
|
||||
- usr/share/doc/*/README.*
|
||||
- usr/share/doc/*/changelog.*
|
||||
- usr/share/doc/*/NEWS.*
|
||||
- usr/share/doc/*/TODO.*
|
||||
test:
|
||||
fedora:
|
||||
image: appimagecrafters/tests-env:fedora-30
|
||||
command: ./AppRun
|
||||
use_host_x: true
|
||||
debian:
|
||||
image: appimagecrafters/tests-env:debian-stable
|
||||
command: ./AppRun
|
||||
use_host_x: true
|
||||
arch:
|
||||
image: appimagecrafters/tests-env:archlinux-latest
|
||||
command: ./AppRun
|
||||
use_host_x: true
|
||||
centos:
|
||||
image: appimagecrafters/tests-env:centos-7
|
||||
command: ./AppRun
|
||||
use_host_x: true
|
||||
ubuntu:
|
||||
image: appimagecrafters/tests-env:ubuntu-xenial
|
||||
command: ./AppRun
|
||||
use_host_x: true
|
||||
AppImage:
|
||||
arch: x86_64
|
||||
update-information: guess
|
||||
sign-key: None
|
||||
|
||||
+210
-210
@@ -1,5 +1,142 @@
|
||||
# Lotus changelog
|
||||
|
||||
# 1.10.0 / 2021-06-23
|
||||
|
||||
This is a mandatory release of Lotus that introduces Filecoin network v13, codenamed the HyperDrive upgrade. The
|
||||
Filecoin mainnet will upgrade, which is epoch 892800, on 2021-06-30T22:00:00Z. The network upgrade introduces the
|
||||
following FIPs:
|
||||
|
||||
- [FIP-0008](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0008.md): Add miner batched sector pre-commit method
|
||||
- [FIP-0011](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0011.md): Remove reward auction from reporting consensus faults
|
||||
- [FIP-0012](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0012.md): DataCap Top up for FIL+ Client Addresses
|
||||
- [FIP-0013](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md): Add ProveCommitSectorAggregated method to reduce on-chain congestion
|
||||
- [FIP-0015](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0015.md): Revert FIP-0009(Exempt Window PoSts from BaseFee burn)
|
||||
|
||||
Note that this release is built on top of Lotus v1.9.0. Enterprising users can use the `master` branch of Lotus to get the latest functionality, including all changes in this release candidate.
|
||||
|
||||
## Proof batching and aggregation
|
||||
|
||||
FIPs [0008](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0008.md) and [0013](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0013.md) combine to allow for a significant increase in the rate of onboarding storage on the Filecoin network. This aims to lead to more useful data being stored on the network, reduced network congestion, and lower network base fee.
|
||||
|
||||
**Check out the documentation [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#precommitsectorsbatch) for details on the new Lotus miner sealing config options, [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#fees-section) for fee config options, and explanations of the new features.**
|
||||
|
||||
Note:
|
||||
- We recommend to keep `PreCommitSectorsBatch` as 1.
|
||||
- We recommend miners to set `PreCommitBatchWait` lower than 30 hours.
|
||||
- We recommend miners to set a longer `CommitBatchSlack` and `PreCommitBatchSlack` to prevent message failures
|
||||
due to expirations.
|
||||
|
||||
### Projected state tree growth
|
||||
|
||||
In order to validate the Hyperdrive changes, we wrote a simulation to seal as many sectors as quickly as possible, assuming the same number and mix of 32GiB and 64GiB miners as the current network.
|
||||
|
||||
Given these assumptions:
|
||||
|
||||
- We'd expect a network storage growth rate of around 530PiB per day. 😳 🎉 🥳 😅
|
||||
- We'd expect network bandwidth dedicated to `SubmitWindowedPoSt` to grow by about 0.02% per day.
|
||||
- We'd expect the [state-tree](https://spec.filecoin.io/#section-systems.filecoin_vm.state_tree) (and therefore [snapshot](https://docs.filecoin.io/get-started/lotus/chain/#lightweight-snapshot)) size to grow by 1.16GiB per day.
|
||||
- Nearly all of the state-tree growth is expected to come from new sector metadata.
|
||||
- We'd expect the daily lotus datastore growth rate to increase by about 10-15% (from current ~21GiB/day).
|
||||
- Most "growth" of the lotus datastore is due to "churn", historical data that's no longer referenced by the latest state-tree.
|
||||
|
||||
### Future improvements
|
||||
|
||||
Various Lotus improvements are planned moving forward to mitigate the effects of the growing state tree size. The primary improvement is the [Lotus splitstore](https://github.com/filecoin-project/lotus/discussions/5788), which will soon be enabled by default. The feature allows for [online garbage collection](https://github.com/filecoin-project/lotus/issues/6577) for nodes that do not seek to maintain full chain and state history, thus eliminating the need for users to delete their datastores and sync from snapshots.
|
||||
|
||||
Other improvements including better compressed snapshots, faster pre-migrations, and improved chain exports are in the roadmap.
|
||||
|
||||
## WindowPost base fee burn
|
||||
|
||||
Included in the HyperDrive upgrade is [FIP-0015](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0015.md) which eliminates the special-case gas treatment of `SubmitWindowedPoSt` messages that was introduced in [FIP-0009](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0009.md). Although `SubmitWindowedPoSt` messages will be relatively cheap, thanks to the introduction of optimistic acceptance of these proofs in [FIP-0010](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0010.md), storage providers should pay attention to their `MaxWindowPoStGasFee` config option: too low and PoSts may not land on chain; too high and they may cost an exorbitant amount!
|
||||
|
||||
## Changelog
|
||||
|
||||
### New Features
|
||||
|
||||
- Implement FIP-0015 ([filecoin-project/lotus#6361](https://github.com/filecoin-project/lotus/pull/6361))
|
||||
- Integrate FIP0013 and FIP0008 ([filecoin-project/lotus#6235](https://github.com/filecoin-project/lotus/pull/6235))
|
||||
- [Configuration docs and cli examples](https://docs.filecoin.io/mine/lotus/miner-configuration/#precommitsectorsbatch)
|
||||
- [cli docs](https://github.com/filecoin-project/lotus/blob/master/documentation/en/cli-lotus-miner.md#lotus-miner-sectors-batching)
|
||||
- Introduce gas prices for aggregate verifications ([filecoin-project/lotus#6347](https://github.com/filecoin-project/lotus/pull/6347))
|
||||
- Introduce v5 actors ([filecoin-project/lotus#6195](https://github.com/filecoin-project/lotus/pull/6195))
|
||||
- Robustify commit batcher ([filecoin-project/lotus#6367](https://github.com/filecoin-project/lotus/pull/6367))
|
||||
- Always flush when timer goes off ([filecoin-project/lotus#6563](https://github.com/filecoin-project/lotus/pull/6563))
|
||||
- Update default fees for aggregates ([filecoin-project/lotus#6548](https://github.com/filecoin-project/lotus/pull/6548))
|
||||
- sealing: Early finalization option ([filecoin-project/lotus#6452](https://github.com/filecoin-project/lotus/pull/6452))
|
||||
- `./lotus-miner/config.toml/[Sealing.FinalizeEarly]`: default to false. Enable if you want to FinalizeSector before commiting
|
||||
- Add filplus utils to CLI ([filecoin-project/lotus#6351](https://github.com/filecoin-project/lotus/pull/6351))
|
||||
- cli doc can be found [here](https://github.com/filecoin-project/lotus/blob/master/documentation/en/cli-lotus.md#lotus-filplus)
|
||||
- Add miner-side MaxDealStartDelay config ([filecoin-project/lotus#6576](https://github.com/filecoin-project/lotus/pull/6576))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
- chainstore: Don't take heaviestLk with backlogged reorgCh ([filecoin-project/lotus#6526](https://github.com/filecoin-project/lotus/pull/6526))
|
||||
- Backport #6041 - storagefsm: Fix batch deal packing behavior ([filecoin-project/lotus#6519](https://github.com/filecoin-project/lotus/pull/6519))
|
||||
- backport: pick the correct partitions-per-post limit ([filecoin-project/lotus#6503](https://github.com/filecoin-project/lotus/pull/6503))
|
||||
- failed sectors should be added into res correctly ([filecoin-project/lotus#6472](https://github.com/filecoin-project/lotus/pull/6472))
|
||||
- sealing: Fix restartSectors race ([filecoin-project/lotus#6491](https://github.com/filecoin-project/lotus/pull/6491))
|
||||
- Fund miners with the aggregate fee when ProveCommitting ([filecoin-project/lotus#6428](https://github.com/filecoin-project/lotus/pull/6428))
|
||||
- Commit and Precommit batcher cannot share a getSectorDeadline method ([filecoin-project/lotus#6416](https://github.com/filecoin-project/lotus/pull/6416))
|
||||
- Fix supported proof type manipulations for v5 actors ([filecoin-project/lotus#6366](https://github.com/filecoin-project/lotus/pull/6366))
|
||||
- events: Fix handling of multiple matched events per epoch ([filecoin-project/lotus#6362](https://github.com/filecoin-project/lotus/pull/6362))
|
||||
- Fix randomness fetching around null blocks ([filecoin-project/lotus#6240](https://github.com/filecoin-project/lotus/pull/6240))
|
||||
|
||||
### Improvements
|
||||
- Appimage v1.10.0 rc3 ([filecoin-project/lotus#6492](https://github.com/filecoin-project/lotus/pull/6492))
|
||||
- Expand on Drand change testing ([filecoin-project/lotus#6500](https://github.com/filecoin-project/lotus/pull/6500))
|
||||
- Backport Fix logging around mineOne ([filecoin-project/lotus#6499](https://github.com/filecoin-project/lotus/pull/6499))
|
||||
- mpool: Add more metrics ([filecoin-project/lotus#6453](https://github.com/filecoin-project/lotus/pull/6453))
|
||||
- Merge backported PRs into v1.10 release branch ([filecoin-project/lotus#6436](https://github.com/filecoin-project/lotus/pull/6436))
|
||||
- Fix tests ([filecoin-project/lotus#6371](https://github.com/filecoin-project/lotus/pull/6371))
|
||||
- Extend the default deal start epoch delay ([filecoin-project/lotus#6350](https://github.com/filecoin-project/lotus/pull/6350))
|
||||
- sealing: Wire up context to batchers ([filecoin-project/lotus#6497](https://github.com/filecoin-project/lotus/pull/6497))
|
||||
- Improve address resolution for messages ([filecoin-project/lotus#6364](https://github.com/filecoin-project/lotus/pull/6364))
|
||||
|
||||
### Dependency Updates
|
||||
- Proofs v8.0.2 ([filecoin-project/lotus#6524](https://github.com/filecoin-project/lotus/pull/6524))
|
||||
- Update to fixed Bellperson ([filecoin-project/lotus#6480](https://github.com/filecoin-project/lotus/pull/6480))
|
||||
- Update to go-praamfetch with fslocks ([filecoin-project/lotus#6473](https://github.com/filecoin-project/lotus/pull/6473))
|
||||
- Update ffi with fixed multicore sdr support ([filecoin-project/lotus#6471](https://github.com/filecoin-project/lotus/pull/6471))
|
||||
- github.com/filecoin-project/go-paramfetch (v0.0.2-0.20200701152213-3e0f0afdc261 -> v0.0.2-0.20210614165157-25a6c7769498)
|
||||
- github.com/filecoin-project/specs-actors/v5 (v5.0.0-20210512015452-4fe3889fff57 -> v5.0.0)
|
||||
- github.com/filecoin-project/go-hamt-ipld/v3 (v3.0.1 -> v3.1.0)
|
||||
- github.com/ipfs/go-log/v2 (v2.1.2-0.20200626104915-0016c0b4b3e4 -> v2.1.3)
|
||||
- github.com/filecoin-project/go-amt-ipld/v3 (v3.0.0 -> v3.1.0)
|
||||
|
||||
### Network Version v13 HyperDrive Upgrade
|
||||
- Set HyperDrive upgrade epoch ([filecoin-project/lotus#6565](https://github.com/filecoin-project/lotus/pull/6565))
|
||||
- version bump to lotus v1.10.0-rc6 ([filecoin-project/lotus#6529](https://github.com/filecoin-project/lotus/pull/6529))
|
||||
- Upgrade epochs for calibration reset ([filecoin-project/lotus#6528](https://github.com/filecoin-project/lotus/pull/6528))
|
||||
- Lotus version 1.10.0-rc5 ([filecoin-project/lotus#6504](https://github.com/filecoin-project/lotus/pull/6504))
|
||||
- Merge releases into v1.10 release ([filecoin-project/lotus#6494](https://github.com/filecoin-project/lotus/pull/6494))
|
||||
- update lotus to v1.10.0-rc3 ([filecoin-project/lotus#6481](https://github.com/filecoin-project/lotus/pull/6481))
|
||||
- updated configuration comments for docs
|
||||
- Lotus version 1.10.0-rc2 ([filecoin-project/lotus#6443](https://github.com/filecoin-project/lotus/pull/6443))
|
||||
- Set ntwk v13 HyperDrive Calibration upgrade epoch ([filecoin-project/lotus#6442](https://github.com/filecoin-project/lotus/pull/6442))
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
💙Thank you to all the contributors!
|
||||
|
||||
| Contributor | Commits | Lines ± | Files Changed |
|
||||
|--------------------|---------|-------------|---------------|
|
||||
| @magik6k | 81 | +9606/-1536 | 361 |
|
||||
| @arajasek | 41 | +6543/-679 | 189 |
|
||||
| @ZenGround0 | 11 | +4074/-727 | 110 |
|
||||
| @anorth | 10 | +2035/-1177 | 55 |
|
||||
| @iand | 1 | +779/-12 | 5 |
|
||||
| @frrist | 2 | +722/-6 | 6 |
|
||||
| @Stebalien | 6 | +368/-24 | 15 |
|
||||
| @jennijuju | 11 | +204/-111 | 19 |
|
||||
| @vyzo | 6 | +155/-66 | 13 |
|
||||
| @coryschwartz | 10 | +171/-27 | 14 |
|
||||
| @Kubuxu | 4 | +177/-13 | 7 |
|
||||
| @ribasushi | 4 | +65/-42 | 5 |
|
||||
| @travisperson | 2 | +11/-11 | 4 |
|
||||
| @kirk-baird | 1 | +1/-5 | 1 |
|
||||
| @wangchao | 2 | +3/-2 | 2 |
|
||||
|
||||
|
||||
# 1.9.0 / 2021-05-17
|
||||
|
||||
@@ -71,143 +208,6 @@ This is an optional Lotus release that introduces various improvements to the se
|
||||
- fix health report (https://github.com/filecoin-project/lotus/pull/6011)
|
||||
- fix(ci): Use recent ubuntu LTS release; Update release params ((https://github.com/filecoin-project/lotus/pull/6011))
|
||||
|
||||
# 1.9.0-rc4 / 2021-05-13
|
||||
|
||||
This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes.
|
||||
|
||||
## Highlights
|
||||
|
||||
- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843)
|
||||
- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876)
|
||||
- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892)
|
||||
- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871)
|
||||
- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833)
|
||||
- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917)
|
||||
- go-fil-markets v1.1.9 -> v1.2.5
|
||||
- For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md
|
||||
- rust-fil-proofs v5.4.1 -> v7.0.1
|
||||
- For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md
|
||||
|
||||
## Changes
|
||||
- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962)
|
||||
- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743)
|
||||
- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778)
|
||||
- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799)
|
||||
- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851)
|
||||
- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709)
|
||||
- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875)
|
||||
- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891)
|
||||
- State CLI improvements (State CLI improvements)
|
||||
- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854)
|
||||
- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791)
|
||||
- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693)
|
||||
- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864)
|
||||
- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805)
|
||||
- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976)
|
||||
- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800)
|
||||
- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867)
|
||||
- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092)
|
||||
- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819)
|
||||
- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900)
|
||||
- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974)
|
||||
- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850)
|
||||
- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814)
|
||||
- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838)
|
||||
- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840)
|
||||
- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184)
|
||||
- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999)
|
||||
- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881)
|
||||
- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270)
|
||||
- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884)
|
||||
- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930)
|
||||
- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971)
|
||||
- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972)
|
||||
- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992)
|
||||
- Add a mining-heartbeat INFO line at every epoch (https://github.com/filecoin-project/lotus/pull/6183)
|
||||
- chore(ci): Enable build on RC tags (https://github.com/filecoin-project/lotus/pull/6245)
|
||||
- Upgrade nerpa to actor v4 and bump the version to rc4 (https://github.com/filecoin-project/lotus/pull/6249)
|
||||
## Fixes
|
||||
- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796)
|
||||
- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792)
|
||||
- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801)
|
||||
- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653)
|
||||
- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804)
|
||||
- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794)
|
||||
- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879)
|
||||
- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934)
|
||||
- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807)
|
||||
- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003)
|
||||
- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943)
|
||||
- fix health report (https://github.com/filecoin-project/lotus/pull/6011)
|
||||
|
||||
|
||||
# 1.9.0-rc2 / 2021-04-30
|
||||
|
||||
This is an optional Lotus release that introduces various improvements to the sealing, mining, and deal-making processes.
|
||||
|
||||
## Highlights
|
||||
|
||||
- OpenRPC Support (https://github.com/filecoin-project/lotus/pull/5843)
|
||||
- Take latency into account when making interactive deals (https://github.com/filecoin-project/lotus/pull/5876)
|
||||
- Update go-commp-utils for >10x faster client commp calculation (https://github.com/filecoin-project/lotus/pull/5892)
|
||||
- add `lotus client cancel-retrieval` cmd to lotus CLI (https://github.com/filecoin-project/lotus/pull/5871)
|
||||
- add `inspect-deal` command to `lotus client` (https://github.com/filecoin-project/lotus/pull/5833)
|
||||
- Local retrieval support (https://github.com/filecoin-project/lotus/pull/5917)
|
||||
- go-fil-markets v1.1.9 -> v1.2.5
|
||||
- For a detailed changelog see https://github.com/filecoin-project/go-fil-markets/blob/master/CHANGELOG.md
|
||||
- rust-fil-proofs v5.4.1 -> v7
|
||||
- For a detailed changelog see https://github.com/filecoin-project/rust-fil-proofs/blob/master/CHANGELOG.md
|
||||
|
||||
## Changes
|
||||
- storagefsm: Apply global events even in broken states (https://github.com/filecoin-project/lotus/pull/5962)
|
||||
- Default the AlwaysKeepUnsealedCopy flag to true (https://github.com/filecoin-project/lotus/pull/5743)
|
||||
- splitstore: compact hotstore prior to garbage collection (https://github.com/filecoin-project/lotus/pull/5778)
|
||||
- ipfs-force bootstrapper update (https://github.com/filecoin-project/lotus/pull/5799)
|
||||
- better logging when unsealing fails (https://github.com/filecoin-project/lotus/pull/5851)
|
||||
- perf: add cache for gas permium estimation (https://github.com/filecoin-project/lotus/pull/5709)
|
||||
- backupds: Compact log on restart (https://github.com/filecoin-project/lotus/pull/5875)
|
||||
- backupds: Improve truncated log handling (https://github.com/filecoin-project/lotus/pull/5891)
|
||||
- State CLI improvements (State CLI improvements)
|
||||
- API proxy struct codegen (https://github.com/filecoin-project/lotus/pull/5854)
|
||||
- move DI stuff for paychmgr into modules (https://github.com/filecoin-project/lotus/pull/5791)
|
||||
- Implement Event observer and Settings for 3rd party dep injection (https://github.com/filecoin-project/lotus/pull/5693)
|
||||
- Export developer and network commands for consumption by derivatives of Lotus (https://github.com/filecoin-project/lotus/pull/5864)
|
||||
- mock sealer: Simulate randomness sideeffects (https://github.com/filecoin-project/lotus/pull/5805)
|
||||
- localstorage: Demote reservation stat error to debug (https://github.com/filecoin-project/lotus/pull/5976)
|
||||
- shed command to unpack miner info dumps (https://github.com/filecoin-project/lotus/pull/5800)
|
||||
- Add two utils to Lotus-shed (https://github.com/filecoin-project/lotus/pull/5867)
|
||||
- add shed election estimate command (https://github.com/filecoin-project/lotus/pull/5092)
|
||||
- Add --actor flag in lotus-shed sectors terminate (https://github.com/filecoin-project/lotus/pull/5819)
|
||||
- Move lotus mpool clear to lotus-shed (https://github.com/filecoin-project/lotus/pull/5900)
|
||||
- Centralize everything on ipfs/go-log/v2 (https://github.com/filecoin-project/lotus/pull/5974)
|
||||
- expose NextID from nice market actor interface (https://github.com/filecoin-project/lotus/pull/5850)
|
||||
- add available options for perm on error (https://github.com/filecoin-project/lotus/pull/5814)
|
||||
- API docs clarification: Document StateSearchMsg replaced message behavior (https://github.com/filecoin-project/lotus/pull/5838)
|
||||
- api: Document StateReplay replaced message behavior (https://github.com/filecoin-project/lotus/pull/5840)
|
||||
- add godocs to miner objects (https://github.com/filecoin-project/lotus/pull/2184)
|
||||
- Add description to the client deal CLI command (https://github.com/filecoin-project/lotus/pull/5999)
|
||||
- lint: don't skip builtin (https://github.com/filecoin-project/lotus/pull/5881)
|
||||
- use deal duration from actors (https://github.com/filecoin-project/lotus/pull/5270)
|
||||
- remote calc winningpost proof (https://github.com/filecoin-project/lotus/pull/5884)
|
||||
- packer: other network images (https://github.com/filecoin-project/lotus/pull/5930)
|
||||
- Convert the chainstore lock to RW (https://github.com/filecoin-project/lotus/pull/5971)
|
||||
- Remove CachedBlockstore (https://github.com/filecoin-project/lotus/pull/5972)
|
||||
- remove messagepool CapGasFee duplicate code (https://github.com/filecoin-project/lotus/pull/5992)
|
||||
|
||||
## Fixes
|
||||
- return buffers after canceling badger operation (https://github.com/filecoin-project/lotus/pull/5796)
|
||||
- avoid holding a lock while calling the View callback (https://github.com/filecoin-project/lotus/pull/5792)
|
||||
- storagefsm: Trigger input processing when below limits (https://github.com/filecoin-project/lotus/pull/5801)
|
||||
- After importing a previously deleted key, be able to delete it again (https://github.com/filecoin-project/lotus/pull/4653)
|
||||
- fix StateManager.Replay on reward actor (https://github.com/filecoin-project/lotus/pull/5804)
|
||||
- make sure atomic 64bit fields are 64bit aligned (https://github.com/filecoin-project/lotus/pull/5794)
|
||||
- Import secp sigs in paych tests (https://github.com/filecoin-project/lotus/pull/5879)
|
||||
- fix ci build-macos (https://github.com/filecoin-project/lotus/pull/5934)
|
||||
- Fix creation of remainder account when it's not a multisig (https://github.com/filecoin-project/lotus/pull/5807)
|
||||
- Fix fallback chainstore (https://github.com/filecoin-project/lotus/pull/6003)
|
||||
- fix 4857: show help for set-addrs (https://github.com/filecoin-project/lotus/pull/5943)
|
||||
- fix health report (https://github.com/filecoin-project/lotus/pull/6011)
|
||||
|
||||
# 1.8.0 / 2021-04-05
|
||||
|
||||
This is a mandatory release of Lotus that upgrades the network to version 12, which introduces various performance improvements to the cron processing of the power actor. The network will upgrade at height 712320, which is 2021-04-29T06:00:00Z.
|
||||
@@ -228,7 +228,7 @@ This release also expands the `lotus-miner sectors extend` CLI, with a new optio
|
||||
|
||||
- The `expiration-cutoff` flag can be passed to skip sectors whose expiration is past a certain point from the current head. It defaults to infinity (no cutoff), but if, say, 28800 was specified, then only sectors expiring in the next 10 days would be extended (2880 epochs in 1 day).
|
||||
|
||||
## Changes
|
||||
## Changes
|
||||
|
||||
- Util for miners to extend all v1 sectors (https://github.com/filecoin-project/lotus/pull/5924)
|
||||
- Upgrade the butterfly network (https://github.com/filecoin-project/lotus/pull/5929)
|
||||
@@ -239,7 +239,7 @@ This release also expands the `lotus-miner sectors extend` CLI, with a new optio
|
||||
|
||||
This is a patch release of Lotus that introduces small fixes to the Storage FSM.
|
||||
|
||||
## Changes
|
||||
## Changes
|
||||
|
||||
- storagefsm: Fix double unlock with ready WaitDeals sectors (https://github.com/filecoin-project/lotus/pull/5783)
|
||||
- backupds: Allow larger values in write log (https://github.com/filecoin-project/lotus/pull/5776)
|
||||
@@ -255,7 +255,7 @@ This is an hotfix release of Lotus that fixes a critical bug introduced in v1.5.
|
||||
|
||||
# 1.5.1 / 2021-03-10
|
||||
|
||||
This is an optional release of Lotus that introduces an important fix to the WindowPoSt computation process. The change is to wait for some confidence before drawing beacon randomness for the proof. Without this, invalid proofs might be generated as the result of a null tipset.
|
||||
This is an optional release of Lotus that introduces an important fix to the WindowPoSt computation process. The change is to wait for some confidence before drawing beacon randomness for the proof. Without this, invalid proofs might be generated as the result of a null tipset.
|
||||
|
||||
## Splitstore
|
||||
|
||||
@@ -348,7 +348,7 @@ FIP-0010 introduces the ability to dispute bad Window PoSts. Node operators are
|
||||
## Changes
|
||||
|
||||
- [#5341](https://github.com/filecoin-project/lotus/pull/5341) Add a `LOTUS_DISABLE_V3_ACTOR_MIGRATION` envvar
|
||||
- Setting this envvar to 1 disables the v3 actor migration, should only be used in the event of a failed migration
|
||||
- Setting this envvar to 1 disables the v3 actor migration, should only be used in the event of a failed migration
|
||||
|
||||
# 1.4.2 / 2021-02-17
|
||||
|
||||
@@ -356,14 +356,14 @@ This is a large, and highly recommended, optional release with new features and
|
||||
|
||||
- [FIP-0007 h/amt-v3](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0007.md) which improves the performance of the Filecoin HAMT and AMT.
|
||||
- [FIP-0010 off-chain Window PoSt Verification](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0010.md) which reduces the gas consumption of `SubmitWindowedPoSt` messages significantly by optimistically accepting Window PoSt proofs without verification, and allowing them to be disputed later by off-chain verifiers.
|
||||
|
||||
|
||||
Note that this release does NOT set an upgrade epoch for v3 actors to take effect. That will be done in the upcoming 1.5.0 release.
|
||||
|
||||
## New Features
|
||||
|
||||
- [#5341](https://github.com/filecoin-project/lotus/pull/5341) Added sector termination API and CLI
|
||||
- Run `lotus-miner sectors terminate`
|
||||
- [#5342](https://github.com/filecoin-project/lotus/pull/5342) Added CLI for using a multisig wallet as miner's owner address
|
||||
|
||||
## New Features
|
||||
|
||||
- [#5341](https://github.com/filecoin-project/lotus/pull/5341) Added sector termination API and CLI
|
||||
- Run `lotus-miner sectors terminate`
|
||||
- [#5342](https://github.com/filecoin-project/lotus/pull/5342) Added CLI for using a multisig wallet as miner's owner address
|
||||
- See how to set it up [here](https://github.com/filecoin-project/lotus/pull/5342#issue-554009129)
|
||||
- [#5363](https://github.com/filecoin-project/lotus/pull/5363), [#5418](https://github.com/filecoin-project/lotus/pull/), [#5476](https://github.com/filecoin-project/lotus/pull/5476), [#5459](https://github.com/filecoin-project/lotus/pull/5459) Integrated [spec-actor v3](https://github.com/filecoin-pro5418ject/specs-actors/releases/tag/v3.0.0)
|
||||
- [#5472](https://github.com/filecoin-project/lotus/pull/5472) Generate actor v3 methods for pond
|
||||
@@ -374,7 +374,7 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec
|
||||
- [#5411](https://github.com/filecoin-project/lotus/pull/5411) Handle batch `PublishStorageDeals` message in sealing recovery
|
||||
- [#5505](https://github.com/filecoin-project/lotus/pull/5505) Exclude expired deals from batching in `PublishStorageDeals` messages
|
||||
- Added `PublishMsgPeriod` and `MaxDealsPerPublishMsg` to miner `Dealmaking` [configuration](https://docs.filecoin.io/mine/lotus/miner-configuration/#dealmaking-section). See how they work [here](https://docs.filecoin.io/mine/lotus/miner-configuration/#publishing-several-deals-in-one-message).
|
||||
- [#5538](https://github.com/filecoin-project/lotus/pull/5538), [#5549](https://github.com/filecoin-project/lotus/pull/5549) Added a command to list pending deals and force publish messages.
|
||||
- [#5538](https://github.com/filecoin-project/lotus/pull/5538), [#5549](https://github.com/filecoin-project/lotus/pull/5549) Added a command to list pending deals and force publish messages.
|
||||
- Run `lotus-miner market pending-publish`
|
||||
- [#5428](https://github.com/filecoin-project/lotus/pull/5428) Moved waiting for `PublishStorageDeals` messages' receipt from markets to lotus
|
||||
- [#5510](https://github.com/filecoin-project/lotus/pull/5510) Added `nerpanet` build option
|
||||
@@ -384,32 +384,32 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec
|
||||
- [#5219](https://github.com/filecoin-project/lotus/pull/5219) Added interactive mode for lotus-wallet
|
||||
- [5529](https://github.com/filecoin-project/lotus/pull/5529) Added support for minder nodes in `lotus-shed rpc` util
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- [#5210](https://github.com/filecoin-project/lotus/pull/5210) Miner should not dial client on restart
|
||||
- [#5403](https://github.com/filecoin-project/lotus/pull/5403) When estimating GasLimit only apply prior messages up to the nonce
|
||||
- [#5410](https://github.com/filecoin-project/lotus/pull/510) Fix the calibnet build option
|
||||
- [#5492](https://github.com/filecoin-project/lotus/pull/5492) Fixed `has` for ipfsbstore for non-existing blocks
|
||||
- [#5361](https://github.com/filecoin-project/lotus/pull/5361) Fixed retrieval hangs when using `IpfsOnlineMode=true`
|
||||
- [#5493](https://github.com/filecoin-project/lotus/pull/5493) Fixed retrieval failure when price-per-byte is zero
|
||||
- [#5506](https://github.com/filecoin-project/lotus/pull/5506) Fixed contexts in the storage adpater
|
||||
- [#5515](https://github.com/filecoin-project/lotus/pull/5515) Properly wire up `StateReadState` on gateway API
|
||||
- [#5582](https://github.com/filecoin-project/lotus/pull/5582) Fixed error logging format strings
|
||||
- [#5614](https://github.com/filecoin-project/lotus/pull/5614) Fixed websocket reconnecting handling
|
||||
## Bug Fixes
|
||||
|
||||
- [#5210](https://github.com/filecoin-project/lotus/pull/5210) Miner should not dial client on restart
|
||||
- [#5403](https://github.com/filecoin-project/lotus/pull/5403) When estimating GasLimit only apply prior messages up to the nonce
|
||||
- [#5410](https://github.com/filecoin-project/lotus/pull/510) Fix the calibnet build option
|
||||
- [#5492](https://github.com/filecoin-project/lotus/pull/5492) Fixed `has` for ipfsbstore for non-existing blocks
|
||||
- [#5361](https://github.com/filecoin-project/lotus/pull/5361) Fixed retrieval hangs when using `IpfsOnlineMode=true`
|
||||
- [#5493](https://github.com/filecoin-project/lotus/pull/5493) Fixed retrieval failure when price-per-byte is zero
|
||||
- [#5506](https://github.com/filecoin-project/lotus/pull/5506) Fixed contexts in the storage adpater
|
||||
- [#5515](https://github.com/filecoin-project/lotus/pull/5515) Properly wire up `StateReadState` on gateway API
|
||||
- [#5582](https://github.com/filecoin-project/lotus/pull/5582) Fixed error logging format strings
|
||||
- [#5614](https://github.com/filecoin-project/lotus/pull/5614) Fixed websocket reconnecting handling
|
||||
|
||||
|
||||
## Improvements
|
||||
|
||||
- [#5389](https://github.com/filecoin-project/lotus/pull/5389) Show verified indicator for `./lotus-miner storage-deals list`
|
||||
## Improvements
|
||||
|
||||
- [#5389](https://github.com/filecoin-project/lotus/pull/5389) Show verified indicator for `./lotus-miner storage-deals list`
|
||||
- [#5229](https://github.com/filecoin-project/lotus/pull/5220) Show power for verified deals in `./lotus-miner setocr list`
|
||||
- [#5407](https://github.com/filecoin-project/lotus/pull/5407) Added explicit check of the miner address protocol
|
||||
- [#5399](https://github.com/filecoin-project/lotus/pull/5399) watchdog: increase heapprof capture threshold to 90%
|
||||
- [#5398](https://github.com/filecoin-project/lotus/pull/5398) storageadapter: Look at precommits on-chain since deal publish msg
|
||||
- [#5470](https://github.com/filecoin-project/lotus/pull/5470) Added `--no-timing` option for `./lotus state compute-state --html`
|
||||
- [#5399](https://github.com/filecoin-project/lotus/pull/5399) watchdog: increase heapprof capture threshold to 90%
|
||||
- [#5398](https://github.com/filecoin-project/lotus/pull/5398) storageadapter: Look at precommits on-chain since deal publish msg
|
||||
- [#5470](https://github.com/filecoin-project/lotus/pull/5470) Added `--no-timing` option for `./lotus state compute-state --html`
|
||||
- [#5417](https://github.com/filecoin-project/lotus/pull/5417) Storage Manager: Always unseal full sectors
|
||||
- [#5393](https://github.com/filecoin-project/lotus/pull/5393) Switched to [filecoin-ffi bls api ](https://github.com/filecoin-project/filecoin-ffi/pull/159)for bls signatures
|
||||
- [#5380](https://github.com/filecoin-project/lotus/pull/5210) Refactor deals API tests
|
||||
- [#5397](https://github.com/filecoin-project/lotus/pull/5397) Fixed a flake in the sync manager edge case test
|
||||
- [#5380](https://github.com/filecoin-project/lotus/pull/5210) Refactor deals API tests
|
||||
- [#5397](https://github.com/filecoin-project/lotus/pull/5397) Fixed a flake in the sync manager edge case test
|
||||
- [#5406](https://github.com/filecoin-project/lotus/pull/5406) Added a test to ensure a correct window post cannot be disputed
|
||||
- [#5294](https://github.com/filecoin-project/lotus/pull/5394) Added jobs to build Lotus docker image and push it to AWS ECR
|
||||
- [#5387](https://github.com/filecoin-project/lotus/pull/5387) Added network info(mainnet|calibnet) in version
|
||||
@@ -418,7 +418,7 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec
|
||||
- [#5047](https://github.com/filecoin-project/lotus/pull/5047) Improved the UX for `./lotus-shed bitfield enc`
|
||||
- [#5282](https://github.com/filecoin-project/lotus/pull/5282) Snake a context through the chian blockstore creation
|
||||
- [#5350](https://github.com/filecoin-project/lotus/pull/5350) Avoid using `mp.cfg` directrly to prevent race condition
|
||||
- [#5449](https://github.com/filecoin-project/lotus/pull/5449) Documented the block-header better
|
||||
- [#5449](https://github.com/filecoin-project/lotus/pull/5449) Documented the block-header better
|
||||
- [#5404](https://github.com/filecoin-project/lotus/pull/5404) Added retrying proofs if an incorrect one is generated
|
||||
- [#4545](https://github.com/filecoin-project/lotus/pull/4545) Made state tipset usage consistent in the API
|
||||
- [#5540](https://github.com/filecoin-project/lotus/pull/5540) Removed unnecessary database reads in validation check
|
||||
@@ -435,14 +435,14 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec
|
||||
- [#5592](https://github.com/filecoin-project/lotus/pull/5592) Verify FFI version before building
|
||||
|
||||
## Dependency Updates
|
||||
- [#5296](https://github.com/filecoin-project/lotus/pull/5396) Upgraded to [raulk/go-watchdog@v1.0.1](https://github.com/raulk/go-watchdog/releases/tag/v1.0.1)
|
||||
- [#5450](https://github.com/filecoin-project/lotus/pull/5450) Dependency updates
|
||||
- [#5425](https://github.com/filecoin-project/lotus/pull/5425) Fixed stale imports in testplans/lotus-soup
|
||||
- [#5535](https://github.com/filecoin-project/lotus/pull/5535) Updated to [go-fil-markets@v1.1.7](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.1.7)
|
||||
- [#5616](https://github.com/filecoin-project/lotus/pull/5600) Updated to [filecoin-ffi@b6e0b35fb49ed0fe](https://github.com/filecoin-project/filecoin-ffi/releases/tag/b6e0b35fb49ed0fe)
|
||||
- [#5599](https://github.com/filecoin-project/lotus/pull/5599) Updated to [go-bitfield@v0.2.4](https://github.com/filecoin-project/go-bitfield/releases/tag/v0.2.4)
|
||||
- [#5614](https://github.com/filecoin-project/lotus/pull/5614), , [#5621](https://github.com/filecoin-project/lotus/pull/5621) Updated to [go-jsonrpc@v0.1.3](https://github.com/filecoin-project/go-jsonrpc/releases/tag/v0.1.3)
|
||||
- [#5459](https://github.com/filecoin-project/lotus/pull/5459) Updated to [spec-actors@v3.0.1](https://github.com/filecoin-project/specs-actors/releases/tag/v3.0.1)
|
||||
- [#5296](https://github.com/filecoin-project/lotus/pull/5396) Upgraded to [raulk/go-watchdog@v1.0.1](https://github.com/raulk/go-watchdog/releases/tag/v1.0.1)
|
||||
- [#5450](https://github.com/filecoin-project/lotus/pull/5450) Dependency updates
|
||||
- [#5425](https://github.com/filecoin-project/lotus/pull/5425) Fixed stale imports in testplans/lotus-soup
|
||||
- [#5535](https://github.com/filecoin-project/lotus/pull/5535) Updated to [go-fil-markets@v1.1.7](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.1.7)
|
||||
- [#5616](https://github.com/filecoin-project/lotus/pull/5600) Updated to [filecoin-ffi@b6e0b35fb49ed0fe](https://github.com/filecoin-project/filecoin-ffi/releases/tag/b6e0b35fb49ed0fe)
|
||||
- [#5599](https://github.com/filecoin-project/lotus/pull/5599) Updated to [go-bitfield@v0.2.4](https://github.com/filecoin-project/go-bitfield/releases/tag/v0.2.4)
|
||||
- [#5614](https://github.com/filecoin-project/lotus/pull/5614), , [#5621](https://github.com/filecoin-project/lotus/pull/5621) Updated to [go-jsonrpc@v0.1.3](https://github.com/filecoin-project/go-jsonrpc/releases/tag/v0.1.3)
|
||||
- [#5459](https://github.com/filecoin-project/lotus/pull/5459) Updated to [spec-actors@v3.0.1](https://github.com/filecoin-project/specs-actors/releases/tag/v3.0.1)
|
||||
|
||||
|
||||
## Network Version v10 Upgrade
|
||||
@@ -450,7 +450,7 @@ Note that this release does NOT set an upgrade epoch for v3 actors to take effec
|
||||
- [#5603](https://github.com/filecoin-project/lotus/pull/5603) Set nerpanet's upgrade epochs up to v3 actors
|
||||
- [#5471](https://github.com/filecoin-project/lotus/pull/5471), [#5456](https://github.com/filecoin-project/lotus/pull/5456) Set calibration net actor v3 migration epochs for testing
|
||||
- [#5434](https://github.com/filecoin-project/lotus/pull/5434) Implemented pre-migration framework
|
||||
- [#5476](https://github.com/filecoin-project/lotus/pull/5477) Tune migration
|
||||
- [#5476](https://github.com/filecoin-project/lotus/pull/5477) Tune migration
|
||||
|
||||
# 1.4.1 / 2021-01-20
|
||||
|
||||
@@ -649,9 +649,9 @@ This is an optional Lotus release that introduces various improvements to the mi
|
||||
- Error out deals that are not activated by proposed deal start epoch (https://github.com/filecoin-project/lotus/pull/5061)
|
||||
|
||||
# 1.2.1 / 2020-11-20
|
||||
|
||||
|
||||
This is a very small release of Lotus that fixes an issue users are experiencing when importing snapshots. There is no need to upgrade unless you experience an issue with creating a new datastore directory in the Lotus repo.
|
||||
|
||||
|
||||
## Changes
|
||||
|
||||
- fix blockstore directory not created automatically (https://github.com/filecoin-project/lotus/pull/4922)
|
||||
@@ -671,7 +671,7 @@ The changes that break consensus are:
|
||||
- Correction of the VM circulating supply calculation (https://github.com/filecoin-project/lotus/pull/4862)
|
||||
- Retuning gas costs (https://github.com/filecoin-project/lotus/pull/4830)
|
||||
- Avoid sending messages to the zero BLS address (https://github.com/filecoin-project/lotus/pull/4888)
|
||||
|
||||
|
||||
## Other Changes
|
||||
|
||||
- delayed pubsub subscribe for messages topic (https://github.com/filecoin-project/lotus/pull/3646)
|
||||
@@ -828,7 +828,7 @@ This is an optional release of Lotus that upgrades Lotus dependencies, and inclu
|
||||
|
||||
This is a patch release of Lotus that builds on the fixes involving worker keys that was introduced in v1.1.1. Miners and node operators should update to this release as soon as possible in order to ensure their blocks are propagated and validated.
|
||||
|
||||
## Changes
|
||||
## Changes
|
||||
|
||||
- Handle worker key changes correctly in runtime (https://github.com/filecoin-project/lotus/pull/4579)
|
||||
|
||||
@@ -1071,7 +1071,7 @@ This consensus-breaking release of Lotus upgrades the actors version to v2.0.0.
|
||||
- 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)
|
||||
- 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)
|
||||
|
||||
@@ -1098,7 +1098,7 @@ We are grateful for every contribution!
|
||||
|
||||
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
|
||||
## Changes
|
||||
|
||||
#### Dependencies
|
||||
|
||||
@@ -1169,7 +1169,7 @@ This consensus-breaking release of Lotus introduces an upgrade to the network. T
|
||||
|
||||
This release also updates go-fil-markets to fix an incompatibility issue between v0.7.2 and earlier versions.
|
||||
|
||||
## Changes
|
||||
## Changes
|
||||
|
||||
#### Dependencies
|
||||
|
||||
@@ -1258,7 +1258,7 @@ This optional release of Lotus introduces some critical fixes to the window PoSt
|
||||
|
||||
## Changes
|
||||
|
||||
#### Some notable improvements:
|
||||
#### Some notable improvements:
|
||||
|
||||
- Correctly construct params for `SubmitWindowedPoSt` messages (https://github.com/filecoin-project/lotus/pull/3909)
|
||||
- Skip sectors correctly for Window PoSt (https://github.com/filecoin-project/lotus/pull/3839)
|
||||
@@ -1294,7 +1294,7 @@ This consensus-breaking release of Lotus is designed to test a network upgrade o
|
||||
- Drand upgrade (https://github.com/filecoin-project/lotus/pull/3670)
|
||||
- Multisig API additions (https://github.com/filecoin-project/lotus/pull/3590)
|
||||
|
||||
#### Storage Miner
|
||||
#### Storage Miner
|
||||
|
||||
- Increase the number of times precommit2 is attempted before moving back to precommit1 (https://github.com/filecoin-project/lotus/pull/3720)
|
||||
|
||||
@@ -1337,7 +1337,7 @@ This release introduces some critical fixes to message selection and gas estimat
|
||||
|
||||
## Changes
|
||||
|
||||
#### Messagepool
|
||||
#### Messagepool
|
||||
|
||||
- Warn when optimal selection fails to pack a block and we fall back to random selection (https://github.com/filecoin-project/lotus/pull/3708)
|
||||
- Add basic command for printing gas performance of messages in the mpool (https://github.com/filecoin-project/lotus/pull/3701)
|
||||
@@ -1407,7 +1407,7 @@ This release also introduces many improvements to Lotus! Among them are a new ve
|
||||
- Add additional info about gas premium (https://github.com/filecoin-project/lotus/pull/3578)
|
||||
- Fix GasPremium capping logic (https://github.com/filecoin-project/lotus/pull/3552)
|
||||
|
||||
#### Payment channels
|
||||
#### Payment channels
|
||||
|
||||
- Get available funds by address or by from/to (https://github.com/filecoin-project/lotus/pull/3547)
|
||||
- Create `lotus paych status` command (https://github.com/filecoin-project/lotus/pull/3523)
|
||||
@@ -1457,7 +1457,7 @@ This patch includes a crucial fix to the message pool selection logic, strongly
|
||||
|
||||
This patch includes a hotfix to the `GasEstimateFeeCap` method, capping the estimated fee to a reasonable level by default.
|
||||
|
||||
## Changes
|
||||
## Changes
|
||||
|
||||
- Added target height to sync wait (https://github.com/filecoin-project/lotus/pull/3502)
|
||||
- Disable codecov annotations (https://github.com/filecoin-project/lotus/pull/3514)
|
||||
@@ -1487,7 +1487,7 @@ This patch includes some bugfixes to the sector sealing process, and updates go-
|
||||
|
||||
# 0.5.7 / 2020-08-31
|
||||
|
||||
This patch release includes some bugfixes and enhancements to the sector lifecycle and message pool logic.
|
||||
This patch release includes some bugfixes and enhancements to the sector lifecycle and message pool logic.
|
||||
|
||||
## Changes
|
||||
|
||||
@@ -1507,7 +1507,7 @@ Hotfix release that fixes a panic in the sealing scheduler (https://github.com/f
|
||||
# 0.5.5
|
||||
|
||||
This patch release introduces a large number of improvements to the sealing process.
|
||||
It also updates go-fil-markets to
|
||||
It also updates go-fil-markets to
|
||||
[version 0.5.8](https://github.com/filecoin-project/go-fil-markets/releases/tag/v0.5.8),
|
||||
and go-libp2p-pubsub to [v0.3.5](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.3.5).
|
||||
|
||||
@@ -1520,16 +1520,16 @@ and go-libp2p-pubsub to [v0.3.5](https://github.com/libp2p/go-libp2p-pubsub/rele
|
||||
|
||||
- The following improvements were introduced in https://github.com/filecoin-project/lotus/pull/3350.
|
||||
|
||||
- Allow `lotus-miner sectors remove` to remove a sector in any state.
|
||||
- Create a separate state in the storage FSM dedicated to submitting the Commit message.
|
||||
- Recovery for when the Deal IDs of deals in a sector get changed in a reorg.
|
||||
- Auto-retry sending Precommit and Commit messages if they run out of gas
|
||||
- Auto-retry sector remove tasks when they fail
|
||||
- Compact worker windows, and allow their tasks to be executed in any order
|
||||
- Allow `lotus-miner sectors remove` to remove a sector in any state.
|
||||
- Create a separate state in the storage FSM dedicated to submitting the Commit message.
|
||||
- Recovery for when the Deal IDs of deals in a sector get changed in a reorg.
|
||||
- Auto-retry sending Precommit and Commit messages if they run out of gas
|
||||
- Auto-retry sector remove tasks when they fail
|
||||
- Compact worker windows, and allow their tasks to be executed in any order
|
||||
|
||||
- Don't simply skip PoSt for bad sectors (https://github.com/filecoin-project/lotus/pull/3323)
|
||||
|
||||
#### Message Pool
|
||||
#### Message Pool
|
||||
|
||||
- Spam Protection: Track required funds for pending messages (https://github.com/filecoin-project/lotus/pull/3313)
|
||||
|
||||
@@ -1554,7 +1554,7 @@ A patch release, containing a few nice bugfixes and improvements:
|
||||
|
||||
# 0.5.3
|
||||
|
||||
Yet another hotfix release.
|
||||
Yet another hotfix release.
|
||||
A lesson for readers, having people who have been awake for 12+ hours review
|
||||
your hotfix PR is not a good idea. Find someone who has enough slept recently
|
||||
enough to give you good code review, otherwise you'll end up quickly bumping
|
||||
@@ -1573,9 +1573,9 @@ This is a hotfix release.
|
||||
|
||||
# 0.5.1 / 2020-08-24
|
||||
|
||||
The Space Race release!
|
||||
The Space Race release!
|
||||
This release contains the genesis car file and bootstrap peers for the space
|
||||
race network.
|
||||
race network.
|
||||
|
||||
Additionally, we included two small fixes to genesis creation:
|
||||
- Randomize ticket value in genesis generation
|
||||
@@ -1593,9 +1593,9 @@ Among the highlights included in this release are:
|
||||
|
||||
- Gas changes: We implemented EIP-1559 and introduced real gas values.
|
||||
- Deal-making: We now support "Committed Capacity" sectors, "fast-retrieval" deals,
|
||||
and the packing of multiple deals into a single sector.
|
||||
and the packing of multiple deals into a single sector.
|
||||
- Renamed features: We renamed some of the binaries, environment variables, and default
|
||||
paths associated with a Lotus node.
|
||||
paths associated with a Lotus node.
|
||||
|
||||
### Gas changes
|
||||
|
||||
@@ -1603,19 +1603,19 @@ We made some significant changes to the mechanics of gas in this release.
|
||||
|
||||
#### Network fee
|
||||
|
||||
We implemented something similar to
|
||||
We implemented something similar to
|
||||
[Ethereum's EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md).
|
||||
The `Message` structure had three changes:
|
||||
- The `GasPrice` field has been removed
|
||||
- A new `GasFeeCap` field has been added, which controls the maximum cost
|
||||
the sender incurs for the message
|
||||
the sender incurs for the message
|
||||
- A new `GasPremium` field has been added, which controls the reward a miner
|
||||
earns for including the message
|
||||
earns for including the message
|
||||
|
||||
A sender will never be charged more than `GasFeeCap * GasLimit`.
|
||||
A sender will never be charged more than `GasFeeCap * GasLimit`.
|
||||
A miner will typically earn `GasPremium * GasLimit` as a reward.
|
||||
|
||||
The `Blockheader` structure has one new field, called `ParentBaseFee`.
|
||||
The `Blockheader` structure has one new field, called `ParentBaseFee`.
|
||||
Informally speaking,the `ParentBaseFee`
|
||||
is increased when blocks are densely packed with messages, and decreased otherwise.
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.15.6 AS builder-deps
|
||||
FROM golang:1.16.4 AS builder-deps
|
||||
MAINTAINER Lotus Development Team
|
||||
|
||||
RUN apt-get update && apt-get install -y ca-certificates build-essential clang ocl-icd-opencl-dev ocl-icd-libopencl1 jq libhwloc-dev
|
||||
|
||||
@@ -6,9 +6,9 @@ all: build
|
||||
unexport GOFLAGS
|
||||
|
||||
GOVERSION:=$(shell go version | cut -d' ' -f 3 | sed 's/^go//' | awk -F. '{printf "%d%03d%03d", $$1, $$2, $$3}')
|
||||
ifeq ($(shell expr $(GOVERSION) \< 1015005), 1)
|
||||
ifeq ($(shell expr $(GOVERSION) \< 1016000), 1)
|
||||
$(warning Your Golang version is go$(shell expr $(GOVERSION) / 1000000).$(shell expr $(GOVERSION) % 1000000 / 1000).$(shell expr $(GOVERSION) % 1000))
|
||||
$(error Update Golang to version to at least 1.15.5)
|
||||
$(error Update Golang to version to at least 1.16.0)
|
||||
endif
|
||||
|
||||
# git modules that need to be loaded
|
||||
@@ -42,12 +42,11 @@ BUILD_DEPS+=build/.filecoin-install
|
||||
CLEAN+=build/.filecoin-install
|
||||
|
||||
ffi-version-check:
|
||||
@[[ "$$(awk '/const Version/{print $$5}' extern/filecoin-ffi/version.go)" -eq 2 ]] || (echo "FFI version mismatch, update submodules"; exit 1)
|
||||
@[[ "$$(awk '/const Version/{print $$5}' extern/filecoin-ffi/version.go)" -eq 3 ]] || (echo "FFI version mismatch, update submodules"; exit 1)
|
||||
BUILD_DEPS+=ffi-version-check
|
||||
|
||||
.PHONY: ffi-version-check
|
||||
|
||||
|
||||
$(MODULES): build/.update-modules ;
|
||||
# dummy file that marks the last time modules were updated
|
||||
build/.update-modules:
|
||||
@@ -81,10 +80,12 @@ nerpanet: build-devnets
|
||||
butterflynet: GOFLAGS+=-tags=butterflynet
|
||||
butterflynet: build-devnets
|
||||
|
||||
interopnet: GOFLAGS+=-tags=interopnet
|
||||
interopnet: build-devnets
|
||||
|
||||
lotus: $(BUILD_DEPS)
|
||||
rm -f lotus
|
||||
go build $(GOFLAGS) -o lotus ./cmd/lotus
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus -i ./build
|
||||
|
||||
.PHONY: lotus
|
||||
BINS+=lotus
|
||||
@@ -92,21 +93,18 @@ BINS+=lotus
|
||||
lotus-miner: $(BUILD_DEPS)
|
||||
rm -f lotus-miner
|
||||
go build $(GOFLAGS) -o lotus-miner ./cmd/lotus-storage-miner
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-miner -i ./build
|
||||
.PHONY: lotus-miner
|
||||
BINS+=lotus-miner
|
||||
|
||||
lotus-worker: $(BUILD_DEPS)
|
||||
rm -f lotus-worker
|
||||
go build $(GOFLAGS) -o lotus-worker ./cmd/lotus-seal-worker
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-worker -i ./build
|
||||
.PHONY: lotus-worker
|
||||
BINS+=lotus-worker
|
||||
|
||||
lotus-shed: $(BUILD_DEPS)
|
||||
rm -f lotus-shed
|
||||
go build $(GOFLAGS) -o lotus-shed ./cmd/lotus-shed
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-shed -i ./build
|
||||
.PHONY: lotus-shed
|
||||
BINS+=lotus-shed
|
||||
|
||||
@@ -138,7 +136,6 @@ install-worker:
|
||||
lotus-seed: $(BUILD_DEPS)
|
||||
rm -f lotus-seed
|
||||
go build $(GOFLAGS) -o lotus-seed ./cmd/lotus-seed
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-seed -i ./build
|
||||
|
||||
.PHONY: lotus-seed
|
||||
BINS+=lotus-seed
|
||||
@@ -172,13 +169,11 @@ lotus-townhall-front:
|
||||
.PHONY: lotus-townhall-front
|
||||
|
||||
lotus-townhall-app: lotus-touch lotus-townhall-front
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build
|
||||
.PHONY: lotus-townhall-app
|
||||
|
||||
lotus-fountain:
|
||||
rm -f lotus-fountain
|
||||
go build -o lotus-fountain ./cmd/lotus-fountain
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-fountain -i ./cmd/lotus-fountain -i ./build
|
||||
.PHONY: lotus-fountain
|
||||
BINS+=lotus-fountain
|
||||
|
||||
@@ -191,28 +186,24 @@ BINS+=lotus-chainwatch
|
||||
lotus-bench:
|
||||
rm -f lotus-bench
|
||||
go build -o lotus-bench ./cmd/lotus-bench
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-bench -i ./build
|
||||
.PHONY: lotus-bench
|
||||
BINS+=lotus-bench
|
||||
|
||||
lotus-stats:
|
||||
rm -f lotus-stats
|
||||
go build $(GOFLAGS) -o lotus-stats ./cmd/lotus-stats
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-stats -i ./build
|
||||
.PHONY: lotus-stats
|
||||
BINS+=lotus-stats
|
||||
|
||||
lotus-pcr:
|
||||
rm -f lotus-pcr
|
||||
go build $(GOFLAGS) -o lotus-pcr ./cmd/lotus-pcr
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-pcr -i ./build
|
||||
.PHONY: lotus-pcr
|
||||
BINS+=lotus-pcr
|
||||
|
||||
lotus-health:
|
||||
rm -f lotus-health
|
||||
go build -o lotus-health ./cmd/lotus-health
|
||||
go run github.com/GeertJohan/go.rice/rice append --exec lotus-health -i ./build
|
||||
.PHONY: lotus-health
|
||||
BINS+=lotus-health
|
||||
|
||||
@@ -243,6 +234,12 @@ BINS+=tvx
|
||||
install-chainwatch: lotus-chainwatch
|
||||
install -C ./lotus-chainwatch /usr/local/bin/lotus-chainwatch
|
||||
|
||||
lotus-sim: $(BUILD_DEPS)
|
||||
rm -f lotus-sim
|
||||
go build $(GOFLAGS) -o lotus-sim ./cmd/lotus-sim
|
||||
.PHONY: lotus-sim
|
||||
BINS+=lotus-sim
|
||||
|
||||
# SYSTEMD
|
||||
|
||||
install-daemon-service: install-daemon
|
||||
@@ -303,17 +300,10 @@ clean-services: clean-all-services
|
||||
|
||||
buildall: $(BINS)
|
||||
|
||||
completions:
|
||||
./scripts/make-completions.sh lotus
|
||||
./scripts/make-completions.sh lotus-miner
|
||||
.PHONY: completions
|
||||
|
||||
install-completions:
|
||||
mkdir -p /usr/share/bash-completion/completions /usr/local/share/zsh/site-functions/
|
||||
install -C ./scripts/bash-completion/lotus /usr/share/bash-completion/completions/lotus
|
||||
install -C ./scripts/bash-completion/lotus-miner /usr/share/bash-completion/completions/lotus-miner
|
||||
install -C ./scripts/zsh-completion/lotus /usr/local/share/zsh/site-functions/_lotus
|
||||
install -C ./scripts/zsh-completion/lotus-miner /usr/local/share/zsh/site-functions/_lotus-miner
|
||||
|
||||
clean:
|
||||
rm -rf $(CLEAN) $(BINS)
|
||||
@@ -333,17 +323,30 @@ type-gen: api-gen
|
||||
method-gen: api-gen
|
||||
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
|
||||
|
||||
actors-gen:
|
||||
go run ./chain/actors/agen
|
||||
go fmt ./...
|
||||
|
||||
api-gen:
|
||||
go run ./gen/api
|
||||
goimports -w api
|
||||
goimports -w api
|
||||
.PHONY: api-gen
|
||||
|
||||
appimage: lotus
|
||||
rm -rf appimage-builder-cache || true
|
||||
rm AppDir/io.filecoin.lotus.desktop || true
|
||||
rm AppDir/icon.svg || true
|
||||
rm Appdir/AppRun || true
|
||||
mkdir -p AppDir/usr/bin
|
||||
cp ./lotus AppDir/usr/bin/
|
||||
appimage-builder
|
||||
|
||||
docsgen: docsgen-md docsgen-openrpc
|
||||
|
||||
docsgen-md-bin: api-gen
|
||||
docsgen-md-bin: api-gen actors-gen
|
||||
go build $(GOFLAGS) -o docgen-md ./api/docgen/cmd
|
||||
docsgen-openrpc-bin: api-gen
|
||||
docsgen-openrpc-bin: api-gen actors-gen
|
||||
go build $(GOFLAGS) -o docgen-openrpc ./api/docgen-openrpc/cmd
|
||||
|
||||
docsgen-md: docsgen-md-full docsgen-md-storage docsgen-md-worker
|
||||
@@ -367,8 +370,21 @@ docsgen-openrpc-worker: docsgen-openrpc-bin
|
||||
|
||||
.PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin
|
||||
|
||||
gen: type-gen method-gen docsgen api-gen
|
||||
gen: actors-gen type-gen method-gen docsgen api-gen circleci
|
||||
@echo ">>> IF YOU'VE MODIFIED THE CLI, REMEMBER TO ALSO MAKE docsgen-cli"
|
||||
.PHONY: gen
|
||||
|
||||
snap: lotus lotus-miner lotus-worker
|
||||
snapcraft
|
||||
# snapcraft upload ./lotus_*.snap
|
||||
|
||||
# separate from gen because it needs binaries
|
||||
docsgen-cli: lotus lotus-miner lotus-worker
|
||||
python ./scripts/generate-lotus-cli.py
|
||||
.PHONY: docsgen-cli
|
||||
|
||||
print-%:
|
||||
@echo $*=$($*)
|
||||
|
||||
circleci:
|
||||
go generate -x ./.circleci
|
||||
@@ -10,7 +10,7 @@
|
||||
<a href="https://circleci.com/gh/filecoin-project/lotus"><img src="https://circleci.com/gh/filecoin-project/lotus.svg?style=svg"></a>
|
||||
<a href="https://codecov.io/gh/filecoin-project/lotus"><img src="https://codecov.io/gh/filecoin-project/lotus/branch/master/graph/badge.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/filecoin-project/lotus"><img src="https://goreportcard.com/badge/github.com/filecoin-project/lotus" /></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.15.5-blue.svg" /></a>
|
||||
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.16-blue.svg" /></a>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
@@ -18,7 +18,9 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more
|
||||
|
||||
## Building & 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/).
|
||||
> Note: The default `master` branch is the dev branch, please use with caution. For the latest stable version, checkout the most recent [`Latest release`](https://github.com/filecoin-project/lotus/releases).
|
||||
|
||||
For complete 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/). Basic build instructions can be found further down in this readme.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
@@ -50,6 +52,88 @@ When implementing a change:
|
||||
7. Title the PR in a meaningful way and describe the rationale and the thought process in the PR description.
|
||||
8. Write clean, thoughtful, and detailed [commit messages](https://chris.beams.io/posts/git-commit/). This is even more important than the PR description, because commit messages are stored _inside_ the Git history. One good rule is: if you are happy posting the commit message as the PR description, then it's a good commit message.
|
||||
|
||||
## Basic Build Instructions
|
||||
**System-specific Software Dependencies**:
|
||||
|
||||
Building Lotus requires some system dependencies, usually provided by your distribution.
|
||||
|
||||
Ubuntu/Debian:
|
||||
```
|
||||
sudo apt install mesa-opencl-icd ocl-icd-opencl-dev gcc git bzr jq pkg-config curl clang build-essential hwloc libhwloc-dev wget -y && sudo apt upgrade -y
|
||||
```
|
||||
|
||||
Fedora:
|
||||
```
|
||||
sudo dnf -y install gcc make git bzr jq pkgconfig mesa-libOpenCL mesa-libOpenCL-devel opencl-headers ocl-icd ocl-icd-devel clang llvm wget hwloc libhwloc-dev
|
||||
```
|
||||
|
||||
For other distributions you can find the required dependencies [here.](https://docs.filecoin.io/get-started/lotus/installation/#system-specific) For instructions specific to macOS, you can find them [here.](https://docs.filecoin.io/get-started/lotus/installation/#macos)
|
||||
|
||||
#### Go
|
||||
|
||||
To build Lotus, you need a working installation of [Go 1.16.4 or higher](https://golang.org/dl/):
|
||||
|
||||
```bash
|
||||
wget -c https://golang.org/dl/go1.16.4.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local
|
||||
```
|
||||
|
||||
**TIP:**
|
||||
You'll need to add `/usr/local/go/bin` to your path. For most Linux distributions you can run something like:
|
||||
|
||||
```shell
|
||||
echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc && source ~/.bashrc
|
||||
```
|
||||
|
||||
See the [official Golang installation instructions](https://golang.org/doc/install) if you get stuck.
|
||||
|
||||
### Build and install Lotus
|
||||
|
||||
Once all the dependencies are installed, you can build and install the Lotus suite (`lotus`, `lotus-miner`, and `lotus-worker`).
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/filecoin-project/lotus.git
|
||||
cd lotus/
|
||||
```
|
||||
|
||||
Note: The default branch `master` is the dev branch where the latest new features, bug fixes and improvement are in. However, if you want to run lotus on Filecoin mainnet and want to run a production-ready lotus, get the latest release[ here](https://github.com/filecoin-project/lotus/releases).
|
||||
|
||||
2. To join mainnet, checkout the [latest release](https://github.com/filecoin-project/lotus/releases).
|
||||
|
||||
If you are changing networks from a previous Lotus installation or there has been a network reset, read the [Switch networks guide](https://docs.filecoin.io/get-started/lotus/switch-networks/) before proceeding.
|
||||
|
||||
For networks other than mainnet, look up the current branch or tag/commit for the network you want to join in the [Filecoin networks dashboard](https://network.filecoin.io), then build Lotus for your specific network below.
|
||||
|
||||
```sh
|
||||
git checkout <tag_or_branch>
|
||||
# For example:
|
||||
git checkout <vX.X.X> # tag for a release
|
||||
```
|
||||
|
||||
Currently, the latest code on the _master_ branch corresponds to mainnet.
|
||||
|
||||
3. If you are in China, see "[Lotus: tips when running in China](https://docs.filecoin.io/get-started/lotus/tips-running-in-china/)".
|
||||
4. This build instruction uses the prebuilt proofs binaries. If you want to build the proof binaries from source check the [complete instructions](https://docs.filecoin.io/get-started/lotus/installation/#build-and-install-lotus). Note, if you are building the proof binaries from source, [installing rustup](https://docs.filecoin.io/get-started/lotus/installation/#rustup) is also needed.
|
||||
|
||||
5. Build and install Lotus:
|
||||
|
||||
```sh
|
||||
make clean all #mainnet
|
||||
|
||||
# Or to join a testnet or devnet:
|
||||
make clean calibnet # Calibration with min 32GiB sectors
|
||||
make clean nerpanet # Nerpa with min 512MiB sectors
|
||||
|
||||
sudo make install
|
||||
```
|
||||
|
||||
This will put `lotus`, `lotus-miner` and `lotus-worker` in `/usr/local/bin`.
|
||||
|
||||
`lotus` will use the `$HOME/.lotus` folder by default for storage (configuration, chain data, wallets, etc). See [advanced options](https://docs.filecoin.io/get-started/lotus/configuration-and-advanced-usage/) for information on how to customize the Lotus folder.
|
||||
|
||||
6. You should now have Lotus installed. You can now [start the Lotus daemon and sync the chain](https://docs.filecoin.io/get-started/lotus/installation/#start-the-lotus-daemon-and-sync-the-chain).
|
||||
|
||||
## License
|
||||
|
||||
Dual-licensed under [MIT](https://github.com/filecoin-project/lotus/blob/master/LICENSE-MIT) + [Apache 2.0](https://github.com/filecoin-project/lotus/blob/master/LICENSE-APACHE)
|
||||
|
||||
+49
-20
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/repo/importmgr"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
@@ -14,7 +15,6 @@ import (
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
@@ -104,6 +104,9 @@ type FullNode interface {
|
||||
// specified block.
|
||||
ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]Message, error) //perm:read
|
||||
|
||||
// ChainGetMessagesInTipset returns message stores in current tipset
|
||||
ChainGetMessagesInTipset(ctx context.Context, tsk types.TipSetKey) ([]Message, error) //perm:read
|
||||
|
||||
// ChainGetTipSetByHeight looks back for a tipset at the specified epoch.
|
||||
// If there are no blocks at the specified epoch, a tipset at an earlier epoch
|
||||
// will be returned.
|
||||
@@ -252,6 +255,13 @@ type FullNode interface {
|
||||
// MpoolBatchPushMessage batch pushes a unsigned message to mempool.
|
||||
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error) //perm:sign
|
||||
|
||||
// MpoolCheckMessages performs logical checks on a batch of messages
|
||||
MpoolCheckMessages(context.Context, []*MessagePrototype) ([][]MessageCheckStatus, error) //perm:read
|
||||
// MpoolCheckPendingMessages performs logical checks for all pending messages from a given address
|
||||
MpoolCheckPendingMessages(context.Context, address.Address) ([][]MessageCheckStatus, error) //perm:read
|
||||
// MpoolCheckReplaceMessages performs logical checks on pending messages with replacement
|
||||
MpoolCheckReplaceMessages(context.Context, []*types.Message) ([][]MessageCheckStatus, error) //perm:read
|
||||
|
||||
// MpoolGetNonce gets next nonce for the specified sender.
|
||||
// Note that this method may not be atomic. Use MpoolPushMessage instead.
|
||||
MpoolGetNonce(context.Context, address.Address) (uint64, error) //perm:read
|
||||
@@ -313,9 +323,11 @@ type FullNode interface {
|
||||
// ClientImport imports file under the specified path into filestore.
|
||||
ClientImport(ctx context.Context, ref FileRef) (*ImportRes, error) //perm:admin
|
||||
// ClientRemoveImport removes file import
|
||||
ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error //perm:admin
|
||||
ClientRemoveImport(ctx context.Context, importID importmgr.ImportID) error //perm:admin
|
||||
// ClientStartDeal proposes a deal with a miner.
|
||||
ClientStartDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) //perm:admin
|
||||
// ClientStatelessDeal fire-and-forget-proposes an offline deal to a miner without subsequent tracking.
|
||||
ClientStatelessDeal(ctx context.Context, params *StartDealParams) (*cid.Cid, error) //perm:write
|
||||
// ClientGetDealInfo returns the latest information about a given deal.
|
||||
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error) //perm:read
|
||||
// ClientListDeals returns information about the deals made by the local client.
|
||||
@@ -335,6 +347,10 @@ type FullNode interface {
|
||||
// ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel
|
||||
// of status updates.
|
||||
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin
|
||||
// ClientListRetrievals returns information about retrievals made by the local client
|
||||
ClientListRetrievals(ctx context.Context) ([]RetrievalInfo, error) //perm:write
|
||||
// ClientGetRetrievalUpdates returns status of updated retrieval deals
|
||||
ClientGetRetrievalUpdates(ctx context.Context) (<-chan RetrievalInfo, error) //perm:write
|
||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read
|
||||
// ClientCalcCommP calculates the CommP and data size of the specified CID
|
||||
@@ -579,15 +595,16 @@ type FullNode interface {
|
||||
// MsigCreate creates a multisig wallet
|
||||
// It takes the following params: <required number of senders>, <approving addresses>, <unlock duration>
|
||||
//<initial balance>, <sender address of the create msg>, <gas price>
|
||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) //perm:sign
|
||||
MsigCreate(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigPropose proposes a multisig message
|
||||
// It takes the following params: <multisig address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the propose msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
MsigPropose(context.Context, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigApprove approves a previously-proposed multisig message by transaction ID
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID> <signer address>
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigApprove(context.Context, address.Address, uint64, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigApproveTxnHash approves a previously-proposed multisig message, specified
|
||||
// using both transaction ID and a hash of the parameters used in the
|
||||
@@ -595,43 +612,49 @@ type FullNode interface {
|
||||
// exactly the transaction you think you are.
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the approve msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigCancel cancels a previously-proposed multisig message
|
||||
// It takes the following params: <multisig address>, <proposed transaction ID>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the cancel msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
MsigCancel(context.Context, address.Address, uint64, address.Address, types.BigInt, address.Address, uint64, []byte) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigAddPropose proposes adding a signer in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
MsigAddPropose(context.Context, address.Address, address.Address, address.Address, bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigAddApprove approves a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
MsigAddApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigAddCancel cancels a previously proposed AddSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <new signer>, <whether the number of required signers should be increased>
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (cid.Cid, error) //perm:sign
|
||||
MsigAddCancel(context.Context, address.Address, address.Address, uint64, address.Address, bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigSwapPropose proposes swapping 2 signers in the multisig
|
||||
// It takes the following params: <multisig address>, <sender address of the propose msg>,
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigSwapPropose(context.Context, address.Address, address.Address, address.Address, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigSwapApprove approves a previously proposed SwapSigner
|
||||
// It takes the following params: <multisig address>, <sender address of the approve msg>, <proposed message ID>,
|
||||
// <proposer address>, <old signer>, <new signer>
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigSwapApprove(context.Context, address.Address, address.Address, uint64, address.Address, address.Address, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigSwapCancel cancels a previously proposed SwapSigner message
|
||||
// It takes the following params: <multisig address>, <sender address of the cancel msg>, <proposed message ID>,
|
||||
// <old signer>, <new signer>
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) //perm:sign
|
||||
MsigSwapCancel(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MsigRemoveSigner proposes the removal of a signer from the multisig.
|
||||
// It accepts the multisig to make the change on, the proposer address to
|
||||
// send the message from, the address to be removed, and a boolean
|
||||
// indicating whether or not the signing threshold should be lowered by one
|
||||
// along with the address removal.
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) //perm:sign
|
||||
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (*MessagePrototype, error) //perm:sign
|
||||
|
||||
// MarketAddBalance adds funds to the market actor
|
||||
MarketAddBalance(ctx context.Context, wallet, addr address.Address, amt types.BigInt) (cid.Cid, error) //perm:sign
|
||||
@@ -664,6 +687,11 @@ type FullNode interface {
|
||||
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error) //perm:write
|
||||
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MethodGroup: Node
|
||||
// These methods are general node management and status commands
|
||||
|
||||
NodeStatus(ctx context.Context, inclChainStatus bool) (NodeStatus, error) //perm:read
|
||||
|
||||
// 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
|
||||
@@ -687,16 +715,17 @@ type MinerSectors struct {
|
||||
|
||||
type ImportRes struct {
|
||||
Root cid.Cid
|
||||
ImportID multistore.StoreID
|
||||
ImportID importmgr.ImportID
|
||||
}
|
||||
|
||||
type Import struct {
|
||||
Key multistore.StoreID
|
||||
Key importmgr.ImportID
|
||||
Err string
|
||||
|
||||
Root *cid.Cid
|
||||
Source string
|
||||
FilePath string
|
||||
Root *cid.Cid
|
||||
Source string
|
||||
FilePath string
|
||||
CARv2FilePath string
|
||||
}
|
||||
|
||||
type DealInfo struct {
|
||||
@@ -879,7 +908,7 @@ type RetrievalOrder struct {
|
||||
Piece *cid.Cid
|
||||
Size uint64
|
||||
|
||||
LocalStore *multistore.StoreID // if specified, get data from local store
|
||||
LocalCARV2FilePath string // if specified, get data from a local CARv2 file.
|
||||
// TODO: support offset
|
||||
Total types.BigInt
|
||||
UnsealPrice types.BigInt
|
||||
|
||||
@@ -58,4 +58,5 @@ type Gateway interface {
|
||||
StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error)
|
||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*MsgLookup, error)
|
||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||||
Version(context.Context) (APIVersion, error)
|
||||
}
|
||||
|
||||
+46
-4
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||
)
|
||||
|
||||
// MODIFYING THE API INTERFACE
|
||||
@@ -54,6 +55,13 @@ type StorageMiner interface {
|
||||
// Get the status of a given sector by ID
|
||||
SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (SectorInfo, error) //perm:read
|
||||
|
||||
// Add piece to an open sector. If no sectors with enough space are open,
|
||||
// either a new sector will be created, or this call will block until more
|
||||
// sectors can be created.
|
||||
SectorAddPieceToAny(ctx context.Context, size abi.UnpaddedPieceSize, r storage.Data, d PieceDealInfo) (SectorOffset, error) //perm:admin
|
||||
|
||||
SectorsUnsealPiece(ctx context.Context, sector storage.SectorRef, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, commd *cid.Cid) error //perm:admin
|
||||
|
||||
// List all staged sectors
|
||||
SectorsList(context.Context) ([]abi.SectorNumber, error) //perm:read
|
||||
|
||||
@@ -91,6 +99,16 @@ type StorageMiner interface {
|
||||
// SectorTerminatePending returns a list of pending sector terminations to be sent in the next batch message
|
||||
SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
|
||||
SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber) error //perm:admin
|
||||
// SectorPreCommitFlush immediately sends a PreCommit message with sectors batched for PreCommit.
|
||||
// Returns null if message wasn't sent
|
||||
SectorPreCommitFlush(ctx context.Context) ([]sealiface.PreCommitBatchRes, error) //perm:admin
|
||||
// SectorPreCommitPending returns a list of pending PreCommit sectors to be sent in the next batch message
|
||||
SectorPreCommitPending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
|
||||
// SectorCommitFlush immediately sends a Commit message with sectors aggregated for Commit.
|
||||
// Returns null if message wasn't sent
|
||||
SectorCommitFlush(ctx context.Context) ([]sealiface.CommitBatchRes, error) //perm:admin
|
||||
// SectorCommitPending returns a list of pending Commit sectors to be sent in the next aggregate message
|
||||
SectorCommitPending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
|
||||
|
||||
// WorkerConnect tells the node to connect to workers RPC
|
||||
WorkerConnect(context.Context, string) error //perm:admin retry:true
|
||||
@@ -124,8 +142,8 @@ type StorageMiner interface {
|
||||
StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pathType storiface.PathType) ([]stores.StorageInfo, error) //perm:admin
|
||||
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error //perm:admin
|
||||
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) //perm:admin
|
||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) //perm:admin
|
||||
|
||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) //perm:admin
|
||||
StorageLocal(ctx context.Context) (map[stores.ID]string, error) //perm:admin
|
||||
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) //perm:admin
|
||||
|
||||
@@ -268,15 +286,17 @@ type AddrUse int
|
||||
const (
|
||||
PreCommitAddr AddrUse = iota
|
||||
CommitAddr
|
||||
DealPublishAddr
|
||||
PoStAddr
|
||||
|
||||
TerminateSectorsAddr
|
||||
)
|
||||
|
||||
type AddressConfig struct {
|
||||
PreCommitControl []address.Address
|
||||
CommitControl []address.Address
|
||||
TerminateControl []address.Address
|
||||
PreCommitControl []address.Address
|
||||
CommitControl []address.Address
|
||||
TerminateControl []address.Address
|
||||
DealPublishControl []address.Address
|
||||
|
||||
DisableOwnerFallback bool
|
||||
DisableWorkerFallback bool
|
||||
@@ -289,3 +309,25 @@ type PendingDealInfo struct {
|
||||
PublishPeriodStart time.Time
|
||||
PublishPeriod time.Duration
|
||||
}
|
||||
|
||||
type SectorOffset struct {
|
||||
Sector abi.SectorNumber
|
||||
Offset abi.PaddedPieceSize
|
||||
}
|
||||
|
||||
// DealInfo is a tuple of deal identity and its schedule
|
||||
type PieceDealInfo struct {
|
||||
PublishCid *cid.Cid
|
||||
DealID abi.DealID
|
||||
DealProposal *market.DealProposal
|
||||
DealSchedule DealSchedule
|
||||
KeepUnsealed bool
|
||||
}
|
||||
|
||||
// DealSchedule communicates the time interval of a storage deal. The deal must
|
||||
// appear in a sealed (proven) sector no later than StartEpoch, otherwise it
|
||||
// is invalid.
|
||||
type DealSchedule struct {
|
||||
StartEpoch abi.ChainEpoch
|
||||
EndEpoch abi.ChainEpoch
|
||||
}
|
||||
|
||||
+7
-7
@@ -35,13 +35,13 @@ type MsgMeta struct {
|
||||
}
|
||||
|
||||
type Wallet interface {
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error)
|
||||
WalletHas(context.Context, address.Address) (bool, error)
|
||||
WalletList(context.Context) ([]address.Address, error)
|
||||
WalletNew(context.Context, types.KeyType) (address.Address, error) //perm:admin
|
||||
WalletHas(context.Context, address.Address) (bool, error) //perm:admin
|
||||
WalletList(context.Context) ([]address.Address, error) //perm:admin
|
||||
|
||||
WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta MsgMeta) (*crypto.Signature, error)
|
||||
WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta MsgMeta) (*crypto.Signature, error) //perm:admin
|
||||
|
||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error)
|
||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
|
||||
WalletDelete(context.Context, address.Address) error
|
||||
WalletExport(context.Context, address.Address) (*types.KeyInfo, error) //perm:admin
|
||||
WalletImport(context.Context, *types.KeyInfo) (address.Address, error) //perm:admin
|
||||
WalletDelete(context.Context, address.Address) error //perm:admin
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -43,7 +42,6 @@ type Worker interface {
|
||||
ReleaseUnsealed(ctx context.Context, sector storage.SectorRef, safeToFree []storage.Range) (storiface.CallID, error) //perm:admin
|
||||
MoveStorage(ctx context.Context, sector storage.SectorRef, types storiface.SectorFileType) (storiface.CallID, error) //perm:admin
|
||||
UnsealPiece(context.Context, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) //perm:admin
|
||||
ReadPiece(context.Context, io.Writer, storage.SectorRef, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) //perm:admin
|
||||
Fetch(context.Context, storage.SectorRef, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) //perm:admin
|
||||
|
||||
TaskDisable(ctx context.Context, tt sealtasks.TaskType) error //perm:admin
|
||||
|
||||
+379
@@ -8,6 +8,7 @@ import (
|
||||
"sort"
|
||||
|
||||
abi "github.com/filecoin-project/go-state-types/abi"
|
||||
market "github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
paych "github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@@ -738,3 +739,381 @@ func (t *SealSeed) UnmarshalCBOR(r io.Reader) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{165}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.PublishCid (cid.Cid) (struct)
|
||||
if len("PublishCid") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"PublishCid\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("PublishCid"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("PublishCid")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.PublishCid == nil {
|
||||
if _, err := w.Write(cbg.CborNull); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteCidBuf(scratch, w, *t.PublishCid); err != nil {
|
||||
return xerrors.Errorf("failed to write cid field t.PublishCid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// t.DealID (abi.DealID) (uint64)
|
||||
if len("DealID") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"DealID\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("DealID"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("DealID")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.DealID)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.DealProposal (market.DealProposal) (struct)
|
||||
if len("DealProposal") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"DealProposal\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("DealProposal"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("DealProposal")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := t.DealProposal.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.DealSchedule (api.DealSchedule) (struct)
|
||||
if len("DealSchedule") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"DealSchedule\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("DealSchedule"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("DealSchedule")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := t.DealSchedule.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.KeepUnsealed (bool) (bool)
|
||||
if len("KeepUnsealed") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"KeepUnsealed\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("KeepUnsealed"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("KeepUnsealed")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cbg.WriteBool(w, t.KeepUnsealed); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *PieceDealInfo) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = PieceDealInfo{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajMap {
|
||||
return fmt.Errorf("cbor input should be of type map")
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("PieceDealInfo: map struct too large (%d)", extra)
|
||||
}
|
||||
|
||||
var name string
|
||||
n := extra
|
||||
|
||||
for i := uint64(0); i < n; i++ {
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name = string(sval)
|
||||
}
|
||||
|
||||
switch name {
|
||||
// t.PublishCid (cid.Cid) (struct)
|
||||
case "PublishCid":
|
||||
|
||||
{
|
||||
|
||||
b, err := br.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := br.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := cbg.ReadCid(br)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to read cid field t.PublishCid: %w", err)
|
||||
}
|
||||
|
||||
t.PublishCid = &c
|
||||
}
|
||||
|
||||
}
|
||||
// t.DealID (abi.DealID) (uint64)
|
||||
case "DealID":
|
||||
|
||||
{
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.DealID = abi.DealID(extra)
|
||||
|
||||
}
|
||||
// t.DealProposal (market.DealProposal) (struct)
|
||||
case "DealProposal":
|
||||
|
||||
{
|
||||
|
||||
b, err := br.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != cbg.CborNull[0] {
|
||||
if err := br.UnreadByte(); err != nil {
|
||||
return err
|
||||
}
|
||||
t.DealProposal = new(market.DealProposal)
|
||||
if err := t.DealProposal.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.DealProposal pointer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// t.DealSchedule (api.DealSchedule) (struct)
|
||||
case "DealSchedule":
|
||||
|
||||
{
|
||||
|
||||
if err := t.DealSchedule.UnmarshalCBOR(br); err != nil {
|
||||
return xerrors.Errorf("unmarshaling t.DealSchedule: %w", err)
|
||||
}
|
||||
|
||||
}
|
||||
// t.KeepUnsealed (bool) (bool)
|
||||
case "KeepUnsealed":
|
||||
|
||||
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajOther {
|
||||
return fmt.Errorf("booleans must be major type 7")
|
||||
}
|
||||
switch extra {
|
||||
case 20:
|
||||
t.KeepUnsealed = false
|
||||
case 21:
|
||||
t.KeepUnsealed = true
|
||||
default:
|
||||
return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
|
||||
}
|
||||
|
||||
default:
|
||||
// Field doesn't exist on this type, so ignore it
|
||||
cbg.ScanForLinks(r, func(cid.Cid) {})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (t *DealSchedule) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{162}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scratch := make([]byte, 9)
|
||||
|
||||
// t.StartEpoch (abi.ChainEpoch) (int64)
|
||||
if len("StartEpoch") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"StartEpoch\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("StartEpoch"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("StartEpoch")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.StartEpoch >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.StartEpoch)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.StartEpoch-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// t.EndEpoch (abi.ChainEpoch) (int64)
|
||||
if len("EndEpoch") > cbg.MaxLength {
|
||||
return xerrors.Errorf("Value in field \"EndEpoch\" was too long")
|
||||
}
|
||||
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("EndEpoch"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.WriteString(w, string("EndEpoch")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.EndEpoch >= 0 {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.EndEpoch)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.EndEpoch-1)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *DealSchedule) UnmarshalCBOR(r io.Reader) error {
|
||||
*t = DealSchedule{}
|
||||
|
||||
br := cbg.GetPeeker(r)
|
||||
scratch := make([]byte, 8)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajMap {
|
||||
return fmt.Errorf("cbor input should be of type map")
|
||||
}
|
||||
|
||||
if extra > cbg.MaxLength {
|
||||
return fmt.Errorf("DealSchedule: map struct too large (%d)", extra)
|
||||
}
|
||||
|
||||
var name string
|
||||
n := extra
|
||||
|
||||
for i := uint64(0); i < n; i++ {
|
||||
|
||||
{
|
||||
sval, err := cbg.ReadStringBuf(br, scratch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name = string(sval)
|
||||
}
|
||||
|
||||
switch name {
|
||||
// t.StartEpoch (abi.ChainEpoch) (int64)
|
||||
case "StartEpoch":
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.StartEpoch = abi.ChainEpoch(extraI)
|
||||
}
|
||||
// t.EndEpoch (abi.ChainEpoch) (int64)
|
||||
case "EndEpoch":
|
||||
{
|
||||
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||
var extraI int64
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch maj {
|
||||
case cbg.MajUnsignedInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 positive overflow")
|
||||
}
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||
}
|
||||
|
||||
t.EndEpoch = abi.ChainEpoch(extraI)
|
||||
}
|
||||
|
||||
default:
|
||||
// Field doesn't exist on this type, so ignore it
|
||||
cbg.ScanForLinks(r, func(cid.Cid) {})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Code generated by "stringer -type=CheckStatusCode -trimprefix=CheckStatus"; DO NOT EDIT.
|
||||
|
||||
package api
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[CheckStatusMessageSerialize-1]
|
||||
_ = x[CheckStatusMessageSize-2]
|
||||
_ = x[CheckStatusMessageValidity-3]
|
||||
_ = x[CheckStatusMessageMinGas-4]
|
||||
_ = x[CheckStatusMessageMinBaseFee-5]
|
||||
_ = x[CheckStatusMessageBaseFee-6]
|
||||
_ = x[CheckStatusMessageBaseFeeLowerBound-7]
|
||||
_ = x[CheckStatusMessageBaseFeeUpperBound-8]
|
||||
_ = x[CheckStatusMessageGetStateNonce-9]
|
||||
_ = x[CheckStatusMessageNonce-10]
|
||||
_ = x[CheckStatusMessageGetStateBalance-11]
|
||||
_ = x[CheckStatusMessageBalance-12]
|
||||
}
|
||||
|
||||
const _CheckStatusCode_name = "MessageSerializeMessageSizeMessageValidityMessageMinGasMessageMinBaseFeeMessageBaseFeeMessageBaseFeeLowerBoundMessageBaseFeeUpperBoundMessageGetStateNonceMessageNonceMessageGetStateBalanceMessageBalance"
|
||||
|
||||
var _CheckStatusCode_index = [...]uint8{0, 16, 27, 42, 55, 72, 86, 110, 134, 154, 166, 188, 202}
|
||||
|
||||
func (i CheckStatusCode) String() string {
|
||||
i -= 1
|
||||
if i < 0 || i >= CheckStatusCode(len(_CheckStatusCode_index)-1) {
|
||||
return "CheckStatusCode(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||
}
|
||||
return _CheckStatusCode_name[_CheckStatusCode_index[i]:_CheckStatusCode_index[i+1]]
|
||||
}
|
||||
+28
-13
@@ -52,8 +52,30 @@ func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Heade
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func getPushUrl(addr string) (string, error) {
|
||||
pushUrl, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch pushUrl.Scheme {
|
||||
case "ws":
|
||||
pushUrl.Scheme = "http"
|
||||
case "wss":
|
||||
pushUrl.Scheme = "https"
|
||||
}
|
||||
///rpc/v0 -> /rpc/streams/v0/push
|
||||
|
||||
pushUrl.Path = path.Join(pushUrl.Path, "../streams/v0/push")
|
||||
return pushUrl.String(), nil
|
||||
}
|
||||
|
||||
// NewStorageMinerRPCV0 creates a new http jsonrpc client for miner
|
||||
func NewStorageMinerRPCV0(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (v0api.StorageMiner, jsonrpc.ClientCloser, error) {
|
||||
pushUrl, err := getPushUrl(addr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var res v0api.StorageMinerStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
[]interface{}{
|
||||
@@ -61,26 +83,19 @@ func NewStorageMinerRPCV0(ctx context.Context, addr string, requestHeader http.H
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
opts...,
|
||||
append([]jsonrpc.Option{
|
||||
rpcenc.ReaderParamEncoder(pushUrl),
|
||||
}, opts...)...,
|
||||
)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
func NewWorkerRPCV0(ctx context.Context, addr string, requestHeader http.Header) (api.Worker, jsonrpc.ClientCloser, error) {
|
||||
u, err := url.Parse(addr)
|
||||
func NewWorkerRPCV0(ctx context.Context, addr string, requestHeader http.Header) (v0api.Worker, jsonrpc.ClientCloser, error) {
|
||||
pushUrl, err := getPushUrl(addr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
switch u.Scheme {
|
||||
case "ws":
|
||||
u.Scheme = "http"
|
||||
case "wss":
|
||||
u.Scheme = "https"
|
||||
}
|
||||
///rpc/v0 -> /rpc/streams/v0/push
|
||||
|
||||
u.Path = path.Join(u.Path, "../streams/v0/push")
|
||||
|
||||
var res api.WorkerStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
@@ -88,7 +103,7 @@ func NewWorkerRPCV0(ctx context.Context, addr string, requestHeader http.Header)
|
||||
&res.Internal,
|
||||
},
|
||||
requestHeader,
|
||||
rpcenc.ReaderParamEncoder(u.String()),
|
||||
rpcenc.ReaderParamEncoder(pushUrl),
|
||||
jsonrpc.WithNoReconnect(),
|
||||
jsonrpc.WithTimeout(30*time.Second),
|
||||
)
|
||||
|
||||
@@ -13,6 +13,8 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
"github.com/filecoin-project/lotus/node/repo/importmgr"
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-filestore"
|
||||
@@ -27,7 +29,6 @@ import (
|
||||
filestore2 "github.com/filecoin-project/go-fil-markets/filestore"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
@@ -89,6 +90,7 @@ func init() {
|
||||
addExample(&pid)
|
||||
|
||||
multistoreIDExample := multistore.StoreID(50)
|
||||
storeIDExample := importmgr.ImportID(50)
|
||||
|
||||
addExample(bitfield.NewFromSet([]uint64{5}))
|
||||
addExample(abi.RegisteredSealProof_StackedDrg32GiBV1_1)
|
||||
@@ -119,6 +121,8 @@ func init() {
|
||||
addExample(time.Minute)
|
||||
addExample(datatransfer.TransferID(3))
|
||||
addExample(datatransfer.Ongoing)
|
||||
addExample(storeIDExample)
|
||||
addExample(&storeIDExample)
|
||||
addExample(multistoreIDExample)
|
||||
addExample(&multistoreIDExample)
|
||||
addExample(retrievalmarket.ClientEventDealAccepted)
|
||||
@@ -175,7 +179,7 @@ func init() {
|
||||
|
||||
// miner specific
|
||||
addExample(filestore2.Path(".lotusminer/fstmp123"))
|
||||
si := multistore.StoreID(12)
|
||||
si := uint64(12)
|
||||
addExample(&si)
|
||||
addExample(retrievalmarket.DealID(5))
|
||||
addExample(abi.ActorID(1000))
|
||||
@@ -261,6 +265,9 @@ func init() {
|
||||
},
|
||||
"methods": []interface{}{}},
|
||||
)
|
||||
|
||||
addExample(api.CheckStatusCode(0))
|
||||
addExample(map[string]interface{}{"abc": 123})
|
||||
}
|
||||
|
||||
func GetAPIType(name, pkg string) (i interface{}, t, permStruct, commonPermStruct reflect.Type) {
|
||||
|
||||
+542
-422
File diff suppressed because it is too large
Load Diff
+210
-70
@@ -4,7 +4,6 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -14,7 +13,6 @@ import (
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
@@ -27,8 +25,10 @@ import (
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/repo/importmgr"
|
||||
"github.com/filecoin-project/specs-storage/storage"
|
||||
"github.com/google/uuid"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -127,6 +127,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"`
|
||||
|
||||
ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]Message, error) `perm:"read"`
|
||||
|
||||
ChainGetNode func(p0 context.Context, p1 string) (*IpldObject, error) `perm:"read"`
|
||||
|
||||
ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]Message, error) `perm:"read"`
|
||||
@@ -179,6 +181,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ClientGetDealUpdates func(p0 context.Context) (<-chan DealInfo, error) `perm:"write"`
|
||||
|
||||
ClientGetRetrievalUpdates func(p0 context.Context) (<-chan RetrievalInfo, error) `perm:"write"`
|
||||
|
||||
ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"`
|
||||
|
||||
ClientImport func(p0 context.Context, p1 FileRef) (*ImportRes, error) `perm:"admin"`
|
||||
@@ -189,11 +193,13 @@ type FullNodeStruct struct {
|
||||
|
||||
ClientListImports func(p0 context.Context) ([]Import, error) `perm:"write"`
|
||||
|
||||
ClientListRetrievals func(p0 context.Context) ([]RetrievalInfo, error) `perm:"write"`
|
||||
|
||||
ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) `perm:"read"`
|
||||
|
||||
ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
|
||||
|
||||
ClientRemoveImport func(p0 context.Context, p1 multistore.StoreID) error `perm:"admin"`
|
||||
ClientRemoveImport func(p0 context.Context, p1 importmgr.ImportID) error `perm:"admin"`
|
||||
|
||||
ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||
|
||||
@@ -205,6 +211,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ClientStartDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
|
||||
ClientStatelessDeal func(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) `perm:"write"`
|
||||
|
||||
CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||
|
||||
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
@@ -235,6 +243,12 @@ type FullNodeStruct struct {
|
||||
|
||||
MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolCheckMessages func(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) `perm:"read"`
|
||||
|
||||
MpoolCheckPendingMessages func(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) `perm:"read"`
|
||||
|
||||
MpoolCheckReplaceMessages func(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) `perm:"read"`
|
||||
|
||||
MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"`
|
||||
|
||||
MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"`
|
||||
@@ -255,19 +269,19 @@ type FullNodeStruct struct {
|
||||
|
||||
MpoolSub func(p0 context.Context) (<-chan MpoolUpdate, error) `perm:"read"`
|
||||
|
||||
MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
@@ -277,15 +291,17 @@ type FullNodeStruct struct {
|
||||
|
||||
MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) `perm:"read"`
|
||||
|
||||
MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) `perm:"sign"`
|
||||
|
||||
NodeStatus func(p0 context.Context, p1 bool) (NodeStatus, error) `perm:"read"`
|
||||
|
||||
PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"`
|
||||
|
||||
@@ -517,6 +533,8 @@ type GatewayStruct struct {
|
||||
|
||||
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) ``
|
||||
|
||||
Version func(p0 context.Context) (APIVersion, error) ``
|
||||
|
||||
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) ``
|
||||
}
|
||||
}
|
||||
@@ -649,12 +667,22 @@ type StorageMinerStruct struct {
|
||||
|
||||
SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"`
|
||||
|
||||
SectorAddPieceToAny func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storage.Data, p3 PieceDealInfo) (SectorOffset, error) `perm:"admin"`
|
||||
|
||||
SectorCommitFlush func(p0 context.Context) ([]sealiface.CommitBatchRes, error) `perm:"admin"`
|
||||
|
||||
SectorCommitPending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"`
|
||||
|
||||
SectorGetExpectedSealDuration func(p0 context.Context) (time.Duration, error) `perm:"read"`
|
||||
|
||||
SectorGetSealDelay func(p0 context.Context) (time.Duration, error) `perm:"read"`
|
||||
|
||||
SectorMarkForUpgrade func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"`
|
||||
|
||||
SectorPreCommitFlush func(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) `perm:"admin"`
|
||||
|
||||
SectorPreCommitPending func(p0 context.Context) ([]abi.SectorID, error) `perm:"admin"`
|
||||
|
||||
SectorRemove func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"`
|
||||
|
||||
SectorSetExpectedSealDuration func(p0 context.Context, p1 time.Duration) error `perm:"write"`
|
||||
@@ -679,6 +707,8 @@ type StorageMinerStruct struct {
|
||||
|
||||
SectorsSummary func(p0 context.Context) (map[SectorState]int, error) `perm:"read"`
|
||||
|
||||
SectorsUnsealPiece func(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error `perm:"admin"`
|
||||
|
||||
SectorsUpdate func(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error `perm:"admin"`
|
||||
|
||||
StorageAddLocal func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||
@@ -721,19 +751,19 @@ type StorageMinerStub struct {
|
||||
|
||||
type WalletStruct struct {
|
||||
Internal struct {
|
||||
WalletDelete func(p0 context.Context, p1 address.Address) error ``
|
||||
WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"`
|
||||
|
||||
WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) ``
|
||||
WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
|
||||
WalletHas func(p0 context.Context, p1 address.Address) (bool, error) ``
|
||||
WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"admin"`
|
||||
|
||||
WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) ``
|
||||
WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
|
||||
WalletList func(p0 context.Context) ([]address.Address, error) ``
|
||||
WalletList func(p0 context.Context) ([]address.Address, error) `perm:"admin"`
|
||||
|
||||
WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) ``
|
||||
WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"admin"`
|
||||
|
||||
WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) ``
|
||||
WalletSign func(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) `perm:"admin"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,8 +788,6 @@ type WorkerStruct struct {
|
||||
|
||||
ProcessSession func(p0 context.Context) (uuid.UUID, error) `perm:"admin"`
|
||||
|
||||
ReadPiece func(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"`
|
||||
|
||||
ReleaseUnsealed func(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) `perm:"admin"`
|
||||
|
||||
Remove func(p0 context.Context, p1 abi.SectorID) error `perm:"admin"`
|
||||
@@ -1075,6 +1103,14 @@ func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.M
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]Message, error) {
|
||||
return s.Internal.ChainGetMessagesInTipset(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]Message, error) {
|
||||
return *new([]Message), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) {
|
||||
return s.Internal.ChainGetNode(p0, p1)
|
||||
}
|
||||
@@ -1283,6 +1319,14 @@ func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) {
|
||||
return s.Internal.ClientGetRetrievalUpdates(p0)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) {
|
||||
return s.Internal.ClientHasLocal(p0, p1)
|
||||
}
|
||||
@@ -1323,6 +1367,14 @@ func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]Import, error) {
|
||||
return *new([]Import), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) {
|
||||
return s.Internal.ClientListRetrievals(p0)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) {
|
||||
return *new([]RetrievalInfo), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) {
|
||||
return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3)
|
||||
}
|
||||
@@ -1339,11 +1391,11 @@ func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error {
|
||||
func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 importmgr.ImportID) error {
|
||||
return s.Internal.ClientRemoveImport(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error {
|
||||
func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 importmgr.ImportID) error {
|
||||
return xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
@@ -1387,6 +1439,14 @@ func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *StartDealParams)
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientStatelessDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) {
|
||||
return s.Internal.ClientStatelessDeal(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientStatelessDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error {
|
||||
return s.Internal.CreateBackup(p0, p1)
|
||||
}
|
||||
@@ -1507,6 +1567,30 @@ func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.S
|
||||
return *new([]cid.Cid), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) {
|
||||
return s.Internal.MpoolCheckMessages(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) {
|
||||
return *new([][]MessageCheckStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) {
|
||||
return s.Internal.MpoolCheckPendingMessages(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) {
|
||||
return *new([][]MessageCheckStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) {
|
||||
return s.Internal.MpoolCheckReplaceMessages(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) {
|
||||
return *new([][]MessageCheckStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error {
|
||||
return s.Internal.MpoolClear(p0, p1)
|
||||
}
|
||||
@@ -1587,60 +1671,60 @@ func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error)
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigApprove(p0, p1, p2, p3)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) {
|
||||
@@ -1675,44 +1759,52 @@ func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Add
|
||||
return *new(MsigVesting), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) {
|
||||
func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) {
|
||||
return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) {
|
||||
return *new(cid.Cid), xerrors.New("method not supported")
|
||||
func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) {
|
||||
return s.Internal.NodeStatus(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) {
|
||||
return *new(NodeStatus), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) {
|
||||
@@ -2603,6 +2695,14 @@ func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) Version(p0 context.Context) (APIVersion, error) {
|
||||
return s.Internal.Version(p0)
|
||||
}
|
||||
|
||||
func (s *GatewayStub) Version(p0 context.Context) (APIVersion, error) {
|
||||
return *new(APIVersion), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) {
|
||||
return s.Internal.WalletBalance(p0, p1)
|
||||
}
|
||||
@@ -3067,6 +3167,30 @@ func (s *StorageMinerStub) SealingSchedDiag(p0 context.Context, p1 bool) (interf
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorAddPieceToAny(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storage.Data, p3 PieceDealInfo) (SectorOffset, error) {
|
||||
return s.Internal.SectorAddPieceToAny(p0, p1, p2, p3)
|
||||
}
|
||||
|
||||
func (s *StorageMinerStub) SectorAddPieceToAny(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storage.Data, p3 PieceDealInfo) (SectorOffset, error) {
|
||||
return *new(SectorOffset), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorCommitFlush(p0 context.Context) ([]sealiface.CommitBatchRes, error) {
|
||||
return s.Internal.SectorCommitFlush(p0)
|
||||
}
|
||||
|
||||
func (s *StorageMinerStub) SectorCommitFlush(p0 context.Context) ([]sealiface.CommitBatchRes, error) {
|
||||
return *new([]sealiface.CommitBatchRes), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorCommitPending(p0 context.Context) ([]abi.SectorID, error) {
|
||||
return s.Internal.SectorCommitPending(p0)
|
||||
}
|
||||
|
||||
func (s *StorageMinerStub) SectorCommitPending(p0 context.Context) ([]abi.SectorID, error) {
|
||||
return *new([]abi.SectorID), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) {
|
||||
return s.Internal.SectorGetExpectedSealDuration(p0)
|
||||
}
|
||||
@@ -3091,6 +3215,22 @@ func (s *StorageMinerStub) SectorMarkForUpgrade(p0 context.Context, p1 abi.Secto
|
||||
return xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorPreCommitFlush(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) {
|
||||
return s.Internal.SectorPreCommitFlush(p0)
|
||||
}
|
||||
|
||||
func (s *StorageMinerStub) SectorPreCommitFlush(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) {
|
||||
return *new([]sealiface.PreCommitBatchRes), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorPreCommitPending(p0 context.Context) ([]abi.SectorID, error) {
|
||||
return s.Internal.SectorPreCommitPending(p0)
|
||||
}
|
||||
|
||||
func (s *StorageMinerStub) SectorPreCommitPending(p0 context.Context) ([]abi.SectorID, error) {
|
||||
return *new([]abi.SectorID), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error {
|
||||
return s.Internal.SectorRemove(p0, p1)
|
||||
}
|
||||
@@ -3187,6 +3327,14 @@ func (s *StorageMinerStub) SectorsSummary(p0 context.Context) (map[SectorState]i
|
||||
return *new(map[SectorState]int), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorsUnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error {
|
||||
return s.Internal.SectorsUnsealPiece(p0, p1, p2, p3, p4, p5)
|
||||
}
|
||||
|
||||
func (s *StorageMinerStub) SectorsUnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error {
|
||||
return xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error {
|
||||
return s.Internal.SectorsUpdate(p0, p1, p2)
|
||||
}
|
||||
@@ -3443,14 +3591,6 @@ func (s *WorkerStub) ProcessSession(p0 context.Context) (uuid.UUID, error) {
|
||||
return *new(uuid.UUID), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *WorkerStruct) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) {
|
||||
return s.Internal.ReadPiece(p0, p1, p2, p3, p4)
|
||||
}
|
||||
|
||||
func (s *WorkerStub) ReadPiece(p0 context.Context, p1 io.Writer, p2 storage.SectorRef, p3 storiface.UnpaddedByteIndex, p4 abi.UnpaddedPieceSize) (storiface.CallID, error) {
|
||||
return *new(storiface.CallID), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) {
|
||||
return s.Internal.ReleaseUnsealed(p0, p1, p2)
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
)
|
||||
|
||||
type BlockMiner struct {
|
||||
ctx context.Context
|
||||
t *testing.T
|
||||
miner TestStorageNode
|
||||
blocktime time.Duration
|
||||
mine int64
|
||||
nulls int64
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewBlockMiner(ctx context.Context, t *testing.T, miner TestStorageNode, blocktime time.Duration) *BlockMiner {
|
||||
return &BlockMiner{
|
||||
ctx: ctx,
|
||||
t: t,
|
||||
miner: miner,
|
||||
blocktime: blocktime,
|
||||
mine: int64(1),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (bm *BlockMiner) MineBlocks() {
|
||||
time.Sleep(time.Second)
|
||||
go func() {
|
||||
defer close(bm.done)
|
||||
for atomic.LoadInt64(&bm.mine) == 1 {
|
||||
select {
|
||||
case <-bm.ctx.Done():
|
||||
return
|
||||
case <-time.After(bm.blocktime):
|
||||
}
|
||||
|
||||
nulls := atomic.SwapInt64(&bm.nulls, 0)
|
||||
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
|
||||
InjectNulls: abi.ChainEpoch(nulls),
|
||||
Done: func(bool, abi.ChainEpoch, error) {},
|
||||
}); err != nil {
|
||||
bm.t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (bm *BlockMiner) Stop() {
|
||||
atomic.AddInt64(&bm.mine, -1)
|
||||
fmt.Println("shutting down mining")
|
||||
<-bm.done
|
||||
}
|
||||
@@ -1,554 +0,0 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
files "github.com/ipfs/go-ipfs-files"
|
||||
"github.com/ipld/go-car"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||
"github.com/filecoin-project/lotus/extern/storage-sealing/sealiface"
|
||||
"github.com/filecoin-project/lotus/markets/storageadapter"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
|
||||
ipld "github.com/ipfs/go-ipld-format"
|
||||
dag "github.com/ipfs/go-merkledag"
|
||||
dstest "github.com/ipfs/go-merkledag/test"
|
||||
unixfile "github.com/ipfs/go-unixfs/file"
|
||||
)
|
||||
|
||||
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||
s := setupOneClientOneMiner(t, b, blocktime)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
MakeDeal(t, s.ctx, 6, s.client, s.miner, carExport, fastRet, startEpoch)
|
||||
}
|
||||
|
||||
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
s := setupOneClientOneMiner(t, b, blocktime)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
MakeDeal(t, s.ctx, 6, s.client, s.miner, false, false, startEpoch)
|
||||
MakeDeal(t, s.ctx, 7, s.client, s.miner, false, false, startEpoch)
|
||||
}
|
||||
|
||||
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool, startEpoch abi.ChainEpoch) {
|
||||
res, data, err := CreateClientFile(ctx, client, rseed)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fcid := res.Root
|
||||
fmt.Println("FILE CID: ", fcid)
|
||||
|
||||
deal := startDeal(t, ctx, miner, client, fcid, fastRet, startEpoch)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
waitDealSealed(t, ctx, miner, client, deal, false)
|
||||
|
||||
// Retrieval
|
||||
info, err := client.ClientGetDealInfo(ctx, *deal)
|
||||
require.NoError(t, err)
|
||||
|
||||
testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data)
|
||||
}
|
||||
|
||||
func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api.ImportRes, []byte, error) {
|
||||
data := make([]byte, 1600)
|
||||
rand.New(rand.NewSource(int64(rseed))).Read(data)
|
||||
|
||||
dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, "sourcefile.dat")
|
||||
err = ioutil.WriteFile(path, data, 0644)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
res, err := client.ClientImport(ctx, api.FileRef{Path: path})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return res, data, nil
|
||||
}
|
||||
|
||||
func TestPublishDealsBatching(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
publishPeriod := 10 * time.Second
|
||||
maxDealsPerMsg := uint64(2)
|
||||
|
||||
// Set max deals per publish deals message to 2
|
||||
minerDef := []StorageMiner{{
|
||||
Full: 0,
|
||||
Opts: node.Override(
|
||||
new(*storageadapter.DealPublisher),
|
||||
storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{
|
||||
Period: publishPeriod,
|
||||
MaxDealsPerMsg: maxDealsPerMsg,
|
||||
})),
|
||||
Preseal: PresealGenesis,
|
||||
}}
|
||||
|
||||
// Create a connect client and miner node
|
||||
n, sn := b(t, OneFull, minerDef)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
s := connectAndStartMining(t, b, blocktime, client, miner)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
// Starts a deal and waits until it's published
|
||||
runDealTillPublish := func(rseed int) {
|
||||
res, _, err := CreateClientFile(s.ctx, s.client, rseed)
|
||||
require.NoError(t, err)
|
||||
|
||||
upds, err := client.ClientGetDealUpdates(s.ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
startDeal(t, s.ctx, s.miner, s.client, res.Root, false, startEpoch)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
for upd := range upds {
|
||||
if upd.DataRef.Root == res.Root && upd.State == storagemarket.StorageDealAwaitingPreCommit {
|
||||
done <- struct{}{}
|
||||
}
|
||||
}
|
||||
}()
|
||||
<-done
|
||||
}
|
||||
|
||||
// Run three deals in parallel
|
||||
done := make(chan struct{}, maxDealsPerMsg+1)
|
||||
for rseed := 1; rseed <= 3; rseed++ {
|
||||
rseed := rseed
|
||||
go func() {
|
||||
runDealTillPublish(rseed)
|
||||
done <- struct{}{}
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait for two of the deals to be published
|
||||
for i := 0; i < int(maxDealsPerMsg); i++ {
|
||||
<-done
|
||||
}
|
||||
|
||||
// Expect a single PublishStorageDeals message that includes the first two deals
|
||||
msgCids, err := s.client.StateListMessages(s.ctx, &api.MessageMatch{To: market.Address}, types.EmptyTSK, 1)
|
||||
require.NoError(t, err)
|
||||
count := 0
|
||||
for _, msgCid := range msgCids {
|
||||
msg, err := s.client.ChainGetMessage(s.ctx, msgCid)
|
||||
require.NoError(t, err)
|
||||
|
||||
if msg.Method == market.Methods.PublishStorageDeals {
|
||||
count++
|
||||
var pubDealsParams market2.PublishStorageDealsParams
|
||||
err = pubDealsParams.UnmarshalCBOR(bytes.NewReader(msg.Params))
|
||||
require.NoError(t, err)
|
||||
require.Len(t, pubDealsParams.Deals, int(maxDealsPerMsg))
|
||||
}
|
||||
}
|
||||
require.Equal(t, 1, count)
|
||||
|
||||
// The third deal should be published once the publish period expires.
|
||||
// Allow a little padding as it takes a moment for the state change to
|
||||
// be noticed by the client.
|
||||
padding := 10 * time.Second
|
||||
select {
|
||||
case <-time.After(publishPeriod + padding):
|
||||
require.Fail(t, "Expected 3rd deal to be published once publish period elapsed")
|
||||
case <-done: // Success
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchDealInput(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
publishPeriod := 10 * time.Second
|
||||
maxDealsPerMsg := uint64(4)
|
||||
|
||||
// Set max deals per publish deals message to maxDealsPerMsg
|
||||
minerDef := []StorageMiner{{
|
||||
Full: 0,
|
||||
Opts: node.Options(
|
||||
node.Override(
|
||||
new(*storageadapter.DealPublisher),
|
||||
storageadapter.NewDealPublisher(nil, storageadapter.PublishMsgConfig{
|
||||
Period: publishPeriod,
|
||||
MaxDealsPerMsg: maxDealsPerMsg,
|
||||
})),
|
||||
node.Override(new(dtypes.GetSealingConfigFunc), func() (dtypes.GetSealingConfigFunc, error) {
|
||||
return func() (sealiface.Config, error) {
|
||||
return sealiface.Config{
|
||||
MaxWaitDealsSectors: 1,
|
||||
MaxSealingSectors: 1,
|
||||
MaxSealingSectorsForDeals: 2,
|
||||
AlwaysKeepUnsealedCopy: true,
|
||||
}, nil
|
||||
}, nil
|
||||
}),
|
||||
),
|
||||
Preseal: PresealGenesis,
|
||||
}}
|
||||
|
||||
// Create a connect client and miner node
|
||||
n, sn := b(t, OneFull, minerDef)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
s := connectAndStartMining(t, b, blocktime, client, miner)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
// Starts a deal and waits until it's published
|
||||
runDealTillSeal := func(rseed int) {
|
||||
res, _, err := CreateClientFile(s.ctx, s.client, rseed)
|
||||
require.NoError(t, err)
|
||||
|
||||
dc := startDeal(t, s.ctx, s.miner, s.client, res.Root, false, startEpoch)
|
||||
waitDealSealed(t, s.ctx, s.miner, s.client, dc, false)
|
||||
}
|
||||
|
||||
// Run maxDealsPerMsg+1 deals in parallel
|
||||
done := make(chan struct{}, maxDealsPerMsg+1)
|
||||
for rseed := 1; rseed <= int(maxDealsPerMsg+1); rseed++ {
|
||||
rseed := rseed
|
||||
go func() {
|
||||
runDealTillSeal(rseed)
|
||||
done <- struct{}{}
|
||||
}()
|
||||
}
|
||||
|
||||
// Wait for maxDealsPerMsg of the deals to be published
|
||||
for i := 0; i < int(maxDealsPerMsg); i++ {
|
||||
<-done
|
||||
}
|
||||
|
||||
sl, err := sn[0].SectorsList(s.ctx)
|
||||
require.NoError(t, err)
|
||||
require.GreaterOrEqual(t, len(sl), 4)
|
||||
require.LessOrEqual(t, len(sl), 5)
|
||||
}
|
||||
|
||||
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
s := setupOneClientOneMiner(t, b, blocktime)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
data := make([]byte, 1600)
|
||||
rand.New(rand.NewSource(int64(8))).Read(data)
|
||||
|
||||
r := bytes.NewReader(data)
|
||||
fcid, err := s.client.ClientImportLocal(s.ctx, r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("FILE CID: ", fcid)
|
||||
|
||||
deal := startDeal(t, s.ctx, s.miner, s.client, fcid, true, startEpoch)
|
||||
|
||||
waitDealPublished(t, s.ctx, s.miner, deal)
|
||||
fmt.Println("deal published, retrieving")
|
||||
// Retrieval
|
||||
info, err := s.client.ClientGetDealInfo(s.ctx, *deal)
|
||||
require.NoError(t, err)
|
||||
|
||||
testRetrieval(t, s.ctx, s.client, fcid, &info.PieceCID, false, data)
|
||||
}
|
||||
|
||||
func TestSecondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
||||
s := setupOneClientOneMiner(t, b, blocktime)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
{
|
||||
data1 := make([]byte, 800)
|
||||
rand.New(rand.NewSource(int64(3))).Read(data1)
|
||||
r := bytes.NewReader(data1)
|
||||
|
||||
fcid1, err := s.client.ClientImportLocal(s.ctx, r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data2 := make([]byte, 800)
|
||||
rand.New(rand.NewSource(int64(9))).Read(data2)
|
||||
r2 := bytes.NewReader(data2)
|
||||
|
||||
fcid2, err := s.client.ClientImportLocal(s.ctx, r2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
deal1 := startDeal(t, s.ctx, s.miner, s.client, fcid1, true, 0)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
waitDealSealed(t, s.ctx, s.miner, s.client, deal1, true)
|
||||
|
||||
deal2 := startDeal(t, s.ctx, s.miner, s.client, fcid2, true, 0)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
waitDealSealed(t, s.ctx, s.miner, s.client, deal2, false)
|
||||
|
||||
// Retrieval
|
||||
info, err := s.client.ClientGetDealInfo(s.ctx, *deal2)
|
||||
require.NoError(t, err)
|
||||
|
||||
rf, _ := s.miner.SectorsRefs(s.ctx)
|
||||
fmt.Printf("refs: %+v\n", rf)
|
||||
|
||||
testRetrieval(t, s.ctx, s.client, fcid2, &info.PieceCID, false, data2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestZeroPricePerByteRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, startEpoch abi.ChainEpoch) {
|
||||
s := setupOneClientOneMiner(t, b, blocktime)
|
||||
defer s.blockMiner.Stop()
|
||||
|
||||
// Set price-per-byte to zero
|
||||
ask, err := s.miner.MarketGetRetrievalAsk(s.ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
ask.PricePerByte = abi.NewTokenAmount(0)
|
||||
err = s.miner.MarketSetRetrievalAsk(s.ctx, ask)
|
||||
require.NoError(t, err)
|
||||
|
||||
MakeDeal(t, s.ctx, 6, s.client, s.miner, false, false, startEpoch)
|
||||
}
|
||||
|
||||
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid {
|
||||
maddr, err := miner.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
addr, err := client.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
deal, err := client.ClientStartDeal(ctx, &api.StartDealParams{
|
||||
Data: &storagemarket.DataRef{
|
||||
TransferType: storagemarket.TTGraphsync,
|
||||
Root: fcid,
|
||||
},
|
||||
Wallet: addr,
|
||||
Miner: maddr,
|
||||
EpochPrice: types.NewInt(1000000),
|
||||
DealStartEpoch: startEpoch,
|
||||
MinBlocksDuration: uint64(build.MinDealDuration),
|
||||
FastRetrieval: fastRet,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
return deal
|
||||
}
|
||||
|
||||
func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal bool) {
|
||||
loop:
|
||||
for {
|
||||
di, err := client.ClientGetDealInfo(ctx, *deal)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch di.State {
|
||||
case storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing:
|
||||
if noseal {
|
||||
return
|
||||
}
|
||||
startSealingWaiting(t, ctx, miner)
|
||||
case storagemarket.StorageDealProposalRejected:
|
||||
t.Fatal("deal rejected")
|
||||
case storagemarket.StorageDealFailing:
|
||||
t.Fatal("deal failed")
|
||||
case storagemarket.StorageDealError:
|
||||
t.Fatal("deal errored", di.Message)
|
||||
case storagemarket.StorageDealActive:
|
||||
fmt.Println("COMPLETE", di)
|
||||
break loop
|
||||
}
|
||||
fmt.Println("Deal state: ", storagemarket.DealStates[di.State])
|
||||
time.Sleep(time.Second / 2)
|
||||
}
|
||||
}
|
||||
|
||||
func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode, deal *cid.Cid) {
|
||||
subCtx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
updates, err := miner.MarketGetDealUpdates(subCtx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
t.Fatal("context timeout")
|
||||
case di := <-updates:
|
||||
if deal.Equals(di.ProposalCid) {
|
||||
switch di.State {
|
||||
case storagemarket.StorageDealProposalRejected:
|
||||
t.Fatal("deal rejected")
|
||||
case storagemarket.StorageDealFailing:
|
||||
t.Fatal("deal failed")
|
||||
case storagemarket.StorageDealError:
|
||||
t.Fatal("deal errored", di.Message)
|
||||
case storagemarket.StorageDealFinalizing, storagemarket.StorageDealAwaitingPreCommit, storagemarket.StorageDealSealing, storagemarket.StorageDealActive:
|
||||
fmt.Println("COMPLETE", di)
|
||||
return
|
||||
}
|
||||
fmt.Println("Deal state: ", storagemarket.DealStates[di.State])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func startSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNode) {
|
||||
snums, err := miner.SectorsList(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, snum := range snums {
|
||||
si, err := miner.SectorsStatus(ctx, snum, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Logf("Sector state: %s", si.State)
|
||||
if si.State == api.SectorState(sealing.WaitDeals) {
|
||||
require.NoError(t, miner.SectorStartSealing(ctx, snum))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) {
|
||||
offers, err := client.ClientFindData(ctx, fcid, piece)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(offers) < 1 {
|
||||
t.Fatal("no offers")
|
||||
}
|
||||
|
||||
rpath, err := ioutil.TempDir("", "lotus-retrieve-test-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(rpath) //nolint:errcheck
|
||||
|
||||
caddr, err := client.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ref := &api.FileRef{
|
||||
Path: filepath.Join(rpath, "ret"),
|
||||
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("retrieval failed: %s", update.Err)
|
||||
}
|
||||
}
|
||||
|
||||
rdata, err := ioutil.ReadFile(filepath.Join(rpath, "ret"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if carExport {
|
||||
rdata = extractCarData(t, ctx, rdata, rpath)
|
||||
}
|
||||
|
||||
if !bytes.Equal(rdata, data) {
|
||||
t.Fatal("wrong data retrieved")
|
||||
}
|
||||
}
|
||||
|
||||
func extractCarData(t *testing.T, ctx context.Context, rdata []byte, rpath string) []byte {
|
||||
bserv := dstest.Bserv()
|
||||
ch, err := car.LoadCar(bserv.Blockstore(), bytes.NewReader(rdata))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b, err := bserv.GetBlock(ctx, ch.Roots[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nd, err := ipld.Decode(b)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dserv := dag.NewDAGService(bserv)
|
||||
fil, err := unixfile.NewUnixfsFile(ctx, dserv, nd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
outPath := filepath.Join(rpath, "retLoadedCAR")
|
||||
if err := files.WriteTo(fil, outPath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rdata, err = ioutil.ReadFile(outPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return rdata
|
||||
}
|
||||
|
||||
type dealsScaffold struct {
|
||||
ctx context.Context
|
||||
client *impl.FullNodeAPI
|
||||
miner TestStorageNode
|
||||
blockMiner *BlockMiner
|
||||
}
|
||||
|
||||
func setupOneClientOneMiner(t *testing.T, b APIBuilder, blocktime time.Duration) *dealsScaffold {
|
||||
n, sn := b(t, OneFull, OneMiner)
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
miner := sn[0]
|
||||
return connectAndStartMining(t, b, blocktime, client, miner)
|
||||
}
|
||||
|
||||
func connectAndStartMining(t *testing.T, b APIBuilder, blocktime time.Duration, client *impl.FullNodeAPI, miner TestStorageNode) *dealsScaffold {
|
||||
ctx := context.Background()
|
||||
addrinfo, err := client.NetAddrsListen(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := miner.NetConnect(ctx, addrinfo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
|
||||
blockMiner := NewBlockMiner(ctx, t, miner, blocktime)
|
||||
blockMiner.MineBlocks()
|
||||
|
||||
return &dealsScaffold{
|
||||
ctx: ctx,
|
||||
client: client,
|
||||
miner: miner,
|
||||
blockMiner: blockMiner,
|
||||
}
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node/impl"
|
||||
)
|
||||
|
||||
//nolint:deadcode,varcheck
|
||||
var log = logging.Logger("apitest")
|
||||
|
||||
func (ts *testSuite) testMining(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
newHeads, err := api.ChainNotify(ctx)
|
||||
require.NoError(t, err)
|
||||
initHead := (<-newHeads)[0]
|
||||
baseHeight := initHead.Val.Height()
|
||||
|
||||
h1, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(h1.Height()), int64(baseHeight))
|
||||
|
||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
<-newHeads
|
||||
|
||||
h2, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
|
||||
}
|
||||
|
||||
func (ts *testSuite) testMiningReal(t *testing.T) {
|
||||
build.InsecurePoStValidation = false
|
||||
defer func() {
|
||||
build.InsecurePoStValidation = true
|
||||
}()
|
||||
|
||||
ctx := context.Background()
|
||||
apis, sn := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
newHeads, err := api.ChainNotify(ctx)
|
||||
require.NoError(t, err)
|
||||
at := (<-newHeads)[0].Val.Height()
|
||||
|
||||
h1, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(at), int64(h1.Height()))
|
||||
|
||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
<-newHeads
|
||||
|
||||
h2, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
|
||||
|
||||
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
<-newHeads
|
||||
|
||||
h3, err := api.ChainHead(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, int64(h3.Height()), int64(h2.Height()))
|
||||
}
|
||||
|
||||
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
|
||||
// test making a deal with a fresh miner, and see if it starts to mine
|
||||
|
||||
ctx := context.Background()
|
||||
n, sn := b(t, OneFull, []StorageMiner{
|
||||
{Full: 0, Preseal: PresealGenesis},
|
||||
{Full: 0, Preseal: 0}, // TODO: Add support for miners on non-first full node
|
||||
})
|
||||
client := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
provider := sn[1]
|
||||
genesisMiner := sn[0]
|
||||
|
||||
addrinfo, err := client.NetAddrsListen(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := provider.NetConnect(ctx, addrinfo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := genesisMiner.NetConnect(ctx, addrinfo); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
data := make([]byte, 600)
|
||||
rand.New(rand.NewSource(5)).Read(data)
|
||||
|
||||
r := bytes.NewReader(data)
|
||||
fcid, err := client.ClientImportLocal(ctx, r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("FILE CID: ", fcid)
|
||||
|
||||
var mine int32 = 1
|
||||
done := make(chan struct{})
|
||||
minedTwo := make(chan struct{})
|
||||
|
||||
m2addr, err := sn[1].ActorAddress(context.TODO())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer close(done)
|
||||
|
||||
complChan := minedTwo
|
||||
for atomic.LoadInt32(&mine) != 0 {
|
||||
wait := make(chan int)
|
||||
mdone := func(mined bool, _ abi.ChainEpoch, err error) {
|
||||
n := 0
|
||||
if mined {
|
||||
n = 1
|
||||
}
|
||||
wait <- n
|
||||
}
|
||||
|
||||
if err := sn[0].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := sn[1].MineOne(ctx, miner.MineReq{Done: mdone}); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expect := <-wait
|
||||
expect += <-wait
|
||||
|
||||
time.Sleep(blocktime)
|
||||
if expect == 0 {
|
||||
// null block
|
||||
continue
|
||||
}
|
||||
|
||||
var nodeOneMined bool
|
||||
for _, node := range sn {
|
||||
mb, err := node.MiningBase(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, b := range mb.Blocks() {
|
||||
if b.Miner == m2addr {
|
||||
nodeOneMined = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if nodeOneMined && complChan != nil {
|
||||
close(complChan)
|
||||
complChan = nil
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
deal := startDeal(t, ctx, provider, client, fcid, false, 0)
|
||||
|
||||
// TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this
|
||||
time.Sleep(time.Second)
|
||||
|
||||
waitDealSealed(t, ctx, provider, client, deal, false)
|
||||
|
||||
<-minedTwo
|
||||
|
||||
atomic.StoreInt32(&mine, 0)
|
||||
fmt.Println("shutting down mining")
|
||||
<-done
|
||||
}
|
||||
|
||||
func (ts *testSuite) testNonGenesisMiner(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
n, sn := ts.makeNodes(t, []FullNodeOpts{
|
||||
FullNodeWithActorsV4At(-1),
|
||||
}, []StorageMiner{
|
||||
{Full: 0, Preseal: PresealGenesis},
|
||||
})
|
||||
|
||||
full, ok := n[0].FullNode.(*impl.FullNodeAPI)
|
||||
if !ok {
|
||||
t.Skip("not testing with a full node")
|
||||
return
|
||||
}
|
||||
genesisMiner := sn[0]
|
||||
|
||||
bm := NewBlockMiner(ctx, t, genesisMiner, 4*time.Millisecond)
|
||||
bm.MineBlocks()
|
||||
t.Cleanup(bm.Stop)
|
||||
|
||||
gaa, err := genesisMiner.ActorAddress(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
gmi, err := full.StateMinerInfo(ctx, gaa, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
testm := n[0].Stb(ctx, t, TestSpt, gmi.Owner)
|
||||
|
||||
ta, err := testm.ActorAddress(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
tid, err := address.IDFromAddress(ta)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(1001), tid)
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/v1api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logging.SetAllLoggers(logging.LevelInfo)
|
||||
err := os.Setenv("BELLMAN_NO_GPU", "1")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
|
||||
}
|
||||
build.InsecurePoStValidation = true
|
||||
}
|
||||
|
||||
type StorageBuilder func(context.Context, *testing.T, abi.RegisteredSealProof, address.Address) TestStorageNode
|
||||
|
||||
type TestNode struct {
|
||||
v1api.FullNode
|
||||
// ListenAddr is the address on which an API server is listening, if an
|
||||
// API server is created for this Node
|
||||
ListenAddr multiaddr.Multiaddr
|
||||
|
||||
Stb StorageBuilder
|
||||
}
|
||||
|
||||
type TestStorageNode struct {
|
||||
lapi.StorageMiner
|
||||
// ListenAddr is the address on which an API server is listening, if an
|
||||
// API server is created for this Node
|
||||
ListenAddr multiaddr.Multiaddr
|
||||
|
||||
MineOne func(context.Context, miner.MineReq) error
|
||||
Stop func(context.Context) error
|
||||
}
|
||||
|
||||
var PresealGenesis = -1
|
||||
|
||||
const GenesisPreseals = 2
|
||||
|
||||
const TestSpt = abi.RegisteredSealProof_StackedDrg2KiBV1_1
|
||||
|
||||
// Options for setting up a mock storage miner
|
||||
type StorageMiner struct {
|
||||
Full int
|
||||
Opts node.Option
|
||||
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, full []FullNodeOpts, storage []StorageMiner) ([]TestNode, []TestStorageNode)
|
||||
type testSuite struct {
|
||||
makeNodes APIBuilder
|
||||
}
|
||||
|
||||
// TestApis is the entry point to API test suite
|
||||
func TestApis(t *testing.T, b APIBuilder) {
|
||||
ts := testSuite{
|
||||
makeNodes: b,
|
||||
}
|
||||
|
||||
t.Run("version", ts.testVersion)
|
||||
t.Run("id", ts.testID)
|
||||
t.Run("testConnectTwo", ts.testConnectTwo)
|
||||
t.Run("testMining", ts.testMining)
|
||||
t.Run("testMiningReal", ts.testMiningReal)
|
||||
t.Run("testSearchMsg", ts.testSearchMsg)
|
||||
t.Run("testNonGenesisMiner", ts.testNonGenesisMiner)
|
||||
}
|
||||
|
||||
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 FullNodeWithActorsV4At = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
|
||||
if upgradeHeight == -1 {
|
||||
upgradeHeight = 3
|
||||
}
|
||||
|
||||
return FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
// prepare for upgrade.
|
||||
Network: network.Version9,
|
||||
Height: 1,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}, {
|
||||
Network: network.Version10,
|
||||
Height: 2,
|
||||
Migration: stmgr.UpgradeActorsV3,
|
||||
}, {
|
||||
Network: network.Version12,
|
||||
Height: upgradeHeight,
|
||||
Migration: stmgr.UpgradeActorsV4,
|
||||
}})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var FullNodeWithSDRAt = func(calico, persian abi.ChainEpoch) FullNodeOpts {
|
||||
return FullNodeOpts{
|
||||
Opts: func(nodes []TestNode) node.Option {
|
||||
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
|
||||
Network: network.Version6,
|
||||
Height: 1,
|
||||
Migration: stmgr.UpgradeActorsV2,
|
||||
}, {
|
||||
Network: network.Version7,
|
||||
Height: calico,
|
||||
Migration: stmgr.UpgradeCalico,
|
||||
}, {
|
||||
Network: network.Version8,
|
||||
Height: persian,
|
||||
}})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var MineNext = miner.MineReq{
|
||||
InjectNulls: 0,
|
||||
Done: func(bool, abi.ChainEpoch, error) {},
|
||||
}
|
||||
|
||||
func (ts *testSuite) testVersion(t *testing.T) {
|
||||
lapi.RunningNodeType = lapi.NodeFull
|
||||
t.Cleanup(func() {
|
||||
lapi.RunningNodeType = lapi.NodeUnknown
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||
napi := apis[0]
|
||||
|
||||
v, err := napi.Version(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
versions := strings.Split(v.Version, "+")
|
||||
if len(versions) <= 0 {
|
||||
t.Fatal("empty version")
|
||||
}
|
||||
require.Equal(t, versions[0], build.BuildVersion)
|
||||
}
|
||||
|
||||
func (ts *testSuite) testSearchMsg(t *testing.T) {
|
||||
apis, miners := ts.makeNodes(t, OneFull, OneMiner)
|
||||
|
||||
api := apis[0]
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
senderAddr, err := api.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
From: senderAddr,
|
||||
To: senderAddr,
|
||||
Value: big.Zero(),
|
||||
}
|
||||
bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond)
|
||||
bm.MineBlocks()
|
||||
defer bm.Stop()
|
||||
|
||||
sm, err := api.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := api.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Receipt.ExitCode != 0 {
|
||||
t.Fatal("did not successfully send message")
|
||||
}
|
||||
|
||||
searchRes, err := api.StateSearchMsg(ctx, types.EmptyTSK, sm.Cid(), lapi.LookbackNoLimit, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if searchRes.TipSet != res.TipSet {
|
||||
t.Fatalf("search ts: %s, different from wait ts: %s", searchRes.TipSet, res.TipSet)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (ts *testSuite) testID(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
|
||||
api := apis[0]
|
||||
|
||||
id, err := api.ID(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Regexp(t, "^12", id.Pretty())
|
||||
}
|
||||
|
||||
func (ts *testSuite) testConnectTwo(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
apis, _ := ts.makeNodes(t, TwoFull, OneMiner)
|
||||
|
||||
p, err := apis[0].NetPeers(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(p) != 0 {
|
||||
t.Error("Node 0 has a peer")
|
||||
}
|
||||
|
||||
p, err = apis[1].NetPeers(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(p) != 0 {
|
||||
t.Error("Node 1 has a peer")
|
||||
}
|
||||
|
||||
addrs, err := apis[1].NetAddrsListen(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := apis[0].NetConnect(ctx, addrs); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
p, err = apis[0].NetPeers(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(p) != 1 {
|
||||
t.Error("Node 0 doesn't have 1 peer")
|
||||
}
|
||||
|
||||
p, err = apis[1].NetPeers(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(p) != 1 {
|
||||
t.Error("Node 0 doesn't have 1 peer")
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
lapi "github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/miner"
|
||||
)
|
||||
|
||||
func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) {
|
||||
senderAddr, err := sender.WalletDefaultAddress(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
From: senderAddr,
|
||||
To: addr,
|
||||
Value: amount,
|
||||
}
|
||||
|
||||
sm, err := sender.MpoolPushMessage(ctx, msg, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1, lapi.LookbackNoLimit, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.Receipt.ExitCode != 0 {
|
||||
t.Fatal("did not successfully send money")
|
||||
}
|
||||
}
|
||||
|
||||
func MineUntilBlock(ctx context.Context, t *testing.T, fn TestNode, sn TestStorageNode, cb func(abi.ChainEpoch)) {
|
||||
for i := 0; i < 1000; i++ {
|
||||
var success bool
|
||||
var err error
|
||||
var epoch abi.ChainEpoch
|
||||
wait := make(chan struct{})
|
||||
mineErr := sn.MineOne(ctx, miner.MineReq{
|
||||
Done: func(win bool, ep abi.ChainEpoch, e error) {
|
||||
success = win
|
||||
err = e
|
||||
epoch = ep
|
||||
wait <- struct{}{}
|
||||
},
|
||||
})
|
||||
if mineErr != nil {
|
||||
t.Fatal(mineErr)
|
||||
}
|
||||
<-wait
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if success {
|
||||
// Wait until it shows up on the given full nodes ChainHead
|
||||
nloops := 50
|
||||
for i := 0; i < nloops; i++ {
|
||||
ts, err := fn.ChainHead(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ts.Height() == epoch {
|
||||
break
|
||||
}
|
||||
if i == nloops-1 {
|
||||
t.Fatal("block never managed to sync to node")
|
||||
}
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
}
|
||||
|
||||
if cb != nil {
|
||||
cb(epoch)
|
||||
}
|
||||
return
|
||||
}
|
||||
t.Log("did not mine block, trying again", i)
|
||||
}
|
||||
t.Fatal("failed to mine 1000 times in a row...")
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,9 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -116,3 +119,79 @@ type ConnMgrInfo struct {
|
||||
Tags map[string]int
|
||||
Conns map[string]time.Time
|
||||
}
|
||||
|
||||
type NodeStatus struct {
|
||||
SyncStatus NodeSyncStatus
|
||||
PeerStatus NodePeerStatus
|
||||
ChainStatus NodeChainStatus
|
||||
}
|
||||
|
||||
type NodeSyncStatus struct {
|
||||
Epoch uint64
|
||||
Behind uint64
|
||||
}
|
||||
|
||||
type NodePeerStatus struct {
|
||||
PeersToPublishMsgs int
|
||||
PeersToPublishBlocks int
|
||||
}
|
||||
|
||||
type NodeChainStatus struct {
|
||||
BlocksPerTipsetLast100 float64
|
||||
BlocksPerTipsetLastFinality float64
|
||||
}
|
||||
|
||||
type CheckStatusCode int
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer -type=CheckStatusCode -trimprefix=CheckStatus
|
||||
const (
|
||||
_ CheckStatusCode = iota
|
||||
// Message Checks
|
||||
CheckStatusMessageSerialize
|
||||
CheckStatusMessageSize
|
||||
CheckStatusMessageValidity
|
||||
CheckStatusMessageMinGas
|
||||
CheckStatusMessageMinBaseFee
|
||||
CheckStatusMessageBaseFee
|
||||
CheckStatusMessageBaseFeeLowerBound
|
||||
CheckStatusMessageBaseFeeUpperBound
|
||||
CheckStatusMessageGetStateNonce
|
||||
CheckStatusMessageNonce
|
||||
CheckStatusMessageGetStateBalance
|
||||
CheckStatusMessageBalance
|
||||
)
|
||||
|
||||
type CheckStatus struct {
|
||||
Code CheckStatusCode
|
||||
OK bool
|
||||
Err string
|
||||
Hint map[string]interface{}
|
||||
}
|
||||
|
||||
type MessageCheckStatus struct {
|
||||
Cid cid.Cid
|
||||
CheckStatus
|
||||
}
|
||||
|
||||
type MessagePrototype struct {
|
||||
Message types.Message
|
||||
ValidNonce bool
|
||||
}
|
||||
|
||||
type RetrievalInfo struct {
|
||||
PayloadCID cid.Cid
|
||||
ID retrievalmarket.DealID
|
||||
PieceCID *cid.Cid
|
||||
PricePerByte abi.TokenAmount
|
||||
UnsealPrice abi.TokenAmount
|
||||
|
||||
Status retrievalmarket.DealStatus
|
||||
Message string // more information about deal state, particularly errors
|
||||
Provider peer.ID
|
||||
BytesReceived uint64
|
||||
BytesPaidFor uint64
|
||||
TotalPaid abi.TokenAmount
|
||||
|
||||
TransferChannelID *datatransfer.ChannelID
|
||||
DataTransfer *DataTransferChannel
|
||||
}
|
||||
|
||||
+12
-3
@@ -8,10 +8,10 @@ import (
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/lotus/node/repo/importmgr"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
||||
@@ -92,6 +92,9 @@ type FullNode interface {
|
||||
// specified block.
|
||||
ChainGetParentMessages(ctx context.Context, blockCid cid.Cid) ([]api.Message, error) //perm:read
|
||||
|
||||
// ChainGetMessagesInTipset returns message stores in current tipset
|
||||
ChainGetMessagesInTipset(ctx context.Context, tsk types.TipSetKey) ([]api.Message, error) //perm:read
|
||||
|
||||
// ChainGetTipSetByHeight looks back for a tipset at the specified epoch.
|
||||
// If there are no blocks at the specified epoch, a tipset at an earlier epoch
|
||||
// will be returned.
|
||||
@@ -301,9 +304,11 @@ type FullNode interface {
|
||||
// ClientImport imports file under the specified path into filestore.
|
||||
ClientImport(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) //perm:admin
|
||||
// ClientRemoveImport removes file import
|
||||
ClientRemoveImport(ctx context.Context, importID multistore.StoreID) error //perm:admin
|
||||
ClientRemoveImport(ctx context.Context, importID importmgr.ImportID) error //perm:admin
|
||||
// ClientStartDeal proposes a deal with a miner.
|
||||
ClientStartDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) //perm:admin
|
||||
// ClientStatelessDeal fire-and-forget-proposes an offline deal to a miner without subsequent tracking.
|
||||
ClientStatelessDeal(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) //perm:write
|
||||
// ClientGetDealInfo returns the latest information about a given deal.
|
||||
ClientGetDealInfo(context.Context, cid.Cid) (*api.DealInfo, error) //perm:read
|
||||
// ClientListDeals returns information about the deals made by the local client.
|
||||
@@ -324,6 +329,10 @@ type FullNode interface {
|
||||
// of status updates.
|
||||
ClientRetrieveWithEvents(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) //perm:admin
|
||||
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
|
||||
// ClientListRetrievals returns information about retrievals made by the local client
|
||||
ClientListRetrievals(ctx context.Context) ([]api.RetrievalInfo, error) //perm:write
|
||||
// ClientGetRetrievalUpdates returns status of updated retrieval deals
|
||||
ClientGetRetrievalUpdates(ctx context.Context) (<-chan api.RetrievalInfo, error) //perm:write
|
||||
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) //perm:read
|
||||
// ClientCalcCommP calculates the CommP and data size of the specified CID
|
||||
ClientDealPieceCID(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) //perm:read
|
||||
@@ -623,7 +632,7 @@ type FullNode interface {
|
||||
// proposal. This method of approval can be used to ensure you only approve
|
||||
// exactly the transaction you think you are.
|
||||
// It takes the following params: <multisig address>, <proposed message ID>, <proposer address>, <recipient address>, <value to transfer>,
|
||||
// <sender address of the approve msg>, <method to call in the proposed message>, <params to include in the proposed message>
|
||||
// <sender address of the approve msg>, <method to call in the approved message>, <params to include in the proposed message>
|
||||
MsigApproveTxnHash(context.Context, address.Address, uint64, address.Address, address.Address, types.BigInt, address.Address, uint64, []byte) (cid.Cid, error) //perm:sign
|
||||
|
||||
// MsigCancel cancels a previously-proposed multisig message
|
||||
|
||||
@@ -63,6 +63,7 @@ type Gateway interface {
|
||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
|
||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||||
Version(context.Context) (api.APIVersion, error)
|
||||
}
|
||||
|
||||
var _ Gateway = *new(FullNode)
|
||||
|
||||
+54
-4
@@ -10,7 +10,6 @@ import (
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-multistore"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
@@ -22,6 +21,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
marketevents "github.com/filecoin-project/lotus/markets/loggers"
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/repo/importmgr"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -45,6 +45,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"`
|
||||
|
||||
ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) `perm:"read"`
|
||||
|
||||
ChainGetNode func(p0 context.Context, p1 string) (*api.IpldObject, error) `perm:"read"`
|
||||
|
||||
ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||
@@ -97,6 +99,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"`
|
||||
|
||||
ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"`
|
||||
|
||||
ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"`
|
||||
|
||||
ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"`
|
||||
@@ -107,11 +111,13 @@ type FullNodeStruct struct {
|
||||
|
||||
ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"`
|
||||
|
||||
ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, error) `perm:"write"`
|
||||
|
||||
ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"`
|
||||
|
||||
ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
|
||||
|
||||
ClientRemoveImport func(p0 context.Context, p1 multistore.StoreID) error `perm:"admin"`
|
||||
ClientRemoveImport func(p0 context.Context, p1 importmgr.ImportID) error `perm:"admin"`
|
||||
|
||||
ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||
|
||||
@@ -123,6 +129,8 @@ type FullNodeStruct struct {
|
||||
|
||||
ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
|
||||
ClientStatelessDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"write"`
|
||||
|
||||
CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||
|
||||
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
@@ -443,6 +451,8 @@ type GatewayStruct struct {
|
||||
|
||||
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) ``
|
||||
|
||||
Version func(p0 context.Context) (api.APIVersion, error) ``
|
||||
|
||||
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) ``
|
||||
}
|
||||
}
|
||||
@@ -506,6 +516,14 @@ func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.M
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) {
|
||||
return s.Internal.ChainGetMessagesInTipset(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) {
|
||||
return *new([]api.Message), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) {
|
||||
return s.Internal.ChainGetNode(p0, p1)
|
||||
}
|
||||
@@ -714,6 +732,14 @@ func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan api.Deal
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) {
|
||||
return s.Internal.ClientGetRetrievalUpdates(p0)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) {
|
||||
return s.Internal.ClientHasLocal(p0, p1)
|
||||
}
|
||||
@@ -754,6 +780,14 @@ func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]api.Import, erro
|
||||
return *new([]api.Import), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) {
|
||||
return s.Internal.ClientListRetrievals(p0)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) {
|
||||
return *new([]api.RetrievalInfo), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) {
|
||||
return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3)
|
||||
}
|
||||
@@ -770,11 +804,11 @@ func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error {
|
||||
func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 importmgr.ImportID) error {
|
||||
return s.Internal.ClientRemoveImport(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error {
|
||||
func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 importmgr.ImportID) error {
|
||||
return xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
@@ -818,6 +852,14 @@ func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *api.StartDealPara
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) ClientStatelessDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) {
|
||||
return s.Internal.ClientStatelessDeal(p0, p1)
|
||||
}
|
||||
|
||||
func (s *FullNodeStub) ClientStatelessDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) {
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error {
|
||||
return s.Internal.CreateBackup(p0, p1)
|
||||
}
|
||||
@@ -2066,6 +2108,14 @@ func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*
|
||||
return nil, xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) Version(p0 context.Context) (api.APIVersion, error) {
|
||||
return s.Internal.Version(p0)
|
||||
}
|
||||
|
||||
func (s *GatewayStub) Version(p0 context.Context) (api.APIVersion, error) {
|
||||
return *new(api.APIVersion), xerrors.New("method not supported")
|
||||
}
|
||||
|
||||
func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) {
|
||||
return s.Internal.WalletBalance(p0, p1)
|
||||
}
|
||||
|
||||
+464
-404
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,9 @@ package v0api
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
@@ -57,4 +59,129 @@ func (w *WrapperV1Full) Version(ctx context.Context) (api.APIVersion, error) {
|
||||
return ver, nil
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) executePrototype(ctx context.Context, p *api.MessagePrototype) (cid.Cid, error) {
|
||||
sm, err := w.FullNode.MpoolPushMessage(ctx, &p.Message, nil)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("pushing message: %w", err)
|
||||
}
|
||||
|
||||
return sm.Cid(), nil
|
||||
}
|
||||
func (w *WrapperV1Full) MsigCreate(ctx context.Context, req uint64, addrs []address.Address, duration abi.ChainEpoch, val types.BigInt, src address.Address, gp types.BigInt) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigCreate(ctx, req, addrs, duration, val, src, gp)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigPropose(ctx context.Context, msig address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigPropose(ctx, msig, to, amt, src, method, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
func (w *WrapperV1Full) MsigApprove(ctx context.Context, msig address.Address, txID uint64, src address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigApprove(ctx, msig, txID, src)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigApproveTxnHash(ctx context.Context, msig address.Address, txID uint64, proposer address.Address, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
p, err := w.FullNode.MsigApproveTxnHash(ctx, msig, txID, proposer, to, amt, src, method, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigCancel(ctx context.Context, msig address.Address, txID uint64, to address.Address, amt types.BigInt, src address.Address, method uint64, params []byte) (cid.Cid, error) {
|
||||
p, err := w.FullNode.MsigCancel(ctx, msig, txID, to, amt, src, method, params)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigAddPropose(ctx context.Context, msig address.Address, src address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigAddPropose(ctx, msig, src, newAdd, inc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigAddApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigAddApprove(ctx, msig, src, txID, proposer, newAdd, inc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigAddCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, newAdd address.Address, inc bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigAddCancel(ctx, msig, src, txID, newAdd, inc)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigSwapPropose(ctx context.Context, msig address.Address, src address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigSwapPropose(ctx, msig, src, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigSwapApprove(ctx context.Context, msig address.Address, src address.Address, txID uint64, proposer address.Address, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigSwapApprove(ctx, msig, src, txID, proposer, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigSwapCancel(ctx context.Context, msig address.Address, src address.Address, txID uint64, oldAdd address.Address, newAdd address.Address) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigSwapCancel(ctx, msig, src, txID, oldAdd, newAdd)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
func (w *WrapperV1Full) MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) {
|
||||
|
||||
p, err := w.FullNode.MsigRemoveSigner(ctx, msig, proposer, toRemove, decrease)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("creating prototype: %w", err)
|
||||
}
|
||||
|
||||
return w.executePrototype(ctx, p)
|
||||
}
|
||||
|
||||
var _ FullNode = &WrapperV1Full{}
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ var (
|
||||
FullAPIVersion0 = newVer(1, 3, 0)
|
||||
FullAPIVersion1 = newVer(2, 1, 0)
|
||||
|
||||
MinerAPIVersion0 = newVer(1, 0, 1)
|
||||
WorkerAPIVersion0 = newVer(1, 0, 0)
|
||||
MinerAPIVersion0 = newVer(1, 2, 0)
|
||||
WorkerAPIVersion0 = newVer(1, 1, 0)
|
||||
)
|
||||
|
||||
//nolint:varcheck,deadcode
|
||||
|
||||
+21
@@ -26,6 +26,27 @@ func Wrap(proxyT, wrapperT, impl interface{}) interface{} {
|
||||
}))
|
||||
}
|
||||
|
||||
for i := 0; i < proxy.Elem().NumField(); i++ {
|
||||
if proxy.Elem().Type().Field(i).Name == "Internal" {
|
||||
continue
|
||||
}
|
||||
|
||||
subProxy := proxy.Elem().Field(i).FieldByName("Internal")
|
||||
for i := 0; i < ri.NumMethod(); i++ {
|
||||
mt := ri.Type().Method(i)
|
||||
if subProxy.FieldByName(mt.Name).Kind() == reflect.Invalid {
|
||||
continue
|
||||
}
|
||||
|
||||
fn := ri.Method(i)
|
||||
of := subProxy.FieldByName(mt.Name)
|
||||
|
||||
subProxy.FieldByName(mt.Name).Set(reflect.MakeFunc(of.Type(), func(args []reflect.Value) (results []reflect.Value) {
|
||||
return fn.Call(args)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
wp := reflect.New(reflect.TypeOf(wrapperT).Elem())
|
||||
wp.Elem().Field(0).Set(proxy)
|
||||
return wp.Interface()
|
||||
|
||||
+133
-48
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"sync"
|
||||
|
||||
"github.com/dgraph-io/badger/v2"
|
||||
"github.com/dgraph-io/badger/v2/options"
|
||||
@@ -73,20 +73,16 @@ func (b *badgerLogger) Warningf(format string, args ...interface{}) {
|
||||
}
|
||||
|
||||
const (
|
||||
stateOpen int64 = iota
|
||||
stateOpen = iota
|
||||
stateClosing
|
||||
stateClosed
|
||||
)
|
||||
|
||||
// Blockstore is a badger-backed IPLD blockstore.
|
||||
//
|
||||
// NOTE: once Close() is called, methods will try their best to return
|
||||
// ErrBlockstoreClosed. This will guaranteed to happen for all subsequent
|
||||
// operation calls after Close() has returned, but it may not happen for
|
||||
// operations in progress. Those are likely to fail with a different error.
|
||||
type Blockstore struct {
|
||||
// state is accessed atomically
|
||||
state int64
|
||||
stateLk sync.RWMutex
|
||||
state int
|
||||
viewers sync.WaitGroup
|
||||
|
||||
DB *badger.DB
|
||||
|
||||
@@ -97,6 +93,8 @@ type Blockstore struct {
|
||||
|
||||
var _ blockstore.Blockstore = (*Blockstore)(nil)
|
||||
var _ blockstore.Viewer = (*Blockstore)(nil)
|
||||
var _ blockstore.BlockstoreIterator = (*Blockstore)(nil)
|
||||
var _ blockstore.BlockstoreGC = (*Blockstore)(nil)
|
||||
var _ io.Closer = (*Blockstore)(nil)
|
||||
|
||||
// Open creates a new badger-backed blockstore, with the supplied options.
|
||||
@@ -124,53 +122,82 @@ func Open(opts Options) (*Blockstore, error) {
|
||||
// Close closes the store. If the store has already been closed, this noops and
|
||||
// returns an error, even if the first closure resulted in error.
|
||||
func (b *Blockstore) Close() error {
|
||||
if !atomic.CompareAndSwapInt64(&b.state, stateOpen, stateClosing) {
|
||||
b.stateLk.Lock()
|
||||
if b.state != stateOpen {
|
||||
b.stateLk.Unlock()
|
||||
return nil
|
||||
}
|
||||
b.state = stateClosing
|
||||
b.stateLk.Unlock()
|
||||
|
||||
defer func() {
|
||||
b.stateLk.Lock()
|
||||
b.state = stateClosed
|
||||
b.stateLk.Unlock()
|
||||
}()
|
||||
|
||||
// wait for all accesses to complete
|
||||
b.viewers.Wait()
|
||||
|
||||
defer atomic.StoreInt64(&b.state, stateClosed)
|
||||
return b.DB.Close()
|
||||
}
|
||||
|
||||
func (b *Blockstore) access() error {
|
||||
b.stateLk.RLock()
|
||||
defer b.stateLk.RUnlock()
|
||||
|
||||
if b.state != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
}
|
||||
|
||||
b.viewers.Add(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Blockstore) isOpen() bool {
|
||||
b.stateLk.RLock()
|
||||
defer b.stateLk.RUnlock()
|
||||
|
||||
return b.state == stateOpen
|
||||
}
|
||||
|
||||
// CollectGarbage runs garbage collection on the value log
|
||||
func (b *Blockstore) CollectGarbage() error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
// compact first to gather the necessary statistics for GC
|
||||
nworkers := runtime.NumCPU() / 2
|
||||
if nworkers < 2 {
|
||||
nworkers = 2
|
||||
}
|
||||
|
||||
err := b.DB.Flatten(nworkers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
for err == nil {
|
||||
err = b.DB.RunValueLogGC(0.125)
|
||||
}
|
||||
|
||||
if err == badger.ErrNoRewrite {
|
||||
// not really an error in this case
|
||||
// not really an error in this case, it signals the end of GC
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Compact runs a synchronous compaction
|
||||
func (b *Blockstore) Compact() error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
}
|
||||
|
||||
nworkers := runtime.NumCPU() / 2
|
||||
if nworkers < 2 {
|
||||
nworkers = 2
|
||||
}
|
||||
|
||||
return b.DB.Flatten(nworkers)
|
||||
}
|
||||
|
||||
// View implements blockstore.Viewer, which leverages zero-copy read-only
|
||||
// access to values.
|
||||
func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
k, pooled := b.PooledStorageKey(cid)
|
||||
if pooled {
|
||||
@@ -191,9 +218,10 @@ func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error {
|
||||
|
||||
// Has implements Blockstore.Has.
|
||||
func (b *Blockstore) Has(cid cid.Cid) (bool, error) {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return false, ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
k, pooled := b.PooledStorageKey(cid)
|
||||
if pooled {
|
||||
@@ -221,9 +249,10 @@ func (b *Blockstore) Get(cid cid.Cid) (blocks.Block, error) {
|
||||
return nil, blockstore.ErrNotFound
|
||||
}
|
||||
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return nil, ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
k, pooled := b.PooledStorageKey(cid)
|
||||
if pooled {
|
||||
@@ -250,9 +279,10 @@ func (b *Blockstore) Get(cid cid.Cid) (blocks.Block, error) {
|
||||
|
||||
// GetSize implements Blockstore.GetSize.
|
||||
func (b *Blockstore) GetSize(cid cid.Cid) (int, error) {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return -1, ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
k, pooled := b.PooledStorageKey(cid)
|
||||
if pooled {
|
||||
@@ -279,9 +309,10 @@ func (b *Blockstore) GetSize(cid cid.Cid) (int, error) {
|
||||
|
||||
// Put implements Blockstore.Put.
|
||||
func (b *Blockstore) Put(block blocks.Block) error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
k, pooled := b.PooledStorageKey(block.Cid())
|
||||
if pooled {
|
||||
@@ -299,9 +330,10 @@ func (b *Blockstore) Put(block blocks.Block) error {
|
||||
|
||||
// PutMany implements Blockstore.PutMany.
|
||||
func (b *Blockstore) PutMany(blocks []blocks.Block) error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
// toReturn tracks the byte slices to return to the pool, if we're using key
|
||||
// prefixing. we can't return each slice to the pool after each Set, because
|
||||
@@ -338,9 +370,10 @@ func (b *Blockstore) PutMany(blocks []blocks.Block) error {
|
||||
|
||||
// DeleteBlock implements Blockstore.DeleteBlock.
|
||||
func (b *Blockstore) DeleteBlock(cid cid.Cid) error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
k, pooled := b.PooledStorageKey(cid)
|
||||
if pooled {
|
||||
@@ -353,9 +386,10 @@ func (b *Blockstore) DeleteBlock(cid cid.Cid) error {
|
||||
}
|
||||
|
||||
func (b *Blockstore) DeleteMany(cids []cid.Cid) error {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
// toReturn tracks the byte slices to return to the pool, if we're using key
|
||||
// prefixing. we can't return each slice to the pool after each Set, because
|
||||
@@ -392,8 +426,8 @@ func (b *Blockstore) DeleteMany(cids []cid.Cid) error {
|
||||
|
||||
// AllKeysChan implements Blockstore.AllKeysChan.
|
||||
func (b *Blockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
return nil, ErrBlockstoreClosed
|
||||
if err := b.access(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txn := b.DB.NewTransaction(false)
|
||||
@@ -405,6 +439,7 @@ func (b *Blockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
|
||||
ch := make(chan cid.Cid)
|
||||
go func() {
|
||||
defer b.viewers.Done()
|
||||
defer close(ch)
|
||||
defer iter.Close()
|
||||
|
||||
@@ -415,7 +450,7 @@ func (b *Blockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
if ctx.Err() != nil {
|
||||
return // context has fired.
|
||||
}
|
||||
if atomic.LoadInt64(&b.state) != stateOpen {
|
||||
if !b.isOpen() {
|
||||
// open iterators will run even after the database is closed...
|
||||
return // closing, yield.
|
||||
}
|
||||
@@ -442,6 +477,56 @@ func (b *Blockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
// Implementation of BlockstoreIterator interface
|
||||
func (b *Blockstore) ForEachKey(f func(cid.Cid) error) error {
|
||||
if err := b.access(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer b.viewers.Done()
|
||||
|
||||
txn := b.DB.NewTransaction(false)
|
||||
defer txn.Discard()
|
||||
|
||||
opts := badger.IteratorOptions{PrefetchSize: 100}
|
||||
if b.prefixing {
|
||||
opts.Prefix = b.prefix
|
||||
}
|
||||
|
||||
iter := txn.NewIterator(opts)
|
||||
defer iter.Close()
|
||||
|
||||
var buf []byte
|
||||
for iter.Rewind(); iter.Valid(); iter.Next() {
|
||||
if !b.isOpen() {
|
||||
return ErrBlockstoreClosed
|
||||
}
|
||||
|
||||
k := iter.Item().Key()
|
||||
if b.prefixing {
|
||||
k = k[b.prefixLen:]
|
||||
}
|
||||
|
||||
klen := base32.RawStdEncoding.DecodedLen(len(k))
|
||||
if klen > len(buf) {
|
||||
buf = make([]byte, klen)
|
||||
}
|
||||
|
||||
n, err := base32.RawStdEncoding.Decode(buf, k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c := cid.NewCidV1(cid.Raw, buf[:n])
|
||||
|
||||
err = f(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HashOnRead implements Blockstore.HashOnRead. It is not supported by this
|
||||
// blockstore.
|
||||
func (b *Blockstore) HashOnRead(_ bool) {
|
||||
|
||||
@@ -30,6 +30,16 @@ type BatchDeleter interface {
|
||||
DeleteMany(cids []cid.Cid) error
|
||||
}
|
||||
|
||||
// BlockstoreIterator is a trait for efficient iteration
|
||||
type BlockstoreIterator interface {
|
||||
ForEachKey(func(cid.Cid) error) error
|
||||
}
|
||||
|
||||
// BlockstoreGC is a trait for blockstores that support online garbage collection
|
||||
type BlockstoreGC interface {
|
||||
CollectGarbage() error
|
||||
}
|
||||
|
||||
// WrapIDStore wraps the underlying blockstore in an "identity" blockstore.
|
||||
// The ID store filters out all puts for blocks with CIDs using the "identity"
|
||||
// hash function. It also extracts inlined blocks from CIDs using the identity
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package blockstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
var _ Blockstore = (*discardstore)(nil)
|
||||
|
||||
type discardstore struct {
|
||||
bs Blockstore
|
||||
}
|
||||
|
||||
func NewDiscardStore(bs Blockstore) Blockstore {
|
||||
return &discardstore{bs: bs}
|
||||
}
|
||||
|
||||
func (b *discardstore) Has(cid cid.Cid) (bool, error) {
|
||||
return b.bs.Has(cid)
|
||||
}
|
||||
|
||||
func (b *discardstore) HashOnRead(hor bool) {
|
||||
b.bs.HashOnRead(hor)
|
||||
}
|
||||
|
||||
func (b *discardstore) Get(cid cid.Cid) (blocks.Block, error) {
|
||||
return b.bs.Get(cid)
|
||||
}
|
||||
|
||||
func (b *discardstore) GetSize(cid cid.Cid) (int, error) {
|
||||
return b.bs.GetSize(cid)
|
||||
}
|
||||
|
||||
func (b *discardstore) View(cid cid.Cid, f func([]byte) error) error {
|
||||
return b.bs.View(cid, f)
|
||||
}
|
||||
|
||||
func (b *discardstore) Put(blk blocks.Block) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *discardstore) PutMany(blks []blocks.Block) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *discardstore) DeleteBlock(cid cid.Cid) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *discardstore) DeleteMany(cids []cid.Cid) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *discardstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
return b.bs.AllKeysChan(ctx)
|
||||
}
|
||||
|
||||
func (b *discardstore) Close() error {
|
||||
if c, ok := b.bs.(io.Closer); ok {
|
||||
return c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
# SplitStore: An actively scalable blockstore for the Filecoin chain
|
||||
|
||||
The SplitStore was first introduced in lotus v1.5.1, as an experiment
|
||||
in reducing the performance impact of large blockstores.
|
||||
|
||||
With lotus v1.11.1, we introduce the next iteration in design and
|
||||
implementation, which we call SplitStore v1.
|
||||
|
||||
The new design (see [#6474](https://github.com/filecoin-project/lotus/pull/6474)
|
||||
evolves the splitstore to be a freestanding compacting blockstore that
|
||||
allows us to keep a small (60-100GB) working set in a hot blockstore
|
||||
and reliably archive out of scope objects in a coldstore. The
|
||||
coldstore can also be a discard store, whereby out of scope objects
|
||||
are discarded or a regular badger blockstore (the default), which can
|
||||
be periodically garbage collected according to configurable user
|
||||
retention policies.
|
||||
|
||||
To enable the splitstore, edit `.lotus/config.toml` and add the following:
|
||||
```
|
||||
[Chainstore]
|
||||
EnableSplitstore = true
|
||||
```
|
||||
|
||||
If you intend to use the discard coldstore, your also need to add the following:
|
||||
```
|
||||
[Chainstore.Splitstore]
|
||||
ColdStoreType = "discard"
|
||||
```
|
||||
In general you _should not_ have to use the discard store, unless you
|
||||
are running a network booster or have very constrained hardware with
|
||||
not enough disk space to maintain a coldstore, even with garbage
|
||||
collection.
|
||||
|
||||
|
||||
## Operation
|
||||
|
||||
When the splitstore is first enabled, the existing blockstore becomes
|
||||
the coldstore and a fresh hotstore is initialized.
|
||||
|
||||
The hotstore is warmed up on first startup so as to load all chain
|
||||
headers and state roots in the current head. This allows us to
|
||||
immediately gain the performance benefits of a smallerblockstore which
|
||||
can be substantial for full archival nodes.
|
||||
|
||||
All new writes are directed to the hotstore, while reads first hit the
|
||||
hotstore, with fallback to the coldstore.
|
||||
|
||||
Once 5 finalities have ellapsed, and every finality henceforth, the
|
||||
blockstore _compacts_. Compaction is the process of moving all
|
||||
unreachable objects within the last 4 finalities from the hotstore to
|
||||
the coldstore. If the system is configured with a discard coldstore,
|
||||
these objects are discarded. Note that chain headers, all the way to
|
||||
genesis, are considered reachable. Stateroots and messages are
|
||||
considered reachable only within the last 4 finalities, unless there
|
||||
is a live reference to them.
|
||||
|
||||
## Compaction
|
||||
|
||||
Compaction works transactionally with the following algorithm:
|
||||
- We prepare a transaction, whereby all i/o referenced objects through the API are tracked.
|
||||
- We walk the chain and mark reachable objects, keeping 4 finalities of state roots and messages and all headers all the way to genesis.
|
||||
- Once the chain walk is complete, we begin full transaction protection with concurrent marking; we walk and mark all references created during the chain walk. On the same time, all I/O through the API concurrently marks objects as live references.
|
||||
- We collect cold objects by iterating through the hotstore and checking the mark set; if an object is not marked, then it is candidate for purge.
|
||||
- When running with a coldstore, we next copy all cold objects to the coldstore.
|
||||
- At this point we are ready to begin purging:
|
||||
- We sort cold objects heaviest first, so as to never delete the consituents of a DAG before the DAG itself (which would leave dangling references)
|
||||
- We delete in small batches taking a lock; each batch is checked again for marks, from the concurrent transactional mark, so as to never delete anything live
|
||||
- We then end the transaction and compact/gc the hotstore.
|
||||
|
||||
## Coldstore Garbage Collection
|
||||
|
||||
TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577)
|
||||
@@ -0,0 +1,273 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
type debugLog struct {
|
||||
readLog, writeLog, deleteLog, stackLog *debugLogOp
|
||||
|
||||
stackMx sync.Mutex
|
||||
stackMap map[string]string
|
||||
}
|
||||
|
||||
type debugLogOp struct {
|
||||
path string
|
||||
mx sync.Mutex
|
||||
log *os.File
|
||||
count int
|
||||
}
|
||||
|
||||
func openDebugLog(path string) (*debugLog, error) {
|
||||
basePath := filepath.Join(path, "debug")
|
||||
err := os.MkdirAll(basePath, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
readLog, err := openDebugLogOp(basePath, "read.log")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
writeLog, err := openDebugLogOp(basePath, "write.log")
|
||||
if err != nil {
|
||||
_ = readLog.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deleteLog, err := openDebugLogOp(basePath, "delete.log")
|
||||
if err != nil {
|
||||
_ = readLog.Close()
|
||||
_ = writeLog.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stackLog, err := openDebugLogOp(basePath, "stack.log")
|
||||
if err != nil {
|
||||
_ = readLog.Close()
|
||||
_ = writeLog.Close()
|
||||
_ = deleteLog.Close()
|
||||
return nil, xerrors.Errorf("error opening stack log: %w", err)
|
||||
}
|
||||
|
||||
return &debugLog{
|
||||
readLog: readLog,
|
||||
writeLog: writeLog,
|
||||
deleteLog: deleteLog,
|
||||
stackLog: stackLog,
|
||||
stackMap: make(map[string]string),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *debugLog) LogReadMiss(cid cid.Cid) {
|
||||
if d == nil {
|
||||
return
|
||||
}
|
||||
|
||||
stack := d.getStack()
|
||||
err := d.readLog.Log("%s %s %s\n", d.timestamp(), cid, stack)
|
||||
if err != nil {
|
||||
log.Warnf("error writing read log: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *debugLog) LogWrite(blk blocks.Block) {
|
||||
if d == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var stack string
|
||||
if enableDebugLogWriteTraces {
|
||||
stack = " " + d.getStack()
|
||||
}
|
||||
|
||||
err := d.writeLog.Log("%s %s%s\n", d.timestamp(), blk.Cid(), stack)
|
||||
if err != nil {
|
||||
log.Warnf("error writing write log: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *debugLog) LogWriteMany(blks []blocks.Block) {
|
||||
if d == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var stack string
|
||||
if enableDebugLogWriteTraces {
|
||||
stack = " " + d.getStack()
|
||||
}
|
||||
|
||||
now := d.timestamp()
|
||||
for _, blk := range blks {
|
||||
err := d.writeLog.Log("%s %s%s\n", now, blk.Cid(), stack)
|
||||
if err != nil {
|
||||
log.Warnf("error writing write log: %s", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *debugLog) LogDelete(cids []cid.Cid) {
|
||||
if d == nil {
|
||||
return
|
||||
}
|
||||
|
||||
now := d.timestamp()
|
||||
for _, c := range cids {
|
||||
err := d.deleteLog.Log("%s %s\n", now, c)
|
||||
if err != nil {
|
||||
log.Warnf("error writing delete log: %s", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *debugLog) Flush() {
|
||||
if d == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// rotate non-empty logs
|
||||
d.readLog.Rotate()
|
||||
d.writeLog.Rotate()
|
||||
d.deleteLog.Rotate()
|
||||
d.stackLog.Rotate()
|
||||
}
|
||||
|
||||
func (d *debugLog) Close() error {
|
||||
if d == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err1 := d.readLog.Close()
|
||||
err2 := d.writeLog.Close()
|
||||
err3 := d.deleteLog.Close()
|
||||
err4 := d.stackLog.Close()
|
||||
|
||||
return multierr.Combine(err1, err2, err3, err4)
|
||||
}
|
||||
|
||||
func (d *debugLog) getStack() string {
|
||||
sk := d.getNormalizedStackTrace()
|
||||
hash := sha256.Sum256([]byte(sk))
|
||||
key := string(hash[:])
|
||||
|
||||
d.stackMx.Lock()
|
||||
repr, ok := d.stackMap[key]
|
||||
if !ok {
|
||||
repr = hex.EncodeToString(hash[:])
|
||||
d.stackMap[key] = repr
|
||||
|
||||
err := d.stackLog.Log("%s\n%s\n", repr, sk)
|
||||
if err != nil {
|
||||
log.Warnf("error writing stack trace for %s: %s", repr, err)
|
||||
}
|
||||
}
|
||||
d.stackMx.Unlock()
|
||||
|
||||
return repr
|
||||
}
|
||||
|
||||
func (d *debugLog) getNormalizedStackTrace() string {
|
||||
sk := string(debug.Stack())
|
||||
|
||||
// Normalization for deduplication
|
||||
// skip first line -- it's the goroutine
|
||||
// for each line that ends in a ), remove the call args -- these are the registers
|
||||
lines := strings.Split(sk, "\n")[1:]
|
||||
for i, line := range lines {
|
||||
if len(line) > 0 && line[len(line)-1] == ')' {
|
||||
idx := strings.LastIndex(line, "(")
|
||||
if idx < 0 {
|
||||
continue
|
||||
}
|
||||
lines[i] = line[:idx]
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func (d *debugLog) timestamp() string {
|
||||
ts, _ := time.Now().MarshalText()
|
||||
return string(ts)
|
||||
}
|
||||
|
||||
func openDebugLogOp(basePath, name string) (*debugLogOp, error) {
|
||||
path := filepath.Join(basePath, name)
|
||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("error opening %s: %w", name, err)
|
||||
}
|
||||
|
||||
return &debugLogOp{path: path, log: file}, nil
|
||||
}
|
||||
|
||||
func (d *debugLogOp) Close() error {
|
||||
d.mx.Lock()
|
||||
defer d.mx.Unlock()
|
||||
|
||||
return d.log.Close()
|
||||
}
|
||||
|
||||
func (d *debugLogOp) Log(template string, arg ...interface{}) error {
|
||||
d.mx.Lock()
|
||||
defer d.mx.Unlock()
|
||||
|
||||
d.count++
|
||||
_, err := fmt.Fprintf(d.log, template, arg...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *debugLogOp) Rotate() {
|
||||
d.mx.Lock()
|
||||
defer d.mx.Unlock()
|
||||
|
||||
if d.count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
err := d.log.Close()
|
||||
if err != nil {
|
||||
log.Warnf("error closing log (file: %s): %s", d.path, err)
|
||||
return
|
||||
}
|
||||
|
||||
arxivPath := fmt.Sprintf("%s-%d", d.path, time.Now().Unix())
|
||||
err = os.Rename(d.path, arxivPath)
|
||||
if err != nil {
|
||||
log.Warnf("error moving log (file: %s): %s", d.path, err)
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
cmd := exec.Command("gzip", arxivPath)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Warnf("error compressing log (file: %s): %s", arxivPath, err)
|
||||
}
|
||||
}()
|
||||
|
||||
d.count = 0
|
||||
d.log, err = os.OpenFile(d.path, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
log.Warnf("error opening log (file: %s): %s", d.path, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,26 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"errors"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
var errMarkSetClosed = errors.New("markset closed")
|
||||
|
||||
// MarkSet is a utility to keep track of seen CID, and later query for them.
|
||||
//
|
||||
// * If the expected dataset is large, it can be backed by a datastore (e.g. bbolt).
|
||||
// * If a probabilistic result is acceptable, it can be backed by a bloom filter (default).
|
||||
// * If a probabilistic result is acceptable, it can be backed by a bloom filter
|
||||
type MarkSet interface {
|
||||
Mark(cid.Cid) error
|
||||
Has(cid.Cid) (bool, error)
|
||||
Close() error
|
||||
SetConcurrent()
|
||||
}
|
||||
|
||||
// markBytes is deliberately a non-nil empty byte slice for serialization.
|
||||
var markBytes = []byte{}
|
||||
|
||||
type MarkSetEnv interface {
|
||||
Create(name string, sizeHint int64) (MarkSet, error)
|
||||
Close() error
|
||||
@@ -28,10 +28,10 @@ type MarkSetEnv interface {
|
||||
|
||||
func OpenMarkSetEnv(path string, mtype string) (MarkSetEnv, error) {
|
||||
switch mtype {
|
||||
case "", "bloom":
|
||||
case "bloom":
|
||||
return NewBloomMarkSetEnv()
|
||||
case "bolt":
|
||||
return NewBoltMarkSetEnv(filepath.Join(path, "markset.bolt"))
|
||||
case "map":
|
||||
return NewMapMarkSetEnv()
|
||||
default:
|
||||
return nil, xerrors.Errorf("unknown mark set type %s", mtype)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package splitstore
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
@@ -21,7 +22,9 @@ var _ MarkSetEnv = (*BloomMarkSetEnv)(nil)
|
||||
|
||||
type BloomMarkSet struct {
|
||||
salt []byte
|
||||
mx sync.RWMutex
|
||||
bf *bbloom.Bloom
|
||||
ts bool
|
||||
}
|
||||
|
||||
var _ MarkSet = (*BloomMarkSet)(nil)
|
||||
@@ -64,14 +67,41 @@ func (s *BloomMarkSet) saltedKey(cid cid.Cid) []byte {
|
||||
}
|
||||
|
||||
func (s *BloomMarkSet) Mark(cid cid.Cid) error {
|
||||
if s.ts {
|
||||
s.mx.Lock()
|
||||
defer s.mx.Unlock()
|
||||
}
|
||||
|
||||
if s.bf == nil {
|
||||
return errMarkSetClosed
|
||||
}
|
||||
|
||||
s.bf.Add(s.saltedKey(cid))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BloomMarkSet) Has(cid cid.Cid) (bool, error) {
|
||||
if s.ts {
|
||||
s.mx.RLock()
|
||||
defer s.mx.RUnlock()
|
||||
}
|
||||
|
||||
if s.bf == nil {
|
||||
return false, errMarkSetClosed
|
||||
}
|
||||
|
||||
return s.bf.Has(s.saltedKey(cid)), nil
|
||||
}
|
||||
|
||||
func (s *BloomMarkSet) Close() error {
|
||||
if s.ts {
|
||||
s.mx.Lock()
|
||||
defer s.mx.Unlock()
|
||||
}
|
||||
s.bf = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *BloomMarkSet) SetConcurrent() {
|
||||
s.ts = true
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
type BoltMarkSetEnv struct {
|
||||
db *bolt.DB
|
||||
}
|
||||
|
||||
var _ MarkSetEnv = (*BoltMarkSetEnv)(nil)
|
||||
|
||||
type BoltMarkSet struct {
|
||||
db *bolt.DB
|
||||
bucketId []byte
|
||||
}
|
||||
|
||||
var _ MarkSet = (*BoltMarkSet)(nil)
|
||||
|
||||
func NewBoltMarkSetEnv(path string) (*BoltMarkSetEnv, error) {
|
||||
db, err := bolt.Open(path, 0644,
|
||||
&bolt.Options{
|
||||
Timeout: 1 * time.Second,
|
||||
NoSync: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BoltMarkSetEnv{db: db}, nil
|
||||
}
|
||||
|
||||
func (e *BoltMarkSetEnv) Create(name string, hint int64) (MarkSet, error) {
|
||||
bucketId := []byte(name)
|
||||
err := e.db.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(bucketId)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error creating bolt db bucket %s: %w", name, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BoltMarkSet{db: e.db, bucketId: bucketId}, nil
|
||||
}
|
||||
|
||||
func (e *BoltMarkSetEnv) Close() error {
|
||||
return e.db.Close()
|
||||
}
|
||||
|
||||
func (s *BoltMarkSet) Mark(cid cid.Cid) error {
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.Put(cid.Hash(), markBytes)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltMarkSet) Has(cid cid.Cid) (result bool, err error) {
|
||||
err = s.db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
v := b.Get(cid.Hash())
|
||||
result = v != nil
|
||||
return nil
|
||||
})
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *BoltMarkSet) Close() error {
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
return tx.DeleteBucket(s.bucketId)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
type MapMarkSetEnv struct{}
|
||||
|
||||
var _ MarkSetEnv = (*MapMarkSetEnv)(nil)
|
||||
|
||||
type MapMarkSet struct {
|
||||
mx sync.RWMutex
|
||||
set map[string]struct{}
|
||||
|
||||
ts bool
|
||||
}
|
||||
|
||||
var _ MarkSet = (*MapMarkSet)(nil)
|
||||
|
||||
func NewMapMarkSetEnv() (*MapMarkSetEnv, error) {
|
||||
return &MapMarkSetEnv{}, nil
|
||||
}
|
||||
|
||||
func (e *MapMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
|
||||
return &MapMarkSet{
|
||||
set: make(map[string]struct{}, sizeHint),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (e *MapMarkSetEnv) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MapMarkSet) Mark(cid cid.Cid) error {
|
||||
if s.ts {
|
||||
s.mx.Lock()
|
||||
defer s.mx.Unlock()
|
||||
}
|
||||
|
||||
if s.set == nil {
|
||||
return errMarkSetClosed
|
||||
}
|
||||
|
||||
s.set[string(cid.Hash())] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MapMarkSet) Has(cid cid.Cid) (bool, error) {
|
||||
if s.ts {
|
||||
s.mx.RLock()
|
||||
defer s.mx.RUnlock()
|
||||
}
|
||||
|
||||
if s.set == nil {
|
||||
return false, errMarkSetClosed
|
||||
}
|
||||
|
||||
_, ok := s.set[string(cid.Hash())]
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
func (s *MapMarkSet) Close() error {
|
||||
if s.ts {
|
||||
s.mx.Lock()
|
||||
defer s.mx.Unlock()
|
||||
}
|
||||
s.set = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MapMarkSet) SetConcurrent() {
|
||||
s.ts = true
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
func TestBoltMarkSet(t *testing.T) {
|
||||
testMarkSet(t, "bolt")
|
||||
func TestMapMarkSet(t *testing.T) {
|
||||
testMarkSet(t, "map")
|
||||
}
|
||||
|
||||
func TestBloomMarkSet(t *testing.T) {
|
||||
|
||||
+263
-792
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,114 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/blockstore"
|
||||
)
|
||||
|
||||
type exposedSplitStore struct {
|
||||
s *SplitStore
|
||||
}
|
||||
|
||||
var _ bstore.Blockstore = (*exposedSplitStore)(nil)
|
||||
|
||||
func (s *SplitStore) Expose() bstore.Blockstore {
|
||||
return &exposedSplitStore{s: s}
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) DeleteBlock(_ cid.Cid) error {
|
||||
return errors.New("DeleteBlock: operation not supported")
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) DeleteMany(_ []cid.Cid) error {
|
||||
return errors.New("DeleteMany: operation not supported")
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) Has(c cid.Cid) (bool, error) {
|
||||
if isIdentiyCid(c) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
has, err := es.s.hot.Has(c)
|
||||
if has || err != nil {
|
||||
return has, err
|
||||
}
|
||||
|
||||
return es.s.cold.Has(c)
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) Get(c cid.Cid) (blocks.Block, error) {
|
||||
if isIdentiyCid(c) {
|
||||
data, err := decodeIdentityCid(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return blocks.NewBlockWithCid(data, c)
|
||||
}
|
||||
|
||||
blk, err := es.s.hot.Get(c)
|
||||
switch err {
|
||||
case bstore.ErrNotFound:
|
||||
return es.s.cold.Get(c)
|
||||
default:
|
||||
return blk, err
|
||||
}
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) GetSize(c cid.Cid) (int, error) {
|
||||
if isIdentiyCid(c) {
|
||||
data, err := decodeIdentityCid(c)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
size, err := es.s.hot.GetSize(c)
|
||||
switch err {
|
||||
case bstore.ErrNotFound:
|
||||
return es.s.cold.GetSize(c)
|
||||
default:
|
||||
return size, err
|
||||
}
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) Put(blk blocks.Block) error {
|
||||
return es.s.Put(blk)
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) PutMany(blks []blocks.Block) error {
|
||||
return es.s.PutMany(blks)
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
return es.s.AllKeysChan(ctx)
|
||||
}
|
||||
|
||||
func (es *exposedSplitStore) HashOnRead(enabled bool) {}
|
||||
|
||||
func (es *exposedSplitStore) View(c cid.Cid, f func([]byte) error) error {
|
||||
if isIdentiyCid(c) {
|
||||
data, err := decodeIdentityCid(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return f(data)
|
||||
}
|
||||
|
||||
err := es.s.hot.View(c, f)
|
||||
switch err {
|
||||
case bstore.ErrNotFound:
|
||||
return es.s.cold.View(c, f)
|
||||
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/blockstore"
|
||||
)
|
||||
|
||||
func (s *SplitStore) gcHotstore() {
|
||||
if err := s.gcBlockstoreOnline(s.hot); err != nil {
|
||||
log.Warnf("error garbage collecting hostore: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SplitStore) gcBlockstoreOnline(b bstore.Blockstore) error {
|
||||
if gc, ok := b.(bstore.BlockstoreGC); ok {
|
||||
log.Info("garbage collecting blockstore")
|
||||
startGC := time.Now()
|
||||
|
||||
if err := gc.CollectGarbage(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infow("garbage collecting hotstore done", "took", time.Since(startGC))
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("blockstore doesn't support online gc: %T", b)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package splitstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
datastore "github.com/ipfs/go-datastore"
|
||||
dssync "github.com/ipfs/go-datastore/sync"
|
||||
@@ -21,22 +23,34 @@ import (
|
||||
|
||||
func init() {
|
||||
CompactionThreshold = 5
|
||||
CompactionCold = 1
|
||||
CompactionBoundary = 2
|
||||
logging.SetLogLevel("splitstore", "DEBUG")
|
||||
}
|
||||
|
||||
func testSplitStore(t *testing.T, cfg *Config) {
|
||||
chain := &mockChain{}
|
||||
// genesis
|
||||
genBlock := mock.MkBlock(nil, 0, 0)
|
||||
genTs := mock.TipSet(genBlock)
|
||||
chain.push(genTs)
|
||||
chain := &mockChain{t: t}
|
||||
|
||||
// the myriads of stores
|
||||
ds := dssync.MutexWrap(datastore.NewMapDatastore())
|
||||
hot := blockstore.NewMemorySync()
|
||||
cold := blockstore.NewMemorySync()
|
||||
hot := newMockStore()
|
||||
cold := newMockStore()
|
||||
|
||||
// this is necessary to avoid the garbage mock puts in the blocks
|
||||
garbage := blocks.NewBlock([]byte{1, 2, 3})
|
||||
err := cold.Put(garbage)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// genesis
|
||||
genBlock := mock.MkBlock(nil, 0, 0)
|
||||
genBlock.Messages = garbage.Cid()
|
||||
genBlock.ParentMessageReceipts = garbage.Cid()
|
||||
genBlock.ParentStateRoot = garbage.Cid()
|
||||
genBlock.Timestamp = uint64(time.Now().Unix())
|
||||
|
||||
genTs := mock.TipSet(genBlock)
|
||||
chain.push(genTs)
|
||||
|
||||
// put the genesis block to cold store
|
||||
blk, err := genBlock.ToStorageBlock()
|
||||
@@ -62,12 +76,22 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
||||
}
|
||||
|
||||
// make some tipsets, but not enough to cause compaction
|
||||
mkBlock := func(curTs *types.TipSet, i int) *types.TipSet {
|
||||
mkBlock := func(curTs *types.TipSet, i int, stateRoot blocks.Block) *types.TipSet {
|
||||
blk := mock.MkBlock(curTs, uint64(i), uint64(i))
|
||||
|
||||
blk.Messages = garbage.Cid()
|
||||
blk.ParentMessageReceipts = garbage.Cid()
|
||||
blk.ParentStateRoot = stateRoot.Cid()
|
||||
blk.Timestamp = uint64(time.Now().Unix())
|
||||
|
||||
sblk, err := blk.ToStorageBlock()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Put(stateRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Put(sblk)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -78,18 +102,6 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
||||
return ts
|
||||
}
|
||||
|
||||
mkGarbageBlock := func(curTs *types.TipSet, i int) {
|
||||
blk := mock.MkBlock(curTs, uint64(i), uint64(i))
|
||||
sblk, err := blk.ToStorageBlock()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Put(sblk)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
waitForCompaction := func() {
|
||||
for atomic.LoadInt32(&ss.compacting) == 1 {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
@@ -98,100 +110,63 @@ func testSplitStore(t *testing.T, cfg *Config) {
|
||||
|
||||
curTs := genTs
|
||||
for i := 1; i < 5; i++ {
|
||||
curTs = mkBlock(curTs, i)
|
||||
stateRoot := blocks.NewBlock([]byte{byte(i), 3, 3, 7})
|
||||
curTs = mkBlock(curTs, i, stateRoot)
|
||||
waitForCompaction()
|
||||
}
|
||||
|
||||
mkGarbageBlock(genTs, 1)
|
||||
|
||||
// count objects in the cold and hot stores
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
countBlocks := func(bs blockstore.Blockstore) int {
|
||||
count := 0
|
||||
ch, err := bs.AllKeysChan(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for range ch {
|
||||
_ = bs.(blockstore.BlockstoreIterator).ForEachKey(func(_ cid.Cid) error {
|
||||
count++
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
coldCnt := countBlocks(cold)
|
||||
hotCnt := countBlocks(hot)
|
||||
|
||||
if coldCnt != 1 {
|
||||
t.Errorf("expected %d blocks, but got %d", 1, coldCnt)
|
||||
if coldCnt != 2 {
|
||||
t.Errorf("expected %d blocks, but got %d", 2, coldCnt)
|
||||
}
|
||||
|
||||
if hotCnt != 5 {
|
||||
t.Errorf("expected %d blocks, but got %d", 5, hotCnt)
|
||||
if hotCnt != 10 {
|
||||
t.Errorf("expected %d blocks, but got %d", 10, hotCnt)
|
||||
}
|
||||
|
||||
// trigger a compaction
|
||||
for i := 5; i < 10; i++ {
|
||||
curTs = mkBlock(curTs, i)
|
||||
stateRoot := blocks.NewBlock([]byte{byte(i), 3, 3, 7})
|
||||
curTs = mkBlock(curTs, i, stateRoot)
|
||||
waitForCompaction()
|
||||
}
|
||||
|
||||
coldCnt = countBlocks(cold)
|
||||
hotCnt = countBlocks(hot)
|
||||
|
||||
if !cfg.EnableFullCompaction {
|
||||
if coldCnt != 5 {
|
||||
t.Errorf("expected %d cold blocks, but got %d", 5, coldCnt)
|
||||
}
|
||||
|
||||
if hotCnt != 5 {
|
||||
t.Errorf("expected %d hot blocks, but got %d", 5, hotCnt)
|
||||
}
|
||||
if coldCnt != 5 {
|
||||
t.Errorf("expected %d cold blocks, but got %d", 5, coldCnt)
|
||||
}
|
||||
|
||||
if cfg.EnableFullCompaction && !cfg.EnableGC {
|
||||
if coldCnt != 3 {
|
||||
t.Errorf("expected %d cold blocks, but got %d", 3, coldCnt)
|
||||
}
|
||||
|
||||
if hotCnt != 7 {
|
||||
t.Errorf("expected %d hot blocks, but got %d", 7, hotCnt)
|
||||
}
|
||||
if hotCnt != 17 {
|
||||
t.Errorf("expected %d hot blocks, but got %d", 17, hotCnt)
|
||||
}
|
||||
|
||||
if cfg.EnableFullCompaction && cfg.EnableGC {
|
||||
if coldCnt != 2 {
|
||||
t.Errorf("expected %d cold blocks, but got %d", 2, coldCnt)
|
||||
}
|
||||
|
||||
if hotCnt != 7 {
|
||||
t.Errorf("expected %d hot blocks, but got %d", 7, hotCnt)
|
||||
}
|
||||
}
|
||||
// Make sure we can revert without panicking.
|
||||
chain.revert(2)
|
||||
}
|
||||
|
||||
func TestSplitStoreSimpleCompaction(t *testing.T) {
|
||||
testSplitStore(t, &Config{TrackingStoreType: "mem"})
|
||||
}
|
||||
|
||||
func TestSplitStoreFullCompactionWithoutGC(t *testing.T) {
|
||||
testSplitStore(t, &Config{
|
||||
TrackingStoreType: "mem",
|
||||
EnableFullCompaction: true,
|
||||
})
|
||||
}
|
||||
|
||||
func TestSplitStoreFullCompactionWithGC(t *testing.T) {
|
||||
testSplitStore(t, &Config{
|
||||
TrackingStoreType: "mem",
|
||||
EnableFullCompaction: true,
|
||||
EnableGC: true,
|
||||
})
|
||||
func TestSplitStoreCompaction(t *testing.T) {
|
||||
testSplitStore(t, &Config{MarkSetType: "map"})
|
||||
}
|
||||
|
||||
type mockChain struct {
|
||||
t testing.TB
|
||||
|
||||
sync.Mutex
|
||||
genesis *types.BlockHeader
|
||||
tipsets []*types.TipSet
|
||||
listener func(revert []*types.TipSet, apply []*types.TipSet) error
|
||||
}
|
||||
@@ -199,12 +174,34 @@ type mockChain struct {
|
||||
func (c *mockChain) push(ts *types.TipSet) {
|
||||
c.Lock()
|
||||
c.tipsets = append(c.tipsets, ts)
|
||||
if c.genesis == nil {
|
||||
c.genesis = ts.Blocks()[0]
|
||||
}
|
||||
c.Unlock()
|
||||
|
||||
if c.listener != nil {
|
||||
err := c.listener(nil, []*types.TipSet{ts})
|
||||
if err != nil {
|
||||
log.Errorf("mockchain: error dispatching listener: %s", err)
|
||||
c.t.Errorf("mockchain: error dispatching listener: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *mockChain) revert(count int) {
|
||||
c.Lock()
|
||||
revert := make([]*types.TipSet, count)
|
||||
if count > len(c.tipsets) {
|
||||
c.Unlock()
|
||||
c.t.Fatalf("not enough tipsets to revert")
|
||||
}
|
||||
copy(revert, c.tipsets[len(c.tipsets)-count:])
|
||||
c.tipsets = c.tipsets[:len(c.tipsets)-count]
|
||||
c.Unlock()
|
||||
|
||||
if c.listener != nil {
|
||||
err := c.listener(revert, nil)
|
||||
if err != nil {
|
||||
c.t.Errorf("mockchain: error dispatching listener: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,7 +215,7 @@ func (c *mockChain) GetTipsetByHeight(_ context.Context, epoch abi.ChainEpoch, _
|
||||
return nil, fmt.Errorf("bad epoch %d", epoch)
|
||||
}
|
||||
|
||||
return c.tipsets[iEpoch-1], nil
|
||||
return c.tipsets[iEpoch], nil
|
||||
}
|
||||
|
||||
func (c *mockChain) GetHeaviestTipSet() *types.TipSet {
|
||||
@@ -232,24 +229,105 @@ func (c *mockChain) SubscribeHeadChanges(change func(revert []*types.TipSet, app
|
||||
c.listener = change
|
||||
}
|
||||
|
||||
func (c *mockChain) WalkSnapshot(_ context.Context, ts *types.TipSet, epochs abi.ChainEpoch, _ bool, _ bool, f func(cid.Cid) error) error {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
type mockStore struct {
|
||||
mx sync.Mutex
|
||||
set map[cid.Cid]blocks.Block
|
||||
}
|
||||
|
||||
start := int(ts.Height()) - 1
|
||||
end := start - int(epochs)
|
||||
if end < 0 {
|
||||
end = -1
|
||||
func newMockStore() *mockStore {
|
||||
return &mockStore{set: make(map[cid.Cid]blocks.Block)}
|
||||
}
|
||||
|
||||
func (b *mockStore) Has(cid cid.Cid) (bool, error) {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
_, ok := b.set[cid]
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
func (b *mockStore) HashOnRead(hor bool) {}
|
||||
|
||||
func (b *mockStore) Get(cid cid.Cid) (blocks.Block, error) {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
|
||||
blk, ok := b.set[cid]
|
||||
if !ok {
|
||||
return nil, blockstore.ErrNotFound
|
||||
}
|
||||
for i := start; i > end; i-- {
|
||||
ts := c.tipsets[i]
|
||||
for _, cid := range ts.Cids() {
|
||||
err := f(cid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return blk, nil
|
||||
}
|
||||
|
||||
func (b *mockStore) GetSize(cid cid.Cid) (int, error) {
|
||||
blk, err := b.Get(cid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return len(blk.RawData()), nil
|
||||
}
|
||||
|
||||
func (b *mockStore) View(cid cid.Cid, f func([]byte) error) error {
|
||||
blk, err := b.Get(cid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return f(blk.RawData())
|
||||
}
|
||||
|
||||
func (b *mockStore) Put(blk blocks.Block) error {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
|
||||
b.set[blk.Cid()] = blk
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *mockStore) PutMany(blks []blocks.Block) error {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
|
||||
for _, blk := range blks {
|
||||
b.set[blk.Cid()] = blk
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *mockStore) DeleteBlock(cid cid.Cid) error {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
|
||||
delete(b.set, cid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *mockStore) DeleteMany(cids []cid.Cid) error {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
|
||||
for _, c := range cids {
|
||||
delete(b.set, c)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *mockStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (b *mockStore) ForEachKey(f func(cid.Cid) error) error {
|
||||
b.mx.Lock()
|
||||
defer b.mx.Unlock()
|
||||
|
||||
for c := range b.set {
|
||||
err := f(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *mockStore) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
)
|
||||
|
||||
func epochToBytes(epoch abi.ChainEpoch) []byte {
|
||||
return uint64ToBytes(uint64(epoch))
|
||||
}
|
||||
|
||||
func bytesToEpoch(buf []byte) abi.ChainEpoch {
|
||||
return abi.ChainEpoch(bytesToUint64(buf))
|
||||
}
|
||||
|
||||
func int64ToBytes(i int64) []byte {
|
||||
return uint64ToBytes(uint64(i))
|
||||
}
|
||||
|
||||
func bytesToInt64(buf []byte) int64 {
|
||||
return int64(bytesToUint64(buf))
|
||||
}
|
||||
|
||||
func uint64ToBytes(i uint64) []byte {
|
||||
buf := make([]byte, 16)
|
||||
n := binary.PutUvarint(buf, i)
|
||||
return buf[:n]
|
||||
}
|
||||
|
||||
func bytesToUint64(buf []byte) uint64 {
|
||||
i, _ := binary.Uvarint(buf)
|
||||
return i
|
||||
}
|
||||
|
||||
func isUnitaryObject(c cid.Cid) bool {
|
||||
pre := c.Prefix()
|
||||
switch pre.Codec {
|
||||
case cid.FilCommitmentSealed, cid.FilCommitmentUnsealed:
|
||||
return true
|
||||
default:
|
||||
return pre.MhType == mh.IDENTITY
|
||||
}
|
||||
}
|
||||
|
||||
func isIdentiyCid(c cid.Cid) bool {
|
||||
return c.Prefix().MhType == mh.IDENTITY
|
||||
}
|
||||
|
||||
func decodeIdentityCid(c cid.Cid) ([]byte, error) {
|
||||
dmh, err := mh.Decode(c.Hash())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("error decoding identity cid %s: %w", c, err)
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if dmh.Code != mh.IDENTITY {
|
||||
return nil, xerrors.Errorf("error decoding identity cid %s: hash type is not identity", c)
|
||||
}
|
||||
|
||||
return dmh.Digest, nil
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
blocks "github.com/ipfs/go-block-format"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
|
||||
bstore "github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// warmup acuiqres the compaction lock and spawns a goroutine to warm up the hotstore;
|
||||
// this is necessary when we sync from a snapshot or when we enable the splitstore
|
||||
// on top of an existing blockstore (which becomes the coldstore).
|
||||
func (s *SplitStore) warmup(curTs *types.TipSet) error {
|
||||
if !atomic.CompareAndSwapInt32(&s.compacting, 0, 1) {
|
||||
return xerrors.Errorf("error locking compaction")
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer atomic.StoreInt32(&s.compacting, 0)
|
||||
|
||||
log.Info("warming up hotstore")
|
||||
start := time.Now()
|
||||
|
||||
err := s.doWarmup(curTs)
|
||||
if err != nil {
|
||||
log.Errorf("error warming up hotstore: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Infow("warm up done", "took", time.Since(start))
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// the actual warmup procedure; it walks the chain loading all state roots at the boundary
|
||||
// and headers all the way up to genesis.
|
||||
// objects are written in batches so as to minimize overhead.
|
||||
func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
|
||||
epoch := curTs.Height()
|
||||
batchHot := make([]blocks.Block, 0, batchSize)
|
||||
count := int64(0)
|
||||
xcount := int64(0)
|
||||
missing := int64(0)
|
||||
err := s.walkChain(curTs, epoch, false,
|
||||
func(c cid.Cid) error {
|
||||
if isUnitaryObject(c) {
|
||||
return errStopWalk
|
||||
}
|
||||
|
||||
count++
|
||||
|
||||
has, err := s.hot.Has(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if has {
|
||||
return nil
|
||||
}
|
||||
|
||||
blk, err := s.cold.Get(c)
|
||||
if err != nil {
|
||||
if err == bstore.ErrNotFound {
|
||||
missing++
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
xcount++
|
||||
|
||||
batchHot = append(batchHot, blk)
|
||||
if len(batchHot) == batchSize {
|
||||
err = s.hot.PutMany(batchHot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
batchHot = batchHot[:0]
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(batchHot) > 0 {
|
||||
err = s.hot.PutMany(batchHot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Infow("warmup stats", "visited", count, "warm", xcount, "missing", missing)
|
||||
|
||||
s.markSetSize = count + count>>2 // overestimate a bit
|
||||
err = s.ds.Put(markSetSizeKey, int64ToBytes(s.markSetSize))
|
||||
if err != nil {
|
||||
log.Warnf("error saving mark set size: %s", err)
|
||||
}
|
||||
|
||||
// save the warmup epoch
|
||||
err = s.ds.Put(warmupEpochKey, epochToBytes(epoch))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error saving warm up epoch: %w", err)
|
||||
}
|
||||
s.mx.Lock()
|
||||
s.warmupEpoch = epoch
|
||||
s.mx.Unlock()
|
||||
|
||||
// also save the compactionIndex, as this is used as an indicator of warmup for upgraded nodes
|
||||
err = s.ds.Put(compactionIndexKey, int64ToBytes(s.compactionIndex))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error saving compaction index: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
// TrackingStore is a persistent store that tracks blocks that are added
|
||||
// to the hotstore, tracking the epoch at which they are written.
|
||||
type TrackingStore interface {
|
||||
Put(cid.Cid, abi.ChainEpoch) error
|
||||
PutBatch([]cid.Cid, abi.ChainEpoch) error
|
||||
Get(cid.Cid) (abi.ChainEpoch, error)
|
||||
Delete(cid.Cid) error
|
||||
DeleteBatch([]cid.Cid) error
|
||||
ForEach(func(cid.Cid, abi.ChainEpoch) error) error
|
||||
Sync() error
|
||||
Close() error
|
||||
}
|
||||
|
||||
// OpenTrackingStore opens a tracking store of the specified type in the
|
||||
// specified path.
|
||||
func OpenTrackingStore(path string, ttype string) (TrackingStore, error) {
|
||||
switch ttype {
|
||||
case "", "bolt":
|
||||
return OpenBoltTrackingStore(filepath.Join(path, "tracker.bolt"))
|
||||
case "mem":
|
||||
return NewMemTrackingStore(), nil
|
||||
default:
|
||||
return nil, xerrors.Errorf("unknown tracking store type %s", ttype)
|
||||
}
|
||||
}
|
||||
|
||||
// NewMemTrackingStore creates an in-memory tracking store.
|
||||
// This is only useful for test or situations where you don't want to open the
|
||||
// real tracking store (eg concurrent read only access on a node's datastore)
|
||||
func NewMemTrackingStore() *MemTrackingStore {
|
||||
return &MemTrackingStore{tab: make(map[cid.Cid]abi.ChainEpoch)}
|
||||
}
|
||||
|
||||
// MemTrackingStore is a simple in-memory tracking store
|
||||
type MemTrackingStore struct {
|
||||
sync.Mutex
|
||||
tab map[cid.Cid]abi.ChainEpoch
|
||||
}
|
||||
|
||||
var _ TrackingStore = (*MemTrackingStore)(nil)
|
||||
|
||||
func (s *MemTrackingStore) Put(cid cid.Cid, epoch abi.ChainEpoch) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.tab[cid] = epoch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemTrackingStore) PutBatch(cids []cid.Cid, epoch abi.ChainEpoch) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
for _, cid := range cids {
|
||||
s.tab[cid] = epoch
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemTrackingStore) Get(cid cid.Cid) (abi.ChainEpoch, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
epoch, ok := s.tab[cid]
|
||||
if ok {
|
||||
return epoch, nil
|
||||
}
|
||||
return 0, xerrors.Errorf("missing tracking epoch for %s", cid)
|
||||
}
|
||||
|
||||
func (s *MemTrackingStore) Delete(cid cid.Cid) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
delete(s.tab, cid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemTrackingStore) DeleteBatch(cids []cid.Cid) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
for _, cid := range cids {
|
||||
delete(s.tab, cid)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemTrackingStore) ForEach(f func(cid.Cid, abi.ChainEpoch) error) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
for cid, epoch := range s.tab {
|
||||
err := f(cid, epoch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemTrackingStore) Sync() error { return nil }
|
||||
func (s *MemTrackingStore) Close() error { return nil }
|
||||
@@ -1,120 +0,0 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
)
|
||||
|
||||
type BoltTrackingStore struct {
|
||||
db *bolt.DB
|
||||
bucketId []byte
|
||||
}
|
||||
|
||||
var _ TrackingStore = (*BoltTrackingStore)(nil)
|
||||
|
||||
func OpenBoltTrackingStore(path string) (*BoltTrackingStore, error) {
|
||||
opts := &bolt.Options{
|
||||
Timeout: 1 * time.Second,
|
||||
NoSync: true,
|
||||
}
|
||||
db, err := bolt.Open(path, 0644, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bucketId := []byte("tracker")
|
||||
err = db.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(bucketId)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error creating bolt db bucket %s: %w", string(bucketId), err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
_ = db.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BoltTrackingStore{db: db, bucketId: bucketId}, nil
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Put(cid cid.Cid, epoch abi.ChainEpoch) error {
|
||||
val := epochToBytes(epoch)
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.Put(cid.Hash(), val)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) PutBatch(cids []cid.Cid, epoch abi.ChainEpoch) error {
|
||||
val := epochToBytes(epoch)
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
for _, cid := range cids {
|
||||
err := b.Put(cid.Hash(), val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Get(cid cid.Cid) (epoch abi.ChainEpoch, err error) {
|
||||
err = s.db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
val := b.Get(cid.Hash())
|
||||
if val == nil {
|
||||
return xerrors.Errorf("missing tracking epoch for %s", cid)
|
||||
}
|
||||
epoch = bytesToEpoch(val)
|
||||
return nil
|
||||
})
|
||||
return epoch, err
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Delete(cid cid.Cid) error {
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.Delete(cid.Hash())
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) DeleteBatch(cids []cid.Cid) error {
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
for _, cid := range cids {
|
||||
err := b.Delete(cid.Hash())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error deleting %s", cid)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) ForEach(f func(cid.Cid, abi.ChainEpoch) error) error {
|
||||
return s.db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.ForEach(func(k, v []byte) error {
|
||||
cid := cid.NewCidV1(cid.Raw, k)
|
||||
epoch := bytesToEpoch(v)
|
||||
return f(cid, epoch)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Sync() error {
|
||||
return s.db.Sync()
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Close() error {
|
||||
return s.db.Close()
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
)
|
||||
|
||||
func TestBoltTrackingStore(t *testing.T) {
|
||||
testTrackingStore(t, "bolt")
|
||||
}
|
||||
|
||||
func testTrackingStore(t *testing.T, tsType string) {
|
||||
t.Helper()
|
||||
|
||||
makeCid := func(key string) cid.Cid {
|
||||
h, err := multihash.Sum([]byte(key), multihash.SHA2_256, -1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return cid.NewCidV1(cid.Raw, h)
|
||||
}
|
||||
|
||||
mustHave := func(s TrackingStore, cid cid.Cid, epoch abi.ChainEpoch) {
|
||||
val, err := s.Get(cid)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if val != epoch {
|
||||
t.Fatal("epoch mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
mustNotHave := func(s TrackingStore, cid cid.Cid) {
|
||||
_, err := s.Get(cid)
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
path, err := ioutil.TempDir("", "snoop-test.*")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s, err := OpenTrackingStore(path, tsType)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
k1 := makeCid("a")
|
||||
k2 := makeCid("b")
|
||||
k3 := makeCid("c")
|
||||
k4 := makeCid("d")
|
||||
|
||||
s.Put(k1, 1) //nolint
|
||||
s.Put(k2, 2) //nolint
|
||||
s.Put(k3, 3) //nolint
|
||||
s.Put(k4, 4) //nolint
|
||||
|
||||
mustHave(s, k1, 1)
|
||||
mustHave(s, k2, 2)
|
||||
mustHave(s, k3, 3)
|
||||
mustHave(s, k4, 4)
|
||||
|
||||
s.Delete(k1) // nolint
|
||||
s.Delete(k2) // nolint
|
||||
|
||||
mustNotHave(s, k1)
|
||||
mustNotHave(s, k2)
|
||||
mustHave(s, k3, 3)
|
||||
mustHave(s, k4, 4)
|
||||
|
||||
s.PutBatch([]cid.Cid{k1}, 1) //nolint
|
||||
s.PutBatch([]cid.Cid{k2}, 2) //nolint
|
||||
|
||||
mustHave(s, k1, 1)
|
||||
mustHave(s, k2, 2)
|
||||
mustHave(s, k3, 3)
|
||||
mustHave(s, k4, 4)
|
||||
|
||||
allKeys := map[string]struct{}{
|
||||
k1.String(): {},
|
||||
k2.String(): {},
|
||||
k3.String(): {},
|
||||
k4.String(): {},
|
||||
}
|
||||
|
||||
err = s.ForEach(func(k cid.Cid, _ abi.ChainEpoch) error {
|
||||
_, ok := allKeys[k.String()]
|
||||
if !ok {
|
||||
t.Fatal("unexpected key")
|
||||
}
|
||||
|
||||
delete(allKeys, k.String())
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(allKeys) != 0 {
|
||||
t.Fatal("not all keys were returned")
|
||||
}
|
||||
|
||||
// no close and reopen and ensure the keys still exist
|
||||
err = s.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s, err = OpenTrackingStore(path, tsType)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mustHave(s, k1, 1)
|
||||
mustHave(s, k2, 2)
|
||||
mustHave(s, k3, 3)
|
||||
mustHave(s, k4, 4)
|
||||
|
||||
s.Close() //nolint:errcheck
|
||||
}
|
||||
+11
-7
@@ -2,28 +2,32 @@ package build
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
)
|
||||
|
||||
//go:embed bootstrap
|
||||
var bootstrapfs embed.FS
|
||||
|
||||
func BuiltinBootstrap() ([]peer.AddrInfo, error) {
|
||||
if DisableBuiltinAssets {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b := rice.MustFindBox("bootstrap")
|
||||
|
||||
if BootstrappersFile != "" {
|
||||
spi := b.MustString(BootstrappersFile)
|
||||
if spi == "" {
|
||||
spi, err := bootstrapfs.ReadFile(path.Join("bootstrap", BootstrappersFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(spi) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return addrutil.ParseAddresses(context.TODO(), strings.Split(strings.TrimSpace(spi), "\n"))
|
||||
return addrutil.ParseAddresses(context.TODO(), strings.Split(strings.TrimSpace(string(spi)), "\n"))
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWRkaF18SR3E6qL6dkGrozT8QJUV5VbhE9E7BZtPmHqdWJ
|
||||
/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWJcJUc23WJjJHGSboGcU3t76z9Lb7CghrH2tiBiDCY4ux
|
||||
/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWBbZd7Su9XfLUQ12RynGQ3ZmGY1nGqFntmqop9pLNJE6g
|
||||
/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWGKRzEY4tJFTmAmrYUpa1CVVohmV9YjJbC9v5XWY2gUji
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWRLZAseMo9h7fRD6ojn6YYDXHsBSavX5YmjBZ9ngtAEec
|
||||
/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWJFtDXgZEQMEkjJPSrbfdvh2xfjVKrXeNFG1t8ioJXAzv
|
||||
/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWP1uB9Lo7yCA3S17TD4Y5wStP5Nk7Vqh53m8GsFjkyujD
|
||||
/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWLrPM4WPK1YRGPCUwndWcDX8GCYgms3DiuofUmxwvhMCn
|
||||
/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWJkikQQkxS58spo76BYzFt4fotaT5NpV2zngvrqm4u5ow
|
||||
/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWLce5FDHR4EX4CrYavphA5xS3uDsX6aoowXh5tzDUxJav
|
||||
/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWA9hFfQG9GjP6bHeuQQbMD3FDtZLdW1NayxKXUT26PQZu
|
||||
/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWMHDi3LVTFG8Szqogt7RkNXvonbQYqSazxBx41A5aeuVz
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/dns4/bootstrap-0.interop.fildev.network/tcp/1347/p2p/12D3KooWLGPq9JL1xwL6gHok7HSNxtK1Q5kyfg4Hk69ifRPghn4i
|
||||
/dns4/bootstrap-1.interop.fildev.network/tcp/1347/p2p/12D3KooWFYS1f31zafv8mqqYu8U3hEqYvaZ6avWzYU3BmZdpyH3h
|
||||
+7
-7
@@ -1,23 +1,23 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"embed"
|
||||
"path"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
)
|
||||
|
||||
// moved from now-defunct build/paramfetch.go
|
||||
var log = logging.Logger("build")
|
||||
|
||||
//go:embed genesis
|
||||
var genesisfs embed.FS
|
||||
|
||||
func MaybeGenesis() []byte {
|
||||
builtinGen, err := rice.FindBox("genesis")
|
||||
genBytes, err := genesisfs.ReadFile(path.Join("genesis", GenesisFile))
|
||||
if err != nil {
|
||||
log.Warnf("loading built-in genesis: %s", err)
|
||||
return nil
|
||||
}
|
||||
genBytes, err := builtinGen.Bytes(GenesisFile)
|
||||
if err != nil {
|
||||
log.Warnf("loading built-in genesis: %s", err)
|
||||
}
|
||||
|
||||
return genBytes
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+16
-5
@@ -3,13 +3,15 @@ package build
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
|
||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||
)
|
||||
|
||||
//go:embed openrpc
|
||||
var openrpcfs embed.FS
|
||||
|
||||
func mustReadGzippedOpenRPCDocument(data []byte) apitypes.OpenRPCDocument {
|
||||
zr, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
@@ -28,16 +30,25 @@ func mustReadGzippedOpenRPCDocument(data []byte) apitypes.OpenRPCDocument {
|
||||
}
|
||||
|
||||
func OpenRPCDiscoverJSON_Full() apitypes.OpenRPCDocument {
|
||||
data := rice.MustFindBox("openrpc").MustBytes("full.json.gz")
|
||||
data, err := openrpcfs.ReadFile("openrpc/full.json.gz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return mustReadGzippedOpenRPCDocument(data)
|
||||
}
|
||||
|
||||
func OpenRPCDiscoverJSON_Miner() apitypes.OpenRPCDocument {
|
||||
data := rice.MustFindBox("openrpc").MustBytes("miner.json.gz")
|
||||
data, err := openrpcfs.ReadFile("openrpc/miner.json.gz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return mustReadGzippedOpenRPCDocument(data)
|
||||
}
|
||||
|
||||
func OpenRPCDiscoverJSON_Worker() apitypes.OpenRPCDocument {
|
||||
data := rice.MustFindBox("openrpc").MustBytes("worker.json.gz")
|
||||
data, err := openrpcfs.ReadFile("openrpc/worker.json.gz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return mustReadGzippedOpenRPCDocument(data)
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14
-2
@@ -1,7 +1,19 @@
|
||||
package build
|
||||
|
||||
import rice "github.com/GeertJohan/go.rice"
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed proof-params/parameters.json
|
||||
var params []byte
|
||||
|
||||
//go:embed proof-params/srs-inner-product.json
|
||||
var srs []byte
|
||||
|
||||
func ParametersJSON() []byte {
|
||||
return rice.MustFindBox("proof-params").MustBytes("parameters.json")
|
||||
return params
|
||||
}
|
||||
|
||||
func SrsJSON() []byte {
|
||||
return srs
|
||||
}
|
||||
|
||||
+17
-14
@@ -24,27 +24,29 @@ var UpgradeIgnitionHeight = abi.ChainEpoch(-2)
|
||||
var UpgradeRefuelHeight = abi.ChainEpoch(-3)
|
||||
var UpgradeTapeHeight = abi.ChainEpoch(-4)
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(10)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
|
||||
var UpgradeAssemblyHeight = abi.ChainEpoch(-5)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-6)
|
||||
|
||||
var UpgradeKumquatHeight = abi.ChainEpoch(15)
|
||||
var UpgradeCalicoHeight = abi.ChainEpoch(20)
|
||||
var UpgradePersianHeight = abi.ChainEpoch(25)
|
||||
var UpgradeOrangeHeight = abi.ChainEpoch(27)
|
||||
var UpgradeClausHeight = abi.ChainEpoch(30)
|
||||
var UpgradeKumquatHeight = abi.ChainEpoch(-7)
|
||||
var UpgradeCalicoHeight = abi.ChainEpoch(-8)
|
||||
var UpgradePersianHeight = abi.ChainEpoch(-9)
|
||||
var UpgradeOrangeHeight = abi.ChainEpoch(-10)
|
||||
var UpgradeClausHeight = abi.ChainEpoch(-11)
|
||||
|
||||
var UpgradeActorsV3Height = abi.ChainEpoch(35)
|
||||
var UpgradeTrustHeight = abi.ChainEpoch(-12)
|
||||
|
||||
var UpgradeNorwegianHeight = abi.ChainEpoch(40)
|
||||
var UpgradeNorwegianHeight = abi.ChainEpoch(-13)
|
||||
|
||||
var UpgradeActorsV4Height = abi.ChainEpoch(45)
|
||||
var UpgradeTurboHeight = abi.ChainEpoch(-14)
|
||||
|
||||
var UpgradeHyperdriveHeight = abi.ChainEpoch(-15)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
func init() {
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1, abi.RegisteredSealProof_StackedDrg8MiBV1)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10))
|
||||
@@ -68,16 +70,17 @@ func init() {
|
||||
UpgradeIgnitionHeight = getUpgradeHeight("LOTUS_IGNITION_HEIGHT", UpgradeIgnitionHeight)
|
||||
UpgradeRefuelHeight = getUpgradeHeight("LOTUS_REFUEL_HEIGHT", UpgradeRefuelHeight)
|
||||
UpgradeTapeHeight = getUpgradeHeight("LOTUS_TAPE_HEIGHT", UpgradeTapeHeight)
|
||||
UpgradeActorsV2Height = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeActorsV2Height)
|
||||
UpgradeAssemblyHeight = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeAssemblyHeight)
|
||||
UpgradeLiftoffHeight = getUpgradeHeight("LOTUS_LIFTOFF_HEIGHT", UpgradeLiftoffHeight)
|
||||
UpgradeKumquatHeight = getUpgradeHeight("LOTUS_KUMQUAT_HEIGHT", UpgradeKumquatHeight)
|
||||
UpgradeCalicoHeight = getUpgradeHeight("LOTUS_CALICO_HEIGHT", UpgradeCalicoHeight)
|
||||
UpgradePersianHeight = getUpgradeHeight("LOTUS_PERSIAN_HEIGHT", UpgradePersianHeight)
|
||||
UpgradeOrangeHeight = getUpgradeHeight("LOTUS_ORANGE_HEIGHT", UpgradeOrangeHeight)
|
||||
UpgradeClausHeight = getUpgradeHeight("LOTUS_CLAUS_HEIGHT", UpgradeClausHeight)
|
||||
UpgradeActorsV3Height = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeActorsV3Height)
|
||||
UpgradeTrustHeight = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeTrustHeight)
|
||||
UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight)
|
||||
UpgradeActorsV4Height = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeActorsV4Height)
|
||||
UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight)
|
||||
UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight)
|
||||
|
||||
BuildType |= Build2k
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const UpgradeSmokeHeight = -2
|
||||
const UpgradeIgnitionHeight = -3
|
||||
const UpgradeRefuelHeight = -4
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(30)
|
||||
var UpgradeAssemblyHeight = abi.ChainEpoch(30)
|
||||
|
||||
const UpgradeTapeHeight = 60
|
||||
const UpgradeLiftoffHeight = -5
|
||||
@@ -32,9 +32,10 @@ const UpgradeCalicoHeight = 120
|
||||
const UpgradePersianHeight = 150
|
||||
const UpgradeClausHeight = 180
|
||||
const UpgradeOrangeHeight = 210
|
||||
const UpgradeActorsV3Height = 240
|
||||
const UpgradeNorwegianHeight = UpgradeActorsV3Height + (builtin2.EpochsInHour * 12)
|
||||
const UpgradeActorsV4Height = 8922
|
||||
const UpgradeTrustHeight = 240
|
||||
const UpgradeNorwegianHeight = UpgradeTrustHeight + (builtin2.EpochsInHour * 12)
|
||||
const UpgradeTurboHeight = 8922
|
||||
const UpgradeHyperdriveHeight = 9999999
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2 << 30))
|
||||
|
||||
@@ -25,7 +25,7 @@ const UpgradeSmokeHeight = -2
|
||||
const UpgradeIgnitionHeight = -3
|
||||
const UpgradeRefuelHeight = -4
|
||||
|
||||
var UpgradeActorsV2Height = abi.ChainEpoch(30)
|
||||
var UpgradeAssemblyHeight = abi.ChainEpoch(30)
|
||||
|
||||
const UpgradeTapeHeight = 60
|
||||
|
||||
@@ -33,17 +33,20 @@ const UpgradeLiftoffHeight = -5
|
||||
|
||||
const UpgradeKumquatHeight = 90
|
||||
|
||||
const UpgradeCalicoHeight = 100
|
||||
const UpgradeCalicoHeight = 120
|
||||
const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 1)
|
||||
|
||||
const UpgradeClausHeight = 250
|
||||
const UpgradeClausHeight = 270
|
||||
|
||||
const UpgradeOrangeHeight = 300
|
||||
|
||||
const UpgradeActorsV3Height = 600
|
||||
const UpgradeNorwegianHeight = 114000
|
||||
const UpgradeTrustHeight = 330
|
||||
|
||||
const UpgradeActorsV4Height = 193789
|
||||
const UpgradeNorwegianHeight = 360
|
||||
|
||||
const UpgradeTurboHeight = 390
|
||||
|
||||
const UpgradeHyperdriveHeight = 420
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(32 << 30))
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
// +build interopnet
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
)
|
||||
|
||||
const BootstrappersFile = "interopnet.pi"
|
||||
const GenesisFile = "interopnet.car"
|
||||
|
||||
var UpgradeBreezeHeight = abi.ChainEpoch(-1)
|
||||
|
||||
const BreezeGasTampingDuration = 0
|
||||
|
||||
var UpgradeSmokeHeight = abi.ChainEpoch(-1)
|
||||
var UpgradeIgnitionHeight = abi.ChainEpoch(-2)
|
||||
var UpgradeRefuelHeight = abi.ChainEpoch(-3)
|
||||
var UpgradeTapeHeight = abi.ChainEpoch(-4)
|
||||
|
||||
var UpgradeAssemblyHeight = abi.ChainEpoch(-5)
|
||||
var UpgradeLiftoffHeight = abi.ChainEpoch(-6)
|
||||
|
||||
var UpgradeKumquatHeight = abi.ChainEpoch(-7)
|
||||
var UpgradeCalicoHeight = abi.ChainEpoch(-8)
|
||||
var UpgradePersianHeight = abi.ChainEpoch(-9)
|
||||
var UpgradeOrangeHeight = abi.ChainEpoch(-10)
|
||||
var UpgradeClausHeight = abi.ChainEpoch(-11)
|
||||
|
||||
var UpgradeTrustHeight = abi.ChainEpoch(-12)
|
||||
|
||||
var UpgradeNorwegianHeight = abi.ChainEpoch(-13)
|
||||
|
||||
var UpgradeTurboHeight = abi.ChainEpoch(-14)
|
||||
|
||||
var UpgradeHyperdriveHeight = abi.ChainEpoch(-15)
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
func init() {
|
||||
policy.SetSupportedProofTypes(
|
||||
abi.RegisteredSealProof_StackedDrg2KiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg8MiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
||||
)
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
|
||||
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
|
||||
policy.SetPreCommitChallengeDelay(abi.ChainEpoch(10))
|
||||
|
||||
getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch {
|
||||
hs, found := os.LookupEnv(ev)
|
||||
if found {
|
||||
h, err := strconv.Atoi(hs)
|
||||
if err != nil {
|
||||
log.Panicf("failed to parse %s env var", ev)
|
||||
}
|
||||
|
||||
return abi.ChainEpoch(h)
|
||||
}
|
||||
|
||||
return def
|
||||
}
|
||||
|
||||
UpgradeBreezeHeight = getUpgradeHeight("LOTUS_BREEZE_HEIGHT", UpgradeBreezeHeight)
|
||||
UpgradeSmokeHeight = getUpgradeHeight("LOTUS_SMOKE_HEIGHT", UpgradeSmokeHeight)
|
||||
UpgradeIgnitionHeight = getUpgradeHeight("LOTUS_IGNITION_HEIGHT", UpgradeIgnitionHeight)
|
||||
UpgradeRefuelHeight = getUpgradeHeight("LOTUS_REFUEL_HEIGHT", UpgradeRefuelHeight)
|
||||
UpgradeTapeHeight = getUpgradeHeight("LOTUS_TAPE_HEIGHT", UpgradeTapeHeight)
|
||||
UpgradeAssemblyHeight = getUpgradeHeight("LOTUS_ACTORSV2_HEIGHT", UpgradeAssemblyHeight)
|
||||
UpgradeLiftoffHeight = getUpgradeHeight("LOTUS_LIFTOFF_HEIGHT", UpgradeLiftoffHeight)
|
||||
UpgradeKumquatHeight = getUpgradeHeight("LOTUS_KUMQUAT_HEIGHT", UpgradeKumquatHeight)
|
||||
UpgradeCalicoHeight = getUpgradeHeight("LOTUS_CALICO_HEIGHT", UpgradeCalicoHeight)
|
||||
UpgradePersianHeight = getUpgradeHeight("LOTUS_PERSIAN_HEIGHT", UpgradePersianHeight)
|
||||
UpgradeOrangeHeight = getUpgradeHeight("LOTUS_ORANGE_HEIGHT", UpgradeOrangeHeight)
|
||||
UpgradeClausHeight = getUpgradeHeight("LOTUS_CLAUS_HEIGHT", UpgradeClausHeight)
|
||||
UpgradeTrustHeight = getUpgradeHeight("LOTUS_ACTORSV3_HEIGHT", UpgradeTrustHeight)
|
||||
UpgradeNorwegianHeight = getUpgradeHeight("LOTUS_NORWEGIAN_HEIGHT", UpgradeNorwegianHeight)
|
||||
UpgradeTurboHeight = getUpgradeHeight("LOTUS_ACTORSV4_HEIGHT", UpgradeTurboHeight)
|
||||
UpgradeHyperdriveHeight = getUpgradeHeight("LOTUS_HYPERDRIVE_HEIGHT", UpgradeHyperdriveHeight)
|
||||
|
||||
BuildType |= BuildInteropnet
|
||||
SetAddressNetwork(address.Testnet)
|
||||
Devnet = true
|
||||
}
|
||||
|
||||
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
||||
|
||||
const PropagationDelaySecs = uint64(6)
|
||||
|
||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||
const BootstrapPeerThreshold = 2
|
||||
|
||||
var WhitelistedBlock = cid.Undef
|
||||
+10
-13
@@ -4,6 +4,7 @@
|
||||
// +build !calibnet
|
||||
// +build !nerpanet
|
||||
// +build !butterflynet
|
||||
// +build !interopnet
|
||||
|
||||
package build
|
||||
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/lotus/chain/actors/policy"
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ const UpgradeSmokeHeight = 51000
|
||||
const UpgradeIgnitionHeight = 94000
|
||||
const UpgradeRefuelHeight = 130800
|
||||
|
||||
const UpgradeActorsV2Height = 138720
|
||||
const UpgradeAssemblyHeight = 138720
|
||||
|
||||
const UpgradeTapeHeight = 140760
|
||||
|
||||
@@ -51,30 +51,27 @@ const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
|
||||
const UpgradeOrangeHeight = 336458
|
||||
|
||||
// 2020-12-22T02:00:00Z
|
||||
const UpgradeClausHeight = 343200
|
||||
var UpgradeClausHeight = abi.ChainEpoch(343200)
|
||||
|
||||
// 2021-03-04T00:00:30Z
|
||||
var UpgradeActorsV3Height = abi.ChainEpoch(550321)
|
||||
const UpgradeTrustHeight = 550321
|
||||
|
||||
// 2021-04-12T22:00:00Z
|
||||
const UpgradeNorwegianHeight = 665280
|
||||
|
||||
// 2021-04-29T06:00:00Z
|
||||
var UpgradeActorsV4Height = abi.ChainEpoch(712320)
|
||||
const UpgradeTurboHeight = 712320
|
||||
|
||||
// 2021-06-30T22:00:00Z
|
||||
var UpgradeHyperdriveHeight = abi.ChainEpoch(892800)
|
||||
|
||||
func init() {
|
||||
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
|
||||
|
||||
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
|
||||
SetAddressNetwork(address.Mainnet)
|
||||
}
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V3_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV3Height = math.MaxInt64
|
||||
}
|
||||
|
||||
if os.Getenv("LOTUS_DISABLE_V4_ACTOR_MIGRATION") == "1" {
|
||||
UpgradeActorsV4Height = math.MaxInt64
|
||||
if os.Getenv("LOTUS_DISABLE_HYPERDRIVE") == "1" {
|
||||
UpgradeHyperdriveHeight = math.MaxInt64
|
||||
}
|
||||
|
||||
Devnet = false
|
||||
|
||||
@@ -27,7 +27,7 @@ const UpgradeRefuelHeight = -3
|
||||
|
||||
const UpgradeLiftoffHeight = -5
|
||||
|
||||
const UpgradeActorsV2Height = 30 // critical: the network can bootstrap from v1 only
|
||||
const UpgradeAssemblyHeight = 30 // critical: the network can bootstrap from v1 only
|
||||
const UpgradeTapeHeight = 60
|
||||
|
||||
const UpgradeKumquatHeight = 90
|
||||
@@ -39,9 +39,10 @@ const UpgradeClausHeight = 250
|
||||
|
||||
const UpgradeOrangeHeight = 300
|
||||
|
||||
const UpgradeActorsV3Height = 600
|
||||
const UpgradeTrustHeight = 600
|
||||
const UpgradeNorwegianHeight = 201000
|
||||
const UpgradeActorsV4Height = 203000
|
||||
const UpgradeTurboHeight = 203000
|
||||
const UpgradeHyperdriveHeight = 999999999
|
||||
|
||||
func init() {
|
||||
// Minimum block production power is set to 4 TiB
|
||||
|
||||
@@ -25,7 +25,7 @@ const UnixfsLinksPerLevel = 1024
|
||||
// Consensus / Network
|
||||
|
||||
const AllowableClockDriftSecs = uint64(1)
|
||||
const NewestNetworkVersion = network.Version11
|
||||
const NewestNetworkVersion = network.Version13
|
||||
const ActorUpgradeNetworkVersion = network.Version4
|
||||
|
||||
// Epochs
|
||||
|
||||
+15
-14
@@ -82,20 +82,21 @@ var (
|
||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
||||
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeActorsV2Height abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -7
|
||||
UpgradePersianHeight abi.ChainEpoch = -8
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -9
|
||||
UpgradeClausHeight abi.ChainEpoch = -10
|
||||
UpgradeActorsV3Height abi.ChainEpoch = -11
|
||||
UpgradeNorwegianHeight abi.ChainEpoch = -12
|
||||
UpgradeActorsV4Height abi.ChainEpoch = -13
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeAssemblyHeight abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -7
|
||||
UpgradePersianHeight abi.ChainEpoch = -8
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -9
|
||||
UpgradeClausHeight abi.ChainEpoch = -10
|
||||
UpgradeTrustHeight abi.ChainEpoch = -11
|
||||
UpgradeNorwegianHeight abi.ChainEpoch = -12
|
||||
UpgradeTurboHeight abi.ChainEpoch = -13
|
||||
UpgradeHyperdriveHeight abi.ChainEpoch = -13
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"v28-fil-inner-product-v1.srs": {
|
||||
"cid": "Qmdq44DjcQnFfU3PJcdX7J49GCqcUYszr1TxMbHtAkvQ3g",
|
||||
"digest": "ae20310138f5ba81451d723f858e3797",
|
||||
"sector_size": 0
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,5 @@ import (
|
||||
_ "github.com/GeertJohan/go.rice/rice"
|
||||
_ "github.com/golang/mock/mockgen"
|
||||
_ "github.com/whyrusleeping/bencher"
|
||||
_ "golang.org/x/tools/cmd/stringer"
|
||||
)
|
||||
|
||||
+15
-6
@@ -1,14 +1,17 @@
|
||||
package build
|
||||
|
||||
import "os"
|
||||
|
||||
var CurrentCommit string
|
||||
var BuildType int
|
||||
|
||||
const (
|
||||
BuildDefault = 0
|
||||
BuildMainnet = 0x1
|
||||
Build2k = 0x2
|
||||
BuildDebug = 0x3
|
||||
BuildCalibnet = 0x4
|
||||
BuildDefault = 0
|
||||
BuildMainnet = 0x1
|
||||
Build2k = 0x2
|
||||
BuildDebug = 0x3
|
||||
BuildCalibnet = 0x4
|
||||
BuildInteropnet = 0x5
|
||||
)
|
||||
|
||||
func buildType() string {
|
||||
@@ -23,14 +26,20 @@ func buildType() string {
|
||||
return "+debug"
|
||||
case BuildCalibnet:
|
||||
return "+calibnet"
|
||||
case BuildInteropnet:
|
||||
return "+interopnet"
|
||||
default:
|
||||
return "+huh?"
|
||||
}
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version, set by build system
|
||||
const BuildVersion = "1.9.0"
|
||||
const BuildVersion = "1.11.1-dev"
|
||||
|
||||
func UserVersion() string {
|
||||
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
|
||||
return BuildVersion
|
||||
}
|
||||
|
||||
return BuildVersion + buildType() + CurrentCommit
|
||||
}
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
lotusactors "github.com/filecoin-project/lotus/chain/actors"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var actors = map[string][]int{
|
||||
"account": lotusactors.Versions,
|
||||
"cron": lotusactors.Versions,
|
||||
"init": lotusactors.Versions,
|
||||
"market": lotusactors.Versions,
|
||||
"miner": lotusactors.Versions,
|
||||
"multisig": lotusactors.Versions,
|
||||
"paych": lotusactors.Versions,
|
||||
"power": lotusactors.Versions,
|
||||
"system": lotusactors.Versions,
|
||||
"reward": lotusactors.Versions,
|
||||
"verifreg": lotusactors.Versions,
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := generateAdapters(); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := generatePolicy("chain/actors/policy/policy.go"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := generateBuiltin("chain/actors/builtin/builtin.go"); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func generateAdapters() error {
|
||||
for act, versions := range actors {
|
||||
actDir := filepath.Join("chain/actors/builtin", act)
|
||||
|
||||
if err := generateState(actDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := generateMessages(actDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
af, err := ioutil.ReadFile(filepath.Join(actDir, "actor.go.template"))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("loading actor template: %w", err)
|
||||
}
|
||||
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"import": func(v int) string { return getVersionImports()[v] },
|
||||
}).Parse(string(af)))
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&b, map[string]interface{}{
|
||||
"versions": versions,
|
||||
"latestVersion": lotusactors.LatestVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("%s.go", act)), b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateState(actDir string) error {
|
||||
af, err := ioutil.ReadFile(filepath.Join(actDir, "state.go.template"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading state adapter template: %w", err)
|
||||
}
|
||||
|
||||
for _, version := range lotusactors.Versions {
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af)))
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
err := tpl.Execute(&b, map[string]interface{}{
|
||||
"v": version,
|
||||
"import": getVersionImports()[version],
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("v%d.go", version)), b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateMessages(actDir string) error {
|
||||
af, err := ioutil.ReadFile(filepath.Join(actDir, "message.go.template"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading message adapter template: %w", err)
|
||||
}
|
||||
|
||||
for _, version := range lotusactors.Versions {
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{}).Parse(string(af)))
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
err := tpl.Execute(&b, map[string]interface{}{
|
||||
"v": version,
|
||||
"import": getVersionImports()[version],
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(actDir, fmt.Sprintf("message%d.go", version)), b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generatePolicy(policyPath string) error {
|
||||
|
||||
pf, err := ioutil.ReadFile(policyPath + ".template")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading policy template file: %w", err)
|
||||
}
|
||||
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"import": func(v int) string { return getVersionImports()[v] },
|
||||
}).Parse(string(pf)))
|
||||
var b bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&b, map[string]interface{}{
|
||||
"versions": lotusactors.Versions,
|
||||
"latestVersion": lotusactors.LatestVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(policyPath, b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateBuiltin(builtinPath string) error {
|
||||
|
||||
bf, err := ioutil.ReadFile(builtinPath + ".template")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil // skip
|
||||
}
|
||||
|
||||
return xerrors.Errorf("loading builtin template file: %w", err)
|
||||
}
|
||||
|
||||
tpl := template.Must(template.New("").Funcs(template.FuncMap{
|
||||
"import": func(v int) string { return getVersionImports()[v] },
|
||||
}).Parse(string(bf)))
|
||||
var b bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&b, map[string]interface{}{
|
||||
"versions": lotusactors.Versions,
|
||||
"latestVersion": lotusactors.LatestVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(builtinPath, b.Bytes(), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getVersionImports() map[int]string {
|
||||
versionImports := make(map[int]string, lotusactors.LatestVersion)
|
||||
for _, v := range lotusactors.Versions {
|
||||
if v == 0 {
|
||||
versionImports[v] = "/"
|
||||
} else {
|
||||
versionImports[v] = "/v" + strconv.Itoa(v) + "/"
|
||||
}
|
||||
}
|
||||
|
||||
return versionImports
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -12,44 +13,111 @@ import (
|
||||
"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"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
builtin5 "github.com/filecoin-project/specs-actors/v5/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)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin3.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load3(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin4.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load4(store, root)
|
||||
})
|
||||
|
||||
builtin.RegisterActorState(builtin5.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load5(store, root)
|
||||
})
|
||||
}
|
||||
|
||||
var Methods = builtin4.MethodsAccount
|
||||
|
||||
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)
|
||||
|
||||
case builtin3.AccountActorCodeID:
|
||||
return load3(store, act.Head)
|
||||
|
||||
case builtin4.AccountActorCodeID:
|
||||
return load4(store, act.Head)
|
||||
|
||||
case builtin5.AccountActorCodeID:
|
||||
return load5(store, act.Head)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, error) {
|
||||
switch av {
|
||||
|
||||
case actors.Version0:
|
||||
return make0(store, addr)
|
||||
|
||||
case actors.Version2:
|
||||
return make2(store, addr)
|
||||
|
||||
case actors.Version3:
|
||||
return make3(store, addr)
|
||||
|
||||
case actors.Version4:
|
||||
return make4(store, addr)
|
||||
|
||||
case actors.Version5:
|
||||
return make5(store, addr)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
func GetActorCodeID(av actors.Version) (cid.Cid, error) {
|
||||
switch av {
|
||||
|
||||
case actors.Version0:
|
||||
return builtin0.AccountActorCodeID, nil
|
||||
|
||||
case actors.Version2:
|
||||
return builtin2.AccountActorCodeID, nil
|
||||
|
||||
case actors.Version3:
|
||||
return builtin3.AccountActorCodeID, nil
|
||||
|
||||
case actors.Version4:
|
||||
return builtin4.AccountActorCodeID, nil
|
||||
|
||||
case actors.Version5:
|
||||
return builtin5.AccountActorCodeID, nil
|
||||
|
||||
}
|
||||
|
||||
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
PubkeyAddress() (address.Address, error)
|
||||
GetState() interface{}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"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"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func init() {
|
||||
{{range .versions}}
|
||||
builtin.RegisterActorState(builtin{{.}}.AccountActorCodeID, func(store adt.Store, root cid.Cid) (cbor.Marshaler, error) {
|
||||
return load{{.}}(store, root)
|
||||
})
|
||||
{{end}}}
|
||||
|
||||
var Methods = builtin4.MethodsAccount
|
||||
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
switch act.Code {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.AccountActorCodeID:
|
||||
return load{{.}}(store, act.Head)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor code %s", act.Code)
|
||||
}
|
||||
|
||||
func MakeState(store adt.Store, av actors.Version, addr address.Address) (State, error) {
|
||||
switch av {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return make{{.}}(store, addr)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
func GetActorCodeID(av actors.Version) (cid.Cid, error) {
|
||||
switch av {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return builtin{{.}}.AccountActorCodeID, nil
|
||||
{{end}}
|
||||
}
|
||||
|
||||
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
type State interface {
|
||||
cbor.Marshaler
|
||||
|
||||
PubkeyAddress() (address.Address, error)
|
||||
GetState() interface{}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
account{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/account"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make{{.v}}(store adt.Store, addr address.Address) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
out.State = account{{.v}}.State{Address:addr}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
account{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
@@ -20,6 +20,12 @@ func load0(store adt.Store, root cid.Cid) (State, error) {
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make0(store adt.Store, addr address.Address) (State, error) {
|
||||
out := state0{store: store}
|
||||
out.State = account0.State{Address: addr}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state0 struct {
|
||||
account0.State
|
||||
store adt.Store
|
||||
@@ -28,3 +34,7 @@ type state0 struct {
|
||||
func (s *state0) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
|
||||
func (s *state0) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ func load2(store adt.Store, root cid.Cid) (State, error) {
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make2(store adt.Store, addr address.Address) (State, error) {
|
||||
out := state2{store: store}
|
||||
out.State = account2.State{Address: addr}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state2 struct {
|
||||
account2.State
|
||||
store adt.Store
|
||||
@@ -28,3 +34,7 @@ type state2 struct {
|
||||
func (s *state2) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
|
||||
func (s *state2) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make3(store adt.Store, addr address.Address) (State, error) {
|
||||
out := state3{store: store}
|
||||
out.State = account3.State{Address: addr}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state3 struct {
|
||||
account3.State
|
||||
store adt.Store
|
||||
@@ -28,3 +34,7 @@ type state3 struct {
|
||||
func (s *state3) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
|
||||
func (s *state3) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ func load4(store adt.Store, root cid.Cid) (State, error) {
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make4(store adt.Store, addr address.Address) (State, error) {
|
||||
out := state4{store: store}
|
||||
out.State = account4.State{Address: addr}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state4 struct {
|
||||
account4.State
|
||||
store adt.Store
|
||||
@@ -28,3 +34,7 @@ type state4 struct {
|
||||
func (s *state4) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
|
||||
func (s *state4) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
account5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/account"
|
||||
)
|
||||
|
||||
var _ State = (*state5)(nil)
|
||||
|
||||
func load5(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state5{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make5(store adt.Store, addr address.Address) (State, error) {
|
||||
out := state5{store: store}
|
||||
out.State = account5.State{Address: addr}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state5 struct {
|
||||
account5.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state5) PubkeyAddress() (address.Address, error) {
|
||||
return s.Address, nil
|
||||
}
|
||||
|
||||
func (s *state5) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
+160
-44
@@ -6,9 +6,19 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
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"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
|
||||
|
||||
builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin"
|
||||
smoothing5 "github.com/filecoin-project/specs-actors/v5/actors/util/smoothing"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/cbor"
|
||||
@@ -16,62 +26,70 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
|
||||
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
|
||||
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
|
||||
smoothing3 "github.com/filecoin-project/specs-actors/v3/actors/util/smoothing"
|
||||
smoothing4 "github.com/filecoin-project/specs-actors/v4/actors/util/smoothing"
|
||||
|
||||
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
|
||||
miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner"
|
||||
proof5 "github.com/filecoin-project/specs-actors/v5/actors/runtime/proof"
|
||||
)
|
||||
|
||||
var SystemActorAddr = builtin0.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin0.CronActorAddr
|
||||
var SystemActorAddr = builtin5.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin5.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin5.CronActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
var (
|
||||
ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch
|
||||
ExpectedLeadersPerEpoch = builtin5.ExpectedLeadersPerEpoch
|
||||
)
|
||||
|
||||
const (
|
||||
EpochDurationSeconds = builtin0.EpochDurationSeconds
|
||||
EpochsInDay = builtin0.EpochsInDay
|
||||
SecondsInDay = builtin0.SecondsInDay
|
||||
EpochDurationSeconds = builtin5.EpochDurationSeconds
|
||||
EpochsInDay = builtin5.EpochsInDay
|
||||
SecondsInDay = builtin5.SecondsInDay
|
||||
)
|
||||
|
||||
const (
|
||||
MethodSend = builtin4.MethodSend
|
||||
MethodConstructor = builtin4.MethodConstructor
|
||||
MethodSend = builtin5.MethodSend
|
||||
MethodConstructor = builtin5.MethodConstructor
|
||||
)
|
||||
|
||||
// These are all just type aliases across actor versions 0, 2, & 3. In the future, that might change
|
||||
// These are all just type aliases across actor versions. In the future, that might change
|
||||
// and we might need to do something fancier.
|
||||
type SectorInfo = proof0.SectorInfo
|
||||
type PoStProof = proof0.PoStProof
|
||||
type SectorInfo = proof5.SectorInfo
|
||||
type PoStProof = proof5.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
return (FilterEstimate)(v0) //nolint:unconvert
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner5.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
}
|
||||
|
||||
// Doesn't change between actors v0, v2, and v3.
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v0) //nolint:unconvert
|
||||
|
||||
}
|
||||
|
||||
func FromV2FilterEstimate(v2 smoothing2.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v2)
|
||||
|
||||
}
|
||||
|
||||
func FromV3FilterEstimate(v3 smoothing3.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v3)
|
||||
|
||||
}
|
||||
|
||||
func FromV4FilterEstimate(v4 smoothing4.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v4)
|
||||
|
||||
}
|
||||
|
||||
func FromV5FilterEstimate(v5 smoothing5.FilterEstimate) FilterEstimate {
|
||||
|
||||
return (FilterEstimate)(v5)
|
||||
|
||||
}
|
||||
|
||||
type ActorStateLoader func(store adt.Store, root cid.Cid) (cbor.Marshaler, error)
|
||||
@@ -92,52 +110,150 @@ func Load(store adt.Store, act *types.Actor) (cbor.Marshaler, error) {
|
||||
|
||||
func ActorNameByCode(c cid.Cid) string {
|
||||
switch {
|
||||
|
||||
case builtin0.IsBuiltinActor(c):
|
||||
return builtin0.ActorNameByCode(c)
|
||||
|
||||
case builtin2.IsBuiltinActor(c):
|
||||
return builtin2.ActorNameByCode(c)
|
||||
|
||||
case builtin3.IsBuiltinActor(c):
|
||||
return builtin3.ActorNameByCode(c)
|
||||
|
||||
case builtin4.IsBuiltinActor(c):
|
||||
return builtin4.ActorNameByCode(c)
|
||||
|
||||
case builtin5.IsBuiltinActor(c):
|
||||
return builtin5.ActorNameByCode(c)
|
||||
|
||||
default:
|
||||
return "<unknown>"
|
||||
}
|
||||
}
|
||||
|
||||
func IsBuiltinActor(c cid.Cid) bool {
|
||||
return builtin0.IsBuiltinActor(c) ||
|
||||
builtin2.IsBuiltinActor(c) ||
|
||||
builtin3.IsBuiltinActor(c) ||
|
||||
builtin4.IsBuiltinActor(c)
|
||||
|
||||
if builtin0.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin2.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin3.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin4.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
if builtin5.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsAccountActor(c cid.Cid) bool {
|
||||
return c == builtin0.AccountActorCodeID ||
|
||||
c == builtin2.AccountActorCodeID ||
|
||||
c == builtin3.AccountActorCodeID ||
|
||||
c == builtin4.AccountActorCodeID
|
||||
|
||||
if c == builtin0.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin5.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsStorageMinerActor(c cid.Cid) bool {
|
||||
return c == builtin0.StorageMinerActorCodeID ||
|
||||
c == builtin2.StorageMinerActorCodeID ||
|
||||
c == builtin3.StorageMinerActorCodeID ||
|
||||
c == builtin4.StorageMinerActorCodeID
|
||||
|
||||
if c == builtin0.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin5.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsMultisigActor(c cid.Cid) bool {
|
||||
return c == builtin0.MultisigActorCodeID ||
|
||||
c == builtin2.MultisigActorCodeID ||
|
||||
c == builtin3.MultisigActorCodeID ||
|
||||
c == builtin4.MultisigActorCodeID
|
||||
|
||||
if c == builtin0.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin5.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsPaymentChannelActor(c cid.Cid) bool {
|
||||
return c == builtin0.PaymentChannelActorCodeID ||
|
||||
c == builtin2.PaymentChannelActorCodeID ||
|
||||
c == builtin3.PaymentChannelActorCodeID ||
|
||||
c == builtin4.PaymentChannelActorCodeID
|
||||
|
||||
if c == builtin0.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin2.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin3.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin4.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
if c == builtin5.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func makeAddress(addr string) address.Address {
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package builtin
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
smoothing{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/util/smoothing"
|
||||
{{end}}
|
||||
|
||||
"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"
|
||||
|
||||
miner{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/builtin/miner"
|
||||
proof{{.latestVersion}} "github.com/filecoin-project/specs-actors{{import .latestVersion}}actors/runtime/proof"
|
||||
)
|
||||
|
||||
var SystemActorAddr = builtin{{.latestVersion}}.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin{{.latestVersion}}.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin{{.latestVersion}}.CronActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
var (
|
||||
ExpectedLeadersPerEpoch = builtin{{.latestVersion}}.ExpectedLeadersPerEpoch
|
||||
)
|
||||
|
||||
const (
|
||||
EpochDurationSeconds = builtin{{.latestVersion}}.EpochDurationSeconds
|
||||
EpochsInDay = builtin{{.latestVersion}}.EpochsInDay
|
||||
SecondsInDay = builtin{{.latestVersion}}.SecondsInDay
|
||||
)
|
||||
|
||||
const (
|
||||
MethodSend = builtin{{.latestVersion}}.MethodSend
|
||||
MethodConstructor = builtin{{.latestVersion}}.MethodConstructor
|
||||
)
|
||||
|
||||
// These are all just type aliases across actor versions. In the future, that might change
|
||||
// and we might need to do something fancier.
|
||||
type SectorInfo = proof{{.latestVersion}}.SectorInfo
|
||||
type PoStProof = proof{{.latestVersion}}.PoStProof
|
||||
type FilterEstimate = smoothing0.FilterEstimate
|
||||
|
||||
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
|
||||
return miner{{.latestVersion}}.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
|
||||
}
|
||||
|
||||
{{range .versions}}
|
||||
func FromV{{.}}FilterEstimate(v{{.}} smoothing{{.}}.FilterEstimate) FilterEstimate {
|
||||
{{if (eq . 0)}}
|
||||
return (FilterEstimate)(v{{.}}) //nolint:unconvert
|
||||
{{else}}
|
||||
return (FilterEstimate)(v{{.}})
|
||||
{{end}}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
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 {
|
||||
{{range .versions}}
|
||||
case builtin{{.}}.IsBuiltinActor(c):
|
||||
return builtin{{.}}.ActorNameByCode(c)
|
||||
{{end}}
|
||||
default:
|
||||
return "<unknown>"
|
||||
}
|
||||
}
|
||||
|
||||
func IsBuiltinActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if builtin{{.}}.IsBuiltinActor(c) {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsAccountActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.AccountActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsStorageMinerActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.StorageMinerActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsMultisigActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.MultisigActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsPaymentChannelActor(c cid.Cid) bool {
|
||||
{{range .versions}}
|
||||
if c == builtin{{.}}.PaymentChannelActorCodeID {
|
||||
return true
|
||||
}
|
||||
{{end}}
|
||||
return false
|
||||
}
|
||||
|
||||
func makeAddress(addr string) address.Address {
|
||||
ret, err := address.NewFromString(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"golang.org/x/xerrors"
|
||||
"github.com/ipfs/go-cid"
|
||||
{{range .versions}}
|
||||
builtin{{.}} "github.com/filecoin-project/specs-actors{{import .}}actors/builtin"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
switch av {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return make{{.}}(store)
|
||||
{{end}}
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
func GetActorCodeID(av actors.Version) (cid.Cid, error) {
|
||||
switch av {
|
||||
{{range .versions}}
|
||||
case actors.Version{{.}}:
|
||||
return builtin{{.}}.CronActorCodeID, nil
|
||||
{{end}}
|
||||
}
|
||||
|
||||
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
var (
|
||||
Address = builtin{{.latestVersion}}.CronActorAddr
|
||||
Methods = builtin{{.latestVersion}}.MethodsCron
|
||||
)
|
||||
|
||||
|
||||
type State interface {
|
||||
GetState() interface{}
|
||||
}
|
||||
@@ -1,10 +1,72 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
"github.com/ipfs/go-cid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
|
||||
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
|
||||
|
||||
builtin3 "github.com/filecoin-project/specs-actors/v3/actors/builtin"
|
||||
|
||||
builtin4 "github.com/filecoin-project/specs-actors/v4/actors/builtin"
|
||||
|
||||
builtin5 "github.com/filecoin-project/specs-actors/v5/actors/builtin"
|
||||
)
|
||||
|
||||
func MakeState(store adt.Store, av actors.Version) (State, error) {
|
||||
switch av {
|
||||
|
||||
case actors.Version0:
|
||||
return make0(store)
|
||||
|
||||
case actors.Version2:
|
||||
return make2(store)
|
||||
|
||||
case actors.Version3:
|
||||
return make3(store)
|
||||
|
||||
case actors.Version4:
|
||||
return make4(store)
|
||||
|
||||
case actors.Version5:
|
||||
return make5(store)
|
||||
|
||||
}
|
||||
return nil, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
func GetActorCodeID(av actors.Version) (cid.Cid, error) {
|
||||
switch av {
|
||||
|
||||
case actors.Version0:
|
||||
return builtin0.CronActorCodeID, nil
|
||||
|
||||
case actors.Version2:
|
||||
return builtin2.CronActorCodeID, nil
|
||||
|
||||
case actors.Version3:
|
||||
return builtin3.CronActorCodeID, nil
|
||||
|
||||
case actors.Version4:
|
||||
return builtin4.CronActorCodeID, nil
|
||||
|
||||
case actors.Version5:
|
||||
return builtin5.CronActorCodeID, nil
|
||||
|
||||
}
|
||||
|
||||
return cid.Undef, xerrors.Errorf("unknown actor version %d", av)
|
||||
}
|
||||
|
||||
var (
|
||||
Address = builtin4.CronActorAddr
|
||||
Methods = builtin4.MethodsCron
|
||||
Address = builtin5.CronActorAddr
|
||||
Methods = builtin5.MethodsCron
|
||||
)
|
||||
|
||||
type State interface {
|
||||
GetState() interface{}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
cron{{.v}} "github.com/filecoin-project/specs-actors{{.import}}actors/builtin/cron"
|
||||
)
|
||||
|
||||
var _ State = (*state{{.v}})(nil)
|
||||
|
||||
func load{{.v}}(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make{{.v}}(store adt.Store) (State, error) {
|
||||
out := state{{.v}}{store: store}
|
||||
out.State = *cron{{.v}}.ConstructState(cron{{.v}}.BuiltInEntries())
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state{{.v}} struct {
|
||||
cron{{.v}}.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state{{.v}}) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func make0(store adt.Store) (State, error) {
|
||||
out := state0{store: store}
|
||||
out.State = *cron0.ConstructState(cron0.BuiltInEntries())
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state0 struct {
|
||||
cron0.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state0) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
cron2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/cron"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func make2(store adt.Store) (State, error) {
|
||||
out := state2{store: store}
|
||||
out.State = *cron2.ConstructState(cron2.BuiltInEntries())
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state2 struct {
|
||||
cron2.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state2) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors/adt"
|
||||
|
||||
cron3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/cron"
|
||||
)
|
||||
|
||||
var _ State = (*state3)(nil)
|
||||
|
||||
func load3(store adt.Store, root cid.Cid) (State, error) {
|
||||
out := state3{store: store}
|
||||
err := store.Get(store.Context(), root, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func make3(store adt.Store) (State, error) {
|
||||
out := state3{store: store}
|
||||
out.State = *cron3.ConstructState(cron3.BuiltInEntries())
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
type state3 struct {
|
||||
cron3.State
|
||||
store adt.Store
|
||||
}
|
||||
|
||||
func (s *state3) GetState() interface{} {
|
||||
return &s.State
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user