Compare commits

..
Author SHA1 Message Date
Aayush Rajasekaran 1ebad94da9 Merge pull request #4117 from filecoin-project/asr/changelog
Lotus version 0.8.1
2020-09-30 21:40:08 -04:00
Aayush Rajasekaran 636810daa5 Lotus version 0.8.1 2020-09-30 21:30:52 -04:00
Łukasz Magiera 954d806367 Merge pull request #4116 from filecoin-project/feat/sched-par-pcc2
sched: Allow some single-thread tasks to run in parallel with PC2/C2
2020-10-01 01:35:05 +02:00
Aayush Rajasekaran 7699f195f1 Merge pull request #4108 from filecoin-project/feat/nice-sectorslist
Improve miner sectors list UX
2020-09-30 19:07:23 -04:00
Łukasz Magiera 6981f776f4 Lower PC2 memory requirements 2020-10-01 00:54:53 +02:00
Łukasz Magiera 1b7cdb9341 Fix storage manager tests 2020-10-01 00:54:34 +02:00
Łukasz Magiera 5e08d56630 sched: Allow some single-thread tasks to run in parallel with PC2/C2 2020-10-01 00:28:44 +02:00
Łukasz Magiera feecee310d Merge pull request #4089 from filecoin-project/feat/update-markets-0.7.0
Markets 0.7.0 with updated data stores
2020-09-30 21:49:14 +02:00
hannahhoward be884e27be feat(markets): update markets 0.7.0 2020-09-30 10:26:50 -07:00
Łukasz Magiera 5bffea6f54 Merge pull request #4064 from filecoin-project/tvx
tvx: a test vector extraction and execution tool
2020-09-30 17:22:42 +02:00
Raúl Kripalani 1c4f8e83d7 tvx/extract-many: add batch id, change generated filename. 2020-09-30 16:11:44 +01:00
Raúl Kripalani ff8663faa0 update test-vectors submodule. 2020-09-30 14:58:22 +01:00
Raúl Kripalani f58881e966 minor fixes. 2020-09-30 14:57:24 +01:00
Łukasz Magiera d2f279c3de Print heman-readable transferred bytes in client list-transfers 2020-09-30 13:51:52 +02:00
Łukasz Magiera 4d4bab12eb Improve miner sectors list UX 2020-09-30 13:34:05 +02:00
Raúl Kripalani eb6191d0ff tvx: precursor selection modes; canonical message fetching; basefee. 2020-09-30 11:02:10 +01:00
Łukasz Magiera 54dfeb1fd9 Merge pull request #4043 from zgfzgf/test-post
add printf in TestWindowPost
2020-09-30 10:53:16 +02:00
Łukasz Magiera c2c64caefe Merge pull request #4020 from zgfzgf/post-trace
add trace wdpost
2020-09-30 10:46:05 +02:00
Łukasz Magiera 90be8d801b Merge branch 'master' into post-trace 2020-09-30 10:03:54 +02:00
Łukasz Magiera 430897c9ac Merge pull request #3445 from filecoin-project/asr/precommit-failed-fix
Fix some failed precommit handling
2020-09-30 09:35:41 +02:00
Aayush Rajasekaran c77ab47cb5 Merge pull request #4103 from filecoin-project/asr/config
Add an option to set config
2020-09-30 03:33:52 -04:00
Łukasz Magiera bc85e3ce50 Merge pull request #4107 from shaodan/worker-no-swap
Add --no-swap flag for worker
2020-09-30 09:25:57 +02:00
Łukasz Magiera 76b1ec1de0 Merge pull request #4065 from filecoin-project/asr/sync-validate
Add lotus shed util to validate a tipset
2020-09-30 09:24:47 +02:00
Aayush Rajasekaran 6abccc4d5e Add an option to set config 2020-09-30 03:19:04 -04:00
Łukasz Magiera 7a3a2f8db9 Merge pull request #3924 from filecoin-project/feat/dont-recompute-PoST-redux
Dont recompute post on revert <<redux>>
2020-09-30 09:18:46 +02:00
Łukasz Magiera 4e8ccb2158 Merge pull request #4092 from filecoin-project/fix/finalize-uns-panic
sectorstorage: Fix potential panic in FinalizeSector
2020-09-30 09:18:01 +02:00
Dan Shao 1affd498c1 Add --no-swap flag for worker 2020-09-30 14:23:35 +08:00
Aayush Rajasekaran e250429f56 Merge pull request #4106 from filecoin-project/asr/validate-address
Add an endpoint to validate whether a string is a well-formed address
2020-09-30 01:58:29 -04:00
Aayush Rajasekaran bc4cbdc895 Update docs 2020-09-30 01:45:03 -04:00
Aayush Rajasekaran a388bcfad6 Add an endpoint to validate whether a string is a well-formed address 2020-09-30 01:43:10 -04:00
Łukasz Magiera e39c5dc372 Merge pull request #4104 from filecoin-project/asr/wallet-fix
Fix wallet list
2020-09-30 07:41:10 +02:00
Aayush Rajasekaran c45c8f34a1 Parametrise whether sync validators should use cache 2020-09-30 01:39:06 -04:00
Aayush Rajasekaran 73d193bd9c Update docs 2020-09-30 01:29:04 -04:00
Aayush Rajasekaran a4e7117429 Add lotus shed util to validate a tipset 2020-09-30 01:29:04 -04:00
Aayush Rajasekaran 9fe32b7777 Fix wallet list 2020-09-30 01:25:47 -04:00
Łukasz Magiera 6025bceaa1 Merge pull request #3431 from filecoin-project/feat/docs-reorg
Docs review and re-organization
2020-09-29 22:29:58 +02:00
Łukasz Magiera 91d04ede0f Merge pull request #4051 from filecoin-project/chore/final-dealstat-version
Chore/final dealstat version
2020-09-29 19:39:16 +02:00
Łukasz Magiera 237c8c4deb Merge pull request #3868 from austinabell/async/stransition
Make state transition in validation async
2020-09-29 16:50:52 +02:00
Łukasz Magiera 0ba911279a Merge pull request #3888 from filecoin-project/feat/bench-cache
Implement caching syscalls for import-bench
2020-09-29 16:38:05 +02:00
Łukasz Magiera baef3c8dd2 sectorstorage: Fix potential panic in FinalizeSector 2020-09-29 15:22:46 +02:00
Łukasz Magiera 867ca2f25d Merge pull request #3434 from filecoin-project/feat/shed-import-object-cmd
add a command to import an ipld object into the chainstore
2020-09-29 15:02:31 +02:00
Jakub Sztandera 247a5e2c49 Go mod tidy
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:50:08 +02:00
Jakub Sztandera 7e8c6e5070 Remove statediff, fix lint, go mod tidy
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:47 +02:00
Jakub Sztandera 0d914ac1d4 Switch to badger
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:47 +02:00
Jakub Sztandera 76db65b1af Update pebble
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:47 +02:00
Jakub Sztandera ff8c0af8c8 Add only-import option
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:47 +02:00
Jakub Sztandera 55c6b88537 Add toggle for badger, flag out gas tracing
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:46 +02:00
Jakub Sztandera 0771c23fb0 Use pebble
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:46 +02:00
Jakub Sztandera 1c6214b76d Usage go-bitfield with buffer pool
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:45 +02:00
Jakub Sztandera b7f18b4601 Disable callers
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:18 +02:00
Jakub Sztandera 242a77b391 go mod tidy
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:18 +02:00
Jakub Sztandera 35cf69ae64 Disable bloomcache
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:18 +02:00
Jakub Sztandera ebc8489ff1 Add global-profile option
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:18 +02:00
Jakub Sztandera f21c5cbbe2 Add start-at
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:18 +02:00
Jakub Sztandera 01386a206c Update options
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:18 +02:00
Jakub Sztandera 3858309368 Add http to import bench
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 782717948a Add logs
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 108fe7823c Add command to trigger gc
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 12a0dd3d0a <3 to linter
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 1f4d1dcc58 Do not sync
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 53ab17cf50 Add no import to import-bench
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 79ba4598d6 Implement cache
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:17 +02:00
Jakub Sztandera 96193c2044 Implement bench-cache
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-29 14:49:11 +02:00
Hector Sanjuan 09e5cc90a4 Add README to documentation/en with explanations 2020-09-29 14:45:55 +02:00
Łukasz Magiera edf1875e88 Merge pull request #4003 from filecoin-project/option-to-hide-sectors
Added an option to show or not show sector info for `lotus-miner info`
2020-09-29 14:26:23 +02:00
Łukasz Magiera 1479142047 Merge pull request #3970 from filecoin-project/feat/mpool-to-wallet
refactor: move nonce generation out of mpool
2020-09-29 13:24:35 +02:00
Dirk McCormick d1c10a61dd fix: message signer - always compare with mpool nonce 2020-09-29 12:20:09 +02:00
Łukasz Magiera 8205149675 Merge pull request #4088 from filecoin-project/feat/walletlist-ux
wallet list cli: Print balances/nonces
2020-09-29 11:33:29 +02:00
Łukasz Magiera eaece306b6 wallet list cli: Print balances/nonces 2020-09-29 11:21:08 +02:00
Raúl Kripalani 044674487e fix double mutex. 2020-09-28 23:14:37 +01:00
Raúl Kripalani 0070d2716c Merge pull request #4078 from filecoin-project/tvx-circsupply 2020-09-28 23:12:43 +01:00
Raúl Kripalani 9b403e26e5 fix lint. 2020-09-28 23:07:45 +01:00
Raúl Kripalani 4b3b35c9de conformance: record and feed circulating supply. 2020-09-28 23:04:52 +01:00
jennijuju 64f24fd276 Added an option to hide sector info for lotus-miner info 2020-09-28 15:42:50 -04:00
Łukasz Magiera 4b61f1756e Merge pull request #4070 from filecoin-project/feat/import-ux
snapshot import progress bar, http support
2020-09-28 20:25:53 +02:00
Jakub Sztandera 2633198e6c Merge pull request #4056 from zgfzgf/tipset-equals
optimize Tipset equals
2020-09-28 20:15:54 +02:00
Łukasz Magiera b84cc46c3d Merge pull request #4074 from filecoin-project/refactor/chain-store-ts-parallel
fetch tipset blocks in parallel
2020-09-28 18:43:43 +02:00
Raúl Kripalani 96f882860f add extract-many command. 2020-09-28 17:02:56 +01:00
Dirk McCormick cfe6f595b0 fix: unsafe append in LoadTipSet 2020-09-28 16:54:18 +02:00
Dirk McCormick 6b16d48bad refactor: fetch tipset blocks in parallel 2020-09-28 15:56:44 +02:00
Raúl Kripalani 9f6862a456 fix lint. 2020-09-28 13:22:56 +01:00
Raúl Kripalani 4c9717187f tvx/extract: small refactor. 2020-09-28 13:19:45 +01:00
Raúl Kripalani a0dffb44d3 tvx/extract: perform sanity check on receipt. 2020-09-28 13:11:34 +01:00
Raúl Kripalani 8f3be78667 tvx/extract: allow passing in block to speed things up. 2020-09-28 13:00:07 +01:00
Raúl Kripalani dfdcbd184d add --repo flag. 2020-09-28 12:35:01 +01:00
Raúl Kripalani f05a40feed use lotus CLI package; document API endpoint setting in usage. 2020-09-28 12:27:42 +01:00
Łukasz Magiera f809529699 daemon cmd: Support imports straight from http 2020-09-28 12:30:12 +02:00
Łukasz Magiera a3145bae07 daemon cmd: Add progress bar to chain import 2020-09-28 12:17:54 +02:00
Łukasz Magiera b14afba859 Merge pull request #4058 from zgfzgf/miner-debug
miner debug where injectNulls != 0
2020-09-28 11:52:42 +02:00
Łukasz Magiera c33b3dfa55 Merge pull request #4022 from filecoin-project/feat/dont-recompute-PoST-abstract
Use abstract types for Dont recompute post on revert
2020-09-28 11:44:38 +02:00
Łukasz Magiera c448d85cf5 Merge pull request #4050 from filecoin-project/fix/stats-network-power
Add back network power to stats
2020-09-28 11:33:03 +02:00
Łukasz Magiera bc495a5c8c Merge pull request #4049 from filecoin-project/fix/miner-power-cli
fix GetPower with no miner address
2020-09-28 11:30:54 +02:00
Łukasz Magiera 18dac6d415 Merge pull request #4067 from IPFSMain-Official/master
add ipfsmain bootstrapper
2020-09-28 09:35:23 +02:00
Łukasz Magiera 5a72662d26 Merge branch 'master' into master 2020-09-28 09:22:21 +02:00
Łukasz Magiera b479988044 Merge pull request #4061 from filecoin-project/dev
Post-upgrade staging branch
2020-09-28 09:20:47 +02:00
刘林欣 a2d24b5b33 add ipfsmain bootstrapper 2020-09-28 13:53:29 +08:00
Raúl Kripalani 9a355c4bc5 fix lint errors. 2020-09-27 21:11:32 +01:00
Raúl Kripalani fe869c9c22 address review comments; lint. 2020-09-27 21:06:07 +01:00
Raúl Kripalani f5f23f7291 driver: option for VM flushing. 2020-09-27 20:55:09 +01:00
Raúl Kripalani a712c109d8 tvx/extract: print confirmation. 2020-09-27 20:30:32 +01:00
Raúl Kripalani e5c56da321 move conformance tvx tool to lotus. 2020-09-27 20:10:05 +01:00
Peter Rabbitson be5dc2c57f Walk back 10 epochs for stat generation 2020-09-27 20:45:45 +02:00
Peter Rabbitson e4c1f090af Disable exclusion of miner-associated addresses 2020-09-27 20:44:50 +02:00
zgfzgf 7a14455ac8 miner debug where injectNulls != 0 2020-09-27 15:01:42 +08:00
zgfzgf 04876c663e modify tipset Equals 2020-09-27 10:17:06 +08:00
zgfzgf 70071e273d optimize tipset Equals func 2020-09-27 09:58:37 +08:00
Peter Rabbitson fb3bcc4ce5 Add startup warning 2020-09-26 21:49:05 +02:00
Peter Rabbitson 1483f1e59a Add filtering of addresses associated with miners 2020-09-26 21:45:34 +02:00
Peter Rabbitson 10cdbadd82 Arrange json as the frontend expects it 2020-09-26 21:44:40 +02:00
Peter Rabbitson 8955b8d8a7 Centralize filtering, output wallet addresses 2020-09-26 21:44:36 +02:00
Travis Person 1c5cb50da3 Add back network power to stats 2020-09-26 17:09:16 +00:00
whyrusleeping bddd6dd8a8 fix GetPower with no miner address 2020-09-26 11:06:16 -05:00
zgfzgf 650725d71e add printf 2020-09-26 17:30:58 +08:00
Łukasz Magiera c243378cab Merge pull request #4032 from filecoin-project/fix/bench-2k
Move policy change to seal bench
2020-09-26 10:27:03 +02:00
Łukasz Magiera e15065b142 Merge pull request #4038 from filecoin-project/feat/state-compute-json
add json output to state compute
2020-09-26 10:20:30 +02:00
Łukasz Magiera 71fa198eee Merge pull request #4004 from ArseniiPetrovich/patch-1
Add glif node to bootstrap peers
2020-09-26 10:19:02 +02:00
Łukasz Magiera ca1715616f Merge branch 'dev' into patch-1 2020-09-26 10:18:47 +02:00
Łukasz Magiera b12bade989 Merge pull request #4007 from maobisheng/master
Add new booststrappers
2020-09-26 10:18:04 +02:00
Łukasz Magiera 28566b4d64 Merge branch 'dev' into master 2020-09-26 10:17:45 +02:00
Łukasz Magiera dfd1473384 Merge pull request #4041 from ipfs-force-community/master
Add one more node located in China
2020-09-26 10:16:01 +02:00
Łukasz Magiera 3fe0aa5026 Merge pull request #4030 from filecoin-project/feat/export-logging
add logging to chain export
2020-09-26 10:14:32 +02:00
Łukasz Magiera 6a502090f4 Merge pull request #4028 from filecoin-project/asr/address-update
Add an envvar to set address network version
2020-09-26 10:14:10 +02:00
Łukasz Magiera 3d40fb294e Merge pull request #3998 from filecoin-project/deps/update-ffi-blst-fix
update ffi to code with blst fixes
2020-09-26 10:12:34 +02:00
Steven Li 81a30cbf06 Add one more node located in China 2020-09-26 16:01:10 +08:00
Łukasz Magiera 2c1d96bcaa Merge pull request #4040 from filecoin-project/asr/changelog
Lotus version 0.8.0
2020-09-26 09:16:49 +02:00
Aayush Rajasekaran 45eadc1b3a Lotus version 0.8.0 2020-09-26 03:13:20 -04:00
Łukasz Magiera b453b8da99 Merge pull request #4039 from filecoin-project/feat/v0.8-actors
Ignition upgrades, for release v0.8.0
2020-09-26 09:13:07 +02:00
whyrusleeping 567261e2c7 set upgrade heights for testground builds 2020-09-26 00:03:03 -07:00
Aayush Rajasekaran 12e97dbea7 Fix docs and linter 2020-09-26 02:59:24 -04:00
Łukasz Magiera ef28ebb14a Ignition upgrades, much excite. 2020-09-25 23:55:37 -07:00
whyrusleeping 8545c08f30 add json output to state compute 2020-09-25 23:47:59 -07:00
Jakub Sztandera eaf3424938 Merge pull request #4033 from filecoin-project/asr/add-supported-proof
Fix AddSupportedProofTypes
2020-09-26 00:13:53 +02:00
Steven Allen a5f13a5b31 Test supported proof types. 2020-09-25 14:36:36 -07:00
Aayush Rajasekaran d8431ff611 Fix AddSupportedProofTypes 2020-09-25 17:33:25 -04:00
Jakub Sztandera 4eec4a0141 Move policy change to seal bench
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-25 23:28:12 +02:00
Steven Allen 6db6a90b1e Merge pull request #4026 from filecoin-project/steb/fix-status-inactive
return an error when we fail to find a sector when checking sector expiration
2020-09-25 13:28:27 -07:00
Travis Person a13d10e42d add logging to chain export 2020-09-25 20:20:18 +00:00
Aayush Rajasekaran 60e43ccbb1 Add an envvar to set address network version 2020-09-25 15:45:27 -04:00
Steven Allen ddcbcdea48 test sector status on expiring sectors 2020-09-25 12:16:35 -07:00
Łukasz Magiera 3491e7b707 Merge pull request #4013 from filecoin-project/feat/update-markets-0.6.3
Update markets to 0.6.3
2020-09-25 20:42:04 +02:00
Steven Allen bdc782617f return an error when we fail to find a sector when checking sector expiration
Returning nil, nil is a footgun.

fix: https://github.com/filecoin-project/lotus/issues/3984
2020-09-25 11:28:38 -07:00
Dirk McCormick 80a7ed8116 refactor: use abstract types instead of specs-actors 2020-09-25 15:54:27 +02:00
zgfzgf 13b38815c2 add trace wdpost 2020-09-25 20:31:07 +08:00
MaoBisheng-IPFSUNION 9dfce400a7 delate 2020-09-25 17:36:57 +08:00
hannahhoward 4ff38aa856 feat(markets): update to 0.6.3 2020-09-25 02:35:34 -07:00
Łukasz Magiera e5873d5dea Merge pull request #4009 from filecoin-project/asr/fractional-asks
Correct helptext
2020-09-25 09:00:02 +02:00
Aayush Rajasekaran 8fbbebbaf1 Correct helptext around set ask 2020-09-25 00:11:10 -04:00
MaoBisheng-IPFSUNION 89bfe84f36 add new booststrappers
we hope to add two booststrappers for the filecoin network to improve the network synchronization
2020-09-25 10:18:12 +08:00
Arsenii Petrovich 585b8cc51d Add glif node to bootstrap peers 2020-09-25 03:54:29 +03:00
whyrusleeping 306c098d30 also update our vendored blst repo 2020-09-24 11:32:38 -07:00
whyrusleeping 6db37b72a8 update ffi to code with blst fixes 2020-09-24 11:05:21 -07:00
Łukasz Magiera 80ee3be4d0 Merge pull request #3870 from filecoin-project/asr/msig-set-locked
Add CLIs for new multisig LockBalance method
2020-09-24 19:42:47 +02:00
Hector Sanjuan e48c525053 Re-add jaeger-tracing 2020-09-24 19:41:14 +02:00
Łukasz Magiera cf9dfdb972 Multisig: fix build 2020-09-24 19:26:32 +02:00
Łukasz Magiera 6ca5308c82 Merge pull request #3996 from filecoin-project/conformance-ntwork-upgrade-adjustments
small adjustments following network upgradability changes
2020-09-24 19:24:45 +02:00
Raúl Kripalani 68663060dc add state.StateTree#Version() accessor. 2020-09-24 17:58:49 +01:00
Raúl Kripalani 87b48c94a6 conformance: supply network version to driver. 2020-09-24 17:58:34 +01:00
Jakub Sztandera 45d8cb08ba Merge pull request #3995 from filecoin-project/feat/more-stateroot-stats
add some more big pictures stats to stateroot stat
2020-09-24 18:57:05 +02:00
Łukasz Magiera 130ae3ccb3 Multisig: Fix from flag descriptions 2020-09-24 18:46:21 +02:00
whyrusleeping 4eaa05db52 add some more big pictures stats to stateroot stat 2020-09-24 09:40:49 -07:00
Łukasz Magiera a19023fada Merge remote-tracking branch 'origin/master' into asr/msig-set-locked 2020-09-24 18:38:02 +02:00
Łukasz Magiera 85caa48814 Merge pull request #3991 from filecoin-project/feat/nicer-syncwait
Make sync wait nicer
2020-09-24 17:03:21 +02:00
Łukasz Magiera cdda66a154 Merge pull request #3942 from filecoin-project/3941-deadline-info
3941: Added cmd `lotus-miner proving deadline <deadline index>`
2020-09-24 16:25:45 +02:00
jennijuju f8f335df55 3941: Added cmd `lotus-miner proving deadline <deadline index>"
- To show the current proving period deadline information of given deadline index.
- It outputs the following:
        - number of partitions in this deadline
        - partitions numbers has submitted PoSt since the current proving period started
        - if the deadline is the current proving deadline
        - for each patition, shows the amount of the sectors in this partition, and their numbers. Also, shows the number of fault sectors and corresponding sector numbers.
2020-09-24 16:23:12 +02:00
Łukasz Magiera 28b46ad08c Merge branch 'zgfzgf-miner-break' into master 2020-09-24 16:03:47 +02:00
Łukasz Magiera 43323b2188 Use continue instead of goto 2020-09-24 16:03:24 +02:00
Łukasz Magiera 17a84c9a2c Merge pull request #3975 from filecoin-project/steb/abstract-actor-policy
Add some actors policy setters for testing
2020-09-24 15:51:41 +02:00
Dirk McCormick 7eb9bec13f feat: dont recompute post on submit redux 2020-09-24 14:38:33 +02:00
Łukasz Magiera 2867b31d2b Merge pull request #3208 from austinabell/extratsload
Update beacon entry load error message
2020-09-24 14:19:00 +02:00
Dirk McCormick 3c524ac0e0 refactor: move nonce generation from mpool to wallet 2020-09-24 14:09:42 +02:00
Łukasz Magiera 1a70dd4fb4 Merge pull request #3977 from filecoin-project/steb/remove-cbor-abstraction
Remove a misleading miner actor abstraction
2020-09-24 14:02:59 +02:00
Łukasz Magiera 15eddf0c96 Make sync wait nicer 2020-09-24 13:39:49 +02:00
Łukasz Magiera bbcad52ce0 Merge pull request #3980 from filecoin-project/feat/batch-blockstore-copy
batch blockstore copies after block validation
2020-09-24 13:07:16 +02:00
Łukasz Magiera ded3a30f55 fix lint 2020-09-24 11:56:54 +02:00
whyrusleeping 38e256cece add some tracing to the vm's blockstore copy 2020-09-23 20:19:20 -07:00
whyrusleeping b4e03d1759 batch blockstore copies after block validation 2020-09-23 18:53:28 -07:00
Aayush Rajasekaran efd2dff0ca Merge pull request #3978 from filecoin-project/asr/changelog
Lotus version 0.7.2
2020-09-23 20:50:12 -04:00
Aayush Rajasekaran 44748775ff Fixup changelog: 2020-09-23 20:49:31 -04:00
Aayush Rajasekaran f729c6b7f5 Update docs 2020-09-23 18:25:45 -04:00
Aayush Rajasekaran 22fafc7054 Lotus version 0.7.2 2020-09-23 18:09:01 -04:00
Steven Allen 32a699d6a3 Add some actors policy setters for testing
Addresses:
* https://github.com/filecoin-project/lotus/pull/3781/files/a307e4593a005888395db34e5af4691ee50d765d#r491966115
* https://github.com/filecoin-project/lotus/pull/3781/files/a307e4593a005888395db34e5af4691ee50d765d#r491966634

Note: This puts everything into a policy package to avoid a dependency cycle
between the build package, the miner package, and the types package. This is
also why I introduced a GetPreCommitChallengeDelay function and removed the
variable.
2020-09-23 15:00:52 -07:00
Steven Allen 46f5b62a76 Remove a misleading miner actor abstraction
We shouldn't implement CBOR functions on the "abstract" miner info. Otherwise,
we could end up trying to actually _use_ this "abstract" info when decoding
state (which won't work across version).

Also remove the use of these CBOR functions, and instead explicitly use miner0
types. We'll have to abstract over versions eventually, but we'll probably need
some form of abstract miner builder (or maybe even adding some "add sector",
etc. functions to the current miner abstraction?
2020-09-23 14:49:53 -07:00
Aayush Rajasekaran e09d291e5d Merge pull request #3939 from filecoin-project/fix/chain-sync-validation
Validate chain sync response indices when fetching messages
2020-09-23 17:35:14 -04:00
Łukasz Magiera 97a97fe992 Merge pull request #3944 from filecoin-project/update-state-arg-name
When doing `sectors update-state`, show a list of existing states if user inputs an invalid one.
2020-09-23 22:19:15 +02:00
Łukasz Magiera f4f5ef6f83 Merge pull request #3963 from filecoin-project/feat/dealstats
Add basic deal stats api server for spacerace slingshot
2020-09-23 22:17:03 +02:00
Łukasz Magiera a1281273bc shed dealtracker: fix lint, env var filter 2020-09-23 22:10:02 +02:00
Łukasz Magiera 42216184e1 Merge pull request #3974 from filecoin-project/feat/update-markets-0.6.2
Update markets v0.6.2
2020-09-23 22:00:15 +02:00
Łukasz Magiera 2c945d33ee Merge pull request #3976 from filecoin-project/fix/state-miner-sectors
fix out-of-bounds when loading all sector infos
2020-09-23 21:56:12 +02:00
Steven Allen 1c1d23d142 fix out-of-bounds when loading all sector infos
fixes #3972
2020-09-23 12:40:44 -07:00
hannahhoward 3fc791b0e8 feat(markets): update markets v0.6.2 2020-09-23 12:17:16 -07:00
Łukasz Magiera 7d39542522 Merge pull request #3741 from filecoin-project/feat/chain-delete-obj
Delete a chain store object
2020-09-23 19:34:02 +02:00
Łukasz Magiera 6c5ed3f07f Some safeguards on chain delete-obj 2020-09-23 19:31:46 +02:00
Łukasz Magiera a2278e26af Merge pull request #3887 from filecoin-project/feat/parallel-sync
Parallel fetch for chain sync
2020-09-23 19:24:54 +02:00
Łukasz Magiera b28b8b9649 Merge pull request #3971 from filecoin-project/init-remove
add init.State#Remove() for testing.
2020-09-23 19:22:12 +02:00
Raúl Kripalani f1ab1af617 add init.State#Remove() for testing. 2020-09-23 17:42:01 +01:00
jennijuju 91a43c477c When doing sectors update-state, show a list of existing states if user inputs an invalid one. 2020-09-23 12:34:34 -04:00
zgfzgf a4ade158f4 change minerStop to minerLoop 2020-09-23 20:24:19 +08:00
Łukasz Magiera c46e1574dd Merge pull request #3781 from filecoin-project/refactor/net-upgrade
Network upgrade support
2020-09-23 11:24:24 +02:00
Aayush Rajasekaran a876a0ba44 Use actor state addresses 2020-09-23 02:32:40 -04:00
Aayush Rajasekaran 819180f739 Implement inefficient OnAddressMapChange predicate 2020-09-23 02:15:01 -04:00
Aayush Rajasekaran 476e7992e8 Add an error return to all actor state interface methods 2020-09-23 01:51:38 -04:00
Aayush Rajasekaran e27fc03f55 Reward state interface only needs cbor.Marshaler 2020-09-23 01:42:10 -04:00
Aayush Rajasekaran ed4bf9b8fe API shouldn't depend on actors directly 2020-09-23 00:51:12 -04:00
Steven Allen 773714792f update oni 2020-09-22 18:40:03 -07:00
Lucas Molas dcf2735836 move validation from protocol to API 2020-09-22 20:19:31 -03:00
Aayush Rajasekaran 77f81fc49b Test fix 2020-09-22 19:07:32 -04:00
Steven Allen 46fb0e74cd add deal state iterator 2020-09-22 14:09:33 -07:00
Steven Allen 2967c4ec10 use abstract actor type methods 2020-09-22 12:02:29 -07:00
whyrusleeping 88ada66280 finish up the total bytes endpoint 2020-09-22 13:31:01 -05:00
whyrusleeping 3cf2fd595f fix appending to array 2020-09-22 13:27:58 -05:00
whyrusleeping 3153ab9ae3 allow graceful shutdown 2020-09-22 13:24:49 -05:00
Steven Allen c91774be3b remove old comment 2020-09-22 11:19:28 -07:00
Steven Allen 441d7ff790 cleanup imports some more 2020-09-22 11:14:55 -07:00
Steven Allen bc24fdbd14 finish migrating statemanager 2020-09-22 11:09:56 -07:00
Steven Allen ab070f2ebe copy actor object when iterating over actors
This is a pretty big footgun.
2020-09-22 11:09:41 -07:00
Steven Allen 5314ba8c6d remove ptr indirection 2020-09-22 10:55:29 -07:00
whyrusleeping f96698b54d finish up other endpoints 2020-09-22 12:54:39 -05:00
Steven Allen fc15888697 fixup some imports 2020-09-22 10:52:23 -07:00
whyrusleeping 9b91628d85 begin adding simple api server for deal stats 2020-09-22 11:05:12 -05:00
zgfzgf 001ba17d37 break error 2020-09-22 15:21:35 +08:00
Aayush Rajasekaran 1dc69e397e Resolve some unnecessary actor upgrade TODOs 2020-09-22 01:34:21 -04:00
Aayush Rajasekaran d56da1b014 Refinements to stmgr and utils 2020-09-22 01:34:20 -04:00
Steven Allen d33dd4f7bc more renames 2020-09-21 16:01:29 -07:00
Steven Allen 63f026f7c3 migrate some more imports 2020-09-21 15:24:45 -07:00
Steven Allen 3f0106cfe5 migrate lotus-shed/genesis-verify to actor abstraction 2020-09-21 15:18:30 -07:00
Steven Allen 4bab784e40 migrate lotus-shed verifreg to specs-actors abstractions 2020-09-21 15:04:39 -07:00
Steven Allen 916421b247 convert lotus-shed balances 2020-09-21 13:43:47 -07:00
Steven Allen a41bf74bad fix: remove incorrect variable 2020-09-21 13:25:03 -07:00
Steven Allen 0ab2459fce convert multisig to new actor abstractions 2020-09-21 13:13:38 -07:00
Steven Allen f9a896f6f2 fix compile 2020-09-21 13:10:41 -07:00
Steven Allen 24ae9205fe cross-version state tree diff 2020-09-21 12:50:12 -07:00
Steven Allen 4cf0c105eb optimize sector loading
And avoid exposing "arrays" via the miner abstraction. We may change these
structures later.
2020-09-21 12:12:08 -07:00
Steven Allen 025663118f non-destructive diff 2020-09-21 10:30:33 -07:00
Łukasz Magiera f7934b083c Merge remote-tracking branch 'origin/master' into refactor/net-upgrade 2020-09-21 19:10:18 +02:00
Łukasz Magiera 46ed0142db Merge pull request #3898 from kenshyx/patch-1
replace Requires with Wants
2020-09-21 19:06:31 +02:00
Hector Sanjuan ad3db0e83c Move unclassified docs back to the docs root 2020-09-21 19:05:49 +02:00
Łukasz Magiera 29913f4c41 Merge pull request #3903 from filecoin-project/3605-sector-list-option
Add an option to hide sectors in Removed from `sectors list`.
2020-09-21 19:04:11 +02:00
Łukasz Magiera 1096f8acc6 miner: Invert show-removed option in sectors list 2020-09-21 18:59:05 +02:00
Łukasz Magiera 14588d1fd2 Merge pull request #3933 from filecoin-project/feat/lotus-shed-consensus
lotus-shed: add consensus check command
2020-09-21 18:54:36 +02:00
Łukasz Magiera 901f7d2b4c Merge pull request #3926 from shepf/master
sync wait add heightDiff maybe useful!
2020-09-21 18:51:45 +02:00
Hector Sanjuan a5e7fd8f5c Re-add docs-check step to circle 2020-09-21 18:43:57 +02:00
Łukasz Magiera 0b5e4a9612 Make GetSectorsForWinningPoSt fast again 2020-09-21 18:28:32 +02:00
vyzo 5663b2d697 change GetChainMessages api to include tipsets for validation 2020-09-21 18:58:52 +03:00
vyzo 44b52941f7 add option to validate messages against expected tipset 2020-09-21 18:50:41 +03:00
vyzo 58a85f378c refactor response compressed index validation into its own function 2020-09-21 18:33:31 +03:00
Raúl Kripalani d3ddd3bff9 Merge pull request #3860 from filecoin-project/refactor/chaos-caller-validation2 2020-09-21 12:55:39 +01:00
Alan Shaw d9f2b909ac chore: update test-vectors 2020-09-21 11:58:45 +01:00
Alan Shaw a79291070e chore: update test-vectors 2020-09-21 11:53:38 +01:00
Alan Shaw d9951cdff4 fix: regen 2020-09-21 10:10:31 +01:00
Alan Shaw c1a9cf7edd refactor: renames 2020-09-21 10:09:05 +01:00
Alan Shaw dfaad08a8b fix: update cbor gen file 2020-09-21 10:09:05 +01:00
Alan Shaw d607ca6118 refactor: remove IsReceiver branch 2020-09-21 10:09:05 +01:00
Alan Shaw 49a94b7cba chore: appease linter 2020-09-21 10:09:05 +01:00
Alan Shaw ab53abf04e feat: add CallerValidationBranchIsReceiver and tests 2020-09-21 10:09:05 +01:00
Alan Shaw cfa041ca8a refactor: chaos caller validation 2020-09-21 10:09:01 +01:00
Łukasz Magiera a307e4593a wdpost: Fix TestWDPostDoPost 2020-09-21 10:06:19 +02:00
Aayush Rajasekaran 286fe04271 Add some TODOs 2020-09-21 02:52:45 -04:00
vyzo f135ec8468 fix handling of end of sync 2020-09-21 09:21:25 +03:00
Aayush Rajasekaran b355eb75eb Add compile-time checks that actors interfaces are correctly implemented 2020-09-21 02:19:32 -04:00
Aayush Rajasekaran a95e34f742 Fix build 2020-09-21 02:02:33 -04:00
Aayush Rajasekaran ed285f1114 Abstract SectorOnChainInfo and SectorPreCommitOnChainInfo 2020-09-21 01:09:42 -04:00
Łukasz Magiera b25dd2a00d More correct / fasterer GetSectorsForWinningPoSt 2020-09-20 23:04:45 +02:00
Travis Person b3d0a5fb4a lotus-shed: add consensus check command 2020-09-20 20:26:20 +00:00
Łukasz Magiera 0d2c8196c6 Merge pull request #3927 from firesWu/master
fix `lotus-miner storage find` error
2020-09-20 12:47:48 +02:00
Jerry c401d2ec4e fix storage find error 2020-09-19 15:48:02 +08:00
shepf 6b40e1e30d sync wait add heightDiff maybe useful! 2020-09-19 14:04:48 +08:00
Aayush Rajasekaran 7c3f638f68 Abstract FilterEstimate, PreCommitDepositForPower, and InitialPledgeForPower 2020-09-19 00:41:24 -04:00
Łukasz Magiera 6050401652 Merge pull request #3925 from filecoin-project/feat/log-shutdown
log shutdown method for lotus daemon and miner
2020-09-18 23:15:41 +02:00
Łukasz Magiera 7109e95f5e Merge pull request #3881 from filcloud/issue-3626-SectorState
fix SectorState
2020-09-18 21:30:18 +02:00
Travis Person eadc61c37a log shutdown method for lotus daemon and miner 2020-09-18 18:07:58 +00:00
Hector Sanjuan 9e2df907f8 Merge remote-tracking branch 'origin/master' into feat/docs-reorg 2020-09-18 15:23:42 +02:00
Hector Sanjuan dfd28ab0c4 Fix links in READMEs. 2020-09-17 20:56:43 +02:00
Hector Sanjuan 784399738a Keep api-methods.md even if not part of the docs 2020-09-17 20:50:37 +02:00
Hector Sanjuan bc9232544c Remove faqs too 2020-09-17 20:48:09 +02:00
Hector Sanjuan 591e32af48 Remove circle_ci docs-check. 2020-09-17 20:46:14 +02:00
Hector Sanjuan a4fd356fcb Delete most docs. Update about page with links to docs.filecoin.io 2020-09-17 20:35:19 +02:00
Hector Sanjuan 6849d18b03 Merge branch 'master' into feat/docs-reorg 2020-09-17 19:28:54 +02:00
jennijuju 14a4acec8c Add an option to hide sectors in Removed for sectors list. 2020-09-17 13:19:50 -04:00
vyzo 6dfc40abc1 error is nil at end, so return batch, nil 2020-09-17 18:23:50 +03:00
vyzo 2946561dec clean up return code 2020-09-17 18:07:01 +03:00
vyzo d7948fcbcd fix log; we want to log time when we succeed! 2020-09-17 18:07:01 +03:00
vyzo fb605f6d7f refactor parallel fetch logic into a separate function 2020-09-17 18:07:01 +03:00
vyzo 2a428f09e6 increase exchange ShufflePeersPrefix to 16, use that as the value of concurrent sync requests 2020-09-17 18:07:01 +03:00
vyzo 8a4b629f40 increase sync request batch size to 8 2020-09-17 18:07:01 +03:00
vyzo b984e94a87 fix bug 2020-09-17 18:07:01 +03:00
vyzo 05a233f84d add some more logging 2020-09-17 18:07:01 +03:00
vyzo 35f6e10646 parallel chain sync 2020-09-17 18:07:01 +03:00
vyzo 61c0b8c3db properly close streams in blocksync
we were leaking streams right and left...
2020-09-17 18:07:01 +03:00
Marius Darila 12e76bc1af replace Requires with Wants
Prevent lotus-miner shutdown when daemon restarts.
2020-09-17 12:17:18 +02:00
Frank d5af25b76c update init sector state list 2020-09-17 10:38:07 +08:00
austinabell ca956ca57e Merge branch 'master' of github.com:filecoin-project/lotus into async/stransition 2020-09-16 11:23:55 -04:00
Frank ed74091c20 add exist sector state check 2020-09-16 19:49:45 +08:00
Aayush Rajasekaran 2ca1d111c5 Multisig: Add a CLI command to cancel locking some balance 2020-09-15 19:52:58 -04:00
Aayush Rajasekaran b20f558abb Multisig: Add a CLI command to approve locking some balance 2020-09-15 19:51:18 -04:00
Aayush Rajasekaran c2148ba106 Multisig: Add a CLI command to propose locking some balance 2020-09-15 19:27:36 -04:00
austinabell e53aee26a3 Make state transition in validation async 2020-09-15 18:36:06 -04:00
hannahhoward 5e445f5a48 docs(apidocs): run docs gen 2020-09-10 10:47:38 -07:00
hannahhoward e86a74156e feat(cli): add command to list 2020-09-10 10:47:38 -07:00
hannahhoward 64d150e215 feat(cli): add chain delete cmd 2020-09-10 10:47:38 -07:00
Hector Sanjuan bd0c6a4ccc Fix filename 2020-09-03 16:35:55 +02:00
Hector Sanjuan af38c902f8 Fix architecture entry 2020-09-03 16:35:18 +02:00
Hector Sanjuan a153e1d586 Fix #2334: Specify seal options to disable with co-located storage worker 2020-09-03 16:35:18 +02:00
Hector Sanjuan fe52c47570 Docs review and re-organization
This:

* Re-organizes the docs into sections that align with what docs.filecoin.io becoming:
  * An installation section
  * A "getting started" section (lotus client focused)
  * A "storing" section (lotus client focused)
  * A "mining" section (miner focused)
  * A "build" section (developer focused)
  * An legacy "architecture" section is left in the last place.

A few high-value documentation pages have been reviewed and updated with the latest recommendations:

* Installation section and lotus setup
* Miner setup
* etc.
...

Other pages have been correctly merged into the new relevant sections. Some pages have not been touched. The filesystem layout of the documentation has been changed into folders corresponding to the sections (as requested by @cw). Some pages that were not linked at all and/or where hidden, have been moved to "unclassified".

This should make the porting of the Lotus documentation to docs.filecoin.io much easier, while ensuring it is more up to date than it was before.

For the moment, this breaks most links as link-aliasing is not supported in lotus-docs.
2020-09-03 16:35:16 +02:00
austinabell 6b63fa379f format 2020-09-02 16:45:50 -04:00
austinabell 485f13de12 Remove load check 2020-09-02 16:45:23 -04:00
austinabell 7f3ba0e6eb Merge branch 'master' of github.com:filecoin-project/lotus into extratsload 2020-09-02 16:44:06 -04:00
Aayush Rajasekaran f58e8bc9a3 Fix some failed precommit handling 2020-09-01 02:18:02 -04:00
whyrusleeping cac848c106 add a command to import an ipld object into the chainstore 2020-08-31 14:24:23 -07:00
austinabell e4daadbfcf Remove extra tipset load from checking beacon entries 2020-08-20 17:54:59 -04:00
212 changed files with 9471 additions and 4501 deletions
+1
View File
@@ -13,3 +13,4 @@
### Conformance testing.
conformance/ @raulk
extern/test-vectors @raulk
cmd/tvx @raulk
+158
View File
@@ -1,5 +1,163 @@
# Lotus changelog
# 0.8.1 / 2020-09-30
This optional release of Lotus introduces a new version of markets which switches to CBOR-map encodings, and allows datastore migrations. The release also introduces several improvements to the mining process, a few performance optimizations, and a battery of UX additions and enhancements.
## Changes
#### Dependencies
- Markets 0.7.0 with updated data stores (https://github.com/filecoin-project/lotus/pull/4089)
- Update ffi to code with blst fixes (https://github.com/filecoin-project/lotus/pull/3998)
#### Core Lotus
- Fix GetPower with no miner address (https://github.com/filecoin-project/lotus/pull/4049)
- Refactor: Move nonce generation out of mpool (https://github.com/filecoin-project/lotus/pull/3970)
#### Performance
- Implement caching syscalls for import-bench (https://github.com/filecoin-project/lotus/pull/3888)
- Fetch tipset blocks in parallel (https://github.com/filecoin-project/lotus/pull/4074)
- Optimize Tipset equals() (https://github.com/filecoin-project/lotus/pull/4056)
- Make state transition in validation async (https://github.com/filecoin-project/lotus/pull/3868)
#### Mining
- Add trace window post (https://github.com/filecoin-project/lotus/pull/4020)
- Use abstract types for Dont recompute post on revert (https://github.com/filecoin-project/lotus/pull/4022)
- Fix injectNulls logic in test miner (https://github.com/filecoin-project/lotus/pull/4058)
- Fix potential panic in FinalizeSector (https://github.com/filecoin-project/lotus/pull/4092)
- Don't recompute post on revert (https://github.com/filecoin-project/lotus/pull/3924)
- Fix some failed precommit handling (https://github.com/filecoin-project/lotus/pull/3445)
- Add --no-swap flag for worker (https://github.com/filecoin-project/lotus/pull/4107)
- Allow some single-thread tasks to run in parallel with PC2/C2 (https://github.com/filecoin-project/lotus/pull/4116)
#### UX
- Add an envvar to set address network version (https://github.com/filecoin-project/lotus/pull/4028)
- Add logging to chain export (https://github.com/filecoin-project/lotus/pull/4030)
- Add JSON output to state compute (https://github.com/filecoin-project/lotus/pull/4038)
- Wallet list CLI: Print balances/nonces (https://github.com/filecoin-project/lotus/pull/4088)
- Added an option to show or not show sector info for `lotus-miner info` (https://github.com/filecoin-project/lotus/pull/4003)
- Add a command to import an ipld object into the chainstore (https://github.com/filecoin-project/lotus/pull/3434)
- Improve the lotus-shed dealtracker (https://github.com/filecoin-project/lotus/pull/4051)
- Docs review and re-organization (https://github.com/filecoin-project/lotus/pull/3431)
- Fix wallet list (https://github.com/filecoin-project/lotus/pull/4104)
- Add an endpoint to validate whether a string is a well-formed address (https://github.com/filecoin-project/lotus/pull/4106)
- Add an option to set config path (https://github.com/filecoin-project/lotus/pull/4103)
- Add printf in TestWindowPost (https://github.com/filecoin-project/lotus/pull/4043)
- Improve miner sectors list UX (https://github.com/filecoin-project/lotus/pull/4108)
#### Tooling
- Move policy change to seal bench (https://github.com/filecoin-project/lotus/pull/4032)
- Add back network power to stats (https://github.com/filecoin-project/lotus/pull/4050)
- Conformance: Record and feed circulating supply (https://github.com/filecoin-project/lotus/pull/4078)
- Snapshot import progress bar, add HTTP support (https://github.com/filecoin-project/lotus/pull/4070)
- Add lotus shed util to validate a tipset (https://github.com/filecoin-project/lotus/pull/4065)
- tvx: a test vector extraction and execution tool (https://github.com/filecoin-project/lotus/pull/4064)
#### Bootstrap
- Add new bootstrappers (https://github.com/filecoin-project/lotus/pull/4007)
- Add Glif node to bootstrap peers (https://github.com/filecoin-project/lotus/pull/4004)
- Add one more node located in China (https://github.com/filecoin-project/lotus/pull/4041)
- Add ipfsmain bootstrapper (https://github.com/filecoin-project/lotus/pull/4067)
# 0.8.0 / 2020-09-26
This consensus-breaking release of Lotus introduces an upgrade to the network. The changes that break consensus are:
- Upgrading to specs-actors v0.9.11, which reduces WindowPoSt faults per [FIP 0002](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0002.md) to reduce cost for honest miners with occasional faults (see https://github.com/filecoin-project/specs-actors/pull/1181)
- Revisions to some cryptoeconomics and network params
This release also updates go-fil-markets to fix an incompatibility issue between v0.7.2 and earlier versions.
## Changes
#### Dependencies
- Update spec actors to 0.9.11 (https://github.com/filecoin-project/lotus/pull/4039)
- Update markets to 0.6.3 (https://github.com/filecoin-project/lotus/pull/4013)
#### Core Lotus
- Network upgrade (https://github.com/filecoin-project/lotus/pull/4039)
- Fix AddSupportedProofTypes (https://github.com/filecoin-project/lotus/pull/4033)
- Return an error when we fail to find a sector when checking sector expiration (https://github.com/filecoin-project/lotus/pull/4026)
- Batch blockstore copies after block validation (https://github.com/filecoin-project/lotus/pull/3980)
- Remove a misleading miner actor abstraction (https://github.com/filecoin-project/lotus/pull/3977)
- Fix out-of-bounds when loading all sector infos (https://github.com/filecoin-project/lotus/pull/3976)
- Fix break condition in the miner (https://github.com/filecoin-project/lotus/pull/3953)
#### UX
- Correct helptext around miners setting ask (https://github.com/filecoin-project/lotus/pull/4009)
- Make sync wait nicer (https://github.com/filecoin-project/lotus/pull/3991)
#### Tooling and validation
- Small adjustments following network upgradability changes (https://github.com/filecoin-project/lotus/pull/3996)
- Add some more big pictures stats to stateroot stat (https://github.com/filecoin-project/lotus/pull/3995)
- Add some actors policy setters for testing (https://github.com/filecoin-project/lotus/pull/3975)
## Contributors
The following contributors had 5 or more commits go into this release.
We are grateful for every contribution!
| Contributor | Commits | Lines ± |
|--------------------|---------|---------------|
| arajasek | 66 | +3140/-1261 |
| Stebalien | 64 | +3797/-3434 |
| magik6k | 48 | +1892/-976 |
| raulk | 40 | +2412/-1549 |
| vyzo | 22 | +287/-196 |
| alanshaw | 15 | +761/-146 |
| whyrusleeping | 15 | +736/-52 |
| hannahhoward | 14 | +1237/837- |
| anton | 6 | +32/-8 |
| travisperson | 5 | +502/-6 |
| Frank | 5 | +78/-39 |
| Jennifer | 5 | +148/-41 |
# 0.7.2 / 2020-09-23
This optional release of Lotus introduces a major refactor around how a Lotus node interacts with code from the specs-actors repo. We now use interfaces to read the state of actors, which is required to be able to reason about different versions of actors code at the same time.
Additionally, this release introduces various improvements to the sync process, as well as changes to better the overall UX experience.
## Changes
#### Core Lotus
- Network upgrade support (https://github.com/filecoin-project/lotus/pull/3781)
- Upgrade markets to `v0.6.2` (https://github.com/filecoin-project/lotus/pull/3974)
- Validate chain sync response indices when fetching messages (https://github.com/filecoin-project/lotus/pull/3939)
- Add height diff to sync wait (https://github.com/filecoin-project/lotus/pull/3926)
- Replace Requires with Wants (https://github.com/filecoin-project/lotus/pull/3898)
- Update state diffing for market actor (https://github.com/filecoin-project/lotus/pull/3889)
- Parallel fetch for sync (https://github.com/filecoin-project/lotus/pull/3887)
- Fix SectorState (https://github.com/filecoin-project/lotus/pull/3881)
#### User Experience
- Add basic deal stats api server for spacerace slingshot (https://github.com/filecoin-project/lotus/pull/3963)
- When doing `sectors update-state`, show a list of existing states if user inputs an invalid one (https://github.com/filecoin-project/lotus/pull/3944)
- Fix `lotus-miner storage find` error (https://github.com/filecoin-project/lotus/pull/3927)
- Log shutdown method for lotus daemon and miner (https://github.com/filecoin-project/lotus/pull/3925)
- Update build and setup instruction link (https://github.com/filecoin-project/lotus/pull/3919)
- Add an option to hide removed sectors from `sectors list` output (https://github.com/filecoin-project/lotus/pull/3903)
#### Testing and validation
- Add init.State#Remove() for testing (https://github.com/filecoin-project/lotus/pull/3971)
- lotus-shed: add consensus check command (https://github.com/filecoin-project/lotus/pull/3933)
- Add keyinfo verify and jwt token command to lotus-shed (https://github.com/filecoin-project/lotus/pull/3914)
- Fix conformance gen (https://github.com/filecoin-project/lotus/pull/3892)
# 0.7.1 / 2020-09-17
This optional release of Lotus introduces some critical fixes to the window PoSt process. It also upgrades some core dependencies, and introduces many improvements to the mining process, deal-making cycle, and overall User Experience.
+2 -2
View File
@@ -1,5 +1,5 @@
<p align="center">
<a href="https://lotu.sh/" title="Lotus Docs">
<a href="https://docs.filecoin.io/" title="Filecoin Docs">
<img src="documentation/images/lotus_logo_h.png" alt="Project Lotus Logo" width="244" />
</a>
</p>
@@ -18,7 +18,7 @@ Lotus is an implementation of the Filecoin Distributed Storage Network. For more
## Building & Documentation
For instructions on how to build lotus from source, please visit [Lotus build and setup instruction](https://docs.filecoin.io/get-started/lotus/installation/#minimal-requirements) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
For instructions on how to build, install and setup lotus, please visit [https://docs.filecoin.io/get-started/lotus](https://docs.filecoin.io/get-started/lotus/).
## Reporting a Vulnerability
+17 -9
View File
@@ -21,9 +21,9 @@ import (
"github.com/filecoin-project/go-state-types/dline"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/types"
marketevents "github.com/filecoin-project/lotus/markets/loggers"
@@ -76,6 +76,9 @@ type FullNode interface {
// blockstore and returns raw bytes.
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
// ChainDeleteObj deletes node referenced by the given CID
ChainDeleteObj(context.Context, cid.Cid) error
// ChainHasObj checks if a given CID exists in the chain blockstore.
ChainHasObj(context.Context, cid.Cid) (bool, error)
@@ -173,6 +176,9 @@ type FullNode interface {
// the reason.
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
// SyncValidateTipset indicates whether the provided tipset is valid or not
SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error)
// MethodGroup: Mpool
// The Mpool methods are for interacting with the message pool. The message pool
// manages all incoming and outgoing 'messages' going over the network.
@@ -241,6 +247,8 @@ type FullNode interface {
WalletImport(context.Context, *types.KeyInfo) (address.Address, error)
// WalletDelete deletes an address from the wallet.
WalletDelete(context.Context, address.Address) error
// WalletValidateAddress validates whether a given string can be decoded as a well-formed address
WalletValidateAddress(context.Context, string) (address.Address, error)
// Other
@@ -272,7 +280,7 @@ type FullNode interface {
// of status updates.
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error)
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error)
// ClientCalcCommP calculates the CommP for a specified file
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
// ClientGenCar generates a CAR file for the specified file.
@@ -313,11 +321,9 @@ type FullNode interface {
// StateNetworkName returns the name of the network the node is synced to
StateNetworkName(context.Context) (dtypes.NetworkName, error)
// StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included.
// If the filterOut boolean is set to true, any sectors in the filter are excluded.
// If false, only those sectors in the filter are included.
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*miner.ChainSectorInfo, error)
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
// StateMinerActiveSectors returns info about sectors that a given miner is actively proving.
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.ChainSectorInfo, error)
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
// and returns the deadline-related calculations.
StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error)
@@ -724,6 +730,8 @@ type ActiveSync struct {
type SyncState struct {
ActiveSyncs []ActiveSync
VMApplied uint64
}
type SyncStateStage int
@@ -790,7 +798,7 @@ type CirculatingSupply struct {
type MiningBaseInfo struct {
MinerPower types.BigInt
NetworkPower types.BigInt
Sectors []proof.SectorInfo
Sectors []builtin.SectorInfo
WorkerKey address.Address
SectorSize abi.SectorSize
PrevBeaconEntry types.BeaconEntry
@@ -807,7 +815,7 @@ type BlockTemplate struct {
Messages []*types.SignedMessage
Epoch abi.ChainEpoch
Timestamp uint64
WinningPoStProof []proof.PoStProof
WinningPoStProof []builtin.PoStProof
}
type DataSize struct {
+35 -20
View File
@@ -29,12 +29,12 @@ import (
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
marketevents "github.com/filecoin-project/lotus/markets/loggers"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-storage/storage"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
@@ -87,6 +87,7 @@ type FullNodeStruct struct {
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
ChainDeleteObj func(context.Context, cid.Cid) error `perm:"admin"`
ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"`
ChainStatObj func(context.Context, cid.Cid, cid.Cid) (api.ObjStat, error) `perm:"read"`
ChainSetHead func(context.Context, types.TipSetKey) error `perm:"admin"`
@@ -111,6 +112,7 @@ type FullNodeStruct struct {
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
SyncUnmarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
SyncValidateTipset func(ctx context.Context, tsk types.TipSetKey) (bool, error) `perm:"read"`
MpoolGetConfig func(context.Context) (*types.MpoolConfig, error) `perm:"read"`
MpoolSetConfig func(context.Context, *types.MpoolConfig) error `perm:"write"`
@@ -128,18 +130,19 @@ type FullNodeStruct struct {
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) `perm:"read"`
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
WalletDelete func(context.Context, address.Address) error `perm:"write"`
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) `perm:"read"`
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
WalletDelete func(context.Context, address.Address) error `perm:"write"`
WalletValidateAddress func(context.Context, string) (address.Address, error) `perm:"read"`
ClientImport func(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) `perm:"admin"`
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
@@ -153,7 +156,7 @@ type FullNodeStruct struct {
ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"`
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
ClientRetrieveWithEvents func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
ClientCalcCommP func(ctx context.Context, inpath string) (*api.CommPRet, error) `perm:"read"`
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
ClientDealSize func(ctx context.Context, root cid.Cid) (api.DataSize, error) `perm:"read"`
@@ -162,8 +165,8 @@ type FullNodeStruct struct {
ClientRetrieveTryRestartInsufficientFunds func(ctx context.Context, paymentChannel address.Address) error `perm:"write"`
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*miner.ChainSectorInfo, error) `perm:"read"`
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*miner.ChainSectorInfo, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (miner.MinerInfo, error) `perm:"read"`
@@ -483,7 +486,7 @@ func (c *FullNodeStruct) ClientRetrieveWithEvents(ctx context.Context, order api
return c.Internal.ClientRetrieveWithEvents(ctx, order, ref)
}
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) {
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) {
return c.Internal.ClientQueryAsk(ctx, p, miner)
}
func (c *FullNodeStruct) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) {
@@ -630,6 +633,10 @@ func (c *FullNodeStruct) WalletDelete(ctx context.Context, addr address.Address)
return c.Internal.WalletDelete(ctx, addr)
}
func (c *FullNodeStruct) WalletValidateAddress(ctx context.Context, str string) (address.Address, error) {
return c.Internal.WalletValidateAddress(ctx, str)
}
func (c *FullNodeStruct) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) {
return c.Internal.MpoolGetNonce(ctx, addr)
}
@@ -662,6 +669,10 @@ func (c *FullNodeStruct) ChainReadObj(ctx context.Context, obj cid.Cid) ([]byte,
return c.Internal.ChainReadObj(ctx, obj)
}
func (c *FullNodeStruct) ChainDeleteObj(ctx context.Context, obj cid.Cid) error {
return c.Internal.ChainDeleteObj(ctx, obj)
}
func (c *FullNodeStruct) ChainHasObj(ctx context.Context, o cid.Cid) (bool, error) {
return c.Internal.ChainHasObj(ctx, o)
}
@@ -730,15 +741,19 @@ func (c *FullNodeStruct) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string
return c.Internal.SyncCheckBad(ctx, bcid)
}
func (c *FullNodeStruct) SyncValidateTipset(ctx context.Context, tsk types.TipSetKey) (bool, error) {
return c.Internal.SyncValidateTipset(ctx, tsk)
}
func (c *FullNodeStruct) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
return c.Internal.StateNetworkName(ctx)
}
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, filter *bitfield.BitField, filterOut bool, tsk types.TipSetKey) ([]*miner.ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, filter, filterOut, tsk)
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, sectorNos *bitfield.BitField, tsk types.TipSetKey) ([]*miner.SectorOnChainInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, sectorNos, tsk)
}
func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*miner.ChainSectorInfo, error) {
func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr address.Address, tsk types.TipSetKey) ([]*miner.SectorOnChainInfo, error) {
return c.Internal.StateMinerActiveSectors(ctx, addr, tsk)
}
+16
View File
@@ -94,6 +94,22 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
require.Less(t, 50000, int(exp.OnTime))
}
dlInfo, err := client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
// Sector should expire.
for {
// Wait for the sector to expire.
status, err := miner.SectorsStatus(ctx, CC, true)
require.NoError(t, err)
if status.OnTime == 0 && status.Early == 0 {
break
}
t.Log("waiting for sector to expire")
// wait one deadline per loop.
time.Sleep(time.Duration(dlInfo.WPoStChallengeWindow) * blocktime)
}
fmt.Println("shutting down mining")
atomic.AddInt64(&mine, -1)
<-done
+9 -12
View File
@@ -153,18 +153,16 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
require.NoError(t, err)
fmt.Printf("Running one proving period\n")
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
for {
head, err := client.ChainHead(ctx)
require.NoError(t, err)
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
fmt.Printf("Now head.Height = %d\n", head.Height())
break
}
if head.Height()%100 == 0 {
fmt.Printf("@%d\n", head.Height())
}
build.Clock.Sleep(blocktime)
}
@@ -186,7 +184,6 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
require.Greater(t, len(parts), 0)
secs := parts[0].AllSectors
require.NoError(t, err)
n, err := secs.Count()
require.NoError(t, err)
require.Equal(t, uint64(2), n)
@@ -210,7 +207,6 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
require.Greater(t, len(parts), 0)
secs := parts[0].AllSectors
require.NoError(t, err)
n, err := secs.Count()
require.NoError(t, err)
require.Equal(t, uint64(2), n)
@@ -236,18 +232,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
require.NoError(t, err)
fmt.Printf("Go through another PP, wait for sectors to become faulty\n")
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
for {
head, err := client.ChainHead(ctx)
require.NoError(t, err)
if head.Height() > di.PeriodStart+(di.WPoStProvingPeriod)+2 {
fmt.Printf("Now head.Height = %d\n", head.Height())
break
}
if head.Height()%100 == 0 {
fmt.Printf("@%d\n", head.Height())
}
build.Clock.Sleep(blocktime)
}
@@ -267,17 +262,17 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
di, err = client.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
fmt.Printf("End for head.Height > %d\n", di.PeriodStart+di.WPoStProvingPeriod+2)
for {
head, err := client.ChainHead(ctx)
require.NoError(t, err)
if head.Height() > di.PeriodStart+di.WPoStProvingPeriod+2 {
fmt.Printf("Now head.Height = %d\n", head.Height())
break
}
if head.Height()%100 == 0 {
fmt.Printf("@%d\n", head.Height())
}
build.Clock.Sleep(blocktime)
}
@@ -300,12 +295,14 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
require.NoError(t, err)
waitUntil := head.Height() + 10
fmt.Printf("End for head.Height > %d\n", waitUntil)
for {
head, err := client.ChainHead(ctx)
require.NoError(t, err)
if head.Height() > waitUntil {
fmt.Printf("Now head.Height = %d\n", head.Height())
break
}
}
+12 -2
View File
@@ -1,2 +1,12 @@
/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWGnRx1WypbTcGsxw8k4fXP2RmFSGqGUxNYn8E6rLS5Qnp
/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWG1ns2ejaTx9HQhe4F5ox6PPE4misuJqNFzHa4pSdVVdq
/dns4/bootstrap-0.testnet.fildev.network/tcp/1347/p2p/12D3KooWJTUBUjtzWJGWU1XSiY21CwmHaCNLNYn2E7jqHEHyZaP7
/dns4/bootstrap-1.testnet.fildev.network/tcp/1347/p2p/12D3KooW9yeKXha4hdrJKq74zEo99T8DhriQdWNoojWnnQbsgB3v
/dns4/bootstrap-2.testnet.fildev.network/tcp/1347/p2p/12D3KooWCrx8yVG9U9Kf7w8KLN3Edkj5ZKDhgCaeMqQbcQUoB6CT
/dns4/bootstrap-4.testnet.fildev.network/tcp/1347/p2p/12D3KooWPkL9LrKRQgHtq7kn9ecNhGU9QaziG8R5tX8v9v7t3h34
/dns4/bootstrap-3.testnet.fildev.network/tcp/1347/p2p/12D3KooWKYSsbpgZ3HAjax5M1BXCwXLa6gVkUARciz7uN3FNtr7T
/dns4/bootstrap-5.testnet.fildev.network/tcp/1347/p2p/12D3KooWQYzqnLASJAabyMpPb1GcWZvNSe7JDcRuhdRqonFoiK9W
/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
Binary file not shown.
+7 -9
View File
@@ -4,27 +4,25 @@ package build
import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/actors/policy"
)
const UpgradeBreezeHeight = -1
const BreezeGasTampingDuration = 0
const UpgradeSmokeHeight = -1
const UpgradeIgnitionHeight = -2
const UpgradeLiftoffHeight = -3
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
}
func init() {
power0.ConsensusMinerMinPower = big.NewInt(2048)
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
verifreg0.MinVerifiedDealSize = big.NewInt(256)
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
BuildType |= Build2k
}
+6
View File
@@ -3,6 +3,8 @@ package build
import (
"sort"
"github.com/filecoin-project/go-address"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/go-state-types/abi"
@@ -44,3 +46,7 @@ func UseNewestNetwork() bool {
}
return false
}
func SetAddressNetwork(n address.Network) {
address.CurrentNetwork = n
}
+16 -2
View File
@@ -4,6 +4,9 @@ package build
import (
"math/big"
"os"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/network"
@@ -22,8 +25,8 @@ const UnixfsLinksPerLevel = 1024
// Consensus / Network
const AllowableClockDriftSecs = uint64(1)
const NewestNetworkVersion = network.Version2
const ActorUpgradeNetworkVersion = network.Version3
const NewestNetworkVersion = network.Version3
const ActorUpgradeNetworkVersion = network.Version4
// Epochs
const ForkLengthThreshold = Finality
@@ -60,9 +63,16 @@ const TicketRandomnessLookback = abi.ChainEpoch(1)
const WinningPoStSectorSetLookback = abi.ChainEpoch(10)
// /////
// Address
const AddressMainnetEnvVar = "_mainnet_"
// /////
// Devnet settings
var Devnet = true
const FilBase = uint64(2_000_000_000)
const FilAllocStorageMining = uint64(1_100_000_000)
@@ -75,6 +85,10 @@ var InitialRewardBalance *big.Int
func init() {
InitialRewardBalance = big.NewInt(int64(FilAllocStorageMining))
InitialRewardBalance = InitialRewardBalance.Mul(InitialRewardBalance, big.NewInt(int64(FilecoinPrecision)))
if os.Getenv("LOTUS_ADDRESS_TYPE") == AddressMainnetEnvVar {
SetAddressNetwork(address.Mainnet)
}
}
// Sync
+5 -1
View File
@@ -74,7 +74,9 @@ var (
UpgradeBreezeHeight abi.ChainEpoch = -1
BreezeGasTampingDuration abi.ChainEpoch = 0
UpgradeSmokeHeight abi.ChainEpoch = -1
UpgradeSmokeHeight abi.ChainEpoch = -1
UpgradeIgnitionHeight abi.ChainEpoch = -2
UpgradeLiftoffHeight abi.ChainEpoch = -3
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
@@ -82,4 +84,6 @@ var (
NewestNetworkVersion = network.Version2
ActorUpgradeNetworkVersion = network.Version3
Devnet = true
)
+21 -11
View File
@@ -6,27 +6,37 @@ package build
import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/policy"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
)
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
0: DrandIncentinet,
UpgradeSmokeHeight: DrandMainnet,
}
const UpgradeBreezeHeight = -1
const UpgradeBreezeHeight = 41280
const BreezeGasTampingDuration = 120
const UpgradeSmokeHeight = -1
const UpgradeSmokeHeight = 51000
const UpgradeIgnitionHeight = 94000
// This signals our tentative epoch for mainnet launch. Can make it later, but not earlier.
// Miners, clients, developers, custodians all need time to prepare.
// We still have upgrades and state changes to do, but can happen after signaling timing here.
const UpgradeLiftoffHeight = 148888
func init() {
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg512MiBV1: {},
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
}
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
policy.SetSupportedProofTypes(
abi.RegisteredSealProof_StackedDrg32GiBV1,
abi.RegisteredSealProof_StackedDrg64GiBV1,
)
Devnet = false
}
const BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds)
const PropagationDelaySecs = uint64(6)
+4 -4
View File
@@ -29,7 +29,7 @@ func buildType() string {
}
// BuildVersion is the local build version, set by build system
const BuildVersion = "0.7.1"
const BuildVersion = "0.8.1"
func UserVersion() string {
return BuildVersion + buildType() + CurrentCommit
@@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
// semver versions of the rpc api exposed
var (
FullAPIVersion = newVer(0, 15, 0)
MinerAPIVersion = newVer(0, 14, 0)
WorkerAPIVersion = newVer(0, 14, 0)
FullAPIVersion = newVer(0, 16, 0)
MinerAPIVersion = newVer(0, 15, 0)
WorkerAPIVersion = newVer(0, 15, 0)
)
//nolint:varcheck,deadcode
+8
View File
@@ -55,3 +55,11 @@ func AsArray(store Store, root cid.Cid, version network.Version) (Array, error)
}
return nil, xerrors.Errorf("unknown network version: %d", version)
}
func NewArray(store Store, version builtin.Version) (Array, error) {
switch version {
case builtin.Version0:
return adt0.MakeEmptyArray(store), nil
}
return nil, xerrors.Errorf("unknown network version: %d", version)
}
+12 -4
View File
@@ -27,6 +27,7 @@ type AdtArrayDiff interface {
// - All values that exist in preArr and in curArr are passed to AdtArrayDiff.Modify()
// - It is the responsibility of AdtArrayDiff.Modify() to determine if the values it was passed have been modified.
func DiffAdtArray(preArr, curArr Array, out AdtArrayDiff) error {
notNew := make(map[int64]struct{}, curArr.Length())
prevVal := new(typegen.Deferred)
if err := preArr.ForEach(prevVal, func(i int64) error {
curVal := new(typegen.Deferred)
@@ -47,14 +48,17 @@ func DiffAdtArray(preArr, curArr Array, out AdtArrayDiff) error {
return err
}
}
return curArr.Delete(uint64(i))
notNew[i] = struct{}{}
return nil
}); err != nil {
return err
}
curVal := new(typegen.Deferred)
return curArr.ForEach(curVal, func(i int64) error {
if _, ok := notNew[i]; ok {
return nil
}
return out.Add(uint64(i), curVal)
})
}
@@ -76,6 +80,7 @@ type AdtMapDiff interface {
}
func DiffAdtMap(preMap, curMap Map, out AdtMapDiff) error {
notNew := make(map[string]struct{})
prevVal := new(typegen.Deferred)
if err := preMap.ForEach(prevVal, func(key string) error {
curVal := new(typegen.Deferred)
@@ -101,14 +106,17 @@ func DiffAdtMap(preMap, curMap Map, out AdtMapDiff) error {
return err
}
}
return curMap.Delete(k)
notNew[key] = struct{}{}
return nil
}); err != nil {
return err
}
curVal := new(typegen.Deferred)
return curMap.ForEach(curVal, func(key string) error {
if _, ok := notNew[key]; ok {
return nil
}
return out.Add(key, curVal)
})
}
+2
View File
@@ -6,6 +6,8 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin/account"
)
var _ State = (*state0)(nil)
type state0 struct {
account.State
store adt.Store
+18 -3
View File
@@ -3,9 +3,13 @@ package builtin
import (
"fmt"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/go-state-types/abi"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
"github.com/filecoin-project/go-state-types/network"
)
type Version int
@@ -17,12 +21,23 @@ const (
// Converts a network version into a specs-actors version.
func VersionForNetwork(version network.Version) Version {
switch version {
case network.Version0, network.Version1, network.Version2:
case network.Version0, network.Version1, network.Version2, network.Version3:
return Version0
default:
panic(fmt.Sprintf("unsupported network version %d", version))
}
}
// TODO: find some way to abstract over this.
// TODO: Why does actors have 2 different versions of this?
type SectorInfo = proof0.SectorInfo
type PoStProof = proof0.PoStProof
type FilterEstimate = smoothing0.FilterEstimate
func FromV0FilterEstimate(v0 smoothing0.FilterEstimate) FilterEstimate {
return (FilterEstimate)(v0)
}
// Doesn't change between actors v0 and v1
func QAPowerForWeight(size abi.SectorSize, duration abi.ChainEpoch, dealWeight, verifiedWeight abi.DealWeight) abi.StoragePower {
return miner0.QAPowerForWeight(size, duration, dealWeight, verifiedWeight)
}
+5
View File
@@ -36,4 +36,9 @@ type State interface {
NetworkName() (dtypes.NetworkName, error)
ForEachActor(func(id abi.ActorID, address address.Address) error) error
// Remove exists to support tooling that manipulates state for testing.
// It should not be used in production code, as init actor entries are
// immutable.
Remove(addrs ...address.Address) error
}
+21
View File
@@ -4,6 +4,7 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
@@ -13,6 +14,8 @@ import (
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
)
var _ State = (*state0)(nil)
type state0 struct {
init_.State
store adt.Store
@@ -44,3 +47,21 @@ func (s *state0) ForEachActor(cb func(id abi.ActorID, address address.Address) e
func (s *state0) NetworkName() (dtypes.NetworkName, error) {
return dtypes.NetworkName(s.State.NetworkName), nil
}
func (s *state0) Remove(addrs ...address.Address) (err error) {
m, err := adt0.AsMap(s.store, s.State.AddressMap)
if err != nil {
return err
}
for _, addr := range addrs {
if err = m.Delete(abi.AddrKey(addr)); err != nil {
return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
}
}
amr, err := m.Root()
if err != nil {
return xerrors.Errorf("failed to get address map root: %w", err)
}
s.State.AddressMap = amr
return nil
}
+11 -3
View File
@@ -7,6 +7,7 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
@@ -31,13 +32,13 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) {
type State interface {
cbor.Marshaler
BalancesChanged(State) bool
BalancesChanged(State) (bool, error)
EscrowTable() (BalanceTable, error)
LockedTable() (BalanceTable, error)
TotalLocked() (abi.TokenAmount, error)
StatesChanged(State) bool
StatesChanged(State) (bool, error)
States() (DealStates, error)
ProposalsChanged(State) bool
ProposalsChanged(State) (bool, error)
Proposals() (DealProposals, error)
VerifyDealsForActivation(
minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
@@ -50,6 +51,7 @@ type BalanceTable interface {
}
type DealStates interface {
ForEach(cb func(id abi.DealID, ds DealState) error) error
Get(id abi.DealID) (*DealState, bool, error)
array() adt.Array
@@ -64,6 +66,12 @@ type DealProposals interface {
decode(*cbg.Deferred) (*DealProposal, error)
}
type PublishStorageDealsParams = market0.PublishStorageDealsParams
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
type ClientDealProposal = market0.ClientDealProposal
type DealState struct {
SectorStartEpoch abi.ChainEpoch // -1 if not yet included in proven sector
LastUpdatedEpoch abi.ChainEpoch // -1 if deal state never updated
+21 -12
View File
@@ -12,6 +12,8 @@ import (
cbg "github.com/whyrusleeping/cbor-gen"
)
var _ State = (*state0)(nil)
type state0 struct {
market.State
store adt.Store
@@ -23,24 +25,24 @@ func (s *state0) TotalLocked() (abi.TokenAmount, error) {
return fml, nil
}
func (s *state0) BalancesChanged(otherState State) bool {
func (s *state0) BalancesChanged(otherState State) (bool, error) {
otherState0, ok := otherState.(*state0)
if !ok {
// there's no way to compare differnt versions of the state, so let's
// there's no way to compare different versions of the state, so let's
// just say that means the state of balances has changed
return true
return true, nil
}
return !s.State.EscrowTable.Equals(otherState0.State.EscrowTable) || !s.State.LockedTable.Equals(otherState0.State.LockedTable)
return !s.State.EscrowTable.Equals(otherState0.State.EscrowTable) || !s.State.LockedTable.Equals(otherState0.State.LockedTable), nil
}
func (s *state0) StatesChanged(otherState State) bool {
func (s *state0) StatesChanged(otherState State) (bool, error) {
otherState0, ok := otherState.(*state0)
if !ok {
// there's no way to compare differnt versions of the state, so let's
// there's no way to compare different versions of the state, so let's
// just say that means the state of balances has changed
return true
return true, nil
}
return !s.State.States.Equals(otherState0.State.States)
return !s.State.States.Equals(otherState0.State.States), nil
}
func (s *state0) States() (DealStates, error) {
@@ -51,14 +53,14 @@ func (s *state0) States() (DealStates, error) {
return &dealStates0{stateArray}, nil
}
func (s *state0) ProposalsChanged(otherState State) bool {
func (s *state0) ProposalsChanged(otherState State) (bool, error) {
otherState0, ok := otherState.(*state0)
if !ok {
// there's no way to compare differnt versions of the state, so let's
// there's no way to compare different versions of the state, so let's
// just say that means the state of balances has changed
return true
return true, nil
}
return !s.State.Proposals.Equals(otherState0.State.Proposals)
return !s.State.Proposals.Equals(otherState0.State.Proposals), nil
}
func (s *state0) Proposals() (DealProposals, error) {
@@ -124,6 +126,13 @@ func (s *dealStates0) Get(dealID abi.DealID) (*DealState, bool, error) {
return &deal, true, nil
}
func (s *dealStates0) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
var ds0 market.DealState
return s.Array.ForEach(&ds0, func(idx int64) error {
return cb(abi.DealID(idx), fromV0DealState(ds0))
})
}
func (s *dealStates0) decode(val *cbg.Deferred) (*DealState, error) {
var ds0 market.DealState
if err := ds0.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
+38 -13
View File
@@ -1,7 +1,7 @@
package miner
import (
"github.com/filecoin-project/go-state-types/dline"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
@@ -10,6 +10,7 @@ import (
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/go-state-types/dline"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
@@ -17,7 +18,14 @@ import (
"github.com/filecoin-project/lotus/chain/types"
)
var Address = builtin0.InitActorAddr
// Unchanged between v0 and v1 actors
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
var WPoStChallengeWindow = miner0.WPoStChallengeWindow
var WPoStChallengeLookback = miner0.WPoStChallengeLookback
var FaultDeclarationCutoff = miner0.FaultDeclarationCutoff
const MinSectorExpiration = miner0.MinSectorExpiration
func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code {
@@ -46,17 +54,18 @@ type State interface {
FindSector(abi.SectorNumber) (*SectorLocation, error)
GetSectorExpiration(abi.SectorNumber) (*SectorExpiration, error)
GetPrecommittedSector(abi.SectorNumber) (*SectorPreCommitOnChainInfo, error)
LoadSectorsFromSet(filter *bitfield.BitField, filterOut bool) (adt.Array, error)
LoadSectors(sectorNos *bitfield.BitField) ([]*SectorOnChainInfo, error)
NumLiveSectors() (uint64, error)
IsAllocated(abi.SectorNumber) (bool, error)
LoadDeadline(idx uint64) (Deadline, error)
ForEachDeadline(cb func(idx uint64, dl Deadline) error) error
NumDeadlines() (uint64, error)
DeadlinesChanged(State) bool
DeadlinesChanged(State) (bool, error)
Info() (MinerInfo, error)
DeadlineInfo(epoch abi.ChainEpoch) *dline.Info
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
// Diff helpers. Used by Diff* functions internally.
sectors() (adt.Array, error)
@@ -70,7 +79,7 @@ type Deadline interface {
ForEachPartition(cb func(idx uint64, part Partition) error) error
PostSubmissions() (bitfield.BitField, error)
PartitionsChanged(Deadline) bool
PartitionsChanged(Deadline) (bool, error)
}
type Partition interface {
@@ -81,9 +90,30 @@ type Partition interface {
ActiveSectors() (bitfield.BitField, error)
}
type SectorOnChainInfo = miner0.SectorOnChainInfo
type SectorOnChainInfo struct {
SectorNumber abi.SectorNumber
SealProof abi.RegisteredSealProof
SealedCID cid.Cid
DealIDs []abi.DealID
Activation abi.ChainEpoch
Expiration abi.ChainEpoch
DealWeight abi.DealWeight
VerifiedDealWeight abi.DealWeight
InitialPledge abi.TokenAmount
ExpectedDayReward abi.TokenAmount
ExpectedStoragePledge abi.TokenAmount
}
type SectorPreCommitInfo = miner0.SectorPreCommitInfo
type SectorPreCommitOnChainInfo = miner0.SectorPreCommitOnChainInfo
type SectorPreCommitOnChainInfo struct {
Info SectorPreCommitInfo
PreCommitDeposit abi.TokenAmount
PreCommitEpoch abi.ChainEpoch
DealWeight abi.DealWeight
VerifiedDealWeight abi.DealWeight
}
type PoStPartition = miner0.PoStPartition
type RecoveryDeclaration = miner0.RecoveryDeclaration
type FaultDeclaration = miner0.FaultDeclaration
@@ -107,11 +137,6 @@ type MinerInfo struct {
WindowPoStPartitionSectors uint64
}
type ChainSectorInfo struct {
Info SectorOnChainInfo
ID abi.SectorNumber
}
type SectorExpiration struct {
OnTime abi.ChainEpoch
+80 -45
View File
@@ -4,19 +4,22 @@ import (
"bytes"
"errors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/dline"
"github.com/filecoin-project/lotus/chain/actors/adt"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/dline"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/actors/adt"
)
var _ State = (*state0)(nil)
type state0 struct {
miner0.State
store adt.Store
@@ -62,7 +65,8 @@ func (s *state0) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
return nil, err
}
return info, nil
ret := fromV0SectorOnChainInfo(*info)
return &ret, nil
}
func (s *state0) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
@@ -76,11 +80,24 @@ func (s *state0) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
}, nil
}
func (s *state0) NumLiveSectors() (uint64, error) {
dls, err := s.State.LoadDeadlines(s.store)
if err != nil {
return 0, err
}
var total uint64
if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner0.Deadline) error {
total += dl.LiveSectors
return nil
}); err != nil {
return 0, err
}
return total, nil
}
// GetSectorExpiration returns the effective expiration of the given sector.
//
// If the sector isn't found or has already been terminated, this method returns
// nil and no error. If the sector does not expire early, the Early expiration
// field is 0.
// If the sector does not expire early, the Early expiration field is 0.
func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
dls, err := s.State.LoadDeadlines(s.store)
if err != nil {
@@ -143,7 +160,7 @@ func (s *state0) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, e
return nil, err
}
if out.Early == 0 && out.OnTime == 0 {
return nil, nil
return nil, xerrors.Errorf("failed to find sector %d", num)
}
return &out, nil
}
@@ -154,39 +171,41 @@ func (s *state0) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOn
return nil, err
}
return info, nil
ret := fromV0SectorPreCommitOnChainInfo(*info)
return &ret, nil
}
func (s *state0) LoadSectorsFromSet(filter *bitfield.BitField, filterOut bool) (adt.Array, error) {
a, err := adt0.AsArray(s.store, s.State.Sectors)
func (s *state0) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
sectors, err := miner0.LoadSectors(s.store, s.State.Sectors)
if err != nil {
return nil, err
}
var v cbg.Deferred
if err := a.ForEach(&v, func(i int64) error {
if filter != nil {
set, err := filter.IsSet(uint64(i))
if err != nil {
return xerrors.Errorf("filter check error: %w", err)
}
if set == filterOut {
err = a.Delete(uint64(i))
if err != nil {
return xerrors.Errorf("filtering error: %w", err)
}
}
// If no sector numbers are specified, load all.
if snos == nil {
infos := make([]*SectorOnChainInfo, 0, sectors.Length())
var info0 miner0.SectorOnChainInfo
if err := sectors.ForEach(&info0, func(_ int64) error {
info := fromV0SectorOnChainInfo(info0)
infos = append(infos, &info)
return nil
}); err != nil {
return nil, err
}
return nil
}); err != nil {
return nil, err
return infos, nil
}
return a, nil
}
func (s *state0) LoadPreCommittedSectors() (adt.Map, error) {
return adt0.AsMap(s.store, s.State.PreCommittedSectors)
// Otherwise, load selected.
infos0, err := sectors.Load(*snos)
if err != nil {
return nil, err
}
infos := make([]*SectorOnChainInfo, len(infos0))
for i, info0 := range infos0 {
info := fromV0SectorOnChainInfo(*info0)
infos[i] = &info
}
return infos, nil
}
func (s *state0) IsAllocated(num abi.SectorNumber) (bool, error) {
@@ -224,14 +243,14 @@ func (s *state0) NumDeadlines() (uint64, error) {
return miner0.WPoStPeriodDeadlines, nil
}
func (s *state0) DeadlinesChanged(other State) bool {
func (s *state0) DeadlinesChanged(other State) (bool, error) {
other0, ok := other.(*state0)
if !ok {
// treat an upgrade as a change, always
return true
return true, nil
}
return s.State.Deadlines.Equals(other0.Deadlines)
return s.State.Deadlines.Equals(other0.Deadlines), nil
}
func (s *state0) Info() (MinerInfo, error) {
@@ -268,8 +287,8 @@ func (s *state0) Info() (MinerInfo, error) {
return mi, nil
}
func (s *state0) DeadlineInfo(epoch abi.ChainEpoch) *dline.Info {
return s.State.DeadlineInfo(epoch)
func (s *state0) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
return s.State.DeadlineInfo(epoch), nil
}
func (s *state0) sectors() (adt.Array, error) {
@@ -279,7 +298,11 @@ func (s *state0) sectors() (adt.Array, error) {
func (s *state0) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
var si miner0.SectorOnChainInfo
err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
return si, err
if err != nil {
return SectorOnChainInfo{}, err
}
return fromV0SectorOnChainInfo(si), nil
}
func (s *state0) precommits() (adt.Map, error) {
@@ -289,7 +312,11 @@ func (s *state0) precommits() (adt.Map, error) {
func (s *state0) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
var sp miner0.SectorPreCommitOnChainInfo
err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
return sp, err
if err != nil {
return SectorPreCommitOnChainInfo{}, err
}
return fromV0SectorPreCommitOnChainInfo(sp), nil
}
func (d *deadline0) LoadPartition(idx uint64) (Partition, error) {
@@ -311,14 +338,14 @@ func (d *deadline0) ForEachPartition(cb func(uint64, Partition) error) error {
})
}
func (d *deadline0) PartitionsChanged(other Deadline) bool {
func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
other0, ok := other.(*deadline0)
if !ok {
// treat an upgrade as a change, always
return true
return true, nil
}
return d.Deadline.Partitions.Equals(other0.Deadline.Partitions)
return d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
}
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
@@ -336,3 +363,11 @@ func (p *partition0) FaultySectors() (bitfield.BitField, error) {
func (p *partition0) RecoveringSectors() (bitfield.BitField, error) {
return p.Partition.Recoveries, nil
}
func fromV0SectorOnChainInfo(v0 miner0.SectorOnChainInfo) SectorOnChainInfo {
return (SectorOnChainInfo)(v0)
}
func fromV0SectorPreCommitOnChainInfo(v0 miner0.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
return (SectorPreCommitOnChainInfo)(v0)
}
+12 -3
View File
@@ -3,9 +3,12 @@ package multisig
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/types"
@@ -28,7 +31,13 @@ type State interface {
cbor.Marshaler
LockedBalance(epoch abi.ChainEpoch) (abi.TokenAmount, error)
StartEpoch() abi.ChainEpoch
UnlockDuration() abi.ChainEpoch
InitialBalance() abi.TokenAmount
StartEpoch() (abi.ChainEpoch, error)
UnlockDuration() (abi.ChainEpoch, error)
InitialBalance() (abi.TokenAmount, error)
Threshold() (uint64, error)
Signers() ([]address.Address, error)
ForEachPendingTxn(func(id int64, txn Transaction) error) error
}
type Transaction = msig0.Transaction
+39 -8
View File
@@ -1,13 +1,21 @@
package multisig
import (
"encoding/binary"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"golang.org/x/xerrors"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
)
var _ State = (*state0)(nil)
type state0 struct {
multisig.State
msig0.State
store adt.Store
}
@@ -15,14 +23,37 @@ func (s *state0) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error
return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
}
func (s *state0) StartEpoch() abi.ChainEpoch {
return s.State.StartEpoch
func (s *state0) StartEpoch() (abi.ChainEpoch, error) {
return s.State.StartEpoch, nil
}
func (s *state0) UnlockDuration() abi.ChainEpoch {
return s.State.UnlockDuration
func (s *state0) UnlockDuration() (abi.ChainEpoch, error) {
return s.State.UnlockDuration, nil
}
func (s *state0) InitialBalance() abi.TokenAmount {
return s.State.InitialBalance
func (s *state0) InitialBalance() (abi.TokenAmount, error) {
return s.State.InitialBalance, nil
}
func (s *state0) Threshold() (uint64, error) {
return s.State.NumApprovalsThreshold, nil
}
func (s *state0) Signers() ([]address.Address, error) {
return s.State.Signers, nil
}
func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
arr, err := adt0.AsMap(s.store, s.State.PendingTxns)
if err != nil {
return err
}
var out msig0.Transaction
return arr.ForEach(&out, func(key string) error {
txid, n := binary.Varint([]byte(key))
if n <= 0 {
return xerrors.Errorf("invalid pending transaction key: %v", key)
}
return cb(txid, (Transaction)(out))
})
}
+12 -12
View File
@@ -45,23 +45,23 @@ func (ms *mockState) MarshalCBOR(io.Writer) error {
}
// Channel owner, who has funded the actor
func (ms *mockState) From() address.Address {
return ms.from
func (ms *mockState) From() (address.Address, error) {
return ms.from, nil
}
// Recipient of payouts from channel
func (ms *mockState) To() address.Address {
return ms.to
func (ms *mockState) To() (address.Address, error) {
return ms.to, nil
}
// Height at which the channel can be `Collected`
func (ms *mockState) SettlingAt() abi.ChainEpoch {
return ms.settlingAt
func (ms *mockState) SettlingAt() (abi.ChainEpoch, error) {
return ms.settlingAt, nil
}
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
func (ms *mockState) ToSend() abi.TokenAmount {
return ms.toSend
func (ms *mockState) ToSend() (abi.TokenAmount, error) {
return ms.toSend, nil
}
// Get total number of lanes
@@ -80,10 +80,10 @@ func (ms *mockState) ForEachLaneState(cb func(idx uint64, dl paych.LaneState) er
return lastErr
}
func (mls *mockLaneState) Redeemed() big.Int {
return mls.redeemed
func (mls *mockLaneState) Redeemed() (big.Int, error) {
return mls.redeemed, nil
}
func (mls *mockLaneState) Nonce() uint64 {
return mls.nonce
func (mls *mockLaneState) Nonce() (uint64, error) {
return mls.nonce, nil
}
+10 -6
View File
@@ -8,6 +8,7 @@ import (
big "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/cbor"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/types"
@@ -32,15 +33,15 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
type State interface {
cbor.Marshaler
// Channel owner, who has funded the actor
From() address.Address
From() (address.Address, error)
// Recipient of payouts from channel
To() address.Address
To() (address.Address, error)
// Height at which the channel can be `Collected`
SettlingAt() abi.ChainEpoch
SettlingAt() (abi.ChainEpoch, error)
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
ToSend() abi.TokenAmount
ToSend() (abi.TokenAmount, error)
// Get total number of lanes
LaneCount() (uint64, error)
@@ -51,6 +52,9 @@ type State interface {
// LaneState is an abstract copy of the state of a single lane
type LaneState interface {
Redeemed() big.Int
Nonce() uint64
Redeemed() (big.Int, error)
Nonce() (uint64, error)
}
type SignedVoucher = paych0.SignedVoucher
type ModVerifyParams = paych0.ModVerifyParams
+14 -12
View File
@@ -9,6 +9,8 @@ import (
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
)
var _ State = (*state0)(nil)
type state0 struct {
paych.State
store adt.Store
@@ -16,23 +18,23 @@ type state0 struct {
}
// Channel owner, who has funded the actor
func (s *state0) From() address.Address {
return s.State.From
func (s *state0) From() (address.Address, error) {
return s.State.From, nil
}
// Recipient of payouts from channel
func (s *state0) To() address.Address {
return s.State.To
func (s *state0) To() (address.Address, error) {
return s.State.To, nil
}
// Height at which the channel can be `Collected`
func (s *state0) SettlingAt() abi.ChainEpoch {
return s.State.SettlingAt
func (s *state0) SettlingAt() (abi.ChainEpoch, error) {
return s.State.SettlingAt, nil
}
// Amount successfully redeemed through the payment channel, paid out on `Collect()`
func (s *state0) ToSend() abi.TokenAmount {
return s.State.ToSend
func (s *state0) ToSend() (abi.TokenAmount, error) {
return s.State.ToSend, nil
}
func (s *state0) getOrLoadLsAmt() (*adt0.Array, error) {
@@ -80,10 +82,10 @@ type laneState0 struct {
paych.LaneState
}
func (ls *laneState0) Redeemed() big.Int {
return ls.LaneState.Redeemed
func (ls *laneState0) Redeemed() (big.Int, error) {
return ls.LaneState.Redeemed, nil
}
func (ls *laneState0) Nonce() uint64 {
return ls.LaneState.Nonce
func (ls *laneState0) Nonce() (uint64, error) {
return ls.LaneState.Nonce, nil
}
+3 -1
View File
@@ -8,6 +8,8 @@ import (
"github.com/filecoin-project/specs-actors/actors/util/adt"
)
var _ State = (*state0)(nil)
type state0 struct {
power0.State
store adt.Store
@@ -53,7 +55,7 @@ func (s *state0) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool
}
func (s *state0) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
return *s.State.ThisEpochQAPowerSmoothed, nil
return builtin.FromV0FilterEstimate(*s.State.ThisEpochQAPowerSmoothed), nil
}
func (s *state0) MinerCounts() (uint64, uint64, error) {
+7 -1
View File
@@ -2,6 +2,7 @@ package reward
import (
"github.com/filecoin-project/go-state-types/abi"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/cbor"
@@ -28,7 +29,7 @@ func Load(store adt.Store, act *types.Actor) (st State, err error) {
}
type State interface {
cbor.Er
cbor.Marshaler
ThisEpochBaselinePower() (abi.StoragePower, error)
ThisEpochReward() (abi.StoragePower, error)
@@ -41,4 +42,9 @@ type State interface {
CumsumBaseline() (abi.StoragePower, error)
CumsumRealized() (abi.StoragePower, error)
InitialPledgeForPower(abi.StoragePower, abi.TokenAmount, *builtin.FilterEstimate, abi.TokenAmount) (abi.TokenAmount, error)
PreCommitDepositForPower(builtin.FilterEstimate, abi.StoragePower) (abi.TokenAmount, error)
}
type AwardBlockRewardParams = reward0.AwardBlockRewardParams
+27 -1
View File
@@ -3,10 +3,14 @@ package reward
import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/specs-actors/actors/util/smoothing"
)
var _ State = (*state0)(nil)
type state0 struct {
reward.State
store adt.Store
@@ -17,7 +21,7 @@ func (s *state0) ThisEpochReward() (abi.StoragePower, error) {
}
func (s *state0) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
return *s.State.ThisEpochRewardSmoothed, nil
return builtin.FromV0FilterEstimate(*s.State.ThisEpochRewardSmoothed), nil
}
func (s *state0) ThisEpochBaselinePower() (abi.StoragePower, error) {
@@ -43,3 +47,25 @@ func (s *state0) CumsumBaseline() (abi.StoragePower, error) {
func (s *state0) CumsumRealized() (abi.StoragePower, error) {
return s.State.CumsumBaseline, nil
}
func (s *state0) InitialPledgeForPower(sectorWeight abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
return miner0.InitialPledgeForPower(
sectorWeight,
s.State.ThisEpochBaselinePower,
networkTotalPledge,
s.State.ThisEpochRewardSmoothed,
&smoothing.FilterEstimate{
PositionEstimate: networkQAPower.PositionEstimate,
VelocityEstimate: networkQAPower.VelocityEstimate,
},
circSupply), nil
}
func (s *state0) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
return miner0.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
&smoothing.FilterEstimate{
PositionEstimate: networkQAPower.PositionEstimate,
VelocityEstimate: networkQAPower.VelocityEstimate,
},
sectorWeight), nil
}
+38 -4
View File
@@ -6,32 +6,66 @@ import (
"github.com/filecoin-project/go-state-types/big"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/adt"
)
var _ State = (*state0)(nil)
type state0 struct {
verifreg0.State
store adt.Store
}
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
func getDataCap(store adt.Store, root cid.Cid, addr address.Address) (bool, abi.StoragePower, error) {
if addr.Protocol() != address.ID {
return false, big.Zero(), xerrors.Errorf("can only look up ID addresses")
}
vh, err := adt0.AsMap(s.store, s.VerifiedClients)
vh, err := adt0.AsMap(store, root)
if err != nil {
return false, big.Zero(), xerrors.Errorf("loading verified clients: %w", err)
return false, big.Zero(), xerrors.Errorf("loading verifreg: %w", err)
}
var dcap abi.StoragePower
if found, err := vh.Get(abi.AddrKey(addr), &dcap); err != nil {
return false, big.Zero(), xerrors.Errorf("looking up verified clients: %w", err)
return false, big.Zero(), xerrors.Errorf("looking up addr: %w", err)
} else if !found {
return false, big.Zero(), nil
}
return true, dcap, nil
}
func (s *state0) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
return getDataCap(s.store, s.State.VerifiedClients, addr)
}
func (s *state0) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
return getDataCap(s.store, s.State.Verifiers, addr)
}
func forEachCap(store adt.Store, root cid.Cid, cb func(addr address.Address, dcap abi.StoragePower) error) error {
vh, err := adt0.AsMap(store, root)
if err != nil {
return xerrors.Errorf("loading verified clients: %w", err)
}
var dcap abi.StoragePower
return vh.ForEach(&dcap, func(key string) error {
a, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
return cb(a, dcap)
})
}
func (s *state0) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
return forEachCap(s.store, s.State.Verifiers, cb)
}
func (s *state0) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
return forEachCap(s.store, s.State.VerifiedClients, cb)
}
@@ -31,4 +31,7 @@ type State interface {
cbor.Marshaler
VerifiedClientDataCap(address.Address) (bool, abi.StoragePower, error)
VerifierDataCap(address.Address) (bool, abi.StoragePower, error)
ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error) error
ForEachClient(func(addr address.Address, dcap abi.StoragePower) error) error
}
+54
View File
@@ -0,0 +1,54 @@
package policy
import (
"github.com/filecoin-project/go-state-types/abi"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
)
// SetSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing.
func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
newTypes := make(map[abi.RegisteredSealProof]struct{}, len(types))
for _, t := range types {
newTypes[t] = struct{}{}
}
// Set for all miner versions.
miner0.SupportedProofTypes = newTypes
}
// AddSupportedProofTypes sets supported proof types, across all actor versions.
// This should only be used for testing.
func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
for _, t := range types {
// Set for all miner versions.
miner0.SupportedProofTypes[t] = struct{}{}
}
}
// SetPreCommitChallengeDelay sets the pre-commit challenge delay across all
// actors versions. Use for testing.
func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
// Set for all miner versions.
miner0.PreCommitChallengeDelay = delay
}
// TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
func GetPreCommitChallengeDelay() abi.ChainEpoch {
return miner0.PreCommitChallengeDelay
}
// SetConsensusMinerMinPower sets the minimum power of an individual miner must
// meet for leader election, across all actor versions. This should only be used
// for testing.
func SetConsensusMinerMinPower(p abi.StoragePower) {
power0.ConsensusMinerMinPower = p
}
// SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
// only be used for testing.
func SetMinVerifiedDealSize(size abi.StoragePower) {
verifreg0.MinVerifiedDealSize = size
}
+36
View File
@@ -0,0 +1,36 @@
package policy
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-state-types/abi"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
)
func TestSupportedProofTypes(t *testing.T) {
var oldTypes []abi.RegisteredSealProof
for t := range miner0.SupportedProofTypes {
oldTypes = append(oldTypes, t)
}
t.Cleanup(func() {
SetSupportedProofTypes(oldTypes...)
})
SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
require.EqualValues(t,
miner0.SupportedProofTypes,
map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
},
)
AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg8MiBV1)
require.EqualValues(t,
miner0.SupportedProofTypes,
map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
abi.RegisteredSealProof_StackedDrg8MiBV1: {},
},
)
}
+89 -26
View File
@@ -97,7 +97,12 @@ type DiffBalanceTablesFunc func(ctx context.Context, oldBalanceTable, newBalance
// OnBalanceChanged runs when the escrow table for available balances changes
func (sp *StatePredicates) OnBalanceChanged(diffBalances DiffBalanceTablesFunc) DiffStorageMarketStateFunc {
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
if !oldState.BalancesChanged(newState) {
bc, err := oldState.BalancesChanged(newState)
if err != nil {
return false, nil, err
}
if !bc {
return false, nil, nil
}
@@ -132,7 +137,12 @@ type DiffAdtArraysFunc func(ctx context.Context, oldDealStateRoot, newDealStateR
// OnDealStateChanged calls diffDealStates when the market deal state changes
func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc) DiffStorageMarketStateFunc {
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
if !oldState.StatesChanged(newState) {
sc, err := oldState.StatesChanged(newState)
if err != nil {
return false, nil, err
}
if !sc {
return false, nil, nil
}
@@ -152,7 +162,12 @@ func (sp *StatePredicates) OnDealStateChanged(diffDealStates DiffDealStatesFunc)
// OnDealProposalChanged calls diffDealProps when the market proposal state changes
func (sp *StatePredicates) OnDealProposalChanged(diffDealProps DiffDealProposalsFunc) DiffStorageMarketStateFunc {
return func(ctx context.Context, oldState market.State, newState market.State) (changed bool, user UserData, err error) {
if !oldState.ProposalsChanged(newState) {
pc, err := oldState.ProposalsChanged(newState)
if err != nil {
return false, nil, err
}
if !pc {
return false, nil, nil
}
@@ -303,7 +318,7 @@ func (sp *StatePredicates) OnInitActorChange(diffInitActorState DiffInitActorSta
if err != nil {
return false, nil, err
}
return diffInitActorState(ctx, &oldState, &newState)
return diffInitActorState(ctx, oldState, newState)
})
}
@@ -379,12 +394,22 @@ type PayChToSendChange struct {
// OnToSendAmountChanges monitors changes on the total amount to send from one party to the other on a payment channel
func (sp *StatePredicates) OnToSendAmountChanges() DiffPaymentChannelStateFunc {
return func(ctx context.Context, oldState paych.State, newState paych.State) (changed bool, user UserData, err error) {
if oldState.ToSend().Equals(newState.ToSend()) {
ots, err := oldState.ToSend()
if err != nil {
return false, nil, err
}
nts, err := newState.ToSend()
if err != nil {
return false, nil, err
}
if ots.Equals(nts) {
return false, nil, nil
}
return true, &PayChToSendChange{
OldToSend: oldState.ToSend(),
NewToSend: newState.ToSend(),
OldToSend: ots,
NewToSend: nts,
}, nil
}
}
@@ -405,7 +430,7 @@ type AddressChange struct {
To AddressPair
}
type DiffInitActorStateFunc func(ctx context.Context, oldState *init_.State, newState *init_.State) (changed bool, user UserData, err error)
type DiffInitActorStateFunc func(ctx context.Context, oldState init_.State, newState init_.State) (changed bool, user UserData, err error)
func (i *InitActorAddressChanges) AsKey(key string) (abi.Keyer, error) {
addr, err := address.NewFromBytes([]byte(key))
@@ -493,33 +518,73 @@ func (i *InitActorAddressChanges) Remove(key string, val *typegen.Deferred) erro
}
func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
return func(ctx context.Context, oldState, newState *init_.State) (changed bool, user UserData, err error) {
/*ctxStore := &contextStore{
ctx: ctx,
cst: sp.cst,
}
return func(ctx context.Context, oldState, newState init_.State) (changed bool, user UserData, err error) {
addressChanges := &InitActorAddressChanges{
Added: []AddressPair{},
Modified: []AddressChange{},
Removed: []AddressPair{},
}
if oldState.AddressMap.Equals(newState.AddressMap) {
return false, nil, nil
}
err = oldState.ForEachActor(func(oldId abi.ActorID, oldAddress address.Address) error {
oldIdAddress, err := address.NewIDAddress(uint64(oldId))
if err != nil {
return err
}
newIdAddress, found, err := newState.ResolveAddress(oldAddress)
if err != nil {
return err
}
if !found {
addressChanges.Removed = append(addressChanges.Removed, AddressPair{
ID: oldIdAddress,
PK: oldAddress,
})
}
if oldIdAddress != newIdAddress {
addressChanges.Modified = append(addressChanges.Modified, AddressChange{
From: AddressPair{
ID: oldIdAddress,
PK: oldAddress,
},
To: AddressPair{
ID: newIdAddress,
PK: oldAddress,
},
})
}
return nil
})
oldAddrs, err := adt0.AsMap(ctxStore, oldState.AddressMap)
if err != nil {
return false, nil, err
}
newAddrs, err := adt0.AsMap(ctxStore, newState.AddressMap)
if err != nil {
return false, nil, err
}
err = newState.ForEachActor(func(newId abi.ActorID, newAddress address.Address) error {
newIdAddress, err := address.NewIDAddress(uint64(newId))
if err != nil {
return err
}
if err := adt.DiffAdtMap(oldAddrs, newAddrs, addressChanges); err != nil {
_, found, err := newState.ResolveAddress(newAddress)
if err != nil {
return err
}
if !found {
addressChanges.Added = append(addressChanges.Added, AddressPair{
ID: newIdAddress,
PK: newAddress,
})
}
return nil
})
if err != nil {
return false, nil, err
}
@@ -527,8 +592,6 @@ func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
return false, nil, nil
}
return true, addressChanges, nil*/
panic("TODO")
return true, addressChanges, nil
}
}
+3 -3
View File
@@ -581,7 +581,7 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
root := adt.MakeEmptyArray(store)
for _, sector := range sectors {
sector := sector
sector := (miner0.SectorOnChainInfo)(sector)
err := root.Set(uint64(sector.SectorNumber), &sector)
require.NoError(t, err)
}
@@ -614,8 +614,8 @@ const (
)
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner.SectorPreCommitInfo {
return &miner.SectorPreCommitInfo{
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner0.SectorPreCommitInfo {
return &miner0.SectorPreCommitInfo{
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
SectorNumber: sectorNo,
SealedCID: sealed,
+92 -31
View File
@@ -7,6 +7,7 @@ import (
"math/rand"
"time"
"github.com/libp2p/go-libp2p-core/helpers"
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
@@ -64,7 +65,15 @@ func NewClient(lc fx.Lifecycle, host host.Host, pmgr peermgr.MaybePeerMgr) Clien
// request options without disrupting external calls. In the future the
// consumers should be forced to use a more standardized service and
// adhere to a single API derived from this function.
func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.ID) (*validatedResponse, error) {
func (c *client) doRequest(
ctx context.Context,
req *Request,
singlePeer *peer.ID,
// In the `GetChainMessages` case, we won't request the headers but we still
// need them to check the integrity of the `CompactedMessages` in the response
// so the tipset blocks need to be provided by the caller.
tipsets []*types.TipSet,
) (*validatedResponse, error) {
// Validate request.
if req.Length == 0 {
return nil, xerrors.Errorf("invalid request of length 0")
@@ -115,7 +124,7 @@ func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.I
}
// Process and validate response.
validRes, err := c.processResponse(req, res)
validRes, err := c.processResponse(req, res, tipsets)
if err != nil {
log.Warnf("processing peer %s response failed: %s",
peer.String(), err)
@@ -143,7 +152,7 @@ func (c *client) doRequest(ctx context.Context, req *Request, singlePeer *peer.I
// errors. Peer penalization should happen here then, before returning, so
// we can apply the correct penalties depending on the cause of the error.
// FIXME: Add the `peer` as argument once we implement penalties.
func (c *client) processResponse(req *Request, res *Response) (*validatedResponse, error) {
func (c *client) processResponse(req *Request, res *Response, tipsets []*types.TipSet) (*validatedResponse, error) {
err := res.statusToError()
if err != nil {
return nil, xerrors.Errorf("status error: %s", err)
@@ -175,6 +184,16 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
// Check for valid block sets and extract them into `TipSet`s.
validRes.tipsets = make([]*types.TipSet, resLength)
for i := 0; i < resLength; i++ {
if res.Chain[i] == nil {
return nil, xerrors.Errorf("response with nil tipset in pos %d", i)
}
for blockIdx, block := range res.Chain[i].Blocks {
if block == nil {
return nil, xerrors.Errorf("tipset with nil block in pos %d", blockIdx)
// FIXME: Maybe we should move this check to `NewTipSet`.
}
}
validRes.tipsets[i], err = types.NewTipSet(res.Chain[i].Blocks)
if err != nil {
return nil, xerrors.Errorf("invalid tipset blocks at height (head - %d): %w", i, err)
@@ -209,31 +228,28 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
// If the headers were also returned check that the compression
// indexes are valid before `toFullTipSets()` is called by the
// consumer.
for tipsetIdx := 0; tipsetIdx < resLength; tipsetIdx++ {
msgs := res.Chain[tipsetIdx].Messages
blocksNum := len(res.Chain[tipsetIdx].Blocks)
if len(msgs.BlsIncludes) != blocksNum {
return nil, xerrors.Errorf("BlsIncludes (%d) does not match number of blocks (%d)",
len(msgs.BlsIncludes), blocksNum)
}
if len(msgs.SecpkIncludes) != blocksNum {
return nil, xerrors.Errorf("SecpkIncludes (%d) does not match number of blocks (%d)",
len(msgs.SecpkIncludes), blocksNum)
}
for blockIdx := 0; blockIdx < blocksNum; blockIdx++ {
for _, mi := range msgs.BlsIncludes[blockIdx] {
if int(mi) >= len(msgs.Bls) {
return nil, xerrors.Errorf("index in BlsIncludes (%d) exceeds number of messages (%d)",
mi, len(msgs.Bls))
}
}
for _, mi := range msgs.SecpkIncludes[blockIdx] {
if int(mi) >= len(msgs.Secpk) {
return nil, xerrors.Errorf("index in SecpkIncludes (%d) exceeds number of messages (%d)",
mi, len(msgs.Secpk))
}
}
err := c.validateCompressedIndices(res.Chain)
if err != nil {
return nil, err
}
} else {
// If we didn't request the headers they should have been provided
// by the caller.
if len(tipsets) < len(res.Chain) {
return nil, xerrors.Errorf("not enought tipsets provided for message response validation, needed %d, have %d", len(res.Chain), len(tipsets))
}
chain := make([]*BSTipSet, 0, resLength)
for i, resChain := range res.Chain {
next := &BSTipSet{
Blocks: tipsets[i].Blocks(),
Messages: resChain.Messages,
}
chain = append(chain, next)
}
err := c.validateCompressedIndices(chain)
if err != nil {
return nil, err
}
}
}
@@ -241,6 +257,42 @@ func (c *client) processResponse(req *Request, res *Response) (*validatedRespons
return validRes, nil
}
func (c *client) validateCompressedIndices(chain []*BSTipSet) error {
resLength := len(chain)
for tipsetIdx := 0; tipsetIdx < resLength; tipsetIdx++ {
msgs := chain[tipsetIdx].Messages
blocksNum := len(chain[tipsetIdx].Blocks)
if len(msgs.BlsIncludes) != blocksNum {
return xerrors.Errorf("BlsIncludes (%d) does not match number of blocks (%d)",
len(msgs.BlsIncludes), blocksNum)
}
if len(msgs.SecpkIncludes) != blocksNum {
return xerrors.Errorf("SecpkIncludes (%d) does not match number of blocks (%d)",
len(msgs.SecpkIncludes), blocksNum)
}
for blockIdx := 0; blockIdx < blocksNum; blockIdx++ {
for _, mi := range msgs.BlsIncludes[blockIdx] {
if int(mi) >= len(msgs.Bls) {
return xerrors.Errorf("index in BlsIncludes (%d) exceeds number of messages (%d)",
mi, len(msgs.Bls))
}
}
for _, mi := range msgs.SecpkIncludes[blockIdx] {
if int(mi) >= len(msgs.Secpk) {
return xerrors.Errorf("index in SecpkIncludes (%d) exceeds number of messages (%d)",
mi, len(msgs.Secpk))
}
}
}
}
return nil
}
// GetBlocks implements Client.GetBlocks(). Refer to the godocs there.
func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error) {
ctx, span := trace.StartSpan(ctx, "bsync.GetBlocks")
@@ -258,7 +310,7 @@ func (c *client) GetBlocks(ctx context.Context, tsk types.TipSetKey, count int)
Options: Headers,
}
validRes, err := c.doRequest(ctx, req, nil)
validRes, err := c.doRequest(ctx, req, nil, nil)
if err != nil {
return nil, err
}
@@ -276,7 +328,7 @@ func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipS
Options: Headers | Messages,
}
validRes, err := c.doRequest(ctx, req, &peer)
validRes, err := c.doRequest(ctx, req, &peer, nil)
if err != nil {
return nil, err
}
@@ -287,7 +339,10 @@ func (c *client) GetFullTipSet(ctx context.Context, peer peer.ID, tsk types.TipS
}
// GetChainMessages implements Client.GetChainMessages(). Refer to the godocs there.
func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error) {
func (c *client) GetChainMessages(ctx context.Context, tipsets []*types.TipSet) ([]*CompactedMessages, error) {
head := tipsets[0]
length := uint64(len(tipsets))
ctx, span := trace.StartSpan(ctx, "GetChainMessages")
if span.IsRecordingEvents() {
span.AddAttributes(
@@ -303,7 +358,7 @@ func (c *client) GetChainMessages(ctx context.Context, head *types.TipSet, lengt
Options: Messages,
}
validRes, err := c.doRequest(ctx, req, nil)
validRes, err := c.doRequest(ctx, req, nil, tipsets)
if err != nil {
return nil, err
}
@@ -357,6 +412,12 @@ func (c *client) sendRequestToPeer(ctx context.Context, peer peer.ID, req *Reque
return nil, xerrors.Errorf("failed to open stream to peer: %w", err)
}
defer func() {
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
// go-libp2p-core 0.7.0
go helpers.FullClose(stream) //nolint:errcheck
}()
// Write request.
_ = stream.SetWriteDeadline(time.Now().Add(WriteReqDeadline))
if err := cborutil.WriteCborRPC(stream, req); err != nil {
+3 -4
View File
@@ -32,10 +32,9 @@ type Client interface {
// or less.
GetBlocks(ctx context.Context, tsk types.TipSetKey, count int) ([]*types.TipSet, error)
// GetChainMessages fetches messages from the network, from the provided
// tipset *backwards*, returning the messages from as many tipsets as the
// count parameter, or less.
GetChainMessages(ctx context.Context, head *types.TipSet, length uint64) ([]*CompactedMessages, error)
// GetChainMessages fetches messages from the network, starting from the first provided tipset
// and returning messages from as many tipsets as requested or less.
GetChainMessages(ctx context.Context, tipsets []*types.TipSet) ([]*CompactedMessages, error)
// GetFullTipSet fetches a full tipset from a given peer. If successful,
// the fetched object contains block headers and all messages in full form.
+3 -1
View File
@@ -40,7 +40,7 @@ const (
WriteReqDeadline = 5 * time.Second
ReadResDeadline = WriteReqDeadline
ReadResMinSpeed = 50 << 10
ShufflePeersPrefix = 5
ShufflePeersPrefix = 16
WriteResDeadline = 60 * time.Second
)
@@ -139,6 +139,8 @@ func (res *Response) statusToError() error {
// FIXME: Rename.
type BSTipSet struct {
// List of blocks belonging to a single tipset to which the
// `CompactedMessages` are linked.
Blocks []*types.BlockHeader
Messages *CompactedMessages
}
+4 -1
View File
@@ -15,6 +15,7 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/helpers"
inet "github.com/libp2p/go-libp2p-core/network"
)
@@ -39,7 +40,9 @@ func (s *server) HandleStream(stream inet.Stream) {
ctx, span := trace.StartSpan(context.Background(), "chainxchg.HandleStream")
defer span.End()
defer stream.Close() //nolint:errcheck
// Note: this will become just stream.Close once we've completed the go-libp2p migration to
// go-libp2p-core 0.7.0
defer helpers.FullClose(stream) //nolint:errcheck
var req Request
if err := cborutil.ReadCborRPC(bufio.NewReader(stream), &req); err != nil {
+3 -4
View File
@@ -14,7 +14,6 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
@@ -28,6 +27,7 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/beacon"
genesis2 "github.com/filecoin-project/lotus/chain/gen/genesis"
"github.com/filecoin-project/lotus/chain/stmgr"
@@ -121,9 +121,8 @@ var DefaultRemainderAccountActor = genesis.Actor{
}
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
// TODO: we really shouldn't modify a global variable here.
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
mr := repo.NewMemory(nil)
lr, err := mr.Lock(repo.StorageMiner)
+4 -9
View File
@@ -4,21 +4,16 @@ import (
"testing"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/actors/policy"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
)
func init() {
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
power0.ConsensusMinerMinPower = big.NewInt(2048)
verifreg0.MinVerifiedDealSize = big.NewInt(256)
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
}
func testGeneration(t testing.TB, n int, msgs int, sectors int) {
+21 -16
View File
@@ -6,6 +6,12 @@ import (
"fmt"
"math/rand"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/ipfs/go-cid"
@@ -19,7 +25,6 @@ import (
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
@@ -109,7 +114,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
}
params := mustEnc(constructorParams)
rval, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
}
@@ -141,7 +146,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
if m.MarketBalance.GreaterThan(big.Zero()) {
params := mustEnc(&minerInfos[i].maddr)
_, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err)
}
@@ -153,7 +158,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
publish := func(params *market.PublishStorageDealsParams) error {
fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker)
ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
if err != nil {
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
}
@@ -210,7 +215,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
}
}
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power0.State) error {
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
st.TotalQualityAdjPower = qaPow
st.TotalRawBytePower = rawPow
@@ -222,7 +227,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
return cid.Undef, xerrors.Errorf("mutating state: %w", err)
}
err = vm.MutateState(ctx, builtin.RewardActorAddr, func(sct cbor.IpldStore, st *reward0.State) error {
err = vm.MutateState(ctx, reward.Address, func(sct cbor.IpldStore, st *reward0.State) error {
*st = *reward0.ConstructState(qaPow)
return nil
})
@@ -252,7 +257,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
sectorWeight := miner0.QAPowerForWeight(m.SectorSize, minerInfos[i].presealExp, dweight.DealWeight, dweight.VerifiedDealWeight)
// we've added fake power for this sector above, remove it now
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power0.State) error {
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
st.TotalQualityAdjPower = types.BigSub(st.TotalQualityAdjPower, sectorWeight) //nolint:scopelint
st.TotalRawBytePower = types.BigSub(st.TotalRawBytePower, types.NewInt(uint64(m.SectorSize)))
return nil
@@ -295,7 +300,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
Sectors: []abi.SectorNumber{preseal.SectorID},
}
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, builtin.StoragePowerActorAddr, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
}
@@ -304,7 +309,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
}
// Sanity-check total network power
err = vm.MutateState(ctx, builtin.StoragePowerActorAddr, func(cst cbor.IpldStore, st *power0.State) error {
err = vm.MutateState(ctx, power.Address, func(cst cbor.IpldStore, st *power0.State) error {
if !st.TotalRawBytePower.Equals(rawPow) {
return xerrors.Errorf("st.TotalRawBytePower doesn't match previously calculated rawPow")
}
@@ -344,7 +349,7 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry
}
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
pwret, err := doExecValue(ctx, vm, builtin.StoragePowerActorAddr, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
if err != nil {
return nil, err
}
@@ -356,33 +361,33 @@ func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*
return &pwr, nil
}
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market.VerifyDealsForActivationReturn, error) {
func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs []abi.DealID, sectorStart, sectorExpiry abi.ChainEpoch) (market0.VerifyDealsForActivationReturn, error) {
params := &market.VerifyDealsForActivationParams{
DealIDs: dealIDs,
SectorStart: sectorStart,
SectorExpiry: sectorExpiry,
}
var dealWeights market.VerifyDealsForActivationReturn
var dealWeights market0.VerifyDealsForActivationReturn
ret, err := doExecValue(ctx, vm,
builtin.StorageMarketActorAddr,
market.Address,
maddr,
abi.NewTokenAmount(0),
builtin.MethodsMarket.VerifyDealsForActivation,
mustEnc(params),
)
if err != nil {
return market.VerifyDealsForActivationReturn{}, err
return market0.VerifyDealsForActivationReturn{}, err
}
if err := dealWeights.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
return market.VerifyDealsForActivationReturn{}, err
return market0.VerifyDealsForActivationReturn{}, err
}
return dealWeights, nil
}
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) {
rwret, err := doExecValue(ctx, vm, builtin.RewardActorAddr, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
if err != nil {
return nil, err
}
+2 -1
View File
@@ -15,6 +15,7 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/types"
@@ -151,7 +152,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
}
smsg, err := fm.api.MpoolPushMessage(ctx, &types.Message{
To: builtin.StorageMarketActorAddr,
To: market.Address,
From: wallet,
Value: toAdd,
Method: builtin.MethodsMarket.AddBalance,
+2 -1
View File
@@ -17,6 +17,7 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/types"
)
@@ -47,7 +48,7 @@ func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, s
func addFundsMsg(toAdd abi.TokenAmount, addr address.Address, wallet address.Address) *types.Message {
params, _ := actors.SerializeParams(&addr)
return &types.Message{
To: builtin.StorageMarketActorAddr,
To: market.Address,
From: wallet,
Value: toAdd,
Method: builtin.MethodsMarket.AddBalance,
-94
View File
@@ -75,8 +75,6 @@ var (
ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium")
ErrTooManyPendingMessages = errors.New("too many pending messages for actor")
ErrNonceGap = errors.New("unfulfilled nonce gap")
ErrTryAgain = errors.New("state inconsistency while pushing message; please try again")
)
const (
@@ -795,98 +793,6 @@ func (mp *MessagePool) getStateBalance(addr address.Address, ts *types.TipSet) (
return act.Balance, nil
}
func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address, cb func(address.Address, uint64) (*types.SignedMessage, error)) (*types.SignedMessage, error) {
// serialize push access to reduce lock contention
mp.addSema <- struct{}{}
defer func() {
<-mp.addSema
}()
mp.curTsLk.Lock()
mp.lk.Lock()
curTs := mp.curTs
fromKey := addr
if fromKey.Protocol() == address.ID {
var err error
fromKey, err = mp.api.StateAccountKey(ctx, fromKey, mp.curTs)
if err != nil {
mp.lk.Unlock()
mp.curTsLk.Unlock()
return nil, xerrors.Errorf("resolving sender key: %w", err)
}
}
nonce, err := mp.getNonceLocked(fromKey, mp.curTs)
if err != nil {
mp.lk.Unlock()
mp.curTsLk.Unlock()
return nil, xerrors.Errorf("get nonce locked failed: %w", err)
}
// release the locks for signing
mp.lk.Unlock()
mp.curTsLk.Unlock()
msg, err := cb(fromKey, nonce)
if err != nil {
return nil, err
}
err = mp.checkMessage(msg)
if err != nil {
return nil, err
}
msgb, err := msg.Serialize()
if err != nil {
return nil, err
}
// reacquire the locks and check state for consistency
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
if mp.curTs != curTs {
return nil, ErrTryAgain
}
mp.lk.Lock()
defer mp.lk.Unlock()
nonce2, err := mp.getNonceLocked(fromKey, mp.curTs)
if err != nil {
return nil, xerrors.Errorf("get nonce locked failed: %w", err)
}
if nonce2 != nonce {
return nil, ErrTryAgain
}
publish, err := mp.verifyMsgBeforeAdd(msg, curTs, true)
if err != nil {
return nil, err
}
if err := mp.checkBalance(msg, curTs); err != nil {
return nil, err
}
if err := mp.addLocked(msg, false); err != nil {
return nil, xerrors.Errorf("add locked failed: %w", err)
}
if err := mp.addLocal(msg, msgb); err != nil {
log.Errorf("addLocal failed: %+v", err)
}
if publish {
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
}
return msg, err
}
func (mp *MessagePool) Remove(from address.Address, nonce uint64, applied bool) {
mp.lk.Lock()
defer mp.lk.Unlock()
+124
View File
@@ -0,0 +1,124 @@
package messagesigner
import (
"bytes"
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/messagepool"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
logging "github.com/ipfs/go-log/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
)
const dsKeyActorNonce = "ActorNonce"
var log = logging.Logger("messagesigner")
type mpoolAPI interface {
GetNonce(address.Address) (uint64, error)
}
// MessageSigner keeps track of nonces per address, and increments the nonce
// when signing a message
type MessageSigner struct {
wallet *wallet.Wallet
mpool mpoolAPI
ds datastore.Batching
}
func NewMessageSigner(wallet *wallet.Wallet, mpool *messagepool.MessagePool, ds dtypes.MetadataDS) *MessageSigner {
return newMessageSigner(wallet, mpool, ds)
}
func newMessageSigner(wallet *wallet.Wallet, mpool mpoolAPI, ds dtypes.MetadataDS) *MessageSigner {
ds = namespace.Wrap(ds, datastore.NewKey("/message-signer/"))
return &MessageSigner{
wallet: wallet,
mpool: mpool,
ds: ds,
}
}
// SignMessage increments the nonce for the message From address, and signs
// the message
func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
nonce, err := ms.nextNonce(msg.From)
if err != nil {
return nil, xerrors.Errorf("failed to create nonce: %w", err)
}
msg.Nonce = nonce
sig, err := ms.wallet.Sign(ctx, msg.From, msg.Cid().Bytes())
if err != nil {
return nil, xerrors.Errorf("failed to sign message: %w", err)
}
return &types.SignedMessage{
Message: *msg,
Signature: *sig,
}, nil
}
// nextNonce increments the nonce.
// If there is no nonce in the datastore, gets the nonce from the message pool.
func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) {
// Nonces used to be created by the mempool and we need to support nodes
// that have mempool nonces, so first check the mempool for a nonce for
// this address. Note that the mempool returns the actor state's nonce
// by default.
nonce, err := ms.mpool.GetNonce(addr)
if err != nil {
return 0, xerrors.Errorf("failed to get nonce from mempool: %w", err)
}
// Get the nonce for this address from the datastore
addrNonceKey := datastore.KeyWithNamespaces([]string{dsKeyActorNonce, addr.String()})
dsNonceBytes, err := ms.ds.Get(addrNonceKey)
switch {
case xerrors.Is(err, datastore.ErrNotFound):
// If a nonce for this address hasn't yet been created in the
// datastore, just use the nonce from the mempool
case err != nil:
return 0, xerrors.Errorf("failed to get nonce from datastore: %w", err)
default:
// There is a nonce in the datastore, so unmarshall and increment it
maj, val, err := cbg.CborReadHeader(bytes.NewReader(dsNonceBytes))
if err != nil {
return 0, xerrors.Errorf("failed to parse nonce from datastore: %w", err)
}
if maj != cbg.MajUnsignedInt {
return 0, xerrors.Errorf("bad cbor type parsing nonce from datastore")
}
dsNonce := val + 1
// The message pool nonce should be <= than the datastore nonce
if nonce <= dsNonce {
nonce = dsNonce
} else {
log.Warnf("mempool nonce was larger than datastore nonce (%d > %d)", nonce, dsNonce)
}
}
// Write the nonce for this address to the datastore
buf := bytes.Buffer{}
_, err = buf.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, nonce))
if err != nil {
return 0, xerrors.Errorf("failed to marshall nonce: %w", err)
}
err = ms.ds.Put(addrNonceKey, buf.Bytes())
if err != nil {
return 0, xerrors.Errorf("failed to write nonce to datastore: %w", err)
}
return nonce, nil
}
+158
View File
@@ -0,0 +1,158 @@
package messagesigner
import (
"context"
"sync"
"testing"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/stretchr/testify/require"
ds_sync "github.com/ipfs/go-datastore/sync"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-datastore"
)
type mockMpool struct {
lk sync.RWMutex
nonces map[address.Address]uint64
}
func newMockMpool() *mockMpool {
return &mockMpool{nonces: make(map[address.Address]uint64)}
}
func (mp *mockMpool) setNonce(addr address.Address, nonce uint64) {
mp.lk.Lock()
defer mp.lk.Unlock()
mp.nonces[addr] = nonce
}
func (mp *mockMpool) GetNonce(addr address.Address) (uint64, error) {
mp.lk.RLock()
defer mp.lk.RUnlock()
return mp.nonces[addr], nil
}
func TestMessageSignerSignMessage(t *testing.T) {
ctx := context.Background()
w, _ := wallet.NewWallet(wallet.NewMemKeyStore())
from1, err := w.GenerateKey(crypto.SigTypeSecp256k1)
require.NoError(t, err)
from2, err := w.GenerateKey(crypto.SigTypeSecp256k1)
require.NoError(t, err)
to1, err := w.GenerateKey(crypto.SigTypeSecp256k1)
require.NoError(t, err)
to2, err := w.GenerateKey(crypto.SigTypeSecp256k1)
require.NoError(t, err)
type msgSpec struct {
msg *types.Message
mpoolNonce [1]uint64
expNonce uint64
}
tests := []struct {
name string
msgs []msgSpec
}{{
// No nonce yet in datastore
name: "no nonce yet",
msgs: []msgSpec{{
msg: &types.Message{
To: to1,
From: from1,
},
expNonce: 0,
}},
}, {
// Get nonce value of zero from mpool
name: "mpool nonce zero",
msgs: []msgSpec{{
msg: &types.Message{
To: to1,
From: from1,
},
mpoolNonce: [1]uint64{0},
expNonce: 0,
}},
}, {
// Get non-zero nonce value from mpool
name: "mpool nonce set",
msgs: []msgSpec{{
msg: &types.Message{
To: to1,
From: from1,
},
mpoolNonce: [1]uint64{5},
expNonce: 5,
}, {
msg: &types.Message{
To: to1,
From: from1,
},
// Should adjust datastore nonce because mpool nonce is higher
mpoolNonce: [1]uint64{10},
expNonce: 10,
}},
}, {
// Nonce should increment independently for each address
name: "nonce increments per address",
msgs: []msgSpec{{
msg: &types.Message{
To: to1,
From: from1,
},
expNonce: 0,
}, {
msg: &types.Message{
To: to1,
From: from1,
},
expNonce: 1,
}, {
msg: &types.Message{
To: to2,
From: from2,
},
mpoolNonce: [1]uint64{5},
expNonce: 5,
}, {
msg: &types.Message{
To: to2,
From: from2,
},
expNonce: 6,
}, {
msg: &types.Message{
To: to1,
From: from1,
},
expNonce: 2,
}},
}}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
mpool := newMockMpool()
ds := ds_sync.MutexWrap(datastore.NewMapDatastore())
ms := newMessageSigner(w, mpool, ds)
for _, m := range tt.msgs {
if len(m.mpoolNonce) == 1 {
mpool.setNonce(m.msg.From, m.mpoolNonce[0])
}
smsg, err := ms.SignMessage(ctx, m.msg)
require.NoError(t, err)
require.Equal(t, m.expNonce, smsg.Message.Nonce)
}
})
}
}
+49
View File
@@ -1,6 +1,7 @@
package state
import (
"bytes"
"context"
"fmt"
@@ -14,6 +15,7 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/builtin"
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/types"
@@ -383,6 +385,7 @@ func (st *StateTree) MutateActor(addr address.Address, f func(*types.Actor) erro
func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error {
var act types.Actor
return st.root.ForEach(&act, func(k string) error {
act := act // copy
addr, err := address.NewFromBytes([]byte(k))
if err != nil {
return xerrors.Errorf("invalid address (%x) found in state tree key: %w", []byte(k), err)
@@ -391,3 +394,49 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
return f(addr, &act)
})
}
// Version returns the version of the StateTree data structure in use.
func (st *StateTree) Version() builtin.Version {
return st.version
}
func Diff(oldTree, newTree *StateTree) (map[string]types.Actor, error) {
out := map[string]types.Actor{}
var (
ncval, ocval cbg.Deferred
buf = bytes.NewReader(nil)
)
if err := newTree.root.ForEach(&ncval, func(k string) error {
var act types.Actor
addr, err := address.NewFromBytes([]byte(k))
if err != nil {
return xerrors.Errorf("address in state tree was not valid: %w", err)
}
found, err := oldTree.root.Get(abi.AddrKey(addr), &ocval)
if err != nil {
return err
}
if found && bytes.Equal(ocval.Raw, ncval.Raw) {
return nil // not changed
}
buf.Reset(ncval.Raw)
err = act.UnmarshalCBOR(buf)
buf.Reset(nil)
if err != nil {
return err
}
out[addr.String()] = act
return nil
}); err != nil {
return nil, err
}
return out, nil
}
+357 -50
View File
@@ -1,42 +1,59 @@
package stmgr
import (
"bytes"
"context"
"encoding/binary"
"math"
multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/specs-actors/actors/migration/nv3"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/builtin"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/util/adt"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
)
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, types.StateTree, *types.TipSet) error{
build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery,
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, ExecCallback, cid.Cid, *types.TipSet) (cid.Cid, error){
build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery,
build.UpgradeIgnitionHeight: UpgradeIgnition,
build.UpgradeLiftoffHeight: UpgradeLiftoff,
}
func (sm *StateManager) handleStateForks(ctx context.Context, st types.StateTree, height abi.ChainEpoch, ts *types.TipSet) (err error) {
func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, height abi.ChainEpoch, cb ExecCallback, ts *types.TipSet) (cid.Cid, error) {
retCid := root
var err error
f, ok := ForksAtHeight[height]
if ok {
err := f(ctx, sm, st, ts)
retCid, err = f(ctx, sm, cb, root, ts)
if err != nil {
return err
return cid.Undef, err
}
}
return nil
return retCid, nil
}
type forEachTree interface {
ForEach(func(address.Address, *types.Actor) error) error
}
func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error {
func doTransfer(cb ExecCallback, tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error {
fromAct, err := tree.GetActor(from)
if err != nil {
return xerrors.Errorf("failed to get 'from' actor for transfer: %w", err)
@@ -62,10 +79,43 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo
return xerrors.Errorf("failed to persist to actor: %w", err)
}
if cb != nil {
// record the transfer in execution traces
fakeMsg := &types.Message{
From: from,
To: to,
Value: amt,
Nonce: math.MaxUint64,
}
fakeRct := &types.MessageReceipt{
ExitCode: 0,
Return: nil,
GasUsed: 0,
}
if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{
MessageReceipt: *fakeRct,
ActorErr: nil,
ExecutionTrace: types.ExecutionTrace{
Msg: fakeMsg,
MsgRct: fakeRct,
Error: "",
Duration: 0,
GasCharges: nil,
Subcalls: nil,
},
Duration: 0,
GasCosts: vm.ZeroGasOutputs(),
}); err != nil {
return xerrors.Errorf("recording transfer: %w", err)
}
}
return nil
}
func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types.StateTree, ts *types.TipSet) error {
func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) {
// Some initial parameters
FundsForMiners := types.FromFil(1_000_000)
LookbackEpoch := abi.ChainEpoch(32000)
@@ -92,22 +142,22 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
// Grab lookback state for account checks
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, LookbackEpoch, ts, false)
if err != nil {
return xerrors.Errorf("failed to get tipset at lookback height: %w", err)
return cid.Undef, xerrors.Errorf("failed to get tipset at lookback height: %w", err)
}
lbtree, err := sm.ParentState(lbts)
if err != nil {
return xerrors.Errorf("loading state tree failed: %w", err)
return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err)
}
ReserveAddress, err := address.NewFromString("t090")
if err != nil {
return xerrors.Errorf("failed to parse reserve address: %w", err)
return cid.Undef, xerrors.Errorf("failed to parse reserve address: %w", err)
}
fetree, ok := tree.(forEachTree)
if !ok {
return xerrors.Errorf("fork transition state tree doesnt support ForEach (%T)", tree)
tree, err := sm.StateTree(root)
if err != nil {
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
}
type transfer struct {
@@ -119,9 +169,9 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
var transfers []transfer
// Take all excess funds away, put them into the reserve account
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
err = tree.ForEach(func(addr address.Address, act *types.Actor) error {
switch act.Code {
case builtin.AccountActorCodeID, builtin.MultisigActorCodeID, builtin.PaymentChannelActorCodeID:
case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID:
sysAcc, err := isSystemAccount(addr)
if err != nil {
return xerrors.Errorf("checking system account: %w", err)
@@ -134,7 +184,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
Amt: act.Balance,
})
}
case builtin.StorageMinerActorCodeID:
case builtin0.StorageMinerActorCodeID:
var st miner0.State
if err := sm.ChainStore().Store(ctx).Get(ctx, act.Head, &st); err != nil {
return xerrors.Errorf("failed to load miner state: %w", err)
@@ -161,33 +211,33 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
return nil
})
if err != nil {
return xerrors.Errorf("foreach over state tree failed: %w", err)
return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err)
}
// Execute transfers from previous step
for _, t := range transfers {
if err := doTransfer(tree, t.From, t.To, t.Amt); err != nil {
return xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
if err := doTransfer(cb, tree, t.From, t.To, t.Amt); err != nil {
return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
}
}
// pull up power table to give miners back some funds proportional to their power
var ps power0.State
powAct, err := tree.GetActor(builtin.StoragePowerActorAddr)
powAct, err := tree.GetActor(builtin0.StoragePowerActorAddr)
if err != nil {
return xerrors.Errorf("failed to load power actor: %w", err)
return cid.Undef, xerrors.Errorf("failed to load power actor: %w", err)
}
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
if err := cst.Get(ctx, powAct.Head, &ps); err != nil {
return xerrors.Errorf("failed to get power actor state: %w", err)
return cid.Undef, xerrors.Errorf("failed to get power actor state: %w", err)
}
totalPower := ps.TotalBytesCommitted
var transfersBack []transfer
// Now, we return some funds to places where they are needed
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
err = tree.ForEach(func(addr address.Address, act *types.Actor) error {
lbact, err := lbtree.GetActor(addr)
if err != nil {
if !xerrors.Is(err, types.ErrActorNotFound) {
@@ -201,7 +251,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
}
switch act.Code {
case builtin.AccountActorCodeID, builtin.MultisigActorCodeID, builtin.PaymentChannelActorCodeID:
case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID:
nbalance := big.Min(prevBalance, AccountCap)
if nbalance.Sign() != 0 {
transfersBack = append(transfersBack, transfer{
@@ -210,7 +260,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
Amt: nbalance,
})
}
case builtin.StorageMinerActorCodeID:
case builtin0.StorageMinerActorCodeID:
var st miner0.State
if err := sm.ChainStore().Store(ctx).Get(ctx, act.Head, &st); err != nil {
return xerrors.Errorf("failed to load miner state: %w", err)
@@ -221,7 +271,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
return xerrors.Errorf("failed to get miner info: %w", err)
}
sectorsArr, err := adt.AsArray(sm.ChainStore().Store(ctx), st.Sectors)
sectorsArr, err := adt0.AsArray(sm.ChainStore().Store(ctx), st.Sectors)
if err != nil {
return xerrors.Errorf("failed to load sectors array: %w", err)
}
@@ -245,7 +295,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
return xerrors.Errorf("failed to load miner state: %w", err)
}
lbsectors, err := adt.AsArray(sm.ChainStore().Store(ctx), lbst.Sectors)
lbsectors, err := adt0.AsArray(sm.ChainStore().Store(ctx), lbst.Sectors)
if err != nil {
return xerrors.Errorf("failed to load lb sectors array: %w", err)
}
@@ -265,53 +315,310 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types
return nil
})
if err != nil {
return xerrors.Errorf("foreach over state tree failed: %w", err)
return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err)
}
for _, t := range transfersBack {
if err := doTransfer(tree, t.From, t.To, t.Amt); err != nil {
return xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
if err := doTransfer(cb, tree, t.From, t.To, t.Amt); err != nil {
return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
}
}
// transfer all burnt funds back to the reserve account
burntAct, err := tree.GetActor(builtin.BurntFundsActorAddr)
burntAct, err := tree.GetActor(builtin0.BurntFundsActorAddr)
if err != nil {
return xerrors.Errorf("failed to load burnt funds actor: %w", err)
return cid.Undef, xerrors.Errorf("failed to load burnt funds actor: %w", err)
}
if err := doTransfer(tree, builtin.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
return xerrors.Errorf("failed to unburn funds: %w", err)
if err := doTransfer(cb, tree, builtin0.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err)
}
// Top up the reimbursement service
reimbAddr, err := address.NewFromString("t0111")
if err != nil {
return xerrors.Errorf("failed to parse reimbursement service address")
return cid.Undef, xerrors.Errorf("failed to parse reimbursement service address")
}
reimb, err := tree.GetActor(reimbAddr)
if err != nil {
return xerrors.Errorf("failed to load reimbursement account actor: %w", err)
return cid.Undef, xerrors.Errorf("failed to load reimbursement account actor: %w", err)
}
difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance)
if err := doTransfer(tree, ReserveAddress, reimbAddr, difference); err != nil {
return xerrors.Errorf("failed to top up reimbursement account: %w", err)
if err := doTransfer(cb, tree, ReserveAddress, reimbAddr, difference); err != nil {
return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err)
}
// Now, a final sanity check to make sure the balances all check out
total := abi.NewTokenAmount(0)
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
err = tree.ForEach(func(addr address.Address, act *types.Actor) error {
total = types.BigAdd(total, act.Balance)
return nil
})
if err != nil {
return xerrors.Errorf("checking final state balance failed: %w", err)
return cid.Undef, xerrors.Errorf("checking final state balance failed: %w", err)
}
exp := types.FromFil(build.FilBase)
if !exp.Equals(total) {
return xerrors.Errorf("resultant state tree account balance was not correct: %s", total)
return cid.Undef, xerrors.Errorf("resultant state tree account balance was not correct: %s", total)
}
return tree.Flush(ctx)
}
func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) {
store := sm.cs.Store(ctx)
nst, err := nv3.MigrateStateTree(ctx, store, root, build.UpgradeIgnitionHeight)
if err != nil {
return cid.Undef, xerrors.Errorf("migrating actors state: %w", err)
}
tree, err := sm.StateTree(nst)
if err != nil {
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
}
err = setNetworkName(ctx, store, tree, "ignition")
if err != nil {
return cid.Undef, xerrors.Errorf("setting network name: %w", err)
}
split1, err := address.NewFromString("t0115")
if err != nil {
return cid.Undef, xerrors.Errorf("first split address: %w", err)
}
split2, err := address.NewFromString("t0116")
if err != nil {
return cid.Undef, xerrors.Errorf("second split address: %w", err)
}
err = resetGenesisMsigs(ctx, sm, store, tree)
if err != nil {
return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err)
}
err = splitGenesisMultisig(ctx, cb, split1, store, tree, 50)
if err != nil {
return cid.Undef, xerrors.Errorf("splitting first msig: %w", err)
}
err = splitGenesisMultisig(ctx, cb, split2, store, tree, 50)
if err != nil {
return cid.Undef, xerrors.Errorf("splitting second msig: %w", err)
}
err = nv3.CheckStateTree(ctx, store, nst, build.UpgradeIgnitionHeight, builtin0.TotalFilecoin)
if err != nil {
return cid.Undef, xerrors.Errorf("sanity check after ignition upgrade failed: %w", err)
}
return tree.Flush(ctx)
}
func UpgradeLiftoff(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) {
tree, err := sm.StateTree(root)
if err != nil {
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
}
err = setNetworkName(ctx, sm.cs.Store(ctx), tree, "mainnet")
if err != nil {
return cid.Undef, xerrors.Errorf("setting network name: %w", err)
}
return tree.Flush(ctx)
}
func setNetworkName(ctx context.Context, store adt0.Store, tree *state.StateTree, name string) error {
ia, err := tree.GetActor(builtin0.InitActorAddr)
if err != nil {
return xerrors.Errorf("getting init actor: %w", err)
}
var initState init0.State
if err := store.Get(ctx, ia.Head, &initState); err != nil {
return xerrors.Errorf("reading init state: %w", err)
}
initState.NetworkName = name
ia.Head, err = store.Put(ctx, &initState)
if err != nil {
return xerrors.Errorf("writing new init state: %w", err)
}
if err := tree.SetActor(builtin0.InitActorAddr, ia); err != nil {
return xerrors.Errorf("setting init actor: %w", err)
}
return nil
}
func splitGenesisMultisig(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64) error {
if portions < 1 {
return xerrors.Errorf("cannot split into 0 portions")
}
mact, err := tree.GetActor(addr)
if err != nil {
return xerrors.Errorf("getting msig actor: %w", err)
}
mst, err := multisig.Load(store, mact)
if err != nil {
return xerrors.Errorf("getting msig state: %w", err)
}
signers, err := mst.Signers()
if err != nil {
return xerrors.Errorf("getting msig signers: %w", err)
}
thresh, err := mst.Threshold()
if err != nil {
return xerrors.Errorf("getting msig threshold: %w", err)
}
ibal, err := mst.InitialBalance()
if err != nil {
return xerrors.Errorf("getting msig initial balance: %w", err)
}
se, err := mst.StartEpoch()
if err != nil {
return xerrors.Errorf("getting msig start epoch: %w", err)
}
ud, err := mst.UnlockDuration()
if err != nil {
return xerrors.Errorf("getting msig unlock duration: %w", err)
}
pending, err := adt0.MakeEmptyMap(store).Root()
if err != nil {
return xerrors.Errorf("failed to create empty map: %w", err)
}
newIbal := big.Div(ibal, types.NewInt(portions))
newState := &multisig0.State{
Signers: signers,
NumApprovalsThreshold: thresh,
NextTxnID: 0,
InitialBalance: newIbal,
StartEpoch: se,
UnlockDuration: ud,
PendingTxns: pending,
}
scid, err := store.Put(ctx, newState)
if err != nil {
return xerrors.Errorf("storing new state: %w", err)
}
newActor := types.Actor{
Code: builtin0.MultisigActorCodeID,
Head: scid,
Nonce: 0,
Balance: big.Zero(),
}
i := uint64(0)
for i < portions {
keyAddr, err := makeKeyAddr(addr, i)
if err != nil {
return xerrors.Errorf("creating key address: %w", err)
}
idAddr, err := tree.RegisterNewAddress(keyAddr)
if err != nil {
return xerrors.Errorf("registering new address: %w", err)
}
err = tree.SetActor(idAddr, &newActor)
if err != nil {
return xerrors.Errorf("setting new msig actor state: %w", err)
}
if err := doTransfer(cb, tree, addr, idAddr, newIbal); err != nil {
return xerrors.Errorf("transferring split msig balance: %w", err)
}
i++
}
return nil
}
func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, error) {
var b bytes.Buffer
if err := splitAddr.MarshalCBOR(&b); err != nil {
return address.Undef, xerrors.Errorf("marshalling split address: %w", err)
}
if err := binary.Write(&b, binary.BigEndian, count); err != nil {
return address.Undef, xerrors.Errorf("writing count into a buffer: %w", err)
}
if err := binary.Write(&b, binary.BigEndian, []byte("Ignition upgrade")); err != nil {
return address.Undef, xerrors.Errorf("writing fork name into a buffer: %w", err)
}
addr, err := address.NewActorAddress(b.Bytes())
if err != nil {
return address.Undef, xerrors.Errorf("create actor address: %w", err)
}
return addr, nil
}
func resetGenesisMsigs(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree) error {
gb, err := sm.cs.GetGenesis()
if err != nil {
return xerrors.Errorf("getting genesis block: %w", err)
}
gts, err := types.NewTipSet([]*types.BlockHeader{gb})
if err != nil {
return xerrors.Errorf("getting genesis tipset: %w", err)
}
cst := cbor.NewCborStore(sm.cs.Blockstore())
genesisTree, err := state.LoadStateTree(cst, gts.ParentState())
if err != nil {
return xerrors.Errorf("loading state tree: %w", err)
}
err = genesisTree.ForEach(func(addr address.Address, genesisActor *types.Actor) error {
if genesisActor.Code == builtin0.MultisigActorCodeID {
currActor, err := tree.GetActor(addr)
if err != nil {
return xerrors.Errorf("loading actor: %w", err)
}
var currState multisig0.State
if err := store.Get(ctx, currActor.Head, &currState); err != nil {
return xerrors.Errorf("reading multisig state: %w", err)
}
currState.StartEpoch = build.UpgradeLiftoffHeight
currActor.Head, err = store.Put(ctx, &currState)
if err != nil {
return xerrors.Errorf("writing new multisig state: %w", err)
}
if err := tree.SetActor(addr, currActor); err != nil {
return xerrors.Errorf("setting multisig actor: %w", err)
}
}
return nil
})
if err != nil {
return xerrors.Errorf("iterating over genesis actors: %w", err)
}
return nil
+18 -16
View File
@@ -8,17 +8,15 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/runtime"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/stmgr"
. "github.com/filecoin-project/lotus/chain/stmgr"
@@ -27,17 +25,16 @@ import (
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log"
cbg "github.com/whyrusleeping/cbor-gen"
)
func init() {
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
power0.ConsensusMinerMinPower = big.NewInt(2048)
verifreg0.MinVerifiedDealSize = big.NewInt(256)
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
}
const testForkHeight = 40
@@ -118,33 +115,38 @@ func TestForkHeightTriggers(t *testing.T) {
t.Fatal(err)
}
stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, st types.StateTree, ts *types.TipSet) error {
stmgr.ForksAtHeight[testForkHeight] = func(ctx context.Context, sm *StateManager, cb ExecCallback, root cid.Cid, ts *types.TipSet) (cid.Cid, error) {
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
st, err := sm.StateTree(root)
if err != nil {
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
}
act, err := st.GetActor(taddr)
if err != nil {
return err
return cid.Undef, err
}
var tas testActorState
if err := cst.Get(ctx, act.Head, &tas); err != nil {
return xerrors.Errorf("in fork handler, failed to run get: %w", err)
return cid.Undef, xerrors.Errorf("in fork handler, failed to run get: %w", err)
}
tas.HasUpgraded = 55
ns, err := cst.Put(ctx, &tas)
if err != nil {
return err
return cid.Undef, err
}
act.Head = ns
if err := st.SetActor(taddr, act); err != nil {
return err
return cid.Undef, err
}
return nil
return st.Flush(ctx)
}
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
@@ -168,7 +170,7 @@ func TestForkHeightTriggers(t *testing.T) {
m := &types.Message{
From: cg.Banker(),
To: builtin.InitActorAddr,
To: lotusinit.Address,
Method: builtin.MethodsInit.Exec,
Params: enc,
GasLimit: types.TestGasLimit,
+236 -116
View File
@@ -5,12 +5,9 @@ import (
"fmt"
"sync"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
@@ -22,16 +19,17 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/specs-actors/actors/builtin"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
@@ -43,12 +41,13 @@ var log = logging.Logger("statemgr")
type StateManager struct {
cs *store.ChainStore
stCache map[string][]cid.Cid
compWait map[string]chan struct{}
stlk sync.Mutex
genesisMsigLk sync.Mutex
newVM func(context.Context, *vm.VMOpts) (*vm.VM, error)
genInfo *genesisInfo
stCache map[string][]cid.Cid
compWait map[string]chan struct{}
stlk sync.Mutex
genesisMsigLk sync.Mutex
newVM func(context.Context, *vm.VMOpts) (*vm.VM, error)
preIgnitionGenInfos *genesisInfo
postIgnitionGenInfos *genesisInfo
}
func NewStateManager(cs *store.ChainStore) *StateManager {
@@ -125,9 +124,8 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c
return st, rec, nil
}
func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (cid.Cid, []*api.InvocResult, error) {
var trace []*api.InvocResult
st, _, err := sm.computeTipSetState(ctx, ts, func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
func traceFunc(trace *[]*api.InvocResult) func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
return func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
ir := &api.InvocResult{
Msg: msg,
MsgRct: &ret.MessageReceipt,
@@ -137,9 +135,14 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
if ret.ActorErr != nil {
ir.Error = ret.ActorErr.Error()
}
trace = append(trace, ir)
*trace = append(*trace, ir)
return nil
})
}
}
func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (cid.Cid, []*api.InvocResult, error) {
var trace []*api.InvocResult
st, _, err := sm.computeTipSetState(ctx, ts, traceFunc(&trace))
if err != nil {
return cid.Undef, nil, err
}
@@ -151,38 +154,42 @@ type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []store.BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount, ts *types.TipSet) (cid.Cid, cid.Cid, error) {
vmopt := &vm.VMOpts{
StateBase: pstate,
Epoch: epoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: baseFee,
makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) {
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: epoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: baseFee,
}
return sm.newVM(ctx, vmopt)
}
vmi, err := sm.newVM(ctx, vmopt)
vmi, err := makeVmWithBaseState(pstate)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
}
runCron := func() error {
// TODO: this nonce-getting is a tiny bit ugly
ca, err := vmi.StateTree().GetActor(builtin.SystemActorAddr)
ca, err := vmi.StateTree().GetActor(builtin0.SystemActorAddr)
if err != nil {
return err
}
cronMsg := &types.Message{
To: builtin.CronActorAddr,
From: builtin.SystemActorAddr,
To: builtin0.CronActorAddr,
From: builtin0.SystemActorAddr,
Nonce: ca.Nonce,
Value: types.NewInt(0),
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little
Method: builtin.MethodsCron.EpochTick,
Method: builtin0.MethodsCron.EpochTick,
Params: nil,
}
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
@@ -204,19 +211,32 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
for i := parentEpoch; i < epoch; i++ {
// handle state forks
// XXX: The state tree
err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts)
newState, err := sm.handleStateForks(ctx, pstate, i, cb, ts)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
}
if pstate != newState {
vmi, err = makeVmWithBaseState(newState)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
}
}
if i > parentEpoch {
// run cron for null rounds if any
if err := runCron(); err != nil {
return cid.Cid{}, cid.Cid{}, err
}
newState, err = vmi.Flush(ctx)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("flushing vm: %w", err)
}
}
vmi.SetBlockHeight(i + 1)
pstate = newState
}
var receipts []cbg.CBORMarshaler
@@ -247,42 +267,34 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
processedMsgs[m.Cid()] = true
}
var params []byte
nv := sm.GetNtwkVersion(ctx, epoch)
if nv < build.ActorUpgradeNetworkVersion {
params, err = actors.SerializeParams(&reward0.AwardBlockRewardParams{
Miner: b.Miner,
Penalty: penalty,
GasReward: gasReward,
WinCount: b.WinCount,
})
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err)
}
} else {
// TODO: ActorUpgrade
params = nil
params, err := actors.SerializeParams(&reward.AwardBlockRewardParams{
Miner: b.Miner,
Penalty: penalty,
GasReward: gasReward,
WinCount: b.WinCount,
})
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err)
}
sysAct, err := vmi.StateTree().GetActor(builtin.SystemActorAddr)
if err != nil {
sysAct, actErr := vmi.StateTree().GetActor(builtin0.SystemActorAddr)
if actErr != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
}
rwMsg := &types.Message{
From: builtin.SystemActorAddr,
To: builtin.RewardActorAddr,
From: builtin0.SystemActorAddr,
To: reward.Address,
Nonce: sysAct.Nonce,
Value: types.NewInt(0),
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
GasLimit: 1 << 30,
Method: builtin.MethodsReward.AwardBlockReward,
Method: builtin0.MethodsReward.AwardBlockReward,
Params: params,
}
ret, err := vmi.ApplyImplicitMessage(ctx, rwMsg)
if err != nil {
ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg)
if actErr != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to apply reward message for miner %s: %w", b.Miner, err)
}
if cb != nil {
@@ -300,7 +312,11 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
return cid.Cid{}, cid.Cid{}, err
}
rectarr := adt.MakeEmptyArray(sm.cs.Store(ctx))
// XXX: Is the height correct? Or should it be epoch-1?
rectarr, err := adt.NewArray(sm.cs.Store(ctx), builtin.VersionForNetwork(sm.GetNtwkVersion(ctx, epoch)))
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to create receipts amt: %w", err)
}
for i, receipt := range receipts {
if err := rectarr.Set(uint64(i), receipt); err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err)
@@ -698,17 +714,13 @@ func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]
return nil, err
}
r, err := adt.AsMap(sm.cs.Store(ctx), st)
stateTree, err := sm.StateTree(st)
if err != nil {
return nil, err
}
var out []address.Address
err = r.ForEach(nil, func(k string) error {
addr, err := address.NewFromBytes([]byte(k))
if err != nil {
return xerrors.Errorf("address in state tree was not valid: %w", err)
}
err = stateTree.ForEach(func(addr address.Address, act *types.Actor) error {
out = append(out, addr)
return nil
})
@@ -725,7 +737,7 @@ func (sm *StateManager) MarketBalance(ctx context.Context, addr address.Address,
return api.MarketBalance{}, err
}
act, err := st.GetActor(builtin.StorageMarketActorAddr)
act, err := st.GetActor(market.Address)
if err != nil {
return api.MarketBalance{}, err
}
@@ -845,51 +857,56 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
return xerrors.Errorf("setting up genesis pledge: %w", err)
}
r, err := adt.AsMap(sm.cs.Store(ctx), st)
if err != nil {
return xerrors.Errorf("getting genesis actors: %w", err)
}
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
var act types.Actor
err = r.ForEach(&act, func(k string) error {
if act.Code == builtin.MultisigActorCodeID {
var s multisig.State
err := sm.cs.Store(ctx).Get(ctx, act.Head, &s)
err = sTree.ForEach(func(kaddr address.Address, act *types.Actor) error {
if act.IsMultisigActor() {
s, err := multisig.Load(sm.cs.Store(ctx), act)
if err != nil {
return err
}
if s.StartEpoch() != 0 {
se, err := s.StartEpoch()
if err != nil {
return err
}
if se != 0 {
return xerrors.New("genesis multisig doesn't start vesting at epoch 0!")
}
ot, f := totalsByEpoch[s.UnlockDuration()]
if f {
totalsByEpoch[s.UnlockDuration()] = big.Add(ot, s.InitialBalance())
} else {
totalsByEpoch[s.UnlockDuration()] = s.InitialBalance()
ud, err := s.UnlockDuration()
if err != nil {
return err
}
} else if act.Code == builtin.AccountActorCodeID {
ib, err := s.InitialBalance()
if err != nil {
return err
}
ot, f := totalsByEpoch[ud]
if f {
totalsByEpoch[ud] = big.Add(ot, ib)
} else {
totalsByEpoch[ud] = ib
}
} else if act.IsAccountActor() {
// should exclude burnt funds actor and "remainder account actor"
// should only ever be "faucet" accounts in testnets
kaddr, err := address.NewFromBytes([]byte(k))
if kaddr == builtin0.BurntFundsActorAddr {
return nil
}
kid, err := sTree.LookupID(kaddr)
if err != nil {
return xerrors.Errorf("decoding address: %w", err)
return xerrors.Errorf("resolving address: %w", err)
}
if kaddr != builtin.BurntFundsActorAddr {
kid, err := sTree.LookupID(kaddr)
if err != nil {
return xerrors.Errorf("resolving address: %w", err)
}
gi.genesisActors = append(gi.genesisActors, genesisActor{
addr: kid,
initBal: act.Balance,
})
}
gi.genesisActors = append(gi.genesisActors, genesisActor{
addr: kid,
initBal: act.Balance,
})
}
return nil
})
@@ -898,6 +915,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
return xerrors.Errorf("error setting up genesis infos: %w", err)
}
// TODO: use network upgrade abstractions or always start at actors v0?
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
for k, v := range totalsByEpoch {
ns := msig0.State{
@@ -908,7 +926,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
gi.genesisMsigs = append(gi.genesisMsigs, ns)
}
sm.genInfo = &gi
sm.preIgnitionGenInfos = &gi
return nil
}
@@ -916,7 +934,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
// sets up information about the actors in the genesis state
// For testnet we use a hardcoded set of multisig states, instead of what's actually in the genesis multisigs
// We also do not consider ANY account actors (including the faucet)
func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error {
func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context) error {
gi := genesisInfo{}
@@ -954,24 +972,24 @@ func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error {
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
// 6 months
sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay)
totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
// 1 year
oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay)
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years
sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay)
sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay)
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
@@ -985,7 +1003,87 @@ func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error {
gi.genesisMsigs = append(gi.genesisMsigs, ns)
}
sm.genInfo = &gi
sm.preIgnitionGenInfos = &gi
return nil
}
// sets up information about the actors in the genesis state, post the ignition fork
func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) error {
gi := genesisInfo{}
gb, err := sm.cs.GetGenesis()
if err != nil {
return xerrors.Errorf("getting genesis block: %w", err)
}
gts, err := types.NewTipSet([]*types.BlockHeader{gb})
if err != nil {
return xerrors.Errorf("getting genesis tipset: %w", err)
}
st, _, err := sm.TipSetState(ctx, gts)
if err != nil {
return xerrors.Errorf("getting genesis tipset state: %w", err)
}
cst := cbor.NewCborStore(sm.cs.Blockstore())
sTree, err := state.LoadStateTree(cst, st)
if err != nil {
return xerrors.Errorf("loading state tree: %w", err)
}
// Unnecessary, should be removed
gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree)
if err != nil {
return xerrors.Errorf("setting up genesis market funds: %w", err)
}
// Unnecessary, should be removed
gi.genesisPledge, err = getFilPowerLocked(ctx, sTree)
if err != nil {
return xerrors.Errorf("setting up genesis pledge: %w", err)
}
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
// 6 months
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay)
totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
// 1 year
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay)
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years
sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay)
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
gi.genesisMsigs = make([]msig0.State, 0, len(totalsByEpoch))
for k, v := range totalsByEpoch {
ns := msig0.State{
// In the pre-ignition logic, we incorrectly set this value in Fil, not attoFil, an off-by-10^18 error
InitialBalance: big.Mul(v, big.NewInt(int64(build.FilecoinPrecision))),
UnlockDuration: k,
PendingTxns: cid.Undef,
// In the pre-ignition logic, the start epoch was 0. This changes in the fork logic of the Ignition upgrade itself.
StartEpoch: build.UpgradeLiftoffHeight,
}
gi.genesisMsigs = append(gi.genesisMsigs, ns)
}
sm.postIgnitionGenInfos = &gi
return nil
}
@@ -995,13 +1093,23 @@ func (sm *StateManager) setupGenesisActorsTestnet(ctx context.Context) error {
// - For Accounts, it counts max(currentBalance - genesisBalance, 0).
func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
vf := big.Zero()
for _, v := range sm.genInfo.genesisMsigs {
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
vf = big.Add(vf, au)
if height <= build.UpgradeIgnitionHeight {
for _, v := range sm.preIgnitionGenInfos.genesisMsigs {
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
vf = big.Add(vf, au)
}
} else {
for _, v := range sm.postIgnitionGenInfos.genesisMsigs {
// In the pre-ignition logic, we simply called AmountLocked(height), assuming startEpoch was 0.
// The start epoch changed in the Ignition upgrade.
au := big.Sub(v.InitialBalance, v.AmountLocked(height-v.StartEpoch))
vf = big.Add(vf, au)
}
}
// there should not be any such accounts in testnet (and also none in mainnet?)
for _, v := range sm.genInfo.genesisActors {
// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
for _, v := range sm.preIgnitionGenInfos.genesisActors {
act, err := st.GetActor(v.addr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to get actor: %w", err)
@@ -1013,14 +1121,16 @@ func (sm *StateManager) GetFilVested(ctx context.Context, height abi.ChainEpoch,
}
}
vf = big.Add(vf, sm.genInfo.genesisPledge)
vf = big.Add(vf, sm.genInfo.genesisMarketFunds)
// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
vf = big.Add(vf, sm.preIgnitionGenInfos.genesisPledge)
// continue to use preIgnitionGenInfos, nothing changed at the Ignition epoch
vf = big.Add(vf, sm.preIgnitionGenInfos.genesisMarketFunds)
return vf, nil
}
func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
ractor, err := st.GetActor(builtin.RewardActorAddr)
ractor, err := st.GetActor(reward.Address)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load reward actor state: %w", err)
}
@@ -1034,7 +1144,7 @@ func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, err
}
func getFilMarketLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
act, err := st.GetActor(builtin.StorageMarketActorAddr)
act, err := st.GetActor(market.Address)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load market actor: %w", err)
}
@@ -1048,7 +1158,7 @@ func getFilMarketLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmou
}
func getFilPowerLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
pactor, err := st.GetActor(builtin.StoragePowerActorAddr)
pactor, err := st.GetActor(power.Address)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load power actor: %w", err)
}
@@ -1077,7 +1187,7 @@ func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (
}
func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
burnt, err := st.GetActor(builtin.BurntFundsActorAddr)
burnt, err := st.GetActor(builtin0.BurntFundsActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err)
}
@@ -1088,10 +1198,16 @@ func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, err
func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
sm.genesisMsigLk.Lock()
defer sm.genesisMsigLk.Unlock()
if sm.genInfo == nil {
err := sm.setupGenesisActorsTestnet(ctx)
if sm.preIgnitionGenInfos == nil {
err := sm.setupPreIgnitionGenesisActorsTestnet(ctx)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup genesis information: %w", err)
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup pre-ignition genesis information: %w", err)
}
}
if sm.postIgnitionGenInfos == nil {
err := sm.setupPostIgnitionGenesisActors(ctx)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup post-ignition genesis information: %w", err)
}
}
@@ -1156,6 +1272,10 @@ func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoc
return network.Version1
}
if height <= build.UpgradeIgnitionHeight {
return network.Version2
}
return build.NewestNetworkVersion
}
+83 -102
View File
@@ -9,15 +9,6 @@ import (
"runtime"
"strings"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
saruntime "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
@@ -26,26 +17,32 @@ import (
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/account"
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
account0 "github.com/filecoin-project/specs-actors/actors/builtin/account"
cron0 "github.com/filecoin-project/specs-actors/actors/builtin/cron"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
@@ -89,7 +86,7 @@ func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr add
}
func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr address.Address) (power.Claim, power.Claim, bool, error) {
act, err := sm.LoadActorRaw(ctx, builtin.StoragePowerActorAddr, st)
act, err := sm.LoadActorRaw(ctx, power.Address, st)
if err != nil {
return power.Claim{}, power.Claim{}, false, xerrors.Errorf("(get sset) failed to load power actor state: %w", err)
}
@@ -105,6 +102,7 @@ func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr addres
}
var mpow power.Claim
var minpow bool
if maddr != address.Undef {
var found bool
mpow, found, err = pas.MinerPower(maddr)
@@ -112,11 +110,11 @@ func GetPowerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr addres
// TODO: return an error when not found?
return power.Claim{}, power.Claim{}, false, err
}
}
minpow, err := pas.MinerNominalPowerMeetsConsensusMinimum(maddr)
if err != nil {
return power.Claim{}, power.Claim{}, false, err
minpow, err = pas.MinerNominalPowerMeetsConsensusMinimum(maddr)
if err != nil {
return power.Claim{}, power.Claim{}, false, err
}
}
return mpow, tpow, minpow, nil
@@ -150,7 +148,7 @@ func MinerSectorInfo(ctx context.Context, sm *StateManager, maddr address.Addres
return mas.GetSector(sid)
}
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *bitfield.BitField, filterOut bool) ([]*miner.ChainSectorInfo, error) {
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, snos *bitfield.BitField) ([]*miner.SectorOnChainInfo, error) {
act, err := sm.LoadActor(ctx, maddr, ts)
if err != nil {
return nil, xerrors.Errorf("(get sset) failed to load miner actor: %w", err)
@@ -161,32 +159,10 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
return nil, xerrors.Errorf("(get sset) failed to load miner actor state: %w", err)
}
sectors, err := mas.LoadSectorsFromSet(filter, filterOut)
if err != nil {
return nil, xerrors.Errorf("(get sset) failed to load sectors: %w", err)
}
var sset []*miner.ChainSectorInfo
var v cbg.Deferred
if err := sectors.ForEach(&v, func(i int64) error {
var oci miner0.SectorOnChainInfo
if err := oci.UnmarshalCBOR(bytes.NewReader(v.Raw)); err != nil {
return err
}
sset = append(sset, &miner.ChainSectorInfo{
Info: oci,
ID: abi.SectorNumber(i),
})
return nil
}); err != nil {
return nil, err
}
return sset, nil
return mas.LoadSectors(snos)
}
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof.SectorInfo, error) {
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof0.SectorInfo, error) {
act, err := sm.LoadActorRaw(ctx, maddr, st)
if err != nil {
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
@@ -197,12 +173,21 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return nil, xerrors.Errorf("failed to load miner actor state: %w", err)
}
// TODO (!!): This was partition.Sectors-partition.Faults originally, which was likely very wrong, and will need to be an upgrade
// ^ THE CURRENT THING HERE WON'T SYNC v
// TODO (!!): Actor Update: Make this active sectors
provingSectors, err := miner.AllPartSectors(mas, miner.Partition.ActiveSectors)
allSectors, err := miner.AllPartSectors(mas, miner.Partition.AllSectors)
if err != nil {
return nil, xerrors.Errorf("merge partition proving sets: %w", err)
return nil, xerrors.Errorf("get all sectors: %w", err)
}
faultySectors, err := miner.AllPartSectors(mas, miner.Partition.FaultySectors)
if err != nil {
return nil, xerrors.Errorf("get faulty sectors: %w", err)
}
provingSectors, err := bitfield.SubtractBitField(allSectors, faultySectors) // TODO: This is wrong, as it can contain faaults, change to just ActiveSectors in an upgrade
if err != nil {
return nil, xerrors.Errorf("calc proving sectors: %w", err)
}
numProvSect, err := provingSectors.Count()
@@ -240,35 +225,31 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return nil, xerrors.Errorf("generating winning post challenges: %w", err)
}
sectors, err := mas.LoadSectorsFromSet(&provingSectors, false)
iter, err := provingSectors.BitIterator()
if err != nil {
return nil, xerrors.Errorf("iterating over proving sectors: %w", err)
}
// Select winning sectors by _index_ in the all-sectors bitfield.
selectedSectors := bitfield.New()
prev := uint64(0)
for _, n := range ids {
sno, err := iter.Nth(n - prev)
if err != nil {
return nil, xerrors.Errorf("iterating over proving sectors: %w", err)
}
selectedSectors.Set(sno)
prev = n
}
sectors, err := mas.LoadSectors(&selectedSectors)
if err != nil {
return nil, xerrors.Errorf("loading proving sectors: %w", err)
}
out := make([]proof.SectorInfo, len(ids))
for i, n := range ids {
sb, err := provingSectors.Slice(n, 1)
if err != nil {
return nil, err
}
sid, err := sb.First()
if err != nil {
return nil, err
}
var sinfo miner.SectorOnChainInfo
found, err := sectors.Get(sid, &sinfo)
if err != nil {
return nil, xerrors.Errorf("loading sector info: %w", err)
}
if !found {
return nil, xerrors.Errorf("didn't find sector info for sector %d", n)
}
out[i] = proof.SectorInfo{
out := make([]proof0.SectorInfo, len(sectors))
for i, sinfo := range sectors {
out[i] = proof0.SectorInfo{
SealProof: spt,
SectorNumber: sinfo.SectorNumber,
SealedCID: sinfo.SealedCID,
@@ -298,7 +279,7 @@ func StateMinerInfo(ctx context.Context, sm *StateManager, ts *types.TipSet, mad
}
func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (bool, error) {
act, err := sm.LoadActor(ctx, builtin.StoragePowerActorAddr, ts)
act, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil {
return false, xerrors.Errorf("failed to load power actor: %w", err)
}
@@ -321,7 +302,7 @@ func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, ma
}
func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts *types.TipSet) (*api.MarketDeal, error) {
act, err := sm.LoadActor(ctx, builtin.StorageMarketActorAddr, ts)
act, err := sm.LoadActor(ctx, market.Address, ts)
if err != nil {
return nil, xerrors.Errorf("failed to load market actor: %w", err)
}
@@ -365,7 +346,7 @@ func GetStorageDeal(ctx context.Context, sm *StateManager, dealID abi.DealID, ts
}
func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([]address.Address, error) {
act, err := sm.LoadActor(ctx, builtin.StoragePowerActorAddr, ts)
act, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil {
return nil, xerrors.Errorf("failed to load power actor: %w", err)
}
@@ -388,6 +369,16 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
return cid.Undef, nil, err
}
for i := ts.Height(); i < height; i++ {
// handle state forks
base, err = sm.handleStateForks(ctx, base, i, traceFunc(&trace), ts)
if err != nil {
return cid.Undef, nil, xerrors.Errorf("error handling state forks: %w", err)
}
// TODO: should we also run cron here?
}
r := store.NewChainRand(sm.cs, ts.Cids())
vmopt := &vm.VMOpts{
StateBase: base,
@@ -404,16 +395,6 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
return cid.Undef, nil, err
}
for i := ts.Height(); i < height; i++ {
// handle state forks
err = sm.handleStateForks(ctx, vmi.StateTree(), i, ts)
if err != nil {
return cid.Undef, nil, xerrors.Errorf("error handling state forks: %w", err)
}
// TODO: should we also run cron here?
}
for i, msg := range msgs {
// TODO: Use the signed message length for secp messages
ret, err := vmi.ApplyMessage(ctx, msg)
@@ -555,24 +536,24 @@ var MethodsMap = map[cid.Cid]map[abi.MethodNum]MethodMeta{}
func init() {
cidToMethods := map[cid.Cid][2]interface{}{
// builtin.SystemActorCodeID: {builtin.MethodsSystem, system.Actor{} }- apparently it doesn't have methods
builtin.InitActorCodeID: {builtin.MethodsInit, init0.Actor{}},
builtin.CronActorCodeID: {builtin.MethodsCron, cron.Actor{}},
builtin.AccountActorCodeID: {builtin.MethodsAccount, account.Actor{}},
builtin.StoragePowerActorCodeID: {builtin.MethodsPower, power0.Actor{}},
builtin.StorageMinerActorCodeID: {builtin.MethodsMiner, miner0.Actor{}},
builtin.StorageMarketActorCodeID: {builtin.MethodsMarket, market0.Actor{}},
builtin.PaymentChannelActorCodeID: {builtin.MethodsPaych, paych.Actor{}},
builtin.MultisigActorCodeID: {builtin.MethodsMultisig, msig0.Actor{}},
builtin.RewardActorCodeID: {builtin.MethodsReward, reward0.Actor{}},
builtin.VerifiedRegistryActorCodeID: {builtin.MethodsVerifiedRegistry, verifreg0.Actor{}},
builtin0.InitActorCodeID: {builtin0.MethodsInit, init0.Actor{}},
builtin0.CronActorCodeID: {builtin0.MethodsCron, cron0.Actor{}},
builtin0.AccountActorCodeID: {builtin0.MethodsAccount, account0.Actor{}},
builtin0.StoragePowerActorCodeID: {builtin0.MethodsPower, power0.Actor{}},
builtin0.StorageMinerActorCodeID: {builtin0.MethodsMiner, miner0.Actor{}},
builtin0.StorageMarketActorCodeID: {builtin0.MethodsMarket, market0.Actor{}},
builtin0.PaymentChannelActorCodeID: {builtin0.MethodsPaych, paych0.Actor{}},
builtin0.MultisigActorCodeID: {builtin0.MethodsMultisig, msig0.Actor{}},
builtin0.RewardActorCodeID: {builtin0.MethodsReward, reward0.Actor{}},
builtin0.VerifiedRegistryActorCodeID: {builtin0.MethodsVerifiedRegistry, verifreg0.Actor{}},
}
for c, m := range cidToMethods {
exports := m[1].(saruntime.Invokee).Exports()
exports := m[1].(vm.Invokee).Exports()
methods := make(map[abi.MethodNum]MethodMeta, len(exports))
// Explicitly add send, it's special.
methods[builtin.MethodSend] = MethodMeta{
methods[builtin0.MethodSend] = MethodMeta{
Name: "Send",
Params: reflect.TypeOf(new(abi.EmptyValue)),
Ret: reflect.TypeOf(new(abi.EmptyValue)),
@@ -612,9 +593,9 @@ func init() {
}
switch abi.MethodNum(number) {
case builtin.MethodSend:
case builtin0.MethodSend:
panic("method 0 is reserved for Send")
case builtin.MethodConstructor:
case builtin0.MethodConstructor:
if fnName != "Constructor" {
panic("method 1 is reserved for Constructor")
}
@@ -644,7 +625,7 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
}
func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) {
pact, err := sm.LoadActor(ctx, builtin.StoragePowerActorAddr, ts)
pact, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil {
return false, xerrors.Errorf("loading power actor state: %w", err)
}
+46 -8
View File
@@ -10,14 +10,18 @@ import (
"strconv"
"sync"
"golang.org/x/sync/errgroup"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/minio/blake2b-simd"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/journal"
bstore "github.com/filecoin-project/lotus/lib/blockstore"
@@ -282,6 +286,16 @@ func (cs *ChainStore) MarkBlockAsValidated(ctx context.Context, blkid cid.Cid) e
return nil
}
func (cs *ChainStore) UnmarkBlockAsValidated(ctx context.Context, blkid cid.Cid) error {
key := blockValidationCacheKeyPrefix.Instance(blkid.String())
if err := cs.ds.Delete(key); err != nil {
return xerrors.Errorf("removing from valid block cache: %w", err)
}
return nil
}
func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
ts, err := types.NewTipSet([]*types.BlockHeader{b})
if err != nil {
@@ -465,14 +479,25 @@ func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
return v.(*types.TipSet), nil
}
var blks []*types.BlockHeader
for _, c := range tsk.Cids() {
b, err := cs.GetBlock(c)
if err != nil {
return nil, xerrors.Errorf("get block %s: %w", c, err)
}
// Fetch tipset block headers from blockstore in parallel
var eg errgroup.Group
cids := tsk.Cids()
blks := make([]*types.BlockHeader, len(cids))
for i, c := range cids {
i, c := i, c
eg.Go(func() error {
b, err := cs.GetBlock(c)
if err != nil {
return xerrors.Errorf("get block %s: %w", c, err)
}
blks = append(blks, b)
blks[i] = b
return nil
})
}
err := eg.Wait()
if err != nil {
return nil, err
}
ts, err := types.NewTipSet(blks)
@@ -1183,6 +1208,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
}
blocksToWalk := ts.Cids()
currentMinHeight := ts.Height()
walkChain := func(blk cid.Cid) error {
if !seen.Visit(blk) {
@@ -1203,6 +1229,13 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
return xerrors.Errorf("unmarshaling block header (cid=%s): %w", blk, err)
}
if currentMinHeight > b.Height {
currentMinHeight = b.Height
if currentMinHeight%builtin.EpochsInDay == 0 {
log.Infow("export", "height", currentMinHeight)
}
}
var cids []cid.Cid
if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots {
mcids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages})
@@ -1251,6 +1284,9 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
return nil
}
log.Infow("export started")
exportStart := build.Clock.Now()
for len(blocksToWalk) > 0 {
next := blocksToWalk[0]
blocksToWalk = blocksToWalk[1:]
@@ -1259,6 +1295,8 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
}
}
log.Infow("export finished", "duration", build.Clock.Now().Sub(exportStart).Seconds())
return nil
}
@@ -1301,7 +1339,7 @@ func (cs *ChainStore) GetLatestBeaconEntry(ts *types.TipSet) (*types.BeaconEntry
}, nil
}
return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset")
return nil, xerrors.Errorf("found NO beacon entries in the 20 latest tipsets")
}
type chainRand struct {
+4 -9
View File
@@ -8,12 +8,9 @@ import (
datastore "github.com/ipfs/go-datastore"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
@@ -22,11 +19,9 @@ import (
)
func init() {
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
power0.ConsensusMinerMinPower = big.NewInt(2048)
verifreg0.MinVerifiedDealSize = big.NewInt(256)
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
}
func BenchmarkGetRandomness(b *testing.B) {
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/builtin"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
)
@@ -35,7 +34,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
return types.NewInt(0), xerrors.Errorf("load state tree: %w", err)
}
act, err := state.GetActor(builtin.StoragePowerActorAddr)
act, err := state.GetActor(power.Address)
if err != nil {
return types.NewInt(0), xerrors.Errorf("get power actor: %w", err)
}
+141 -99
View File
@@ -7,7 +7,6 @@ import (
"fmt"
"os"
"sort"
"strconv"
"strings"
"sync"
"time"
@@ -18,6 +17,7 @@ import (
"github.com/Gurpartap/async"
"github.com/hashicorp/go-multierror"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
@@ -33,7 +33,6 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/util/adt"
blst "github.com/supranational/blst/bindings/go"
@@ -63,20 +62,12 @@ var (
// where the Syncer publishes candidate chain heads to be synced.
LocalIncoming = "incoming"
log = logging.Logger("chain")
defaultMessageFetchWindowSize = 200
)
log = logging.Logger("chain")
func init() {
if s := os.Getenv("LOTUS_BSYNC_MSG_WINDOW"); s != "" {
val, err := strconv.Atoi(s)
if err != nil {
log.Errorf("failed to parse LOTUS_BSYNC_MSG_WINDOW: %s", err)
return
}
defaultMessageFetchWindowSize = val
}
}
concurrentSyncRequests = exchange.ShufflePeersPrefix
syncRequestBatchSize = 8
syncRequestRetries = 5
)
// Syncer is in charge of running the chain synchronization logic. As such, it
// is tasked with these functions, amongst others:
@@ -132,8 +123,6 @@ type Syncer struct {
verifier ffiwrapper.Verifier
windowSize int
tickerCtxCancel context.CancelFunc
checkptLk sync.Mutex
@@ -175,7 +164,6 @@ func NewSyncer(ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.C
receiptTracker: newBlockReceiptTracker(),
connmgr: connmgr,
verifier: verifier,
windowSize: defaultMessageFetchWindowSize,
incoming: pubsub.New(50),
}
@@ -387,21 +375,28 @@ func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) bool {
return syncer.InformNewHead(from, fts)
}
func copyBlockstore(from, to bstore.Blockstore) error {
cids, err := from.AllKeysChan(context.TODO())
func copyBlockstore(ctx context.Context, from, to bstore.Blockstore) error {
ctx, span := trace.StartSpan(ctx, "copyBlockstore")
defer span.End()
cids, err := from.AllKeysChan(ctx)
if err != nil {
return err
}
// TODO: should probably expose better methods on the blockstore for this operation
var blks []blocks.Block
for c := range cids {
b, err := from.Get(c)
if err != nil {
return err
}
if err := to.Put(b); err != nil {
return err
}
blks = append(blks, b)
}
if err := to.PutMany(blks); err != nil {
return err
}
return nil
@@ -602,7 +597,7 @@ func isPermanent(err error) bool {
return !errors.Is(err, ErrTemporal)
}
func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet) error {
func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet, useCache bool) error {
ctx, span := trace.StartSpan(ctx, "validateTipSet")
defer span.End()
@@ -618,7 +613,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
b := b // rebind to a scoped variable
futures = append(futures, async.Err(func() error {
if err := syncer.ValidateBlock(ctx, b); err != nil {
if err := syncer.ValidateBlock(ctx, b, useCache); err != nil {
if isPermanent(err) {
syncer.bad.Add(b.Cid(), NewBadBlockReason([]cid.Cid{b.Cid()}, err.Error()))
}
@@ -640,7 +635,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
}
func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, baseTs *types.TipSet) error {
act, err := syncer.sm.LoadActor(ctx, builtin.StoragePowerActorAddr, baseTs)
act, err := syncer.sm.LoadActor(ctx, power.Address, baseTs)
if err != nil {
return xerrors.Errorf("failed to load power actor: %w", err)
}
@@ -685,7 +680,7 @@ func blockSanityChecks(h *types.BlockHeader) error {
}
// ValidateBlock should match up with 'Semantical Validation' in validation.md in the spec
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (err error) {
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, useCache bool) (err error) {
defer func() {
// b.Cid() could panic for empty blocks that are used in tests.
if rerr := recover(); rerr != nil {
@@ -694,13 +689,15 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
}
}()
isValidated, err := syncer.store.IsBlockValidated(ctx, b.Cid())
if err != nil {
return xerrors.Errorf("check block validation cache %s: %w", b.Cid(), err)
}
if useCache {
isValidated, err := syncer.store.IsBlockValidated(ctx, b.Cid())
if err != nil {
return xerrors.Errorf("check block validation cache %s: %w", b.Cid(), err)
}
if isValidated {
return nil
if isValidated {
return nil
}
}
validationStart := build.Clock.Now()
@@ -787,31 +784,35 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
b.Header.ParentWeight, pweight)
}
// Stuff that needs stateroot / worker address
stateroot, precp, err := syncer.sm.TipSetState(ctx, baseTs)
if err != nil {
return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err)
}
if stateroot != h.ParentStateRoot {
msgs, err := syncer.store.MessagesForTipset(baseTs)
stateRootCheck := async.Err(func() error {
stateroot, precp, err := syncer.sm.TipSetState(ctx, baseTs)
if err != nil {
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
} else {
log.Warn("Messages for tipset with mismatching state:")
for i, m := range msgs {
mm := m.VMMessage()
log.Warnf("Message[%d]: from=%s to=%s method=%d params=%x", i, mm.From, mm.To, mm.Method, mm.Params)
}
return xerrors.Errorf("get tipsetstate(%d, %s) failed: %w", h.Height, h.Parents, err)
}
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", stateroot, h.ParentStateRoot)
}
if stateroot != h.ParentStateRoot {
msgs, err := syncer.store.MessagesForTipset(baseTs)
if err != nil {
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
} else {
log.Warn("Messages for tipset with mismatching state:")
for i, m := range msgs {
mm := m.VMMessage()
log.Warnf("Message[%d]: from=%s to=%s method=%d params=%x", i, mm.From, mm.To, mm.Method, mm.Params)
}
}
if precp != h.ParentMessageReceipts {
return xerrors.Errorf("parent receipts root did not match computed value (%s != %s)", precp, h.ParentMessageReceipts)
}
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", stateroot, h.ParentStateRoot)
}
if precp != h.ParentMessageReceipts {
return xerrors.Errorf("parent receipts root did not match computed value (%s != %s)", precp, h.ParentMessageReceipts)
}
return nil
})
// Stuff that needs worker address
waddr, err := stmgr.GetMinerWorkerRaw(ctx, syncer.sm, lbst, h.Miner)
if err != nil {
return xerrors.Errorf("GetMinerWorkerRaw failed: %w", err)
@@ -932,6 +933,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
winnerCheck,
msgsCheck,
baseFeeCheck,
stateRootCheck,
}
var merr error
@@ -959,8 +961,10 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
return mulErr
}
if err := syncer.store.MarkBlockAsValidated(ctx, b.Cid()); err != nil {
return xerrors.Errorf("caching block validation %s: %w", b.Cid(), err)
if useCache {
if err := syncer.store.MarkBlockAsValidated(ctx, b.Cid()); err != nil {
return xerrors.Errorf("caching block validation %s: %w", b.Cid(), err)
}
}
return nil
@@ -1462,7 +1466,7 @@ func (syncer *Syncer) syncMessagesAndCheckState(ctx context.Context, headers []*
return syncer.iterFullTipsets(ctx, headers, func(ctx context.Context, fts *store.FullTipSet) error {
log.Debugw("validating tipset", "height", fts.TipSet().Height(), "size", len(fts.TipSet().Cids()))
if err := syncer.ValidateTipSet(ctx, fts); err != nil {
if err := syncer.ValidateTipSet(ctx, fts, true); err != nil {
log.Errorf("failed to validate tipset: %+v", err)
return xerrors.Errorf("message processing failed: %w", err)
}
@@ -1482,8 +1486,6 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
span.AddAttributes(trace.Int64Attribute("num_headers", int64(len(headers))))
windowSize := syncer.windowSize
mainLoop:
for i := len(headers) - 1; i >= 0; {
fts, err := syncer.store.TryFillTipSet(headers[i])
if err != nil {
@@ -1497,35 +1499,20 @@ mainLoop:
continue
}
batchSize := windowSize
batchSize := concurrentSyncRequests * syncRequestBatchSize
if i < batchSize {
batchSize = i
batchSize = i + 1
}
nextI := (i + 1) - batchSize // want to fetch batchSize values, 'i' points to last one we want to fetch, so its 'inclusive' of our request, thus we need to add one to our request start index
ss.SetStage(api.StageFetchingMessages)
var bstout []*exchange.CompactedMessages
for len(bstout) < batchSize {
next := headers[nextI]
nreq := batchSize - len(bstout)
bstips, err := syncer.Exchange.GetChainMessages(ctx, next, uint64(nreq))
if err != nil {
// TODO check errors for temporary nature
if windowSize > 1 {
windowSize /= 2
log.Infof("error fetching messages: %s; reducing window size to %d and trying again", err, windowSize)
continue mainLoop
}
return xerrors.Errorf("message processing failed: %w", err)
}
bstout = append(bstout, bstips...)
nextI += len(bstips)
}
startOffset := i + 1 - batchSize
bstout, batchErr := syncer.fetchMessages(ctx, headers[startOffset:startOffset+batchSize], startOffset)
ss.SetStage(api.StageMessages)
if batchErr != nil {
return xerrors.Errorf("failed to fetch messages: %w", err)
}
for bsi := 0; bsi < len(bstout); bsi++ {
// temp storage so we don't persist data we dont want to
bs := bstore.NewTemporary()
@@ -1545,36 +1532,91 @@ mainLoop:
return err
}
if err := persistMessages(bs, bstip); err != nil {
if err := persistMessages(ctx, bs, bstip); err != nil {
return err
}
if err := copyBlockstore(bs, syncer.store.Blockstore()); err != nil {
if err := copyBlockstore(ctx, bs, syncer.store.Blockstore()); err != nil {
return xerrors.Errorf("message processing failed: %w", err)
}
}
if i >= windowSize {
newWindowSize := windowSize + 10
if newWindowSize > int(exchange.MaxRequestLength) {
newWindowSize = int(exchange.MaxRequestLength)
}
if newWindowSize > windowSize {
windowSize = newWindowSize
log.Infof("successfully fetched %d messages; increasing window size to %d", len(bstout), windowSize)
}
}
i -= batchSize
}
// remember our window size
syncer.windowSize = windowSize
return nil
}
func persistMessages(bs bstore.Blockstore, bst *exchange.CompactedMessages) error {
func (syncer *Syncer) fetchMessages(ctx context.Context, headers []*types.TipSet, startOffset int) ([]*exchange.CompactedMessages, error) {
batchSize := len(headers)
batch := make([]*exchange.CompactedMessages, batchSize)
var wg sync.WaitGroup
var mx sync.Mutex
var batchErr error
start := build.Clock.Now()
for j := 0; j < batchSize; j += syncRequestBatchSize {
wg.Add(1)
go func(j int) {
defer wg.Done()
nreq := syncRequestBatchSize
if j+nreq > batchSize {
nreq = batchSize - j
}
failed := false
for offset := 0; !failed && offset < nreq; {
nextI := j + offset
lastI := j + nreq
var requestErr error
var requestResult []*exchange.CompactedMessages
for retry := 0; requestResult == nil && retry < syncRequestRetries; retry++ {
if retry > 0 {
log.Infof("fetching messages at %d (retry %d)", startOffset+nextI, retry)
} else {
log.Infof("fetching messages at %d", startOffset+nextI)
}
result, err := syncer.Exchange.GetChainMessages(ctx, headers[nextI:lastI])
if err != nil {
requestErr = multierror.Append(requestErr, err)
} else {
requestResult = result
}
}
mx.Lock()
if requestResult != nil {
copy(batch[j+offset:], requestResult)
offset += len(requestResult)
} else {
log.Errorf("error fetching messages at %d: %s", nextI, requestErr)
batchErr = multierror.Append(batchErr, requestErr)
failed = true
}
mx.Unlock()
}
}(j)
}
wg.Wait()
if batchErr != nil {
return nil, batchErr
}
log.Infof("fetching messages for %d tipsets at %d done; took %s", batchSize, startOffset, build.Clock.Since(start))
return batch, nil
}
func persistMessages(ctx context.Context, bs bstore.Blockstore, bst *exchange.CompactedMessages) error {
_, span := trace.StartSpan(ctx, "persistMessages")
defer span.End()
for _, m := range bst.Bls {
//log.Infof("putting BLS message: %s", m.Cid())
if _, err := store.PutMessage(bs, m); err != nil {
@@ -1706,7 +1748,7 @@ func (syncer *Syncer) getLatestBeaconEntry(_ context.Context, ts *types.TipSet)
cur = next
}
return nil, xerrors.Errorf("found NO beacon entries in the 20 blocks prior to given tipset")
return nil, xerrors.Errorf("found NO beacon entries in the 20 latest tipsets")
}
func (syncer *Syncer) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool {
+6 -11
View File
@@ -19,13 +19,10 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
"github.com/filecoin-project/lotus/chain/store"
@@ -43,11 +40,9 @@ func init() {
if err != nil {
panic(err)
}
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
power0.ConsensusMinerMinPower = big.NewInt(2048)
verifreg0.MinVerifiedDealSize = big.NewInt(256)
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
}
const source = 0
@@ -737,7 +732,7 @@ func TestSyncInputs(t *testing.T) {
err := s.ValidateBlock(context.TODO(), &types.FullBlock{
Header: &types.BlockHeader{},
})
}, false)
if err == nil {
t.Fatal("should error on empty block")
}
@@ -746,7 +741,7 @@ func TestSyncInputs(t *testing.T) {
h.ElectionProof = nil
err = s.ValidateBlock(context.TODO(), &types.FullBlock{Header: h})
err = s.ValidateBlock(context.TODO(), &types.FullBlock{Header: h}, false)
if err == nil {
t.Fatal("should error on block with nil election proof")
}
+14 -2
View File
@@ -5,7 +5,7 @@ import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/specs-actors/actors/builtin"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
)
var ErrActorNotFound = errors.New("actor not found")
@@ -19,5 +19,17 @@ type Actor struct {
}
func (a *Actor) IsAccountActor() bool {
return a.Code == builtin.AccountActorCodeID
return a.Code == builtin0.AccountActorCodeID
}
func (a *Actor) IsStorageMinerActor() bool {
return a.Code == builtin0.StorageMinerActorCodeID
}
func (a *Actor) IsMultisigActor() bool {
return a.Code == builtin0.MultisigActorCodeID
}
func (a *Actor) IsPaymentChannelActor() bool {
return a.Code == builtin0.PaymentChannelActorCodeID
}
+7 -3
View File
@@ -167,12 +167,16 @@ func (ts *TipSet) Equals(ots *TipSet) bool {
return false
}
if len(ts.blks) != len(ots.blks) {
if ts.height != ots.height {
return false
}
for i, b := range ts.blks {
if b.Cid() != ots.blks[i].Cid() {
if len(ts.cids) != len(ots.cids) {
return false
}
for i, cid := range ts.cids {
if cid != ots.cids[i] {
return false
}
}
+40
View File
@@ -1,9 +1,12 @@
package chain
import (
"crypto/rand"
"encoding/json"
"testing"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
)
@@ -35,3 +38,40 @@ func TestSignedMessageJsonRoundtrip(t *testing.T) {
t.Fatal(err)
}
}
func TestAddressType(t *testing.T) {
build.SetAddressNetwork(address.Testnet)
addr, err := makeRandomAddress()
if err != nil {
t.Fatal(err)
}
if string(addr[0]) != address.TestnetPrefix {
t.Fatalf("address should start with %s", address.TestnetPrefix)
}
build.SetAddressNetwork(address.Mainnet)
addr, err = makeRandomAddress()
if err != nil {
t.Fatal(err)
}
if string(addr[0]) != address.MainnetPrefix {
t.Fatalf("address should start with %s", address.MainnetPrefix)
}
}
func makeRandomAddress() (string, error) {
bytes := make([]byte, 32)
_, err := rand.Read(bytes)
if err != nil {
return "", err
}
addr, err := address.NewActorAddress(bytes)
if err != nil {
return "", err
}
return addr.String(), nil
}
+32 -26
View File
@@ -5,7 +5,6 @@ import (
"context"
"encoding/binary"
"fmt"
gruntime "runtime"
"time"
"github.com/filecoin-project/go-address"
@@ -460,8 +459,10 @@ func (rt *Runtime) stateCommit(oldh, newh cid.Cid) aerrors.ActorError {
}
func (rt *Runtime) finilizeGasTracing() {
if rt.lastGasCharge != nil {
rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime)
if enableTracing {
if rt.lastGasCharge != nil {
rt.lastGasCharge.TimeTaken = time.Since(rt.lastGasChargeTime)
}
}
}
@@ -490,34 +491,39 @@ func (rt *Runtime) chargeGasFunc(skip int) func(GasCharge) {
}
var enableTracing = false
func (rt *Runtime) chargeGasInternal(gas GasCharge, skip int) aerrors.ActorError {
toUse := gas.Total()
var callers [10]uintptr
cout := gruntime.Callers(2+skip, callers[:])
if enableTracing {
var callers [10]uintptr
now := build.Clock.Now()
if rt.lastGasCharge != nil {
rt.lastGasCharge.TimeTaken = now.Sub(rt.lastGasChargeTime)
cout := 0 //gruntime.Callers(2+skip, callers[:])
now := build.Clock.Now()
if rt.lastGasCharge != nil {
rt.lastGasCharge.TimeTaken = now.Sub(rt.lastGasChargeTime)
}
gasTrace := types.GasTrace{
Name: gas.Name,
Extra: gas.Extra,
TotalGas: toUse,
ComputeGas: gas.ComputeGas,
StorageGas: gas.StorageGas,
TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti,
VirtualComputeGas: gas.VirtualCompute,
VirtualStorageGas: gas.VirtualStorage,
Callers: callers[:cout],
}
rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace)
rt.lastGasChargeTime = now
rt.lastGasCharge = &gasTrace
}
gasTrace := types.GasTrace{
Name: gas.Name,
Extra: gas.Extra,
TotalGas: toUse,
ComputeGas: gas.ComputeGas,
StorageGas: gas.StorageGas,
TotalVirtualGas: gas.VirtualCompute*GasComputeMulti + gas.VirtualStorage*GasStorageMulti,
VirtualComputeGas: gas.VirtualCompute,
VirtualStorageGas: gas.VirtualStorage,
Callers: callers[:cout],
}
rt.executionTrace.GasCharges = append(rt.executionTrace.GasCharges, &gasTrace)
rt.lastGasChargeTime = now
rt.lastGasCharge = &gasTrace
// overflow safe
if rt.gasUsed > rt.gasAvailable-toUse {
rt.gasUsed = rt.gasAvailable
+42 -9
View File
@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"reflect"
"sync/atomic"
"time"
block "github.com/ipfs/go-block-format"
@@ -28,6 +29,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/lotus/chain/actors/builtin/account"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore"
@@ -39,6 +41,12 @@ var log = logging.Logger("vm")
var actorLog = logging.Logger("actors")
var gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
// stat counters
var (
StatSends uint64
StatApplied uint64
)
// ResolveToKeyAddr returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`.
func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Address) (address.Address, error) {
if addr.Protocol() == address.BLS || addr.Protocol() == address.SECP256K1 {
@@ -203,6 +211,8 @@ type ApplyRet struct {
func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
gasCharge *GasCharge, start time.Time) ([]byte, aerrors.ActorError, *Runtime) {
defer atomic.AddUint64(&StatSends, 1)
st := vm.cstate
origin := msg.From
@@ -217,14 +227,21 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
}
rt := vm.makeRuntime(ctx, msg, origin, on, gasUsed, nac)
rt.lastGasChargeTime = start
if enableTracing {
rt.lastGasChargeTime = start
if parent != nil {
rt.lastGasChargeTime = parent.lastGasChargeTime
rt.lastGasCharge = parent.lastGasCharge
defer func() {
parent.lastGasChargeTime = rt.lastGasChargeTime
parent.lastGasCharge = rt.lastGasCharge
}()
}
}
if parent != nil {
rt.lastGasChargeTime = parent.lastGasChargeTime
rt.lastGasCharge = parent.lastGasCharge
defer func() {
parent.gasUsed = rt.gasUsed
parent.lastGasChargeTime = rt.lastGasChargeTime
parent.lastGasCharge = rt.lastGasCharge
}()
}
if gasCharge != nil {
@@ -311,6 +328,7 @@ func checkMessage(msg *types.Message) error {
func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*ApplyRet, error) {
start := build.Clock.Now()
defer atomic.AddUint64(&StatApplied, 1)
ret, actorErr, rt := vm.send(ctx, msg, nil, nil, start)
rt.finilizeGasTracing()
return &ApplyRet{
@@ -330,6 +348,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
start := build.Clock.Now()
ctx, span := trace.StartSpan(ctx, "vm.ApplyMessage")
defer span.End()
defer atomic.AddUint64(&StatApplied, 1)
msg := cmsg.VMMessage()
if span.IsRecordingEvents() {
span.AddAttributes(
@@ -384,7 +403,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
}
// this should never happen, but is currently still exercised by some tests
if !fromActor.Code.Equals(builtin.AccountActorCodeID) {
if !fromActor.IsAccountActor() {
gasOutputs := ZeroGasOutputs()
gasOutputs.MinerPenalty = minerPenaltyAmount
return &ApplyRet{
@@ -493,7 +512,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
return nil, xerrors.Errorf("failed to burn base fee: %w", err)
}
if err := vm.transferFromGasHolder(builtin.RewardActorAddr, gasHolder, gasOutputs.MinerTip); err != nil {
if err := vm.transferFromGasHolder(reward.Address, gasHolder, gasOutputs.MinerTip); err != nil {
return nil, xerrors.Errorf("failed to give miner gas reward: %w", err)
}
@@ -545,7 +564,7 @@ func (vm *VM) Flush(ctx context.Context) (cid.Cid, error) {
return cid.Undef, xerrors.Errorf("flushing vm: %w", err)
}
if err := Copy(from, to, root); err != nil {
if err := Copy(ctx, from, to, root); err != nil {
return cid.Undef, xerrors.Errorf("copying tree: %w", err)
}
@@ -599,9 +618,18 @@ func linksForObj(blk block.Block, cb func(cid.Cid)) error {
}
}
func Copy(from, to blockstore.Blockstore, root cid.Cid) error {
func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) error {
ctx, span := trace.StartSpan(ctx, "vm.Copy") // nolint
defer span.End()
var numBlocks int
var totalCopySize int
var batch []block.Block
batchCp := func(blk block.Block) error {
numBlocks++
totalCopySize += len(blk.RawData())
batch = append(batch, blk)
if len(batch) > 100 {
if err := to.PutMany(batch); err != nil {
@@ -622,6 +650,11 @@ func Copy(from, to blockstore.Blockstore, root cid.Cid) error {
}
}
span.AddAttributes(
trace.Int64Attribute("numBlocks", int64(numBlocks)),
trace.Int64Attribute("copySize", int64(totalCopySize)),
)
return nil
}
+38
View File
@@ -40,6 +40,7 @@ var chainCmd = &cli.Command{
chainHeadCmd,
chainGetBlock,
chainReadObjCmd,
chainDeleteObjCmd,
chainStatObjCmd,
chainGetMsgCmd,
chainSetHeadCmd,
@@ -193,6 +194,43 @@ var chainReadObjCmd = &cli.Command{
},
}
var chainDeleteObjCmd = &cli.Command{
Name: "delete-obj",
Usage: "Delete an object from the chain blockstore",
Description: "WARNING: Removing wrong objects from the chain blockstore may lead to sync issues",
ArgsUsage: "[objectCid]",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
c, err := cid.Decode(cctx.Args().First())
if err != nil {
return fmt.Errorf("failed to parse cid input: %s", err)
}
if !cctx.Bool("really-do-it") {
return xerrors.Errorf("pass the --really-do-it flag to proceed")
}
err = api.ChainDeleteObj(ctx, c)
if err != nil {
return err
}
fmt.Printf("Obj %s deleted\n", c.String())
return nil
},
}
var chainStatObjCmd = &cli.Command{
Name: "stat-obj",
Usage: "Collect size and ipld link counts for objs",
+6 -6
View File
@@ -569,7 +569,7 @@ func interactiveDeal(cctx *cli.Context) error {
continue
}
ask = *a.Ask
ask = *a
// TODO: run more validation
state = "confirm"
@@ -951,15 +951,15 @@ var clientQueryAskCmd = &cli.Command{
}
fmt.Printf("Ask: %s\n", maddr)
fmt.Printf("Price per GiB: %s\n", types.FIL(ask.Ask.Price))
fmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.Ask.VerifiedPrice))
fmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.Ask.MaxPieceSize))))
fmt.Printf("Price per GiB: %s\n", types.FIL(ask.Price))
fmt.Printf("Verified Price per GiB: %s\n", types.FIL(ask.VerifiedPrice))
fmt.Printf("Max Piece size: %s\n", types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))))
size := cctx.Int64("size")
if size == 0 {
return nil
}
perEpoch := types.BigDiv(types.BigMul(ask.Ask.Price, types.NewInt(uint64(size))), types.NewInt(1<<30))
perEpoch := types.BigDiv(types.BigMul(ask.Price, types.NewInt(uint64(size))), types.NewInt(1<<30))
fmt.Printf("Price per Block: %s\n", types.FIL(perEpoch))
duration := cctx.Int64("duration")
@@ -1423,7 +1423,7 @@ func toChannelOutput(useColor bool, otherPartyColumn string, channel lapi.DataTr
otherPartyColumn: otherParty,
"Root Cid": rootCid,
"Initiated?": initiated,
"Transferred": channel.Transferred,
"Transferred": units.BytesSize(float64(channel.Transferred)),
"Voucher": voucher,
"Message": channel.Message,
}
+337 -70
View File
@@ -2,8 +2,6 @@ package cli
import (
"bytes"
"context"
"encoding/binary"
"encoding/hex"
"fmt"
"os"
@@ -11,22 +9,26 @@ import (
"strconv"
"text/tabwriter"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/go-address"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/specs-actors/actors/builtin"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build"
types "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/types"
)
var multisigCmd = &cli.Command{
@@ -43,6 +45,9 @@ var multisigCmd = &cli.Command{
msigSwapProposeCmd,
msigSwapApproveCmd,
msigSwapCancelCmd,
msigLockProposeCmd,
msigLockApproveCmd,
msigLockCancelCmd,
msigVestedCmd,
},
}
@@ -146,7 +151,7 @@ var msigCreateCmd = &cli.Command{
// get address of newly created miner
var execreturn init_.ExecReturn
var execreturn init0.ExecReturn
if err := execreturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
return err
}
@@ -179,50 +184,73 @@ var msigInspectCmd = &cli.Command{
defer closer()
ctx := ReqContext(cctx)
store := adt.WrapStore(ctx, cbor.NewCborStore(apibstore.NewAPIBlockstore(api)))
maddr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
act, err := api.StateGetActor(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
obj, err := api.ChainReadObj(ctx, act.Head)
if err != nil {
return err
}
head, err := api.ChainHead(ctx)
if err != nil {
return err
}
var mstate msig0.State
if err := mstate.UnmarshalCBOR(bytes.NewReader(obj)); err != nil {
act, err := api.StateGetActor(ctx, maddr, head.Key())
if err != nil {
return err
}
mstate, err := multisig.Load(store, act)
if err != nil {
return err
}
locked, err := mstate.LockedBalance(head.Height())
if err != nil {
return err
}
locked := mstate.AmountLocked(head.Height() - mstate.StartEpoch)
fmt.Printf("Balance: %s\n", types.FIL(act.Balance))
fmt.Printf("Spendable: %s\n", types.FIL(types.BigSub(act.Balance, locked)))
if cctx.Bool("vesting") {
fmt.Printf("InitialBalance: %s\n", types.FIL(mstate.InitialBalance))
fmt.Printf("StartEpoch: %d\n", mstate.StartEpoch)
fmt.Printf("UnlockDuration: %d\n", mstate.UnlockDuration)
ib, err := mstate.InitialBalance()
if err != nil {
return err
}
fmt.Printf("InitialBalance: %s\n", types.FIL(ib))
se, err := mstate.StartEpoch()
if err != nil {
return err
}
fmt.Printf("StartEpoch: %d\n", se)
ud, err := mstate.UnlockDuration()
if err != nil {
return err
}
fmt.Printf("UnlockDuration: %d\n", ud)
}
fmt.Printf("Threshold: %d / %d\n", mstate.NumApprovalsThreshold, len(mstate.Signers))
signers, err := mstate.Signers()
if err != nil {
return err
}
threshold, err := mstate.Threshold()
if err != nil {
return err
}
fmt.Printf("Threshold: %d / %d\n", threshold, len(signers))
fmt.Println("Signers:")
for _, s := range mstate.Signers {
for _, s := range signers {
fmt.Printf("\t%s\n", s)
}
pending, err := GetMultisigPending(ctx, api, mstate.PendingTxns)
if err != nil {
return fmt.Errorf("reading pending transactions: %w", err)
pending := make(map[int64]multisig.Transaction)
if err := mstate.ForEachPendingTxn(func(id int64, txn multisig.Transaction) error {
pending[id] = txn
return nil
}); err != nil {
return xerrors.Errorf("reading pending transactions: %w", err)
}
fmt.Println("Transactions: ", len(pending))
@@ -239,7 +267,7 @@ var msigInspectCmd = &cli.Command{
fmt.Fprintf(w, "ID\tState\tApprovals\tTo\tValue\tMethod\tParams\n")
for _, txid := range txids {
tx := pending[txid]
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%x\n", txid, state(tx), len(tx.Approved), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%x\n", txid, "pending", len(tx.Approved), tx.To, types.FIL(tx.Value), tx.Method, tx.Params)
}
if err := w.Flush(); err != nil {
return xerrors.Errorf("flushing output: %+v", err)
@@ -251,43 +279,6 @@ var msigInspectCmd = &cli.Command{
},
}
func GetMultisigPending(ctx context.Context, lapi api.FullNode, hroot cid.Cid) (map[int64]*msig0.Transaction, error) {
bs := apibstore.NewAPIBlockstore(lapi)
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
nd, err := adt.AsMap(store, hroot)
if err != nil {
return nil, err
}
txs := make(map[int64]*msig0.Transaction)
var tx msig0.Transaction
err = nd.ForEach(&tx, func(k string) error {
txid, _ := binary.Varint([]byte(k))
cpy := tx // copy so we don't clobber on future iterations.
txs[txid] = &cpy
return nil
})
if err != nil {
return nil, xerrors.Errorf("failed to iterate transactions hamt: %w", err)
}
return txs, nil
}
func state(tx *msig0.Transaction) string {
/* // TODO(why): I strongly disagree with not having these... but i need to move forward
if tx.Complete {
return "done"
}
if tx.Canceled {
return "canceled"
}
*/
return "pending"
}
var msigProposeCmd = &cli.Command{
Name: "propose",
Usage: "Propose a multisig transaction",
@@ -365,7 +356,7 @@ var msigProposeCmd = &cli.Command{
return fmt.Errorf("failed to look up multisig %s: %w", msig, err)
}
if act.Code != builtin.MultisigActorCodeID {
if !act.IsMultisigActor() {
return fmt.Errorf("actor %s is not a multisig actor", msig)
}
@@ -971,6 +962,282 @@ var msigSwapCancelCmd = &cli.Command{
},
}
var msigLockProposeCmd = &cli.Command{
Name: "lock-propose",
Usage: "Propose to lock up some balance",
ArgsUsage: "[multisigAddress startEpoch unlockDuration amount]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "from",
Usage: "account to send the propose message from",
},
},
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 4 {
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, start epoch, unlock duration, and amount"))
}
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
msig, err := address.NewFromString(cctx.Args().Get(0))
if err != nil {
return err
}
start, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64)
if err != nil {
return err
}
duration, err := strconv.ParseUint(cctx.Args().Get(2), 10, 64)
if err != nil {
return err
}
amount, err := types.ParseFIL(cctx.Args().Get(3))
if err != nil {
return err
}
var from address.Address
if cctx.IsSet("from") {
f, err := address.NewFromString(cctx.String("from"))
if err != nil {
return err
}
from = f
} else {
defaddr, err := api.WalletDefaultAddress(ctx)
if err != nil {
return err
}
from = defaddr
}
params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{
StartEpoch: abi.ChainEpoch(start),
UnlockDuration: abi.ChainEpoch(duration),
Amount: abi.NewTokenAmount(amount.Int64()),
})
if actErr != nil {
return actErr
}
msgCid, err := api.MsigPropose(ctx, msig, msig, big.Zero(), from, uint64(builtin.MethodsMultisig.LockBalance), params)
if err != nil {
return err
}
fmt.Println("sent lock proposal in message: ", msgCid)
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
if err != nil {
return err
}
if wait.Receipt.ExitCode != 0 {
return fmt.Errorf("lock proposal returned exit %d", wait.Receipt.ExitCode)
}
return nil
},
}
var msigLockApproveCmd = &cli.Command{
Name: "lock-approve",
Usage: "Approve a message to lock up some balance",
ArgsUsage: "[multisigAddress proposerAddress txId startEpoch unlockDuration amount]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "from",
Usage: "account to send the approve message from",
},
},
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 6 {
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, proposer address, tx id, start epoch, unlock duration, and amount"))
}
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
msig, err := address.NewFromString(cctx.Args().Get(0))
if err != nil {
return err
}
prop, err := address.NewFromString(cctx.Args().Get(1))
if err != nil {
return err
}
txid, err := strconv.ParseUint(cctx.Args().Get(2), 10, 64)
if err != nil {
return err
}
start, err := strconv.ParseUint(cctx.Args().Get(3), 10, 64)
if err != nil {
return err
}
duration, err := strconv.ParseUint(cctx.Args().Get(4), 10, 64)
if err != nil {
return err
}
amount, err := types.ParseFIL(cctx.Args().Get(5))
if err != nil {
return err
}
var from address.Address
if cctx.IsSet("from") {
f, err := address.NewFromString(cctx.String("from"))
if err != nil {
return err
}
from = f
} else {
defaddr, err := api.WalletDefaultAddress(ctx)
if err != nil {
return err
}
from = defaddr
}
params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{
StartEpoch: abi.ChainEpoch(start),
UnlockDuration: abi.ChainEpoch(duration),
Amount: abi.NewTokenAmount(amount.Int64()),
})
if actErr != nil {
return actErr
}
msgCid, err := api.MsigApprove(ctx, msig, txid, prop, msig, big.Zero(), from, uint64(builtin.MethodsMultisig.LockBalance), params)
if err != nil {
return err
}
fmt.Println("sent lock approval in message: ", msgCid)
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
if err != nil {
return err
}
if wait.Receipt.ExitCode != 0 {
return fmt.Errorf("lock approval returned exit %d", wait.Receipt.ExitCode)
}
return nil
},
}
var msigLockCancelCmd = &cli.Command{
Name: "lock-cancel",
Usage: "Cancel a message to lock up some balance",
ArgsUsage: "[multisigAddress txId startEpoch unlockDuration amount]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "from",
Usage: "account to send the cancel message from",
},
},
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 6 {
return ShowHelp(cctx, fmt.Errorf("must pass multisig address, tx id, start epoch, unlock duration, and amount"))
}
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
msig, err := address.NewFromString(cctx.Args().Get(0))
if err != nil {
return err
}
txid, err := strconv.ParseUint(cctx.Args().Get(1), 10, 64)
if err != nil {
return err
}
start, err := strconv.ParseUint(cctx.Args().Get(2), 10, 64)
if err != nil {
return err
}
duration, err := strconv.ParseUint(cctx.Args().Get(3), 10, 64)
if err != nil {
return err
}
amount, err := types.ParseFIL(cctx.Args().Get(4))
if err != nil {
return err
}
var from address.Address
if cctx.IsSet("from") {
f, err := address.NewFromString(cctx.String("from"))
if err != nil {
return err
}
from = f
} else {
defaddr, err := api.WalletDefaultAddress(ctx)
if err != nil {
return err
}
from = defaddr
}
params, actErr := actors.SerializeParams(&msig0.LockBalanceParams{
StartEpoch: abi.ChainEpoch(start),
UnlockDuration: abi.ChainEpoch(duration),
Amount: abi.NewTokenAmount(amount.Int64()),
})
if actErr != nil {
return actErr
}
msgCid, err := api.MsigCancel(ctx, msig, txid, msig, big.Zero(), from, uint64(builtin.MethodsMultisig.LockBalance), params)
if err != nil {
return err
}
fmt.Println("sent lock cancellation in message: ", msgCid)
wait, err := api.StateWaitMsg(ctx, msgCid, build.MessageConfidence)
if err != nil {
return err
}
if wait.Receipt.ExitCode != 0 {
return fmt.Errorf("lock cancellation returned exit %d", wait.Receipt.ExitCode)
}
return nil
},
}
var msigVestedCmd = &cli.Command{
Name: "vested",
Usage: "Gets the amount vested in an msig between two epochs",
+23 -29
View File
@@ -12,39 +12,31 @@ import (
"testing"
"time"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/go-state-types/big"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/multiformats/go-multiaddr"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api/test"
"github.com/filecoin-project/lotus/chain/wallet"
builder "github.com/filecoin-project/lotus/node/test"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/multiformats/go-multiaddr"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/api/test"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
builder "github.com/filecoin-project/lotus/node/test"
)
func init() {
power0.ConsensusMinerMinPower = big.NewInt(2048)
miner0.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
verifreg0.MinVerifiedDealSize = big.NewInt(256)
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
policy.SetConsensusMinerMinPower(abi.NewStoragePower(2048))
policy.SetMinVerifiedDealSize(abi.NewStoragePower(256))
}
// TestPaymentChannels does a basic test to exercise the payment channel CLI
@@ -89,7 +81,9 @@ func TestPaymentChannels(t *testing.T) {
// Wait for the chain to reach the settle height
chState := getPaychState(ctx, t, paymentReceiver, chAddr)
waitForHeight(ctx, t, paymentReceiver, chState.SettlingAt())
sa, err := chState.SettlingAt()
require.NoError(t, err)
waitForHeight(ctx, t, paymentReceiver, sa)
// receiver: paych collect <channel>
cmd = []string{chAddr.String()}
+32 -11
View File
@@ -19,6 +19,7 @@ import (
"github.com/multiformats/go-multiaddr"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/multiformats/go-multihash"
"github.com/urfave/cli/v2"
@@ -33,7 +34,9 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin/exported"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
)
@@ -259,13 +262,13 @@ var stateSectorsCmd = &cli.Command{
return err
}
sectors, err := api.StateMinerSectors(ctx, maddr, nil, true, ts.Key())
sectors, err := api.StateMinerSectors(ctx, maddr, nil, ts.Key())
if err != nil {
return err
}
for _, s := range sectors {
fmt.Printf("%d: %x\n", s.Info.SectorNumber, s.Info.SealedCID)
fmt.Printf("%d: %x\n", s.SectorNumber, s.SealedCID)
}
return nil
@@ -305,7 +308,7 @@ var stateActiveSectorsCmd = &cli.Command{
}
for _, s := range sectors {
fmt.Printf("%d: %x\n", s.Info.SectorNumber, s.Info.SealedCID)
fmt.Printf("%d: %x\n", s.SectorNumber, s.SealedCID)
}
return nil
@@ -818,6 +821,10 @@ var stateComputeStateCmd = &cli.Command{
Name: "html",
Usage: "generate html report",
},
&cli.BoolFlag{
Name: "json",
Usage: "generate json output",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
@@ -834,14 +841,14 @@ var stateComputeStateCmd = &cli.Command{
}
h := abi.ChainEpoch(cctx.Uint64("vm-height"))
if h == 0 {
if ts == nil {
head, err := api.ChainHead(ctx)
if err != nil {
return err
}
ts = head
if ts == nil {
head, err := api.ChainHead(ctx)
if err != nil {
return err
}
ts = head
}
if h == 0 {
h = ts.Height()
}
@@ -862,14 +869,28 @@ var stateComputeStateCmd = &cli.Command{
return err
}
if cctx.Bool("json") {
out, err := json.Marshal(stout)
if err != nil {
return err
}
fmt.Println(string(out))
return nil
}
if cctx.Bool("html") {
st, err := state.LoadStateTree(cbor.NewCborStore(apibstore.NewAPIBlockstore(api)), stout.Root)
if err != nil {
return xerrors.Errorf("loading state tree: %w", err)
}
codeCache := map[address.Address]cid.Cid{}
getCode := func(addr address.Address) (cid.Cid, error) {
if c, found := codeCache[addr]; found {
return c, nil
}
c, err := api.StateGetActor(ctx, addr, ts.Key())
c, err := st.GetActor(addr)
if err != nil {
return cid.Cid{}, err
}
+41 -2
View File
@@ -225,6 +225,16 @@ var syncCheckpointCmd = &cli.Command{
}
func SyncWait(ctx context.Context, napi api.FullNode) error {
tick := time.Second / 4
lastLines := 0
ticker := time.NewTicker(tick)
defer ticker.Stop()
samples := 8
i := 0
var app, lastApp uint64
for {
state, err := napi.SyncState(ctx)
if err != nil {
@@ -249,14 +259,41 @@ func SyncWait(ctx context.Context, napi api.FullNode) error {
ss := state.ActiveSyncs[working]
var baseHeight abi.ChainEpoch
var target []cid.Cid
var theight abi.ChainEpoch
var heightDiff int64
if ss.Base != nil {
baseHeight = ss.Base.Height()
heightDiff = int64(ss.Base.Height())
}
if ss.Target != nil {
target = ss.Target.Cids()
theight = ss.Target.Height()
heightDiff = int64(ss.Target.Height()) - heightDiff
} else {
heightDiff = 0
}
fmt.Printf("\r\x1b[2KWorker %d: Target Height: %d\tTarget: %s\tState: %s\tHeight: %d", working, theight, target, ss.Stage, ss.Height)
for i := 0; i < lastLines; i++ {
fmt.Print("\r\x1b[2K\x1b[A")
}
fmt.Printf("Worker: %d; Base: %d; Target: %d (diff: %d)\n", working, baseHeight, theight, heightDiff)
fmt.Printf("State: %s; Current Epoch: %d; Todo: %d\n", ss.Stage, ss.Height, theight-ss.Height)
lastLines = 2
if i%samples == 0 {
lastApp = app
app = state.VMApplied
}
if i > 0 {
fmt.Printf("Validated %d messages (%d per second)\n", state.VMApplied, (app-lastApp)*uint64(time.Second/tick)/uint64(samples))
lastLines++
}
_ = target // todo: maybe print? (creates a bunch of line wrapping issues with most tipsets)
if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs) {
fmt.Println("\nDone!")
@@ -267,7 +304,9 @@ func SyncWait(ctx context.Context, napi api.FullNode) error {
case <-ctx.Done():
fmt.Println("\nExit by user")
return nil
case <-build.Clock.After(1 * time.Second):
case <-ticker.C:
}
i++
}
}
+3 -2
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"time"
"github.com/hako/durafmt"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-state-types/abi"
@@ -36,11 +37,11 @@ func parseTipSet(ctx context.Context, api api.FullNode, vals []string) (*types.T
func EpochTime(curr, e abi.ChainEpoch) string {
switch {
case curr > e:
return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e)))
return fmt.Sprintf("%d (%s ago)", e, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(curr-e))).LimitFirstN(2))
case curr == e:
return fmt.Sprintf("%d (now)", e)
case curr < e:
return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr)))
return fmt.Sprintf("%d (in %s)", e, durafmt.Parse(time.Second*time.Duration(int64(build.BlockDelaySecs)*int64(e-curr))).LimitFirstN(2))
}
panic("math broke")
+59 -6
View File
@@ -9,13 +9,16 @@ import (
"os"
"strings"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
types "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/urfave/cli/v2"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
types "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/lib/tablewriter"
)
var walletCmd = &cli.Command{
@@ -66,6 +69,13 @@ var walletNew = &cli.Command{
var walletList = &cli.Command{
Name: "list",
Usage: "List wallet address",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "addr-only",
Usage: "Only print addresses",
Aliases: []string{"a"},
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
@@ -79,9 +89,52 @@ var walletList = &cli.Command{
return err
}
// Assume an error means no default key is set
def, _ := api.WalletDefaultAddress(ctx)
tw := tablewriter.New(
tablewriter.Col("Address"),
tablewriter.Col("Balance"),
tablewriter.Col("Nonce"),
tablewriter.Col("Default"),
tablewriter.NewLineCol("Error"))
for _, addr := range addrs {
fmt.Println(addr.String())
if cctx.Bool("addr-only") {
fmt.Println(addr.String())
} else {
a, err := api.StateGetActor(ctx, addr, types.EmptyTSK)
if err != nil {
if !strings.Contains(err.Error(), "actor not found") {
tw.Write(map[string]interface{}{
"Address": addr,
"Error": err,
})
continue
}
a = &types.Actor{
Balance: big.Zero(),
}
}
row := map[string]interface{}{
"Address": addr,
"Balance": types.FIL(a.Balance),
"Nonce": a.Nonce,
}
if addr == def {
row["Default"] = "X"
}
tw.Write(row)
}
}
if !cctx.Bool("addr-only") {
return tw.Flush(os.Stdout)
}
return nil
},
}
+98
View File
@@ -0,0 +1,98 @@
package main
import (
"bufio"
"context"
"errors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/ipfs/go-datastore"
"github.com/minio/blake2b-simd"
cbg "github.com/whyrusleeping/cbor-gen"
)
type cachingVerifier struct {
ds datastore.Datastore
backend ffiwrapper.Verifier
}
const bufsize = 128
func (cv cachingVerifier) withCache(execute func() (bool, error), param cbg.CBORMarshaler) (bool, error) {
hasher := blake2b.New256()
wr := bufio.NewWriterSize(hasher, bufsize)
err := param.MarshalCBOR(wr)
if err != nil {
log.Errorf("could not marshal call info: %+v", err)
return execute()
}
err = wr.Flush()
if err != nil {
log.Errorf("could not flush: %+v", err)
return execute()
}
hash := hasher.Sum(nil)
key := datastore.NewKey(string(hash))
fromDs, err := cv.ds.Get(key)
if err == nil {
switch fromDs[0] {
case 's':
return true, nil
case 'f':
return false, nil
case 'e':
return false, errors.New(string(fromDs[1:]))
default:
log.Errorf("bad cached result in cache %s(%x)", fromDs[0], fromDs[0])
return execute()
}
} else if errors.Is(err, datastore.ErrNotFound) {
// recalc
ok, err := execute()
var save []byte
if err != nil {
if ok {
log.Errorf("success with an error: %+v", err)
} else {
save = append([]byte{'e'}, []byte(err.Error())...)
}
} else if ok {
save = []byte{'s'}
} else {
save = []byte{'f'}
}
if len(save) != 0 {
errSave := cv.ds.Put(key, save)
if errSave != nil {
log.Errorf("error saving result: %+v", errSave)
}
}
return ok, err
} else {
log.Errorf("could not get data from cache: %+v", err)
return execute()
}
}
func (cv *cachingVerifier) VerifySeal(svi proof.SealVerifyInfo) (bool, error) {
return cv.withCache(func() (bool, error) {
return cv.backend.VerifySeal(svi)
}, &svi)
}
func (cv *cachingVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) {
return cv.backend.VerifyWinningPoSt(ctx, info)
}
func (cv *cachingVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) {
return cv.withCache(func() (bool, error) {
return cv.backend.VerifyWindowPoSt(ctx, info)
}, &info)
}
func (cv *cachingVerifier) GenerateWinningPoStSectorChallenge(ctx context.Context, proofType abi.RegisteredPoStProof, a abi.ActorID, rnd abi.PoStRandomness, u uint64) ([]uint64, error) {
return cv.backend.GenerateWinningPoStSectorChallenge(ctx, proofType, a, rnd, u)
}
var _ ffiwrapper.Verifier = (*cachingVerifier)(nil)
+165 -43
View File
@@ -16,6 +16,8 @@ import (
"sort"
"time"
"github.com/cockroachdb/pebble"
"github.com/cockroachdb/pebble/bloom"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
@@ -24,12 +26,16 @@ import (
"github.com/filecoin-project/lotus/lib/blockstore"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/ipld/go-car"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
bdg "github.com/dgraph-io/badger/v2"
"github.com/ipfs/go-datastore"
badger "github.com/ipfs/go-ds-badger2"
pebbleds "github.com/ipfs/go-ds-pebble"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
)
@@ -60,6 +66,29 @@ var importBenchCmd = &cli.Command{
Name: "repodir",
Usage: "set the repo directory for the lotus bench run (defaults to /tmp)",
},
&cli.StringFlag{
Name: "syscall-cache",
Usage: "read and write syscall results from datastore",
},
&cli.BoolFlag{
Name: "export-traces",
Usage: "should we export execution traces",
Value: true,
},
&cli.BoolFlag{
Name: "no-import",
Usage: "should we import the chain? if set to true chain has to be previously imported",
},
&cli.BoolFlag{
Name: "global-profile",
Value: true,
},
&cli.Int64Flag{
Name: "start-at",
},
&cli.BoolFlag{
Name: "only-import",
},
},
Action: func(cctx *cli.Context) error {
vm.BatchSealVerifyParallelism = cctx.Int("batch-seal-verify-threads")
@@ -74,6 +103,10 @@ var importBenchCmd = &cli.Command{
}
defer cfi.Close() //nolint:errcheck // read only file
go func() {
http.ListenAndServe("localhost:6060", nil) //nolint:errcheck
}()
var tdir string
if rdir := cctx.String("repodir"); rdir != "" {
tdir = rdir
@@ -85,33 +118,105 @@ var importBenchCmd = &cli.Command{
tdir = tmp
}
bds, err := badger.NewDatastore(tdir, nil)
bdgOpt := badger.DefaultOptions
bdgOpt.GcInterval = 0
bdgOpt.Options = bdg.DefaultOptions("")
bdgOpt.Options.SyncWrites = false
bdgOpt.Options.Truncate = true
bdgOpt.Options.DetectConflicts = false
var bds datastore.Batching
if false {
cache := 512
bds, err = pebbleds.NewDatastore(tdir, &pebble.Options{
// Pebble has a single combined cache area and the write
// buffers are taken from this too. Assign all available
// memory allowance for cache.
Cache: pebble.NewCache(int64(cache * 1024 * 1024)),
// The size of memory table(as well as the write buffer).
// Note, there may have more than two memory tables in the system.
// MemTableStopWritesThreshold can be configured to avoid the memory abuse.
MemTableSize: cache * 1024 * 1024 / 4,
// The default compaction concurrency(1 thread),
// Here use all available CPUs for faster compaction.
MaxConcurrentCompactions: runtime.NumCPU(),
// Per-level options. Options for at least one level must be specified. The
// options for the last level are used for all subsequent levels.
Levels: []pebble.LevelOptions{
{TargetFileSize: 16 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10), Compression: pebble.NoCompression},
},
Logger: log,
})
} else {
bds, err = badger.NewDatastore(tdir, &bdgOpt)
}
if err != nil {
return err
}
defer bds.Close() //nolint:errcheck
bs := blockstore.NewBlockstore(bds)
cbs, err := blockstore.CachedBlockstore(context.TODO(), bs, blockstore.DefaultCacheOpts())
cacheOpts := blockstore.DefaultCacheOpts()
cacheOpts.HasBloomFilterSize = 0
cbs, err := blockstore.CachedBlockstore(context.TODO(), bs, cacheOpts)
if err != nil {
return err
}
bs = cbs
ds := datastore.NewMapDatastore()
cs := store.NewChainStore(bs, ds, vm.Syscalls(ffiwrapper.ProofVerifier))
var verifier ffiwrapper.Verifier = ffiwrapper.ProofVerifier
if cctx.IsSet("syscall-cache") {
scds, err := badger.NewDatastore(cctx.String("syscall-cache"), &bdgOpt)
if err != nil {
return xerrors.Errorf("opening syscall-cache datastore: %w", err)
}
defer scds.Close() //nolint:errcheck
verifier = &cachingVerifier{
ds: scds,
backend: verifier,
}
}
if cctx.Bool("only-gc") {
return nil
}
cs := store.NewChainStore(bs, ds, vm.Syscalls(verifier))
stm := stmgr.NewStateManager(cs)
prof, err := os.Create("import-bench.prof")
if err != nil {
return err
}
defer prof.Close() //nolint:errcheck
if cctx.Bool("global-profile") {
prof, err := os.Create("import-bench.prof")
if err != nil {
return err
}
defer prof.Close() //nolint:errcheck
if err := pprof.StartCPUProfile(prof); err != nil {
return err
if err := pprof.StartCPUProfile(prof); err != nil {
return err
}
}
head, err := cs.Import(cfi)
if err != nil {
return err
var head *types.TipSet
if !cctx.Bool("no-import") {
head, err = cs.Import(cfi)
if err != nil {
return err
}
} else {
cr, err := car.NewCarReader(cfi)
if err != nil {
return err
}
head, err = cs.LoadTipSet(types.NewTipSetKey(cr.Header.Roots...))
if err != nil {
return err
}
}
if cctx.Bool("only-import") {
return nil
}
gb, err := cs.GetTipsetByHeight(context.TODO(), 0, head, true)
@@ -124,6 +229,20 @@ var importBenchCmd = &cli.Command{
return err
}
startEpoch := abi.ChainEpoch(1)
if cctx.IsSet("start-at") {
startEpoch = abi.ChainEpoch(cctx.Int64("start-at"))
start, err := cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(cctx.Int64("start-at")), head, true)
if err != nil {
return err
}
err = cs.SetHead(start)
if err != nil {
return err
}
}
if h := cctx.Int64("height"); h != 0 {
tsh, err := cs.GetTipsetByHeight(context.TODO(), abi.ChainEpoch(h), head, true)
if err != nil {
@@ -134,7 +253,7 @@ var importBenchCmd = &cli.Command{
ts := head
tschain := []*types.TipSet{ts}
for ts.Height() != 0 {
for ts.Height() > startEpoch {
next, err := cs.LoadTipSet(ts.Parents())
if err != nil {
return err
@@ -144,45 +263,48 @@ var importBenchCmd = &cli.Command{
ts = next
}
ibj, err := os.Create("import-bench.json")
if err != nil {
return err
var enc *json.Encoder
if cctx.Bool("export-traces") {
ibj, err := os.Create("import-bench.json")
if err != nil {
return err
}
defer ibj.Close() //nolint:errcheck
enc = json.NewEncoder(ibj)
}
defer ibj.Close() //nolint:errcheck
enc := json.NewEncoder(ibj)
var lastTse *TipSetExec
lastState := tschain[len(tschain)-1].ParentState()
for i := len(tschain) - 2; i >= 0; i-- {
for i := len(tschain) - 1; i >= 1; i-- {
cur := tschain[i]
start := time.Now()
log.Infof("computing state (height: %d, ts=%s)", cur.Height(), cur.Cids())
if cur.ParentState() != lastState {
lastTrace := lastTse.Trace
st, trace, err := stm.ExecutionTrace(context.TODO(), cur)
if err != nil {
return err
}
tse := &TipSetExec{
TipSet: cur.Key(),
Trace: trace,
Duration: time.Since(start),
}
if enc != nil {
stripCallers(tse.Trace)
if err := enc.Encode(tse); err != nil {
return xerrors.Errorf("failed to write out tipsetexec: %w", err)
}
}
if tschain[i-1].ParentState() != st {
stripCallers(tse.Trace)
lastTrace := tse.Trace
d, err := json.MarshalIndent(lastTrace, "", " ")
if err != nil {
panic(err)
}
fmt.Println("TRACE")
fmt.Println(string(d))
return xerrors.Errorf("tipset chain had state mismatch at height %d (%s != %s)", cur.Height(), cur.ParentState(), lastState)
}
start := time.Now()
st, trace, err := stm.ExecutionTrace(context.TODO(), cur)
if err != nil {
return err
}
stripCallers(trace)
lastTse = &TipSetExec{
TipSet: cur.Key(),
Trace: trace,
Duration: time.Since(start),
}
lastState = st
if err := enc.Encode(lastTse); err != nil {
return xerrors.Errorf("failed to write out tipsetexec: %w", err)
//fmt.Println(statediff.Diff(context.Background(), bs, tschain[i-1].ParentState(), st, statediff.ExpandActors))
return xerrors.Errorf("tipset chain had state mismatch at height %d (%s != %s)", cur.Height(), cur.ParentState(), st)
}
}
+3 -3
View File
@@ -27,11 +27,11 @@ import (
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper/basicfs"
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-storage/storage"
lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/genesis"
)
@@ -76,8 +76,6 @@ func main() {
log.Info("Starting lotus-bench")
miner.SupportedProofTypes[abi.RegisteredSealProof_StackedDrg2KiBV1] = struct{}{}
app := &cli.App{
Name: "lotus-bench",
Usage: "Benchmark performance of lotus on your hardware",
@@ -147,6 +145,8 @@ var sealBenchCmd = &cli.Command{
},
},
Action: func(c *cli.Context) error {
policy.AddSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
if c.Bool("no-gpu") {
err := os.Setenv("BELLMAN_NO_GPU", "1")
if err != nil {
+5 -1
View File
@@ -684,7 +684,11 @@ func (p *Processor) diffMinerPartitions(ctx context.Context, m minerActorInfo, e
return err
}
curMiner := m.state
if !prevMiner.DeadlinesChanged(curMiner) {
dc, err := prevMiner.DeadlinesChanged(curMiner)
if err != nil {
return err
}
if !dc {
return nil
}
panic("TODO")
+7 -18
View File
@@ -12,10 +12,10 @@ import (
"strconv"
"time"
"github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2"
@@ -28,11 +28,11 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/tools/stats"
)
@@ -375,7 +375,7 @@ func (r *refunder) ProcessTipset(ctx context.Context, tipset *types.TipSet, refu
continue
}
if a.Code != builtin.StorageMinerActorCodeID {
if !a.IsStorageMinerActor() {
continue
}
@@ -396,24 +396,13 @@ func (r *refunder) ProcessTipset(ctx context.Context, tipset *types.TipSet, refu
var sn abi.SectorNumber
nv, err := r.api.StateNetworkVersion(ctx, tipset.Key())
if err != nil {
log.Warnw("failed to get network version")
var proveCommitSector miner0.ProveCommitSectorParams
if err := proveCommitSector.UnmarshalCBOR(bytes.NewBuffer(m.Params)); err != nil {
log.Warnw("failed to decode provecommit params", "err", err, "method", messageMethod, "cid", msg.Cid, "miner", m.To)
continue
}
if nv < build.ActorUpgradeNetworkVersion {
var proveCommitSector miner0.ProveCommitSectorParams
if err := proveCommitSector.UnmarshalCBOR(bytes.NewBuffer(m.Params)); err != nil {
log.Warnw("failed to decode provecommit params", "err", err, "method", messageMethod, "cid", msg.Cid, "miner", m.To)
continue
}
sn = proveCommitSector.SectorNumber
} else {
// TODO: ActorUpgrade
sn = 0
}
sn = proveCommitSector.SectorNumber
// We use the parent tipset key because precommit information is removed when ProveCommitSector is executed
precommitChainInfo, err := r.api.StateSectorPreCommitInfo(ctx, m.To, sn, tipset.Parents())
+7
View File
@@ -109,6 +109,11 @@ var runCmd = &cli.Command{
Name: "no-local-storage",
Usage: "don't use storageminer repo for sector storage",
},
&cli.BoolFlag{
Name: "no-swap",
Usage: "don't use swap",
Value: false,
},
&cli.BoolFlag{
Name: "addpiece",
Usage: "enable addpiece",
@@ -346,6 +351,7 @@ var runCmd = &cli.Command{
LocalWorker: sectorstorage.NewLocalWorker(sectorstorage.WorkerConfig{
SealProof: spt,
TaskTypes: taskTypes,
NoSwap: cctx.Bool("no-swap"),
}, remote, localStore, nodeApi),
localStore: localStore,
ls: lr,
@@ -465,6 +471,7 @@ func watchMinerConn(ctx context.Context, cctx *cli.Context, nodeApi api.StorageM
"run",
fmt.Sprintf("--listen=%s", cctx.String("listen")),
fmt.Sprintf("--no-local-storage=%t", cctx.Bool("no-local-storage")),
fmt.Sprintf("--no-swap=%t", cctx.Bool("no-swap")),
fmt.Sprintf("--addpiece=%t", cctx.Bool("addpiece")),
fmt.Sprintf("--precommit1=%t", cctx.Bool("precommit1")),
fmt.Sprintf("--unseal=%t", cctx.Bool("unseal")),
+159 -17
View File
@@ -3,15 +3,24 @@ package main
import (
"context"
"fmt"
"strconv"
"github.com/docker/go-units"
lotusbuiltin "github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
@@ -21,9 +30,6 @@ import (
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/util/adt"
)
type accountInfo struct {
@@ -45,6 +51,7 @@ var auditsCmd = &cli.Command{
Subcommands: []*cli.Command{
chainBalanceCmd,
chainBalanceStateCmd,
chainPledgeCmd,
},
}
@@ -90,7 +97,7 @@ var chainBalanceCmd = &cli.Command{
Type: string(act.Code.Hash()[2:]),
}
if act.Code == builtin.StorageMinerActorCodeID {
if act.IsStorageMinerActor() {
pow, err := api.StateMinerPower(ctx, addr, tsk)
if err != nil {
return xerrors.Errorf("failed to get power: %w", err)
@@ -167,10 +174,10 @@ var chainBalanceStateCmd = &cli.Command{
cs := store.NewChainStore(bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier))
cst := cbor.NewCborStore(bs)
store := adt.WrapStore(ctx, cst)
sm := stmgr.NewStateManager(cs)
// Options: (a) encode the version in the chain or (b) pass a flag.
tree, err := state.LoadStateTree(cst, sroot)
if err != nil {
return err
@@ -191,7 +198,7 @@ var chainBalanceStateCmd = &cli.Command{
PreCommits: types.FIL(big.NewInt(0)),
}
if act.Code == builtin.StorageMinerActorCodeID && minerInfo {
if minerInfo && act.IsStorageMinerActor() {
pow, _, _, err := stmgr.GetPowerRaw(ctx, sm, sroot, addr)
if err != nil {
return xerrors.Errorf("failed to get power: %w", err)
@@ -199,24 +206,29 @@ var chainBalanceStateCmd = &cli.Command{
ai.Power = pow.RawBytePower
var st miner.State
if err := cst.Get(ctx, act.Head, &st); err != nil {
st, err := miner.Load(store, act)
if err != nil {
return xerrors.Errorf("failed to read miner state: %w", err)
}
sectors, err := adt.AsArray(cs.Store(ctx), st.Sectors)
liveSectorCount, err := st.NumLiveSectors()
if err != nil {
return xerrors.Errorf("failed to load sector set: %w", err)
return xerrors.Errorf("failed to compute live sector count: %w", err)
}
ai.InitialPledge = types.FIL(st.InitialPledgeRequirement)
ai.LockedFunds = types.FIL(st.LockedFunds)
ai.PreCommits = types.FIL(st.PreCommitDeposits)
ai.Sectors = sectors.Length()
lockedFunds, err := st.LockedFunds()
if err != nil {
return xerrors.Errorf("failed to compute locked funds: %w", err)
}
var minfo miner.MinerInfo
if err := cst.Get(ctx, st.Info, &minfo); err != nil {
return xerrors.Errorf("failed to read miner info: %w", err)
ai.InitialPledge = types.FIL(lockedFunds.InitialPledgeRequirement)
ai.LockedFunds = types.FIL(lockedFunds.VestingFunds)
ai.PreCommits = types.FIL(lockedFunds.PreCommitDeposits)
ai.Sectors = liveSectorCount
minfo, err := st.Info()
if err != nil {
return xerrors.Errorf("failed to get miner info: %w", err)
}
ai.Worker = minfo.Worker
@@ -244,3 +256,133 @@ var chainBalanceStateCmd = &cli.Command{
return nil
},
}
var chainPledgeCmd = &cli.Command{
Name: "stateroot-pledge",
Description: "Calculate sector pledge numbers",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo",
Value: "~/.lotus",
},
},
ArgsUsage: "[stateroot epoch]",
Action: func(cctx *cli.Context) error {
logging.SetLogLevel("badger", "ERROR")
ctx := context.TODO()
if !cctx.Args().Present() {
return fmt.Errorf("must pass state root")
}
sroot, err := cid.Decode(cctx.Args().First())
if err != nil {
return fmt.Errorf("failed to parse input: %w", err)
}
epoch, err := strconv.ParseInt(cctx.Args().Get(1), 10, 64)
if err != nil {
return xerrors.Errorf("parsing epoch arg: %w", err)
}
fsrepo, err := repo.NewFS(cctx.String("repo"))
if err != nil {
return err
}
lkrepo, err := fsrepo.Lock(repo.FullNode)
if err != nil {
return err
}
defer lkrepo.Close() //nolint:errcheck
ds, err := lkrepo.Datastore("/chain")
if err != nil {
return err
}
mds, err := lkrepo.Datastore("/metadata")
if err != nil {
return err
}
bs := blockstore.NewBlockstore(ds)
cs := store.NewChainStore(bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier))
cst := cbor.NewCborStore(bs)
store := adt.WrapStore(ctx, cst)
sm := stmgr.NewStateManager(cs)
state, err := state.LoadStateTree(cst, sroot)
if err != nil {
return err
}
var (
powerSmoothed lotusbuiltin.FilterEstimate
pledgeCollateral abi.TokenAmount
)
if act, err := state.GetActor(power.Address); err != nil {
return xerrors.Errorf("loading miner actor: %w", err)
} else if s, err := power.Load(store, act); err != nil {
return xerrors.Errorf("loading power actor state: %w", err)
} else if p, err := s.TotalPowerSmoothed(); err != nil {
return xerrors.Errorf("failed to determine total power: %w", err)
} else if c, err := s.TotalLocked(); err != nil {
return xerrors.Errorf("failed to determine pledge collateral: %w", err)
} else {
powerSmoothed = p
pledgeCollateral = c
}
circ, err := sm.GetCirculatingSupplyDetailed(ctx, abi.ChainEpoch(epoch), state)
if err != nil {
return err
}
fmt.Println("(real) circulating supply: ", types.FIL(circ.FilCirculating))
if circ.FilCirculating.LessThan(big.Zero()) {
circ.FilCirculating = big.Zero()
}
rewardActor, err := state.GetActor(reward.Address)
if err != nil {
return xerrors.Errorf("loading miner actor: %w", err)
}
rewardState, err := reward.Load(store, rewardActor)
if err != nil {
return xerrors.Errorf("loading reward actor state: %w", err)
}
fmt.Println("FilVested", types.FIL(circ.FilVested))
fmt.Println("FilMined", types.FIL(circ.FilMined))
fmt.Println("FilBurnt", types.FIL(circ.FilBurnt))
fmt.Println("FilLocked", types.FIL(circ.FilLocked))
fmt.Println("FilCirculating", types.FIL(circ.FilCirculating))
for _, sectorWeight := range []abi.StoragePower{
types.NewInt(32 << 30),
types.NewInt(64 << 30),
types.NewInt(32 << 30 * 10),
types.NewInt(64 << 30 * 10),
} {
initialPledge, err := rewardState.InitialPledgeForPower(
sectorWeight,
pledgeCollateral,
&powerSmoothed,
circ.FilCirculating,
)
if err != nil {
return xerrors.Errorf("calculating initial pledge: %w", err)
}
fmt.Println("IP ", units.HumanSize(float64(sectorWeight.Uint64())), types.FIL(initialPledge))
}
return nil
},
}
+286
View File
@@ -0,0 +1,286 @@
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/client"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/multiformats/go-multiaddr"
"github.com/urfave/cli/v2"
)
var consensusCmd = &cli.Command{
Name: "consensus",
Usage: "tools for gathering information about consensus between nodes",
Flags: []cli.Flag{},
Subcommands: []*cli.Command{
consensusCheckCmd,
},
}
type consensusItem struct {
multiaddr multiaddr.Multiaddr
genesisTipset *types.TipSet
targetTipset *types.TipSet
headTipset *types.TipSet
peerID peer.ID
version api.Version
api api.FullNode
}
var consensusCheckCmd = &cli.Command{
Name: "check",
Usage: "verify if all nodes agree upon a common tipset for a given tipset height",
Description: `Consensus check verifies that all nodes share a common tipset for a given
height.
The height flag specifies a chain height to start a comparison from. There are two special
arguments for this flag. All other expected values should be chain tipset heights.
@common - Use the maximum common chain height between all nodes
@expected - Use the current time and the genesis timestamp to determine a height
Examples
Find the highest common tipset and look back 10 tipsets
lotus-shed consensus check --height @common --lookback 10
Calculate the expected tipset height and look back 10 tipsets
lotus-shed consensus check --height @expected --lookback 10
Check if nodes all share a common genesis
lotus-shed consensus check --height 0
Check that all nodes agree upon the tipset for 1day post genesis
lotus-shed consensus check --height 2880 --lookback 0
`,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "height",
Value: "@common",
Usage: "height of tipset to start check from",
},
&cli.IntFlag{
Name: "lookback",
Value: int(build.MessageConfidence * 2),
Usage: "number of tipsets behind to look back when comparing nodes",
},
},
Action: func(cctx *cli.Context) error {
filePath := cctx.Args().First()
var input *bufio.Reader
if cctx.Args().Len() == 0 {
input = bufio.NewReader(os.Stdin)
} else {
var err error
inputFile, err := os.Open(filePath)
if err != nil {
return err
}
defer inputFile.Close() //nolint:errcheck
input = bufio.NewReader(inputFile)
}
var nodes []*consensusItem
ctx := lcli.ReqContext(cctx)
for {
strma, errR := input.ReadString('\n')
strma = strings.TrimSpace(strma)
if len(strma) == 0 {
if errR == io.EOF {
break
}
continue
}
apima, err := multiaddr.NewMultiaddr(strma)
if err != nil {
return err
}
ainfo := lcli.APIInfo{Addr: apima}
addr, err := ainfo.DialArgs()
if err != nil {
return err
}
api, closer, err := client.NewFullNodeRPC(cctx.Context, addr, nil)
if err != nil {
return err
}
defer closer()
peerID, err := api.ID(ctx)
if err != nil {
return err
}
version, err := api.Version(ctx)
if err != nil {
return err
}
genesisTipset, err := api.ChainGetGenesis(ctx)
if err != nil {
return err
}
headTipset, err := api.ChainHead(ctx)
if err != nil {
return err
}
nodes = append(nodes, &consensusItem{
genesisTipset: genesisTipset,
headTipset: headTipset,
multiaddr: apima,
api: api,
peerID: peerID,
version: version,
})
if errR != nil && errR != io.EOF {
return err
}
if errR == io.EOF {
break
}
}
if len(nodes) == 0 {
return fmt.Errorf("no nodes")
}
genesisBuckets := make(map[types.TipSetKey][]*consensusItem)
for _, node := range nodes {
genesisBuckets[node.genesisTipset.Key()] = append(genesisBuckets[node.genesisTipset.Key()], node)
}
if len(genesisBuckets) != 1 {
for _, nodes := range genesisBuckets {
for _, node := range nodes {
log.Errorw(
"genesis do not match",
"genesis_tipset", node.genesisTipset.Key(),
"peer_id", node.peerID,
"version", node.version,
)
}
}
return fmt.Errorf("genesis does not match between all nodes")
}
target := abi.ChainEpoch(0)
switch cctx.String("height") {
case "@common":
minTipset := nodes[0].headTipset
for _, node := range nodes {
if node.headTipset.Height() < minTipset.Height() {
minTipset = node.headTipset
}
}
target = minTipset.Height()
case "@expected":
tnow := uint64(time.Now().Unix())
tgen := nodes[0].genesisTipset.MinTimestamp()
target = abi.ChainEpoch((tnow - tgen) / build.BlockDelaySecs)
default:
h, err := strconv.Atoi(strings.TrimSpace(cctx.String("height")))
if err != nil {
return fmt.Errorf("failed to parse string: %s", cctx.String("height"))
}
target = abi.ChainEpoch(h)
}
lookback := abi.ChainEpoch(cctx.Int("lookback"))
if lookback > target {
target = abi.ChainEpoch(0)
} else {
target = target - lookback
}
for _, node := range nodes {
targetTipset, err := node.api.ChainGetTipSetByHeight(ctx, target, types.EmptyTSK)
if err != nil {
log.Errorw("error checking target", "err", err)
node.targetTipset = nil
} else {
node.targetTipset = targetTipset
}
}
for _, node := range nodes {
log.Debugw(
"node info",
"peer_id", node.peerID,
"version", node.version,
"genesis_tipset", node.genesisTipset.Key(),
"head_tipset", node.headTipset.Key(),
"target_tipset", node.targetTipset.Key(),
)
}
targetBuckets := make(map[types.TipSetKey][]*consensusItem)
for _, node := range nodes {
if node.targetTipset == nil {
targetBuckets[types.EmptyTSK] = append(targetBuckets[types.EmptyTSK], node)
continue
}
targetBuckets[node.targetTipset.Key()] = append(targetBuckets[node.targetTipset.Key()], node)
}
if nodes, ok := targetBuckets[types.EmptyTSK]; ok {
for _, node := range nodes {
log.Errorw(
"targeted tipset not found",
"peer_id", node.peerID,
"version", node.version,
"genesis_tipset", node.genesisTipset.Key(),
"head_tipset", node.headTipset.Key(),
"target_tipset", node.targetTipset.Key(),
)
}
return fmt.Errorf("targeted tipset not found")
}
if len(targetBuckets) != 1 {
for _, nodes := range targetBuckets {
for _, node := range nodes {
log.Errorw(
"targeted tipset not found",
"peer_id", node.peerID,
"version", node.version,
"genesis_tipset", node.genesisTipset.Key(),
"head_tipset", node.headTipset.Key(),
"target_tipset", node.targetTipset.Key(),
)
}
}
return fmt.Errorf("nodes not in consensus at tipset height %d", target)
}
return nil
},
}
+325
View File
@@ -0,0 +1,325 @@
package main
import (
"context"
"encoding/json"
"net"
"net/http"
"sync"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/ipfs/go-cid"
"github.com/urfave/cli/v2"
)
type dealStatsServer struct {
api api.FullNode
}
// Requested by @jbenet
// How many epochs back to look at for dealstats
var epochLookback = abi.ChainEpoch(10)
// these lists grow continuously with the network
// TODO: need to switch this to an LRU of sorts, to ensure refreshes
var knownFiltered = new(sync.Map)
var resolvedWallets = new(sync.Map)
func init() {
for _, a := range []string{
"t0100", // client for genesis miner
"t0101", // client for genesis miner
"t0102", // client for genesis miner
"t0112", // client for genesis miner
"t0113", // client for genesis miner
"t0114", // client for genesis miner
"t1nslxql4pck5pq7hddlzym3orxlx35wkepzjkm3i", // SR1 dealbot wallet
"t1stghxhdp2w53dym2nz2jtbpk6ccd4l2lxgmezlq", // SR1 dealbot wallet
"t1mcr5xkgv4jdl3rnz77outn6xbmygb55vdejgbfi", // SR1 dealbot wallet
"t1qiqdbbmrdalbntnuapriirduvxu5ltsc5mhy7si", // SR1 dealbot wallet
} {
a, err := address.NewFromString(a)
if err != nil {
panic(err)
}
knownFiltered.Store(a, true)
}
}
type dealCountResp struct {
Epoch int64 `json:"epoch"`
Endpoint string `json:"endpoint"`
Payload int64 `json:"payload"`
}
func (dss *dealStatsServer) handleStorageDealCount(w http.ResponseWriter, r *http.Request) {
epoch, deals := dss.filteredDealList()
if epoch == 0 {
w.WriteHeader(500)
return
}
if err := json.NewEncoder(w).Encode(&dealCountResp{
Endpoint: "COUNT_DEALS",
Payload: int64(len(deals)),
Epoch: epoch,
}); err != nil {
log.Warnf("failed to write back deal count response: %s", err)
return
}
}
type dealAverageResp struct {
Epoch int64 `json:"epoch"`
Endpoint string `json:"endpoint"`
Payload int64 `json:"payload"`
}
func (dss *dealStatsServer) handleStorageDealAverageSize(w http.ResponseWriter, r *http.Request) {
epoch, deals := dss.filteredDealList()
if epoch == 0 {
w.WriteHeader(500)
return
}
var totalBytes int64
for _, d := range deals {
totalBytes += int64(d.deal.Proposal.PieceSize.Unpadded())
}
if err := json.NewEncoder(w).Encode(&dealAverageResp{
Endpoint: "AVERAGE_DEAL_SIZE",
Payload: totalBytes / int64(len(deals)),
Epoch: epoch,
}); err != nil {
log.Warnf("failed to write back deal average response: %s", err)
return
}
}
type dealTotalResp struct {
Epoch int64 `json:"epoch"`
Endpoint string `json:"endpoint"`
Payload int64 `json:"payload"`
}
func (dss *dealStatsServer) handleStorageDealTotalReal(w http.ResponseWriter, r *http.Request) {
epoch, deals := dss.filteredDealList()
if epoch == 0 {
w.WriteHeader(500)
return
}
var totalBytes int64
for _, d := range deals {
totalBytes += int64(d.deal.Proposal.PieceSize.Unpadded())
}
if err := json.NewEncoder(w).Encode(&dealTotalResp{
Endpoint: "DEAL_BYTES",
Payload: totalBytes,
Epoch: epoch,
}); err != nil {
log.Warnf("failed to write back deal average response: %s", err)
return
}
}
type clientStatsOutput struct {
Epoch int64 `json:"epoch"`
Endpoint string `json:"endpoint"`
Payload []*clientStats `json:"payload"`
}
type clientStats struct {
Client address.Address `json:"client"`
DataSize int64 `json:"data_size"`
NumCids int `json:"num_cids"`
NumDeals int `json:"num_deals"`
NumMiners int `json:"num_miners"`
cids map[cid.Cid]bool
providers map[address.Address]bool
}
func (dss *dealStatsServer) handleStorageClientStats(w http.ResponseWriter, r *http.Request) {
epoch, deals := dss.filteredDealList()
if epoch == 0 {
w.WriteHeader(500)
return
}
stats := make(map[address.Address]*clientStats)
for _, d := range deals {
st, ok := stats[d.deal.Proposal.Client]
if !ok {
st = &clientStats{
Client: d.resolvedWallet,
cids: make(map[cid.Cid]bool),
providers: make(map[address.Address]bool),
}
stats[d.deal.Proposal.Client] = st
}
st.DataSize += int64(d.deal.Proposal.PieceSize.Unpadded())
st.cids[d.deal.Proposal.PieceCID] = true
st.providers[d.deal.Proposal.Provider] = true
st.NumDeals++
}
out := clientStatsOutput{
Epoch: epoch,
Endpoint: "CLIENT_DEAL_STATS",
Payload: make([]*clientStats, 0, len(stats)),
}
for _, cs := range stats {
cs.NumCids = len(cs.cids)
cs.NumMiners = len(cs.providers)
out.Payload = append(out.Payload, cs)
}
if err := json.NewEncoder(w).Encode(out); err != nil {
log.Warnf("failed to write back client stats response: %s", err)
return
}
}
type dealInfo struct {
deal api.MarketDeal
resolvedWallet address.Address
}
// filteredDealList returns the current epoch and a list of filtered deals
// on error returns an epoch of 0
func (dss *dealStatsServer) filteredDealList() (int64, map[string]dealInfo) {
ctx := context.Background()
head, err := dss.api.ChainHead(ctx)
if err != nil {
log.Warnf("failed to get chain head: %s", err)
return 0, nil
}
head, err = dss.api.ChainGetTipSetByHeight(ctx, head.Height()-epochLookback, head.Key())
if err != nil {
log.Warnf("failed to walk back %s epochs: %s", epochLookback, err)
return 0, nil
}
// Disabled as per @pooja's request
//
// // Exclude any address associated with a miner
// miners, err := dss.api.StateListMiners(ctx, head.Key())
// if err != nil {
// log.Warnf("failed to get miner list: %s", err)
// return 0, nil
// }
// for _, m := range miners {
// info, err := dss.api.StateMinerInfo(ctx, m, head.Key())
// if err != nil {
// log.Warnf("failed to get info for known miner '%s': %s", m, err)
// continue
// }
// knownFiltered.Store(info.Owner, true)
// knownFiltered.Store(info.Worker, true)
// for _, a := range info.ControlAddresses {
// knownFiltered.Store(a, true)
// }
// }
deals, err := dss.api.StateMarketDeals(ctx, head.Key())
if err != nil {
log.Warnf("failed to get market deals: %s", err)
return 0, nil
}
ret := make(map[string]dealInfo, len(deals))
for dealKey, d := range deals {
// Counting no-longer-active deals as per Pooja's request
// // https://github.com/filecoin-project/specs-actors/blob/v0.9.9/actors/builtin/market/deal.go#L81-L85
// if d.State.SectorStartEpoch < 0 {
// continue
// }
if _, isFiltered := knownFiltered.Load(d.Proposal.Client); isFiltered {
continue
}
if _, wasSeen := resolvedWallets.Load(d.Proposal.Client); !wasSeen {
w, err := dss.api.StateAccountKey(ctx, d.Proposal.Client, head.Key())
if err != nil {
log.Warnf("failed to resolve id '%s' to wallet address: %s", d.Proposal.Client, err)
continue
} else {
resolvedWallets.Store(d.Proposal.Client, w)
}
}
w, _ := resolvedWallets.Load(d.Proposal.Client)
if _, isFiltered := knownFiltered.Load(w); isFiltered {
continue
}
ret[dealKey] = dealInfo{
deal: d,
resolvedWallet: w.(address.Address),
}
}
return int64(head.Height()), ret
}
var serveDealStatsCmd = &cli.Command{
Name: "serve-deal-stats",
Flags: []cli.Flag{},
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)
_ = ctx
dss := &dealStatsServer{api}
mux := &http.ServeMux{}
mux.HandleFunc("/api/storagedeal/count", dss.handleStorageDealCount)
mux.HandleFunc("/api/storagedeal/averagesize", dss.handleStorageDealAverageSize)
mux.HandleFunc("/api/storagedeal/totalreal", dss.handleStorageDealTotalReal)
mux.HandleFunc("/api/storagedeal/clientstats", dss.handleStorageClientStats)
s := &http.Server{
Addr: ":7272",
Handler: mux,
}
go func() {
<-ctx.Done()
if err := s.Shutdown(context.TODO()); err != nil {
log.Error(err)
}
}()
list, err := net.Listen("tcp", ":7272") // nolint
if err != nil {
panic(err)
}
log.Warnf("deal-stat server listening on %s\n== NOTE: QUERIES ARE EXPENSIVE - YOU MUST FRONT-CACHE THIS SERVICE\n", list.Addr().String())
return s.Serve(list)
},
}
+36 -21
View File
@@ -14,16 +14,17 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin/account"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/specs-actors/actors/builtin"
saacc "github.com/filecoin-project/specs-actors/actors/builtin/account"
saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner"
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
)
type addrInfo struct {
@@ -90,36 +91,50 @@ var genesisVerifyCmd = &cli.Command{
kminers := make(map[address.Address]minerInfo)
ctx := context.TODO()
store := adt.WrapStore(ctx, cst)
if err := stree.ForEach(func(addr address.Address, act *types.Actor) error {
switch act.Code {
case builtin.StorageMinerActorCodeID:
var st saminer.State
if err := cst.Get(ctx, act.Head, &st); err != nil {
return err
switch {
case act.IsStorageMinerActor():
_, err := miner.Load(store, act)
if err != nil {
return xerrors.Errorf("miner actor: %w", err)
}
// TODO: actually verify something here?
kminers[addr] = minerInfo{}
case act.IsMultisigActor():
st, err := multisig.Load(store, act)
if err != nil {
return xerrors.Errorf("multisig actor: %w", err)
}
kminers[addr] = minerInfo{}
case builtin.MultisigActorCodeID:
var st samsig.State
if err := cst.Get(ctx, act.Head, &st); err != nil {
signers, err := st.Signers()
if err != nil {
return xerrors.Errorf("multisig actor: %w", err)
}
threshold, err := st.Threshold()
if err != nil {
return xerrors.Errorf("multisig actor: %w", err)
}
kmultisigs[addr] = msigInfo{
Balance: types.FIL(act.Balance),
Signers: st.Signers,
Threshold: st.NumApprovalsThreshold,
Signers: signers,
Threshold: threshold,
}
msigAddrs = append(msigAddrs, addr)
case builtin.AccountActorCodeID:
var st saacc.State
if err := cst.Get(ctx, act.Head, &st); err != nil {
log.Warn(xerrors.Errorf("account actor %s: %w", addr, err))
case act.IsAccountActor():
st, err := account.Load(store, act)
if err != nil {
// TODO: magik6k: this _used_ to log instead of failing, why?
return xerrors.Errorf("account actor %s: %w", addr, err)
}
pkaddr, err := st.PubkeyAddress()
if err != nil {
return xerrors.Errorf("failed to get actor pk address %s: %w", addr, err)
}
kaccounts[addr] = addrInfo{
Key: st.Address,
Key: pkaddr,
Balance: types.FIL(act.Balance.Copy()),
}
accAddrs = append(accAddrs, addr)
+57
View File
@@ -1,10 +1,13 @@
package main
import (
"encoding/hex"
"fmt"
"io"
"os"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"github.com/ipld/go-car"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
@@ -81,3 +84,57 @@ var importCarCmd = &cli.Command{
}
},
}
var importObjectCmd = &cli.Command{
Name: "import-obj",
Usage: "import a raw ipld object into your datastore",
Action: func(cctx *cli.Context) error {
r, err := repo.NewFS(cctx.String("repo"))
if err != nil {
return xerrors.Errorf("opening fs repo: %w", err)
}
exists, err := r.Exists()
if err != nil {
return err
}
if !exists {
return xerrors.Errorf("lotus repo doesn't exist")
}
lr, err := r.Lock(repo.FullNode)
if err != nil {
return err
}
defer lr.Close() //nolint:errcheck
ds, err := lr.Datastore("/chain")
if err != nil {
return err
}
bs := blockstore.NewBlockstore(ds)
c, err := cid.Decode(cctx.Args().Get(0))
if err != nil {
return err
}
data, err := hex.DecodeString(cctx.Args().Get(1))
if err != nil {
return err
}
blk, err := block.NewBlockWithCid(data, c)
if err != nil {
return err
}
if err := bs.Put(blk); err != nil {
return err
}
return nil
},
}
+11
View File
@@ -25,6 +25,7 @@ func main() {
staterootCmd,
auditsCmd,
importCarCmd,
importObjectCmd,
commpToCidCmd,
fetchParamCmd,
proofsCmd,
@@ -35,6 +36,9 @@ func main() {
mathCmd,
mpoolStatsCmd,
exportChainCmd,
consensusCmd,
serveDealStatsCmd,
syncCmd,
}
app := &cli.App{
@@ -49,6 +53,13 @@ func main() {
Hidden: true,
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME
},
&cli.StringFlag{
Name: "log-level",
Value: "info",
},
},
Before: func(cctx *cli.Context) error {
return logging.SetLogLevel("lotus-shed", cctx.String("log-level"))
},
}
+4 -3
View File
@@ -14,11 +14,12 @@ import (
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/go-address"
lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/specs-actors/actors/builtin"
)
var (
@@ -121,7 +122,7 @@ var mpoolStatsCmd = &cli.Command{
return false, err
}
ism := act.Code == builtin.StorageMinerActorCodeID
ism := act.IsStorageMinerActor()
mcache[addr] = ism
return ism, nil
}
@@ -143,7 +144,7 @@ var mpoolStatsCmd = &cli.Command{
seen: time.Now(),
}
if u.Message.Message.Method == builtin.MethodsMiner.SubmitWindowedPoSt {
if u.Message.Message.Method == builtin0.MethodsMiner.SubmitWindowedPoSt {
miner, err := isMiner(u.Message.Message.To)
if err != nil {
+14
View File
@@ -182,6 +182,11 @@ var staterootStatCmd = &cli.Command{
return infos[i].Stat.Size > infos[j].Stat.Size
})
var totalActorsSize uint64
for _, info := range infos {
totalActorsSize += info.Stat.Size
}
outcap := 10
if cctx.Args().Len() > outcap {
outcap = cctx.Args().Len()
@@ -190,6 +195,15 @@ var staterootStatCmd = &cli.Command{
outcap = len(infos)
}
totalStat, err := api.ChainStatObj(ctx, ts.ParentState(), cid.Undef)
if err != nil {
return err
}
fmt.Println("Total state tree size: ", totalStat.Size)
fmt.Println("Sum of actor state size: ", totalActorsSize)
fmt.Println("State tree structure size: ", totalStat.Size-totalActorsSize)
fmt.Print("Addr\tType\tSize\n")
for _, inf := range infos[:outcap] {
cmh, err := multihash.Decode(inf.Actor.Code.Hash())
+64
View File
@@ -0,0 +1,64 @@
package main
import (
"fmt"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/urfave/cli/v2"
)
var syncCmd = &cli.Command{
Name: "sync",
Usage: "tools for diagnosing sync issues",
Flags: []cli.Flag{},
Subcommands: []*cli.Command{
syncValidateCmd,
},
}
var syncValidateCmd = &cli.Command{
Name: "validate",
Usage: "checks whether a provided tipset is valid",
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)
if cctx.Args().Len() < 1 {
fmt.Println("usage: <blockCid1> <blockCid2>...")
fmt.Println("At least one block cid must be provided")
return nil
}
args := cctx.Args().Slice()
var tscids []cid.Cid
for _, s := range args {
c, err := cid.Decode(s)
if err != nil {
return fmt.Errorf("block cid was invalid: %s", err)
}
tscids = append(tscids, c)
}
tsk := types.NewTipSetKey(tscids...)
valid, err := api.SyncValidateTipset(ctx, tsk)
if err != nil {
fmt.Println("Tipset is invalid: ", err)
}
if valid {
fmt.Println("Tipset is valid")
}
return nil
},
}
+37 -63
View File
@@ -8,13 +8,15 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/util/adt"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
cbor "github.com/ipfs/go-ipld-cbor"
@@ -57,7 +59,7 @@ var verifRegAddVerifierCmd = &cli.Command{
return err
}
params, err := actors.SerializeParams(&verifreg.AddVerifierParams{Address: target, Allowance: allowance})
params, err := actors.SerializeParams(&verifreg0.AddVerifierParams{Address: target, Allowance: allowance})
if err != nil {
return err
}
@@ -70,9 +72,9 @@ var verifRegAddVerifierCmd = &cli.Command{
ctx := lcli.ReqContext(cctx)
msg := &types.Message{
To: builtin.VerifiedRegistryActorAddr,
To: verifreg.Address,
From: fromk,
Method: builtin.MethodsVerifiedRegistry.AddVerifier,
Method: builtin0.MethodsVerifiedRegistry.AddVerifier,
Params: params,
}
@@ -131,7 +133,7 @@ var verifRegVerifyClientCmd = &cli.Command{
return err
}
params, err := actors.SerializeParams(&verifreg.AddVerifiedClientParams{Address: target, Allowance: allowance})
params, err := actors.SerializeParams(&verifreg0.AddVerifiedClientParams{Address: target, Allowance: allowance})
if err != nil {
return err
}
@@ -144,9 +146,9 @@ var verifRegVerifyClientCmd = &cli.Command{
ctx := lcli.ReqContext(cctx)
msg := &types.Message{
To: builtin.VerifiedRegistryActorAddr,
To: verifreg.Address,
From: fromk,
Method: builtin.MethodsVerifiedRegistry.AddVerifiedClient,
Method: builtin0.MethodsVerifiedRegistry.AddVerifiedClient,
Params: params,
}
@@ -181,7 +183,7 @@ var verifRegListVerifiersCmd = &cli.Command{
defer closer()
ctx := lcli.ReqContext(cctx)
act, err := api.StateGetActor(ctx, builtin.VerifiedRegistryActorAddr, types.EmptyTSK)
act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK)
if err != nil {
return err
}
@@ -189,31 +191,14 @@ var verifRegListVerifiersCmd = &cli.Command{
apibs := apibstore.NewAPIBlockstore(api)
store := adt.WrapStore(ctx, cbor.NewCborStore(apibs))
var st verifreg.State
if err := store.Get(ctx, act.Head, &st); err != nil {
return err
}
vh, err := adt.AsMap(store, st.Verifiers)
st, err := verifreg.Load(store, act)
if err != nil {
return err
}
var dcap verifreg.DataCap
if err := vh.ForEach(&dcap, func(k string) error {
addr, err := address.NewFromBytes([]byte(k))
if err != nil {
return err
}
fmt.Printf("%s: %s\n", addr, dcap)
return nil
}); err != nil {
return st.ForEachVerifier(func(addr address.Address, dcap abi.StoragePower) error {
_, err := fmt.Printf("%s: %s\n", addr, dcap)
return err
}
return nil
})
},
}
@@ -228,7 +213,7 @@ var verifRegListClientsCmd = &cli.Command{
defer closer()
ctx := lcli.ReqContext(cctx)
act, err := api.StateGetActor(ctx, builtin.VerifiedRegistryActorAddr, types.EmptyTSK)
act, err := api.StateGetActor(ctx, verifreg.Address, types.EmptyTSK)
if err != nil {
return err
}
@@ -236,31 +221,14 @@ var verifRegListClientsCmd = &cli.Command{
apibs := apibstore.NewAPIBlockstore(api)
store := adt.WrapStore(ctx, cbor.NewCborStore(apibs))
var st verifreg.State
if err := store.Get(ctx, act.Head, &st); err != nil {
return err
}
vh, err := adt.AsMap(store, st.VerifiedClients)
st, err := verifreg.Load(store, act)
if err != nil {
return err
}
var dcap verifreg.DataCap
if err := vh.ForEach(&dcap, func(k string) error {
addr, err := address.NewFromBytes([]byte(k))
if err != nil {
return err
}
fmt.Printf("%s: %s\n", addr, dcap)
return nil
}); err != nil {
return st.ForEachClient(func(addr address.Address, dcap abi.StoragePower) error {
_, err := fmt.Printf("%s: %s\n", addr, dcap)
return err
}
return nil
})
},
}
@@ -318,7 +286,17 @@ var verifRegCheckVerifierCmd = &cli.Command{
defer closer()
ctx := lcli.ReqContext(cctx)
act, err := api.StateGetActor(ctx, builtin.VerifiedRegistryActorAddr, types.EmptyTSK)
head, err := api.ChainHead(ctx)
if err != nil {
return err
}
vid, err := api.StateLookupID(ctx, vaddr, head.Key())
if err != nil {
return err
}
act, err := api.StateGetActor(ctx, verifreg.Address, head.Key())
if err != nil {
return err
}
@@ -326,20 +304,16 @@ var verifRegCheckVerifierCmd = &cli.Command{
apibs := apibstore.NewAPIBlockstore(api)
store := adt.WrapStore(ctx, cbor.NewCborStore(apibs))
var st verifreg.State
if err := store.Get(ctx, act.Head, &st); err != nil {
return err
}
vh, err := adt.AsMap(store, st.Verifiers)
st, err := verifreg.Load(store, act)
if err != nil {
return err
}
var dcap verifreg.DataCap
if found, err := vh.Get(abi.AddrKey(vaddr), &dcap); err != nil {
found, dcap, err := st.VerifierDataCap(vid)
if err != nil {
return err
} else if !found {
}
if !found {
return fmt.Errorf("not found")
}
+12 -4
View File
@@ -33,6 +33,12 @@ var infoCmd = &cli.Command{
Subcommands: []*cli.Command{
infoAllCmd,
},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "hide-sectors-info",
Usage: "hide sectors info",
},
},
Action: infoCmdAct,
}
@@ -199,10 +205,12 @@ func infoCmdAct(cctx *cli.Context) error {
fmt.Printf("Expected Seal Duration: %s\n\n", sealdur)
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)
if err != nil {
return err
if !cctx.Bool("hide-sectors-info") {
fmt.Println("Sectors:")
err = sectorsInfo(ctx, nodeApi)
if err != nil {
return err
}
}
// TODO: grab actr state / info
+2 -2
View File
@@ -156,12 +156,12 @@ var setAskCmd = &cli.Command{
Flags: []cli.Flag{
&cli.Uint64Flag{
Name: "price",
Usage: "Set the price of the ask for unverified deals (specified as FIL / GiB / Epoch) to `PRICE`",
Usage: "Set the price of the ask for unverified deals (specified as attoFIL / GiB / Epoch) to `PRICE`",
Required: true,
},
&cli.Uint64Flag{
Name: "verified-price",
Usage: "Set the price of the ask for verified deals (specified as FIL / GiB / Epoch) to `PRICE`",
Usage: "Set the price of the ask for verified deals (specified as attoFIL / GiB / Epoch) to `PRICE`",
Required: true,
},
&cli.StringFlag{
+92
View File
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"strconv"
"text/tabwriter"
"github.com/fatih/color"
@@ -22,6 +23,7 @@ var provingCmd = &cli.Command{
Subcommands: []*cli.Command{
provingInfoCmd,
provingDeadlinesCmd,
provingDeadlineInfoCmd,
provingFaultsCmd,
},
}
@@ -279,3 +281,93 @@ var provingDeadlinesCmd = &cli.Command{
return tw.Flush()
},
}
var provingDeadlineInfoCmd = &cli.Command{
Name: "deadline",
Usage: "View the current proving period deadline information by its index ",
ArgsUsage: "<deadlineIdx>",
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 1 {
return xerrors.Errorf("must pass deadline index")
}
dlIdx, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64)
if err != nil {
return xerrors.Errorf("could not parse deadline index: %w", err)
}
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(cctx)
maddr, err := getActorAddress(ctx, nodeApi, cctx.String("actor"))
if err != nil {
return err
}
deadlines, err := api.StateMinerDeadlines(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting deadlines: %w", err)
}
di, err := api.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting deadlines: %w", err)
}
partitions, err := api.StateMinerPartitions(ctx, maddr, dlIdx, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("getting partitions for deadline %d: %w", dlIdx, err)
}
provenPartitions, err := deadlines[dlIdx].PostSubmissions.Count()
if err != nil {
return err
}
fmt.Printf("Deadline Index: %d\n", dlIdx)
fmt.Printf("Partitions: %d\n", len(partitions))
fmt.Printf("Proven Partitions: %d\n", provenPartitions)
fmt.Printf("Current: %t\n\n", di.Index == dlIdx)
for pIdx, partition := range partitions {
sectorCount, err := partition.AllSectors.Count()
if err != nil {
return err
}
sectorNumbers, err := partition.AllSectors.All(sectorCount)
if err != nil {
return err
}
faultsCount, err := partition.FaultySectors.Count()
if err != nil {
return err
}
fn, err := partition.FaultySectors.All(faultsCount)
if err != nil {
return err
}
fmt.Printf("Partition Index: %d\n", pIdx)
fmt.Printf("Sectors: %d\n", sectorCount)
fmt.Printf("Sector Numbers: %v\n", sectorNumbers)
fmt.Printf("Faults: %d\n", faultsCount)
fmt.Printf("Faulty Sectors: %d\n", fn)
}
return nil
},
}
+3 -1
View File
@@ -163,8 +163,10 @@ var runCmd = &cli.Command{
sigChan := make(chan os.Signal, 2)
go func() {
select {
case <-sigChan:
case sig := <-sigChan:
log.Warnw("received shutdown", "signal", sig)
case <-shutdownChan:
log.Warn("received shutdown")
}
log.Warn("Shutting down...")
+118 -25
View File
@@ -5,20 +5,25 @@ import (
"os"
"sort"
"strconv"
"text/tabwriter"
"time"
"github.com/docker/go-units"
"github.com/fatih/color"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/tablewriter"
lcli "github.com/filecoin-project/lotus/cli"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
)
var sectorsCmd = &cli.Command{
@@ -137,7 +142,24 @@ var sectorsStatusCmd = &cli.Command{
var sectorsListCmd = &cli.Command{
Name: "list",
Usage: "List sectors",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "show-removed",
Usage: "show removed sectors",
},
&cli.BoolFlag{
Name: "color",
Aliases: []string{"c"},
Value: true,
},
&cli.BoolFlag{
Name: "fast",
Usage: "don't show on-chain info for better performance",
},
},
Action: func(cctx *cli.Context) error {
color.NoColor = !cctx.Bool("color")
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
@@ -162,53 +184,114 @@ var sectorsListCmd = &cli.Command{
return err
}
activeSet, err := fullApi.StateMinerActiveSectors(ctx, maddr, types.EmptyTSK)
head, err := fullApi.ChainHead(ctx)
if err != nil {
return err
}
activeSet, err := fullApi.StateMinerActiveSectors(ctx, maddr, head.Key())
if err != nil {
return err
}
activeIDs := make(map[abi.SectorNumber]struct{}, len(activeSet))
for _, info := range activeSet {
activeIDs[info.ID] = struct{}{}
activeIDs[info.SectorNumber] = struct{}{}
}
sset, err := fullApi.StateMinerSectors(ctx, maddr, nil, true, types.EmptyTSK)
sset, err := fullApi.StateMinerSectors(ctx, maddr, nil, head.Key())
if err != nil {
return err
}
commitedIDs := make(map[abi.SectorNumber]struct{}, len(activeSet))
for _, info := range sset {
commitedIDs[info.ID] = struct{}{}
commitedIDs[info.SectorNumber] = struct{}{}
}
sort.Slice(list, func(i, j int) bool {
return list[i] < list[j]
})
w := tabwriter.NewWriter(os.Stdout, 8, 4, 1, ' ', 0)
tw := tablewriter.New(
tablewriter.Col("ID"),
tablewriter.Col("State"),
tablewriter.Col("OnChain"),
tablewriter.Col("Active"),
tablewriter.Col("Expiration"),
tablewriter.Col("Deals"),
tablewriter.Col("DealWeight"),
tablewriter.NewLineCol("Error"),
tablewriter.NewLineCol("EarlyExpiration"))
fast := cctx.Bool("fast")
for _, s := range list {
st, err := nodeApi.SectorsStatus(ctx, s, false)
st, err := nodeApi.SectorsStatus(ctx, s, !fast)
if err != nil {
fmt.Fprintf(w, "%d:\tError: %s\n", s, err)
tw.Write(map[string]interface{}{
"ID": s,
"Error": err,
})
continue
}
_, inSSet := commitedIDs[s]
_, inASet := activeIDs[s]
if cctx.Bool("show-removed") || st.State != api.SectorState(sealing.Removed) {
_, inSSet := commitedIDs[s]
_, inASet := activeIDs[s]
fmt.Fprintf(w, "%d: %s\tsSet: %s\tactive: %s\ttktH: %d\tseedH: %d\tdeals: %v\t toUpgrade:%t\n",
s,
st.State,
yesno(inSSet),
yesno(inASet),
st.Ticket.Epoch,
st.Seed.Epoch,
st.Deals,
st.ToUpgrade,
)
dw := .0
if st.Expiration-st.Activation > 0 {
dw = float64(big.Div(st.DealWeight, big.NewInt(int64(st.Expiration-st.Activation))).Uint64())
}
var deals int
for _, deal := range st.Deals {
if deal != 0 {
deals++
}
}
exp := st.Expiration
if st.OnTime > 0 && st.OnTime < exp {
exp = st.OnTime // Can be different when the sector was CC upgraded
}
m := map[string]interface{}{
"ID": s,
"State": color.New(stateOrder[sealing.SectorState(st.State)].col).Sprint(st.State),
"OnChain": yesno(inSSet),
"Active": yesno(inASet),
}
if deals > 0 {
m["Deals"] = color.GreenString("%d", deals)
} else {
m["Deals"] = color.BlueString("CC")
if st.ToUpgrade {
m["Deals"] = color.CyanString("CC(upgrade)")
}
}
if !fast {
if !inSSet {
m["Expiration"] = "n/a"
} else {
m["Expiration"] = lcli.EpochTime(head.Height(), exp)
if !fast && deals > 0 {
m["DealWeight"] = units.BytesSize(dw)
}
if st.Early > 0 {
m["EarlyExpiration"] = color.YellowString(lcli.EpochTime(head.Height(), st.Early))
}
}
}
tw.Write(m)
}
}
return w.Flush()
return tw.Flush(os.Stdout)
},
}
@@ -394,8 +477,9 @@ var sectorsCapacityCollateralCmd = &cli.Command{
}
var sectorsUpdateCmd = &cli.Command{
Name: "update-state",
Usage: "ADVANCED: manually update the state of a sector, this may aid in error recovery",
Name: "update-state",
Usage: "ADVANCED: manually update the state of a sector, this may aid in error recovery",
ArgsUsage: "<sectorNum> <newState>",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
@@ -421,13 +505,22 @@ var sectorsUpdateCmd = &cli.Command{
return xerrors.Errorf("could not parse sector number: %w", err)
}
newState := cctx.Args().Get(1)
if _, ok := sealing.ExistSectorStateList[sealing.SectorState(newState)]; !ok {
fmt.Printf(" \"%s\" is not a valid state. Possible states for sectors are: \n", newState)
for state := range sealing.ExistSectorStateList {
fmt.Printf("%s\n", string(state))
}
return nil
}
return nodeApi.SectorsUpdate(ctx, abi.SectorNumber(id), api.SectorState(cctx.Args().Get(1)))
},
}
func yesno(b bool) string {
if b {
return "YES"
return color.GreenString("YES")
}
return "NO"
return color.RedString("NO")
}
+1 -1
View File
@@ -370,7 +370,7 @@ var storageFindCmd = &cli.Command{
}
fmt.Printf("In %s (%s)\n", info.id, types[:len(types)-2])
fmt.Printf("\tSealing: %t; Storage: %t\n", info.store.CanSeal, info.store.CanSeal)
fmt.Printf("\tSealing: %t; Storage: %t\n", info.store.CanSeal, info.store.CanStore)
if localPath, ok := local[info.id]; ok {
fmt.Printf("\tLocal (%s)\n", localPath)
} else {
+64 -14
View File
@@ -3,11 +3,14 @@
package main
import (
"bufio"
"context"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"runtime/pprof"
"strings"
@@ -23,6 +26,7 @@ import (
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
"golang.org/x/xerrors"
"gopkg.in/cheggaaa/pb.v1"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
@@ -100,11 +104,11 @@ var DaemonCmd = &cli.Command{
},
&cli.StringFlag{
Name: "import-chain",
Usage: "on first run, load chain from given file and validate",
Usage: "on first run, load chain from given file or url and validate",
},
&cli.StringFlag{
Name: "import-snapshot",
Usage: "import chain state from a given chain export file",
Usage: "import chain state from a given chain export file or url",
},
&cli.BoolFlag{
Name: "halt-after-import",
@@ -123,6 +127,10 @@ var DaemonCmd = &cli.Command{
Usage: "manage open file limit",
Value: true,
},
&cli.StringFlag{
Name: "config",
Usage: "specify path of config file to use",
},
},
Action: func(cctx *cli.Context) error {
err := runmetrics.Enable(runmetrics.RunMetricOptions{
@@ -176,6 +184,10 @@ var DaemonCmd = &cli.Command{
return xerrors.Errorf("opening fs repo: %w", err)
}
if cctx.String("config") != "" {
r.SetConfigPath(cctx.String("config"))
}
if err := r.Init(repo.FullNode); err != nil && err != repo.ErrRepoExists {
return xerrors.Errorf("repo init error: %w", err)
}
@@ -206,11 +218,6 @@ var DaemonCmd = &cli.Command{
issnapshot = true
}
chainfile, err := homedir.Expand(chainfile)
if err != nil {
return err
}
if err := ImportChain(r, chainfile, issnapshot); err != nil {
return err
}
@@ -326,12 +333,42 @@ func importKey(ctx context.Context, api api.FullNode, f string) error {
return nil
}
func ImportChain(r repo.Repo, fname string, snapshot bool) error {
fi, err := os.Open(fname)
if err != nil {
return err
func ImportChain(r repo.Repo, fname string, snapshot bool) (err error) {
var rd io.Reader
var l int64
if strings.HasPrefix(fname, "http://") || strings.HasPrefix(fname, "https://") {
resp, err := http.Get(fname) //nolint:gosec
if err != nil {
return err
}
defer resp.Body.Close() //nolint:errcheck
if resp.StatusCode != http.StatusOK {
return xerrors.Errorf("non-200 response: %d", resp.StatusCode)
}
rd = resp.Body
l = resp.ContentLength
} else {
fname, err = homedir.Expand(fname)
if err != nil {
return err
}
fi, err := os.Open(fname)
if err != nil {
return err
}
defer fi.Close() //nolint:errcheck
st, err := os.Stat(fname)
if err != nil {
return err
}
rd = fi
l = st.Size()
}
defer fi.Close() //nolint:errcheck
lr, err := r.Lock(repo.FullNode)
if err != nil {
@@ -353,8 +390,21 @@ func ImportChain(r repo.Repo, fname string, snapshot bool) error {
cst := store.NewChainStore(bs, mds, vm.Syscalls(ffiwrapper.ProofVerifier))
log.Info("importing chain from file...")
ts, err := cst.Import(fi)
log.Infof("importing chain from %s...", fname)
bufr := bufio.NewReaderSize(rd, 1<<20)
bar := pb.New64(l)
br := bar.NewProxyReader(bufr)
bar.ShowTimeLeft = true
bar.ShowPercent = true
bar.ShowSpeed = true
bar.Units = pb.U_BYTES
bar.Start()
ts, err := cst.Import(br)
bar.Finish()
if err != nil {
return xerrors.Errorf("importing chain failed: %w", err)
}
+3 -1
View File
@@ -66,8 +66,10 @@ func serveRPC(a api.FullNode, stop node.StopFunc, addr multiaddr.Multiaddr, shut
shutdownDone := make(chan struct{})
go func() {
select {
case <-sigCh:
case sig := <-sigCh:
log.Warnw("received shutdown", "signal", sig)
case <-shutdownCh:
log.Warn("received shutdown")
}
log.Warn("Shutting down...")
+44
View File
@@ -0,0 +1,44 @@
package main
import (
"reflect"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/ipfs/go-cid"
"github.com/multiformats/go-multihash"
)
var ActorMethodTable = make(map[string][]string, 64)
var Actors = map[cid.Cid]interface{}{
builtin.InitActorCodeID: builtin.MethodsInit,
builtin.CronActorCodeID: builtin.MethodsCron,
builtin.AccountActorCodeID: builtin.MethodsAccount,
builtin.StoragePowerActorCodeID: builtin.MethodsPower,
builtin.StorageMinerActorCodeID: builtin.MethodsMiner,
builtin.StorageMarketActorCodeID: builtin.MethodsMarket,
builtin.PaymentChannelActorCodeID: builtin.MethodsPaych,
builtin.MultisigActorCodeID: builtin.MethodsMultisig,
builtin.RewardActorCodeID: builtin.MethodsReward,
builtin.VerifiedRegistryActorCodeID: builtin.MethodsVerifiedRegistry,
}
func init() {
for code, methods := range Actors {
cmh, err := multihash.Decode(code.Hash()) // identity hash.
if err != nil {
panic(err)
}
var (
aname = string(cmh.Digest)
rt = reflect.TypeOf(methods)
nf = rt.NumField()
)
ActorMethodTable[aname] = append(ActorMethodTable[aname], "Send")
for i := 0; i < nf; i++ {
ActorMethodTable[aname] = append(ActorMethodTable[aname], rt.Field(i).Name)
}
}
}
+92
View File
@@ -0,0 +1,92 @@
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
"github.com/fatih/color"
"github.com/urfave/cli/v2"
"github.com/filecoin-project/lotus/conformance"
"github.com/filecoin-project/test-vectors/schema"
)
var execFlags struct {
file string
}
var execCmd = &cli.Command{
Name: "exec",
Description: "execute one or many test vectors against Lotus; supplied as a single JSON file, or a ndjson stdin stream",
Action: runExecLotus,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Usage: "input file; if not supplied, the vector will be read from stdin",
TakesFile: true,
Destination: &execFlags.file,
},
},
}
func runExecLotus(_ *cli.Context) error {
if file := execFlags.file; file != "" {
// we have a single test vector supplied as a file.
file, err := os.Open(file)
if err != nil {
return fmt.Errorf("failed to open test vector: %w", err)
}
var (
dec = json.NewDecoder(file)
tv schema.TestVector
)
if err = dec.Decode(&tv); err != nil {
return fmt.Errorf("failed to decode test vector: %w", err)
}
return executeTestVector(tv)
}
for dec := json.NewDecoder(os.Stdin); ; {
var tv schema.TestVector
switch err := dec.Decode(&tv); err {
case nil:
if err = executeTestVector(tv); err != nil {
return err
}
case io.EOF:
// we're done.
return nil
default:
// something bad happened.
return err
}
}
}
func executeTestVector(tv schema.TestVector) error {
log.Println("executing test vector:", tv.Meta.ID)
r := new(conformance.LogReporter)
switch class := tv.Class; class {
case "message":
conformance.ExecuteMessageVector(r, &tv)
case "tipset":
conformance.ExecuteTipsetVector(r, &tv)
default:
return fmt.Errorf("test vector class %s not supported", class)
}
if r.Failed() {
log.Println(color.HiRedString("❌ test vector failed"))
} else {
log.Println(color.GreenString("✅ test vector succeeded"))
}
return nil
}

Some files were not shown because too many files have changed in this diff Show More