Compare commits

...
Author SHA1 Message Date
whyrusleeping e6f454ac33 fix setup of burnt funds actor state 2020-08-24 18:45:09 +00:00
whyrusleeping ee20eec451 randomize ticket in genesis creation 2020-08-24 18:40:51 +00:00
Aayush Rajasekaran 9e2f56b0b7 Merge pull request #3226 from filecoin-project/fix/mpool-state-inconsistencies
Address potential mpool state inconsistencies
2020-08-21 17:17:57 -04:00
Whyrusleeping 5c315b4503 Merge pull request #3212 from filecoin-project/feat/space-race-params
space race parameters
2020-08-21 14:16:50 -07:00
vyzo 817358f1bb better semantics for mpool clear local argument
local messages should be kept unless the parameter is true
2020-08-21 23:48:35 +03:00
vyzo 3debf005a8 add --really-do-it flag to mpool clear command 2020-08-21 23:32:41 +03:00
vyzo 087955e927 add localonly option to MpoolClear 2020-08-21 23:32:41 +03:00
vyzo e33d398c33 remove pending local messages from the datastore when clearing the mpool 2020-08-21 23:32:41 +03:00
vyzo 9fc674feb4 update mpool documentation 2020-08-21 23:32:41 +03:00
vyzo 0c875774ce add mpool clear cli command 2020-08-21 23:32:41 +03:00
vyzo 3027283756 add MpoolClear api 2020-08-21 23:32:41 +03:00
vyzo 161cb32078 recover from errors in head change 2020-08-21 23:32:41 +03:00
Whyrusleeping 84bbf7f420 Merge pull request #3227 from filecoin-project/feat/drand-incentinet
Feat/drand incentinet
2020-08-21 13:06:03 -07:00
Aayush Rajasekaran d022dba14a Merge pull request #3210 from filecoin-project/asr/docs
Update changelog for 0.5.0
2020-08-21 15:44:46 -04:00
Aayush Rajasekaran bf98ebe33e Merge pull request #3223 from filecoin-project/fix/nil-commd-commr
If sectorInfo doesnt have CommD or CommR set during commit, don't crash
2020-08-21 15:18:11 -04:00
Aayush Rajasekaran 7d704bf86b Merge pull request #3230 from filecoin-project/feat/update-markets-0.5.7
Update to markets v0.5.7
2020-08-21 15:10:40 -04:00
Aayush Rajasekaran aabb90293d Merge pull request #3214 from filecoin-project/fix/genesis-remainder
Actually set genesis remainder account balance
2020-08-21 15:07:14 -04:00
Aayush Rajasekaran 6b8beabad0 Merge pull request #3211 from filecoin-project/testnet-peers
Testnet peers
2020-08-21 15:04:46 -04:00
hannahhoward 438fa637df feat(markets): update to markets v0.5.7 2020-08-21 11:49:16 -07:00
Travis Person 30b28b7f7b Update drand to incentinet 2020-08-21 17:46:43 +00:00
Hector Sanjuan 4b80bc93b0 build/drand.go: add settings for incentinet. 2020-08-21 17:45:55 +00:00
whyrusleeping 2e78f2c267 If sectorInfo doesnt have CommD or CommR set during commit, don't crash 2020-08-21 09:31:28 -07:00
vyzo 8df9c483f3 Merge pull request #3218 from filecoin-project/fix/update-pubsub
update go-libp2p-pubsub@master
2020-08-21 18:15:22 +03:00
vyzo 7c1e0d2132 update go-libp2p-pubsub@master 2020-08-21 10:53:30 +03:00
whyrusleeping 4bf7619d32 Actually set genesis remainder account balance 2020-08-20 18:59:16 -07:00
Whyrusleeping 659babc6b3 Merge pull request #3215 from filecoin-project/fix/fd-limit-test
fix fd limit test
2020-08-20 18:58:54 -07:00
whyrusleeping 38a2f82f78 fix fd limit test 2020-08-20 18:43:43 -07:00
whyrusleeping 7456cdeb42 space race parameters 2020-08-20 17:21:33 -07:00
Travis Person 0eac90b596 Testnet peers 2020-08-21 00:11:30 +00:00
Aayush Rajasekaran 393ac5a7c7 Update changelog 2020-08-20 19:52:47 -04:00
vyzo d1718369a1 Merge pull request #3205 from filecoin-project/fix/update-pubsub
update pubsub and bump behaviour penalty threshold to 6
2020-08-20 23:37:17 +03:00
Łukasz Magiera 57af7e8d1e Merge pull request #3206 from filecoin-project/docs/env-var
add a doc on environment variables that can be used to tweak lotus
2020-08-20 22:29:19 +02:00
Whyrusleeping af3fe206d6 Merge pull request #3122 from filecoin-project/feat/cmd-improvements
sorted deal listings
2020-08-20 13:29:01 -07:00
vyzo 29f6d50c49 Merge pull request #3207 from filecoin-project/fix/more-pubsub-metrics
pubsub metrics for RPCs
2020-08-20 23:28:17 +03:00
vyzo 896edfe072 pubsub metrics for RPCs 2020-08-20 23:14:32 +03:00
whyrusleeping 2010bf55b7 add a doc on environment variables that can be used to tweak lotus 2020-08-20 12:52:50 -07:00
vyzo ccd000cc16 update go-libp2p-pubsub@master 2020-08-20 22:52:40 +03:00
vyzo de05120e69 increase behaviour penalty threshold to 6 2020-08-20 22:32:41 +03:00
Aayush Rajasekaran d8a669c85a Merge pull request #3200 from filecoin-project/asr/docs
Update links
2020-08-20 15:00:38 -04:00
vyzo 87f1b7564c Merge pull request #3196 from filecoin-project/fix/pubsub-behavioural-penalty-threshold
Address issues with pubsub behavioural penalties
2020-08-20 20:19:54 +03:00
Aayush Rajasekaran 807504fa16 Update faucet link 2020-08-20 13:13:20 -04:00
Aayush Rajasekaran 93e566d7e0 Change docs.lotu.sh links to lotu.sh 2020-08-20 12:45:41 -04:00
vyzo 6193f4e062 pubsub: increase gossip history length to 10 heartbeats 2020-08-20 18:09:17 +03:00
Łukasz Magiera 364e3229b9 Merge pull request #3178 from filecoin-project/feat/miner-init-from-flag
add a from flag for miner init
2020-08-20 17:09:03 +02:00
vyzo 98d6d25c74 pubsub: set behaviour penalty threshold, increase IWANT follow up time to 5s 2020-08-20 18:08:02 +03:00
vyzo 67bf952c5a gomod: update go-libp2p-pubsub@master 2020-08-20 18:06:06 +03:00
Łukasz Magiera 0acc461cb1 Merge pull request #3185 from filecoin-project/fix/chainwatch/fix-nil-smoothing-estimate
fix(chainwatch): Handle RewardState.EpochSmoothingEstimate == nil
2020-08-20 11:20:58 +02:00
Łukasz Magiera cd82f79d35 Merge pull request #3191 from filecoin-project/feat/miner-data-transfers
Add data transfer list command to miner
2020-08-20 11:18:56 +02:00
Łukasz Magiera e035e29595 Merge pull request #3189 from filecoin-project/fix/pcr-impursement
lotus-pcr: fix refund math
2020-08-20 11:00:29 +02:00
Łukasz Magiera b89e94ee86 Merge pull request #3190 from filecoin-project/feat/noise-first
NOISE first
2020-08-20 10:57:53 +02:00
Łukasz Magiera fc41b72bb6 Merge pull request #3181 from filecoin-project/asr/cc-upgrade-fix
Do not try to replace CC sectors with a deal-less sector
2020-08-20 10:56:57 +02:00
hannahhoward 0086f76a90 feat(lotus-miner): add data transfer list cmd
add equivalent command to list data transfers on miner side, extract common functionality for reuse
2020-08-20 01:35:48 -07:00
vyzo 92faf5c5f9 don't prefer TLS over NOISE 2020-08-20 11:33:19 +03:00
Travis Person 3eeec8d438 lotus-pcr: fix refund math 2020-08-20 08:28:53 +00:00
Mike Greenberg bf10de82df fix(chainwatch): Handle RewardState.EpochSmoothingEstimate == nil 2020-08-20 01:55:17 -04:00
Aayush Rajasekaran e9c526b218 Do not try to replace CC sectors with a deal-less sector 2020-08-19 22:41:23 -04:00
whyrusleeping 2675ffb128 add a from flag for miner init 2020-08-19 17:34:58 -07:00
Łukasz Magiera 885f357c59 Merge pull request #3175 from filecoin-project/feat/control-addersses-control
Wire up miner control addresses, use for PoSt
2020-08-20 02:24:33 +02:00
Łukasz Magiera de41f63fa4 miner info: Also print locked pledge 2020-08-20 02:03:42 +02:00
Łukasz Magiera a4807b18bc gofmt, api docstring 2020-08-20 01:26:13 +02:00
Łukasz Magiera b42625d824 docs: Explain setting miner control addresses 2020-08-20 01:18:03 +02:00
Łukasz Magiera 71cf358ee3 Fix windowpost test 2020-08-20 01:18:01 +02:00
Łukasz Magiera 5ea61abfe1 Wire up miner control addresses, use for post 2020-08-20 01:17:03 +02:00
Łukasz Magiera 0292c979ab Merge pull request #3043 from filecoin-project/feat/paych-cli-tests
Payment Channel CLI tests
2020-08-20 00:23:00 +02:00
Łukasz Magiera a78258efdf Merge pull request #3157 from filecoin-project/docs/paych
Payment channel lotu.sh docs
2020-08-20 00:13:49 +02:00
Łukasz Magiera bee6c0e26e Merge remote-tracking branch 'origin/master' into feat/paych-cli-tests 2020-08-20 00:12:47 +02:00
Łukasz Magiera 6e492e41d1 Merge pull request #3165 from filecoin-project/fix/validator-ignore-nonce-errors
ignore, don't reject messages with nonce that is too low
2020-08-20 00:00:20 +02:00
Łukasz Magiera f943ea7d5d Merge pull request #3170 from filecoin-project/frrist/chainwatch-SectorOnChainInfo-ext
refactor(cw): add new values to sector_info table and smoothing estimate
2020-08-19 23:58:22 +02:00
Łukasz Magiera ed098390cb Merge pull request #3172 from filecoin-project/feat/lotus-shed-jwt
lotus-shed: add simple jwt creation support
2020-08-19 23:32:01 +02:00
Łukasz Magiera 3ed3e4f5d7 Merge pull request #3162 from filecoin-project/feat/data-transfer-status
Find out what's up with data transfers!
2020-08-19 23:30:44 +02:00
Whyrusleeping 6117afe0be Merge pull request #3174 from filecoin-project/keyko-io-fix/genesis-multisig
Keyko io fix/genesis multisig
2020-08-19 13:56:36 -07:00
whyrusleeping f5dcd4a25f set missing miner ID field 2020-08-19 13:42:34 -07:00
frrist 05f1a23c94 feat(chainwatch): power actor smoothing estimate 2020-08-19 13:34:58 -07:00
whyrusleeping 621d675938 fixup tests 2020-08-19 13:32:53 -07:00
whyrusleeping 4f25c1c60e minor improvements to multisig cli commands 2020-08-19 13:10:07 -07:00
frrist fecaeda382 feat(chainwatch): reward actor smoothing estimate 2020-08-19 13:05:07 -07:00
frrist 3df85ca784 refactor(chainwatch): add new values to sector_info table 2020-08-19 13:05:07 -07:00
whyrusleeping 2ab202a03d fixup ID allocation and a few other things 2020-08-19 12:54:33 -07:00
Travis Person f1632376e7 lotus-shed: add simple jwt creation support 2020-08-19 19:21:36 +00:00
whyrusleeping 073efeeacb Merge branch 'fix/genesis-multisig' of git://github.com/keyko-io/lotus into keyko-io-fix/genesis-multisig 2020-08-19 10:51:15 -07:00
vyzo 19253dbbb1 Merge pull request #3169 from filecoin-project/fix/drand-delivery-cap
fix drand topic first message delivery cap
2020-08-19 20:02:08 +03:00
vyzo 6c5a91735a fix drand topic first message delivery cap 2020-08-19 18:45:31 +03:00
Dirk McCormick 20cb9425cc docs: paych edits 2020-08-19 08:43:06 -04:00
Sami Mäkelä 74f35c88ad checking verifreg handling 2020-08-19 15:27:50 +03:00
vyzo c7a6e32c96 ignore, don't reject messages with nonce that is too low
we seem to have a problem with this leading to many rejected messages and negative scores for
potentially innocent peers.
2020-08-19 13:20:16 +03:00
Sami Mäkelä 99e71badbf check that accounts aren't overwritten 2020-08-19 13:03:59 +03:00
Sami Mäkelä e894f360a5 merge 2020-08-19 12:26:19 +03:00
Sami Mäkelä 63ad6bc325 need to merge 2020-08-19 12:25:38 +03:00
hannahhoward 4fc5f9fe9f feat(cli): data transfer watch option
make watching data transfer CLI updates only an option
2020-08-18 18:23:51 -07:00
hannahhoward 66ac7c195c feat(cli): add updates to data transfer
Add an API to get data transfer updates and add modify the CLI to be an
ongoing monitoring plan
2020-08-18 17:36:29 -07:00
Łukasz Magiera 80e6e56a82 Merge pull request #2145 from filecoin-project/next
Next Testnet Staging
2020-08-19 02:14:30 +02:00
Łukasz Magiera 0471b10de5 Merge remote-tracking branch 'origin/master' into next 2020-08-19 02:03:14 +02:00
Łukasz Magiera 2dfc15c67d docs: Expand sealing issue template 2020-08-19 01:57:57 +02:00
David Dias d0f6804283 docs: add badgers 2020-08-19 01:57:25 +02:00
hannahhoward ef7f7375e7 fix(cli): cleanup data-transfers
cleanup output for data transfers.
2020-08-18 16:45:20 -07:00
Łukasz Magiera 7f6c86daae Merge pull request #3024 from filecoin-project/docs/expand-sealing-template
docs: Expand sealing issue template
2020-08-19 01:45:01 +02:00
Łukasz Magiera d2d72c76e0 docs: Expand sealing issue template 2020-08-19 01:40:28 +02:00
Łukasz Magiera ec4603e55d Merge pull request #3160 from filecoin-project/asr/cc-upgrade-fixes
cc upgrade fixes
2020-08-19 01:29:05 +02:00
hannahhoward f511cc188a feat(cli): data transfer command
add command to monitor data transfers
2020-08-18 16:26:21 -07:00
Aayush Rajasekaran 7de7e65dbc Calculate depositMinimum for upgrading as replaced sector's Initialpledge 2020-08-18 19:22:43 -04:00
Aayush Rajasekaran 98f00b510f re-mark replaced sectors as for upgrade if precommit fails 2020-08-18 18:53:56 -04:00
Łukasz Magiera e47e51275a Merge pull request #3138 from filecoin-project/feat/remainder
place the remainder of unallocated funds in a 'remainder' account
2020-08-18 23:52:19 +02:00
whyrusleeping 916bebadef setup proper template defaults 2020-08-18 14:34:35 -07:00
whyrusleeping abca69b476 configurable remainder account 2020-08-18 14:30:49 -07:00
Łukasz Magiera 71aa3a59d9 Merge pull request #3047 from filecoin-project/asr/burn-genesis
Do not include the burnt funds actor as a genesis account actor
2020-08-18 23:10:32 +02:00
Łukasz Magiera 19be380b53 Merge pull request #3152 from filecoin-project/fix/chainwatch/rpc-peer-id-bug
fix(api): Filter malformed peer ID before RPC marshaling
2020-08-18 23:07:55 +02:00
Łukasz Magiera 574a22de6c genesis: Set remainder account balance correctly 2020-08-18 22:52:25 +02:00
Mike Greenberg 8675ca561d fix(api): Filter malformed peer ID before RPC marshaling 2020-08-18 16:29:21 -04:00
Dirk McCormick 2b15831672 docs: payment channels 2020-08-18 16:07:04 -04:00
Łukasz Magiera 1dd554ad71 Merge pull request #3155 from filecoin-project/misc/selection-misc
Use conditional probability for miners
2020-08-18 21:56:41 +02:00
Łukasz Magiera 3fd4921ea3 Merge pull request #3147 from filecoin-project/feat/fsm-seal-limits
fsm: Config for limiting max sealing sectors
2020-08-18 21:54:41 +02:00
Łukasz Magiera a03192a39b Separate concurrent sealing sector limit for deals 2020-08-18 21:48:18 +02:00
vyzo 6d9707c784 fix OptimalSelection3 test 2020-08-18 22:24:07 +03:00
Łukasz Magiera d23cd2e507 Merge pull request #3136 from filecoin-project/asr/genesis-hardcode
Create a testnet version of setupGenesisActors
2020-08-18 21:21:04 +02:00
Łukasz Magiera 25448798b0 Merge pull request #3154 from filecoin-project/chore/add_missing_error_arg
Missing error argument
2020-08-18 21:19:20 +02:00
Łukasz Magiera d1cb60bdee Merge pull request #3118 from filecoin-project/feat/improve-pcr
lotus-pcr: refund provecommit sectors
2020-08-18 21:18:45 +02:00
Jakub Sztandera e0b72ba049 Reduce number of runs to 1
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 21:10:04 +02:00
Jakub Sztandera 4d01cbfb62 Increase precision of output
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 21:10:04 +02:00
Jakub Sztandera 8d4427a8bc add best ticket reward to tests
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 21:10:04 +02:00
Jakub Sztandera 8bca545cab Add test for winnerProba
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 21:10:04 +02:00
Jakub Sztandera 9c98cf8bc1 Fix blockProbabilities
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 21:10:04 +02:00
Jakub Sztandera 8acd926636 Use conditional probability for noWinners, fix tests
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 21:10:04 +02:00
Jakub Sztandera 12f7ead55e Merge pull request #3144 from filecoin-project/feat/dedup-for-basefee
Basefee change depends on unique messages not all messages
2020-08-18 21:08:29 +02:00
Peter Rabbitson 02d21c2833 Missing error argument 2020-08-18 21:08:20 +02:00
Łukasz Magiera b23cac19ab Merge pull request #3151 from filecoin-project/asr/specs-update
Update to specs-actors v0.9.3
2020-08-18 20:56:51 +02:00
Aayush Rajasekaran 446a4f6272 Update to specs-actors v0.9.3 2020-08-18 14:24:46 -04:00
whyrusleeping 42730bcf1c handle potential overallocation 2020-08-18 10:56:54 -07:00
Aayush Rajasekaran 214eeccb18 Create a testnet version of setupGenesisActors 2020-08-18 13:56:47 -04:00
Łukasz Magiera 2570712a29 Merge pull request #3135 from filecoin-project/feat/genesis-block-linkage
proper genesis block history
2020-08-18 19:28:55 +02:00
Łukasz Magiera 6a7d72c030 fsm: fail early on too-many-sealing-sectors in pledge 2020-08-18 19:26:17 +02:00
Łukasz Magiera e7d65be90a gofmt 2020-08-18 18:27:28 +02:00
Łukasz Magiera baf91f08a1 Unbreak tests 2020-08-18 18:27:18 +02:00
Łukasz Magiera 255bd6881a Merge pull request #3142 from filecoin-project/asr/client-retrieve
Create eventless version of ClientRetrieve
2020-08-18 18:15:16 +02:00
Łukasz Magiera 886d9cd5eb fsm: handle already-precommitted CommitFailed sectors correctly 2020-08-18 18:02:25 +02:00
Jakub Sztandera c9fdd4bee2 Fix testgrounds build
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 17:40:53 +02:00
Dirk McCormick 043b63d8d8 feat: payment channel CLI tests 2020-08-18 11:26:08 -04:00
Łukasz Magiera 6a49bd6d8e fsm: Config for limiting max sealing sectors 2020-08-18 16:54:05 +02:00
Łukasz Magiera 65ffde9e4b fsm: Config for max WaitDeals sectors 2020-08-18 16:20:31 +02:00
Jakub Sztandera c841f26256 Basefee change depends on unique messages not all messages
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-18 15:28:50 +02:00
Łukasz Magiera 4cd56b3b99 impl: wait in ClientRetrieve 2020-08-18 15:27:56 +02:00
Łukasz Magiera 2d73b04f7d Merge pull request #3137 from filecoin-project/fix/chainwatch/calibration-improvements-2
More Chainwatch Improvements
2020-08-18 15:10:42 +02:00
Łukasz Magiera 36d87eb8e9 more checks around genesis CID 2020-08-18 15:04:31 +02:00
Łukasz Magiera 1ba5dd4c72 Merge pull request #3139 from filecoin-project/fix/mpool-push-deadlock
fix deadlock in mpool.Push
2020-08-18 14:09:00 +02:00
Łukasz Magiera b4d9b6efaf Merge pull request #3140 from filecoin-project/asr/restart-timer
restart WaitDeals timers if miner restarts
2020-08-18 13:54:55 +02:00
Sami Mäkelä 4ae02ef1b9 looks like it's working 2020-08-18 13:58:32 +03:00
Sami Mäkelä 88fbc044b3 adding actors for genesis msig addresses 2020-08-18 13:58:29 +03:00
Aayush Rajasekaran 8942c02f28 Add a reminder comment 2020-08-18 06:01:48 -04:00
Aayush Rajasekaran add56c8b81 Create eventless version of ClientRetrieve 2020-08-18 05:49:56 -04:00
Aayush Rajasekaran 37ff876bc6 restart WaitDeals timers if miner restarts 2020-08-18 05:07:14 -04:00
vyzo 4287f76ed4 fix deadlock in mpool.Push 2020-08-18 10:19:46 +03:00
whyrusleeping 64e18131c1 place the remainder of unallocated funds in a 'remainder' account 2020-08-17 23:38:58 -07:00
Mike Greenberg fabf26cc21 fix(chainwatch): Actually capture human actor names 2020-08-18 00:22:01 -04:00
Mike Greenberg 94e4f8d116 fix(chainwatch): Ignore blocks missing from local blockstore during processing 2020-08-18 00:22:01 -04:00
Mike Greenberg 6734287789 fix(chainwatch): Change tmp table names to not collide 2020-08-18 00:22:01 -04:00
whyrusleeping 13e5b72cdb proper genesis block history
Commit hash originally stamped into the ethereum blockchain:
https://etherscan.io/tx/0xe8f51c9eefb682cd866f059462577b6dd3d2685ff4b6437f6c940ff4f4aaf067
2020-08-17 21:13:43 -07:00
Aayush Rajasekaran 8cae101c04 Merge pull request #3134 from filecoin-project/fix/active-detection-timeout
Remove timeouts on deal committed checks
2020-08-17 22:53:17 -04:00
hannahhoward d1743555d4 fix(markets): remove timeouts on deal committed checks 2020-08-17 19:07:13 -07:00
Łukasz Magiera b463749594 Merge pull request #3131 from filecoin-project/asr/no-peerid
strip peerid when setting on-chain addrs
2020-08-18 03:21:42 +02:00
Aayush Rajasekaran 4ef5a58b36 strip peerid when setting on-chain addrs 2020-08-17 21:18:26 -04:00
Łukasz Magiera 1bd90d0701 Merge pull request #3130 from filecoin-project/fix/reachability-cli
cli: Fix net reachability
2020-08-18 03:14:11 +02:00
Łukasz Magiera 127d6d0576 cli: Fix net reachability 2020-08-18 03:12:50 +02:00
Łukasz Magiera 9db478fd2e Bump version 2020-08-18 02:58:54 +02:00
Łukasz Magiera 1cf2d1aad5 Merge pull request #3127 from filecoin-project/asr/set-peerid
Add a CLI method to set peerid
2020-08-18 02:58:17 +02:00
Aayush Rajasekaran 01b5118a08 Add a CLI method to set peerid 2020-08-17 20:53:02 -04:00
Łukasz Magiera 5c71d25872 Merge pull request #3126 from filecoin-project/feat/lotus-keygen
add lotus keygen utility
2020-08-18 02:46:12 +02:00
whyrusleeping ef8b9eae93 add lotus keygen utility 2020-08-17 17:29:26 -07:00
Łukasz Magiera dfa2ac6807 Merge pull request #3123 from filecoin-project/fix/retrieval-nil-serializing
Fix/retrieval nil serializing
2020-08-18 02:20:12 +02:00
whyrusleeping f05cff478f sorted deal listings 2020-08-17 14:48:49 -07:00
Ingar Shu cb71386ed9 Don't send finishing event if there is no error 2020-08-17 14:39:08 -07:00
Ingar Shu 7fbbf23e5a Initialize FundsSpent to zero in RetrievalEvent 2020-08-17 14:39:08 -07:00
Ingar Shu 5ace7479ad Don't try to output nil channel values 2020-08-17 14:39:08 -07:00
Travis Person 5040623a12 lotus-pcr: refund provecommit sectors 2020-08-17 21:29:59 +00:00
vyzo ff7f0a9dcd Merge pull request #3090 from filecoin-project/fix/pubsub-validation-clown-shoes
Fix clown shoes in pubsub validation
2020-08-17 23:31:45 +03:00
vyzo ca552cf83b deduplicate some block validation logic 2020-08-17 21:03:08 +03:00
Łukasz Magiera 2e78ed685f Merge pull request #3113 from filecoin-project/fix/chainwatch/calibration-improvements
Chainwatch Improvements
2020-08-17 19:06:05 +02:00
Łukasz Magiera 01df17f1e7 Merge pull request #3103 from filecoin-project/fix/fsm-recover-bork-snark
fsm: Recover from errors from VerifySeal in checkCommit
2020-08-17 19:00:16 +02:00
Łukasz Magiera f87ede501c Merge pull request #3101 from filecoin-project/fix/fsm-no-pci-panic
fsm: Fix panic on missing precommit info
2020-08-17 18:53:28 +02:00
Łukasz Magiera bb79af7721 fsm: Recover from errors from VerifySeal in checkCommit 2020-08-17 18:53:09 +02:00
Łukasz Magiera a66e202f02 fsm: Fix panic on missing precommit info 2020-08-17 18:45:38 +02:00
Łukasz Magiera 29db7047a3 Merge pull request #3112 from filecoin-project/fix/sched-hang
Fix sealing sched hands on unclean worker disconnect
2020-08-17 18:43:25 +02:00
Łukasz Magiera 6ef7a30b19 Merge pull request #3089 from filecoin-project/integrate/storage-fsm
integrate extern/{storage-fsm,sector-storage} into lotus source tree
2020-08-17 18:37:54 +02:00
Raúl Kripalani 1f016262cd readd int64 cast + nolint directive. 2020-08-17 17:26:07 +01:00
Mike Greenberg 80fef50b90 feat(chainwatch): Include detailed economic data per epoch 2020-08-17 12:22:34 -04:00
Łukasz Magiera 704578c9c2 Merge pull request #3108 from austinabell/msload
Remove unnecessary miner state load for checking slashed
2020-08-17 18:11:09 +02:00
Łukasz Magiera cfc1a54ee5 Merge pull request #3110 from filecoin-project/badgers
docs: add badgers
2020-08-17 17:57:28 +02:00
Łukasz Magiera f31473c4cf Update jsonrpc to fix sealing sched hangs 2020-08-17 17:36:21 +02:00
Łukasz Magiera 09dbd12638 Merge pull request #3107 from yaohcn/feat/addpiece-configurable
make addpiece configurable
2020-08-17 17:35:09 +02:00
Mike Greenberg b37a39588e feat(chainwatch): Add full version to help/startup log via build param 2020-08-17 11:31:59 -04:00
Mike Greenberg 0b498d25f6 fix(chainwatch): Actor code are human readable 2020-08-17 11:18:35 -04:00
David Dias f5b0c30633 docs: add badgers 2020-08-17 15:21:27 +01:00
Raúl Kripalani 862bafc63a fix lint errors. 2020-08-17 14:39:33 +01:00
austinabell c3c6fda9d5 Remove unnecessary miner state load for checking slashed 2020-08-17 09:32:47 -04:00
Raúl Kripalani efdc428d5d keep storage-fsm (renamed to storage-sealing) and sector-storage in extern. 2020-08-17 14:26:18 +01:00
Łukasz Magiera 7595b1d8d4 cli: pprof goroutines command 2020-08-17 11:49:11 +02:00
yaohcn 39bcfab37c make addpiece configurable 2020-08-17 17:39:50 +08:00
Łukasz Magiera ae40555558 Merge pull request #3104 from filecoin-project/feat/pubsub-metrics
collect pubsub metrics through the tracer
2020-08-17 10:39:46 +02:00
Łukasz Magiera 9c30b17b5a Merge pull request #3105 from yaohcn/fix/restart-flag
add missing restart flag
2020-08-17 10:37:24 +02:00
yaohcn aded4b4199 add missing restart flag 2020-08-17 16:04:50 +08:00
Łukasz Magiera eb616bff7f Merge pull request #3100 from filecoin-project/feat/mpool-improve-repub
trigger early republish from head changes
2020-08-17 09:46:46 +02:00
vyzo 8cf9595d35 collect pubsub metrics through the tracer 2020-08-17 10:46:20 +03:00
Łukasz Magiera 5c23ec73cb Merge pull request #3102 from filecoin-project/fix/mpool-docs
Some small improvements in mpool docs
2020-08-17 09:44:00 +02:00
vyzo 8d7994cd82 fix confusing wording 2020-08-17 10:12:54 +03:00
vyzo fb77a758ff note defaults in mpool configuration docs 2020-08-17 10:10:25 +03:00
vyzo 3b6e2bdb7b trigger early republish from head changes 2020-08-17 10:03:39 +03:00
Łukasz Magiera 1898b82dc4 Merge pull request #3086 from filecoin-project/feat/mpool-doc-config-cmd
Mpool documentation and config cli command
2020-08-17 08:47:40 +02:00
Łukasz Magiera 290011166f Merge pull request #3083 from filecoin-project/asr/docs
Show how to set env vars
2020-08-17 08:40:14 +02:00
Łukasz Magiera c5c819afca Merge pull request #3098 from filecoin-project/feat/config-cmd
Add config command that prints the default config file for a storage …
2020-08-17 08:36:51 +02:00
Łukasz Magiera c2687f9064 Merge pull request #3084 from shaodan/next
Fix typo
2020-08-17 08:34:28 +02:00
Łukasz Magiera 548e94d3fc Merge pull request #3079 from filecoin-project/fix/chainwatch-slow-read
fix a small issue in chain watch
2020-08-17 08:23:38 +02:00
vyzo ae88a99c84 add some lightweight validation of local messages 2020-08-17 09:04:22 +03:00
lanzafame 0d3aaabd2c Add config command that prints the default config file for a storage miner 2020-08-17 13:51:04 +10:00
vyzo 884d4ad9df fix clown shoes pubsub validation: we always accept our own self-published messages 2020-08-16 20:46:19 +03:00
Raúl Kripalani 4f6d01d2ea fix path in failing test. 2020-08-16 12:28:39 +01:00
Raúl Kripalani 2b511d2f57 fix lint errors. 2020-08-16 11:44:22 +01:00
Raúl Kripalani 1eed341951 fix test compilation error. 2020-08-16 11:14:24 +01:00
Raúl Kripalani 3c17cd655e integrate extern/sector-storage into lotus proper. 2020-08-16 11:09:58 +01:00
Raúl Kripalani fb0ccc9260 integrate extern/storage-fsm into lotus proper. 2020-08-16 10:42:13 +01:00
vyzo aa679a7359 add message pool documentation 2020-08-16 10:57:17 +03:00
vyzo 054fc4a614 add client command for mpool config 2020-08-16 09:57:53 +03:00
Dan Shao 10b5e3e576 fix typo 2020-08-16 10:20:32 +08:00
Aayush Rajasekaran e3c241e613 Show how to set env vars 2020-08-15 21:48:42 -04:00
vyzo 7f27c80a6a move sleep into the select
as it is it simply slows down the writer if there are many messages
2020-08-15 21:20:02 +03:00
Łukasz Magiera 9a23ede4fd Merge pull request #3075 from filecoin-project/fix/inter-filffi
Update filecoin-ffi to fix Intel build
2020-08-15 13:57:27 +02:00
Łukasz Magiera 9328dc27f3 Update filecoin-ffi to fix Intel build 2020-08-15 13:19:10 +02:00
Whyrusleeping 98643b90f8 Merge pull request #3068 from filecoin-project/feat/fundmgr-fix
Temporary fix for fund manager add issues
2020-08-14 21:10:08 -07:00
hannahhoward aa419155f6 feat(fundmgr): temp fix for funding issues 2020-08-14 19:37:20 -07:00
Łukasz Magiera b75ba5ea46 Merge pull request #3066 from filecoin-project/feat/cmd-improvements
add a market balance command, and a verbose mode for storage-deals list
2020-08-15 01:51:18 +02:00
whyrusleeping 8dfcf2b7d3 make things print nicerly 2020-08-14 16:46:11 -07:00
whyrusleeping 8774a7b2dd add a market balance command, and a verbose mode for storage-deals list 2020-08-14 16:45:40 -07:00
Łukasz Magiera 9012fea2f6 Merge pull request #3067 from filecoin-project/fix/addpiece-with-data
Fix AddPiece with data and multiple workers
2020-08-15 01:42:33 +02:00
Łukasz Magiera a52e406c0d Fix AddPiece with data and multiple workers 2020-08-15 01:36:29 +02:00
Łukasz Magiera 45476a208e Merge pull request #3053 from filecoin-project/feat/worker-addpiece2
Support AddPiece on workers
2020-08-14 23:50:17 +02:00
Łukasz Magiera 4ca5fef0de rpcenc: fix bug 2020-08-14 23:49:08 +02:00
Łukasz Magiera 42bb91c2e6 gofmt 2020-08-14 23:40:41 +02:00
Łukasz Magiera 1ecec49885 build: Bump versions 2020-08-14 23:40:11 +02:00
Łukasz Magiera 7fa2f20e8c Merge pull request #3064 from filecoin-project/asr/circ-supply-api
Include more info in StateCirculatingSupply
2020-08-14 23:31:28 +02:00
Łukasz Magiera d9ad6fb8c8 worker: Make disconnects less bad 2020-08-14 23:24:41 +02:00
Łukasz Magiera aa611e49fd rpcenc: Add timeout for readers 2020-08-14 23:12:55 +02:00
Aayush Rajasekaran 0359a458e4 Include more info in StateCirculatingSupply 2020-08-14 16:53:30 -04:00
Łukasz Magiera 0377d6952b Merge remote-tracking branch 'origin/next' into feat/worker-addpiece2 2020-08-14 21:17:30 +02:00
Łukasz Magiera ec242c1ba7 Update jsonrpc with stacktraces on panic 2020-08-14 21:16:42 +02:00
Łukasz Magiera 4a0171d26a Merge pull request #3058 from filecoin-project/feat/update-markets-0.5.6
Update markets 0.5.6
2020-08-14 21:13:00 +02:00
Łukasz Magiera 8955690d76 Merge pull request #3062 from filecoin-project/fix/post-conf-wait
wdpost: Wait for the correct confidence
2020-08-14 21:10:24 +02:00
Łukasz Magiera 25cb3a15e7 wdpost: Wait for the correct confidence 2020-08-14 21:03:20 +02:00
hannahhoward 6b5525b8d2 feat(markets): update markets 0.5.6
update markets to 0.5.6, removing use of validators that moved inside markets
2020-08-14 11:14:03 -07:00
Łukasz Magiera 0c75dd3865 Support AddPiece on workers 2020-08-14 16:06:53 +02:00
Łukasz Magiera 4d204d2c25 Merge pull request #3022 from filecoin-project/feat/fix-rename-miner-withdraw
miner: fix/rename miner actor withdraw
2020-08-14 13:51:58 +02:00
Łukasz Magiera 75eaa1bf5b Merge remote-tracking branch 'origin/next' into feat/fix-rename-miner-withdraw 2020-08-14 13:40:12 +02:00
vyzo b44d188912 Merge pull request #3040 from filecoin-project/misc/use-zipf-selection-test
Add competitve selection test with Zipf premium distribution
2020-08-14 10:25:29 +03:00
vyzo a5d2ec0df8 appease linter 2020-08-14 10:12:55 +03:00
vyzo b844f70a3c make competitve selection test parameteric on distribution function, add test for Zipf distribution 2020-08-14 10:09:25 +03:00
Aayush Rajasekaran 5fe85c07b1 Merge pull request #3046 from filecoin-project/asr/collateral
Move estimation correction into markets adapters
2020-08-13 22:27:43 -04:00
Aayush Rajasekaran 5ca410ae99 extract overestimation factor into a constant 2020-08-13 22:21:20 -04:00
Aayush Rajasekaran 2d90bcff3c jeromy is a bad software engineer 2020-08-13 22:14:45 -04:00
Aayush Rajasekaran c2a24b7b4c Update markets 2020-08-13 22:13:31 -04:00
Aayush Rajasekaran b49276ef47 Double provider collateral estimates in the client atadpter 2020-08-13 21:54:39 -04:00
whyrusleeping eb2879ca22 allow client to specify provider collateral 2020-08-13 21:47:36 -04:00
Aayush Rajasekaran 5702ea236c Do not include the burnt funds actor as a genesis account actor 2020-08-13 20:19:47 -04:00
Łukasz Magiera b3f27c0075 Merge pull request #3044 from filecoin-project/frrist/fix-error-actor-not-found
fix: chainwatch actor not found handling
2020-08-13 23:23:52 +02:00
frrist 50d4c2e0ac fix: error checking for actor not found 2020-08-13 14:10:05 -07:00
Łukasz Magiera 6c1ecb4d16 Merge pull request #3039 from filecoin-project/frrist/fix-id-map-table-v2
fix: chainwatch id_address_map
2020-08-13 20:49:22 +02:00
Jakub Sztandera f27a122787 Use Zipf distribution for messages
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 20:22:56 +02:00
frrist 55f88b46cf fix: best attempt at fixing the id_address_map 2020-08-13 11:14:58 -07:00
Jakub Sztandera 15a81707b4 Merge pull request #3036 from filecoin-project/feat/noise-gas-premium
Add noise to GasPremium calculation to help out message selection
2020-08-13 19:33:41 +02:00
Jakub Sztandera a6d79b26e4 Add comments
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 19:27:31 +02:00
Whyrusleeping 2db1001a07 Merge pull request #3033 from filecoin-project/fix/paych-alloc-lane
Fix bug with paych allocate lane
2020-08-13 10:24:12 -07:00
Jakub Sztandera d94119dada Merge pull request #3037 from filecoin-project/feat/mpool-selection-fixes
Some optimal selection fixes
2020-08-13 19:15:35 +02:00
vyzo 9aa8791920 make selection2 test less touchy 2020-08-13 20:02:08 +03:00
Jakub Sztandera ff7e441c82 Add noise to GasPremium calculation to help out message selection
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 18:57:06 +02:00
vyzo 2eff03fa1f small fixes in optimal selection
1. Remove noop updates from the previous dependencies
2. Update subsequent dependencies, which was the intention
2020-08-13 19:49:07 +03:00
Łukasz Magiera 5c0d86373e Merge pull request #3034 from filecoin-project/feat/stat-gas-limit-total
Add total gas used and limit to stats
2020-08-13 17:42:04 +02:00
Jakub Sztandera 8a8017c536 Merge pull request #3020 from filecoin-project/feat/lower-default-comm-maxfee
config: Set lower default max commit maxfee
2020-08-13 17:32:06 +02:00
Jakub Sztandera 3198d2d1e5 Add total gas used
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 16:55:12 +02:00
Jakub Sztandera dd619e85ff Add total gas limit to stats
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 16:48:29 +02:00
Dirk McCormick 536b2ad9d7 fix: paych - bug with allocating lane 2020-08-13 10:14:11 -04:00
Łukasz Magiera 7fc15b70ec Merge pull request #3025 from filecoin-project/feat/retdeals-in-allinfo
miner: Add retrieval deal list to miner allinfo
2020-08-13 15:58:12 +02:00
Jakub Sztandera 428e315d2a Merge pull request #3023 from filecoin-project/feat/mpool-optimimal-selection-redux
Further improvements for optimal message selection
2020-08-13 15:46:51 +02:00
Jakub Sztandera 91b5ec1aba Merge pull request #3032 from filecoin-project/feat/mpool-fix-capmaxfee
mpool: Fix capGasFee math again
2020-08-13 14:47:46 +02:00
Łukasz Magiera a883b1b9a9 Merge pull request #3031 from filecoin-project/feat/cleanup-pledgecoll-api
api: Remove unused StatePledgeCollateral
2020-08-13 14:16:48 +02:00
Łukasz Magiera 47582c0bb3 mpool: Fix capGasFee math again 2020-08-13 14:16:29 +02:00
Jakub Sztandera 0daed04c07 Don't run the test 50 times
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:11 +02:00
vyzo 09f5a64ce0 use gasPerf for negative performance check
it's the same in actually because effPerf<0 iff gasPerf<0, but we should be consistent

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:11 +02:00
vyzo f3eec33bec make OptimalSelection3 test pass
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:11 +02:00
vyzo 1aa8b6cab2 make OptimalSelection2 test pass
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:11 +02:00
vyzo 0f5598e59b compute average boost in tests
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:11 +02:00
vyzo 5e8ae7498a only adjust next chains if they have positve perf
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:11 +02:00
vyzo 7bbf1c7db2 don't mix negative performing chains with their parent, add some comments
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:10 +02:00
Jakub Sztandera f35555964d Better "optimal selection
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:10 +02:00
vyzo d25f386bb5 mixin the previous chain's effective performance to capture effect of dependencies
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-13 14:08:10 +02:00
Łukasz Magiera a366522c8d Fix lotus-fountain build 2020-08-13 14:04:45 +02:00
Łukasz Magiera 9a39bb4e78 api: Remove unused StatePledgeCollateral 2020-08-13 14:03:59 +02:00
Łukasz Magiera ccfb33c294 Merge pull request #3028 from filecoin-project/feat/fix-sched-deadlock
sealing sched: Fix deadlock in worker watcher
2020-08-13 13:46:07 +02:00
Łukasz Magiera 0cb58311c3 Merge pull request #3029 from filecoin-project/feat/net-reachability
cli: net reachability command
2020-08-13 13:45:19 +02:00
Łukasz Magiera 3b23ab952b gofmt 2020-08-13 13:44:43 +02:00
Łukasz Magiera 069c39fc12 Add reachability info to miner info all 2020-08-13 13:44:03 +02:00
Łukasz Magiera 3f2a62b5e2 cli: net reachability command 2020-08-13 13:18:14 +02:00
Łukasz Magiera 632fd36205 sealing sched: Fix deadlock in worker watcher 2020-08-13 12:17:24 +02:00
Łukasz Magiera f212ca60c8 Merge pull request #3027 from yaohcn/change-lock
change to RLock
2020-08-13 11:39:13 +02:00
yaohcn 1555984785 change to RLock 2020-08-13 17:31:18 +08:00
Łukasz Magiera 066bac0607 miner: Add retrieval deal list to miner allinfo 2020-08-13 10:51:13 +02:00
Łukasz Magiera 02650c7f25 miner: drop rewardsCmd from miner cmd list 2020-08-13 10:25:21 +02:00
Łukasz Magiera 936d861df5 gofmt 2020-08-13 10:20:41 +02:00
Łukasz Magiera f0d32f2c01 miner: fix/rename miner actor withdraw 2020-08-13 10:20:09 +02:00
Łukasz Magiera 7e36188519 Merge pull request #3013 from filecoin-project/frrist/fix-id-map-table
fix: id_address_map conflicts
2020-08-13 09:55:48 +02:00
Łukasz Magiera 97489f8bf9 config: Set lower default max commit maxfee 2020-08-13 09:40:19 +02:00
Whyrusleeping 5ac8424f93 Merge pull request #3014 from filecoin-project/feat/update-markets-v0.5.5
Update markets v0.5.5
2020-08-12 19:25:24 -07:00
hannahhoward c9a4bfba1a feat(markets): update markets v0.5.5 2020-08-12 19:02:20 -07:00
Whyrusleeping bd31e8d37e Merge pull request #2991 from filecoin-project/refactor/paych-lane-amt
paych: use spec-actors paych with AMT for lane states
2020-08-12 17:51:17 -07:00
Steven Allen cac3d07abb Fix payment channel for actor changes
Also, allocate the next available lane, instead of max+1. That way, we fill
holes.

Finally, check some error cases.
2020-08-12 17:29:00 -07:00
Dirk McCormick 335d165db6 refactor: use spec-actors paych with AMT for lane states 2020-08-12 17:06:18 -07:00
frrist 69a472c4ea bug: fix id_address_map table conflicts on reorg 2020-08-12 16:54:45 -07:00
frrist ce21557d64 bug: fix bug in predicate and add tests 2020-08-12 16:52:08 -07:00
Łukasz Magiera 0a2c2e9a07 Merge pull request #3012 from filecoin-project/feat/balance-checking
add function to check entire state tree balance
2020-08-13 01:29:38 +02:00
whyrusleeping b3a31d8823 add function to check entire state tree balance 2020-08-12 15:45:46 -07:00
Łukasz Magiera 4308d37c84 Merge pull request #3011 from filecoin-project/fix/nil-tipset-storageprovider
Add nil check in tipset change handler
2020-08-13 00:04:17 +02:00
Whyrusleeping cc54efd88b Merge pull request #2678 from filecoin-project/asr/genesis-expected
Check repo's genesis against baked-in genesis
2020-08-12 15:02:59 -07:00
Aayush Rajasekaran cae98ac0ab Update local-dev-net.md 2020-08-12 17:38:27 -04:00
Łukasz Magiera e7e068ebb5 Merge pull request #3008 from filecoin-project/fix/lints
Fix lint errors an broken tests
2020-08-12 23:28:01 +02:00
Ingar Shu 43e1b57c3f add nil check in tipset change handler 2020-08-12 14:27:39 -07:00
Łukasz Magiera 5561d66082 Merge pull request #3002 from keyko-io/feat/verified-price
Showing verified price in asks
2020-08-12 23:26:53 +02:00
Aayush Rajasekaran d614135ebb Check repo's genesis against baked-in genesis 2020-08-12 17:22:16 -04:00
Steven Allen 3ef3f570fb Fix lint errors an broken tests 2020-08-12 23:16:44 +02:00
Aayush Rajasekaran c73d597d87 Merge pull request #2961 from filecoin-project/asr/genesis-premined
Revise TotalCircSupply
2020-08-12 17:12:54 -04:00
Łukasz Magiera e83fa0dd04 Merge pull request #3009 from filecoin-project/feat/offline_commp_calculation
Stop requiring miner address / sector size for `lotus client commP`
2020-08-12 22:51:34 +02:00
Łukasz Magiera 73ad453748 Merge pull request #3010 from filecoin-project/fix/paych-sentinel-type
Use regular cid as paych sentinel type
2020-08-12 22:49:56 +02:00
Łukasz Magiera 8408a56e55 Merge pull request #3005 from filecoin-project/feat/max-msg-fee-config
Miner fee config
2020-08-12 22:37:15 +02:00
Dirk McCormick e689c305d2 fix: revert to using cid for paych wait sentinel 2020-08-12 16:29:44 -04:00
Łukasz Magiera 12f7e2d9bf Use a struct for send metadata in MpoolPushMessage 2020-08-12 22:17:29 +02:00
Aayush Rajasekaran 5b280057b8 Move genesis locked funds into filVested 2020-08-12 16:16:35 -04:00
Peter Rabbitson fd49ef8de6 Stop requiring miner address / sector size for lotus client commP
At present, and at least for the medium term (even with the transition to NSE)
the structure of a piece (and thus commP) will remain identical for every size
of sector.

The offline deal flow would benefit greatly if the `lotus client commP`
interface is able to calculate commP without having access to a fully synced
sync, or without even being online.

This is particularly important for filecoin-discover, as we want to allow
miners to spot-check their purchased HDDs, way before they need to accept
the mainnet deal proposals.

See comment/links in node/impl/client/client.go for details on code flow
2020-08-12 22:03:00 +02:00
Łukasz Magiera fd4d2067a9 mpool: Fix capGasFee math 2020-08-12 22:01:31 +02:00
Łukasz Magiera e1a1b325bc Merge remote-tracking branch 'origin/next' into feat/max-msg-fee-config 2020-08-12 21:55:03 +02:00
Łukasz Magiera 43586ed9a1 Merge pull request #3000 from filecoin-project/feat/mpool-add-semaphore
Add semaphore in push and friends to reduce lock contention
2020-08-12 21:53:59 +02:00
Łukasz Magiera ba28169356 Merge remote-tracking branch 'origin/master' into next 2020-08-12 21:33:06 +02:00
Aayush Rajasekaran b6b5a79833 Get FilMined from the reward actor's state, not balance 2020-08-12 15:32:11 -04:00
Aayush Rajasekaran 165bcc1e38 Extract stmgr's genesis infos into a new struct 2020-08-12 15:32:11 -04:00
Aayush Rajasekaran 48ab706691 Subtract out genesis pledge and market funds when calculating circ supply 2020-08-12 15:32:11 -04:00
Aayush Rajasekaran fe2da35a45 Move GetCircSupply out of the vm, and into stmgr 2020-08-12 15:32:07 -04:00
Aayush Rajasekaran 5933e64de1 Include premined actors in vested funds calculation 2020-08-12 15:19:48 -04:00
Łukasz Magiera bfa0ae16b0 Merge pull request #2965 from filecoin-project/steb/update-actors
Update specs-actors & cbor-gen
2020-08-12 21:18:05 +02:00
Łukasz Magiera fd41a16f84 Merge pull request #3007 from filecoin-project/fix/rbf-gaspremoim
Validate message pool config, validate GasPremium < GasFeeCap
2020-08-12 20:40:08 +02:00
Łukasz Magiera 491e24c90a Merge pull request #2994 from filecoin-project/ingar/retrieval-logging
Generate more useful output during client retrieval
2020-08-12 20:36:14 +02:00
Jakub Sztandera f7c222e42e Validate message pool config, validate GasPremium < GasFeeCap
don't use configured RBF for mpool

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-12 20:31:34 +02:00
Łukasz Magiera 2a699e1de9 Merge pull request #3006 from filecoin-project/fix/disable-secio
RIP secio
2020-08-12 20:17:19 +02:00
vyzo e17732b365 remove secio support, replace with noise 2020-08-12 21:15:16 +03:00
vyzo e50ea377ef gomod: add go-libp2p-noise, remove go-libp2p-secio 2020-08-12 21:14:52 +03:00
Jakub Sztandera c68b023d3f Merge pull request #2939 from filecoin-project/feat/mpool-repub
Update messagepool republish logic
2020-08-12 20:08:28 +02:00
Łukasz Magiera 6fe743f3a9 Fix tests 2020-08-12 20:03:07 +02:00
Łukasz Magiera 03c1776b43 types: Add text (un)marshaler on FIL 2020-08-12 19:58:39 +02:00
Łukasz Magiera 78eaac6534 config: Test deafult toml roundtrip 2020-08-12 19:55:43 +02:00
Ingar Shu 8f56814ffb Change formatting, stringify errors before returning over JSONRPC 2020-08-12 10:54:15 -07:00
Łukasz Magiera 6f890a3edd Miner fee config 2020-08-12 19:47:09 +02:00
Steven Allen 6f031993ba Use the deadline open as the wpost commit epoch 2020-08-12 10:33:18 -07:00
Steven Allen 41f1c74ae2 Set a minimum sector lifetime 2020-08-12 10:33:18 -07:00
Steven Allen e18904bff5 [WIP] fix post submission 2020-08-12 10:33:18 -07:00
Steven Allen 5c715021c1 update chain-validation 2020-08-12 10:33:07 -07:00
vyzo 43b30a80c1 retry PushWithNonce if it fails with ErrTryAgain 2020-08-12 20:32:41 +03:00
Whyrusleeping ed72aa1307 implement randomness distinction 2020-08-12 10:32:39 -07:00
Steven Allen 9248e5a572 Update specs-actors, cbor-gen, and go-address 2020-08-12 10:32:39 -07:00
Steven Allen 9135a5d048 Pass bitfields by-value
This ensures we can't end up decoding nil bitfields from clients when not
expecting them.

Part of https://github.com/filecoin-project/specs-actors/issues/895. Please see
this issue for details and leave any comments there.
2020-08-12 10:32:39 -07:00
vyzo f2ac17845b relinquish the lock while signing in PushWithNonce 2020-08-12 20:26:58 +03:00
Łukasz Magiera d0147aa50f Add maxFee param to MpoolPushMessage 2020-08-12 19:06:16 +02:00
Łukasz Magiera 9d20a5c97b Merge pull request #3003 from filecoin-project/fix/charset-html
Set charset to UTF-8 in compute state output
2020-08-12 16:50:45 +02:00
Sami Mäkelä 5791765526 these were mixed up 2020-08-12 17:48:36 +03:00
Sami Mäkelä b179eaea21 updating this 2020-08-12 17:46:53 +03:00
Sami Mäkelä b252715f53 bad merge 2020-08-12 17:40:29 +03:00
Jakub Sztandera f2e89e6b16 Set charset to UTF-8 in compute state output
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-12 16:38:32 +02:00
Sami Mäkelä 8367e79279 now working 2020-08-12 17:36:07 +03:00
Sami Mäkelä 5169785c91 merge 2020-08-12 14:15:03 +03:00
Sami Mäkelä ac6e716ebd merge 2020-08-12 14:12:33 +03:00
Łukasz Magiera e2c6cc6c6d Merge pull request #2958 from filecoin-project/asr/sync-test
MessagesForTipset should filter out bad nonce messages
2020-08-12 13:05:57 +02:00
vyzo 7be18df6ea add semaphore in push and friends to reduce lock contention 2020-08-12 10:38:40 +03:00
vyzo 472e502218 fix republishing chain selection to account for edge case of inordinately long chains 2020-08-12 09:41:02 +03:00
vyzo 7b16fe3792 hold ts lock longer 2020-08-12 09:18:04 +03:00
vyzo 47f81f1ad6 increase repub message limit to 30 2020-08-12 09:13:57 +03:00
vyzo cf34fe5cc3 extend the republish interval to something more reasonable
pubsub timecache duration + 5 blocks + propagation delay
2020-08-12 09:13:57 +03:00
vyzo 7396212c89 slightly increase the replublish interval to include the propagation delay as well 2020-08-12 09:13:57 +03:00
vyzo e876617c82 new message republishing logic 2020-08-12 09:13:57 +03:00
vyzo 42951d05a5 refactor messagepool provider out of the main messagepool implementation 2020-08-12 09:13:57 +03:00
Aayush Rajasekaran 45cac72f7a Merge pull request #2996 from filecoin-project/asr/msg-nil
Add checks to ValidForBlockInclusion
2020-08-11 20:04:20 -04:00
Aayush Rajasekaran 922d568e12 Add checks to ValidForBlockInclusion 2020-08-11 19:51:12 -04:00
Łukasz Magiera a5e0a05932 Merge pull request #2995 from filecoin-project/feat/v28-proofs
v28 Proofs
2020-08-12 01:10:06 +02:00
Whyrusleeping 8c516df87b Merge pull request #2992 from filecoin-project/feat/configurable-chain-store-caches
add env vars to configure chain store cache sizes
2020-08-11 16:01:38 -07:00
Łukasz Magiera f537c48f93 v28 Proofs 2020-08-12 00:33:30 +02:00
Jakub Sztandera 4b93c5d194 Merge pull request #2993 from filecoin-project/fix/gasperf-div-0
Small fixes to mpool Trim
2020-08-12 00:31:35 +02:00
whyrusleeping 1fc768fb32 add env vars to configure chain store cache sizes 2020-08-11 15:07:17 -07:00
Jakub Sztandera 2efb18f677 Small fixes to mpool Trim
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 23:55:06 +02:00
Jakub Sztandera d6f9383528 Merge pull request #2979 from filecoin-project/feat/mpool-optimal-seletion
nearly optimal message pool seletion
2020-08-11 23:45:43 +02:00
Ingar Shu 02b0c8dd94 Watch context for completion also 2020-08-11 14:43:55 -07:00
Jakub Sztandera f018e870dc Address review
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 23:35:06 +02:00
Ingar Shu 53e06f358a client retrieval logging 2020-08-11 13:04:00 -07:00
vyzo 9032163c5a turn probability eyeballing into an actual test 2020-08-11 20:47:50 +03:00
Jakub Sztandera a45febc065 Fix MpoolLocker
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 19:32:31 +02:00
Łukasz Magiera 75f5afc0da Merge pull request #2985 from filecoin-project/refactor/paych-mgr-api
Refactor paych mgr apis for easier mocking
2020-08-11 19:23:52 +02:00
vyzo a467deede6 fix typos in comment 2020-08-11 20:20:59 +03:00
Łukasz Magiera 763074bb2d Merge pull request #2986 from filecoin-project/refactor/paych-wait-sentinel
Paych manager: use special type for wait sentinel
2020-08-11 19:17:32 +02:00
Dirk McCormick f857ee159e refactor: unify manager interfaces for easier mocks 2020-08-11 13:15:39 -04:00
vyzo 2aaf14b558 mute timing logs if they are under 1ms 2020-08-11 20:00:51 +03:00
Łukasz Magiera 01af855450 Merge pull request #2983 from nikkolasg/feat/cachedrand
Use cache of verified drand values
2020-08-11 18:34:14 +02:00
vyzo d3baf2b9eb fix edge case in chain creation 2020-08-11 19:32:28 +03:00
Łukasz Magiera 51cf4a5749 Merge pull request #2962 from filecoin-project/refactor/rip-paych-pubsub
Paych refactor: replace custom pubsub impl with lib
2020-08-11 18:32:05 +02:00
Łukasz Magiera 0409c5a482 Merge pull request #2944 from filecoin-project/feat/stmgr-wait-ignore-gas
stmgr: Allow replacing gas values in WaitMsg
2020-08-11 17:51:28 +02:00
Jakub Sztandera 56e3f7da7d Fix getGasReward and Trim
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 17:18:46 +02:00
Dirk McCormick a881e58cd6 refactor: use special type for paych wait sentinel 2020-08-11 10:45:45 -04:00
Jakub Sztandera 4da3aedacb Work on competitve test a bit
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
vyzo 0091f3a9ce add competitive selection test
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
vyzo 268d435ce0 add some optimal selection tests
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
Jakub Sztandera b309e80e41 Wire in Ticket Quality to MpoolSelect
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
Jakub Sztandera 2057433f48 Add needed files
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
Jakub Sztandera d3c8f295c2 Use real blockProbabilities function
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
vyzo 080614098d fix edge case of effective performance for chains that dont fit in any partition
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:27 +02:00
vyzo 8eff3a25f9 use BlockGasLimit instead of residual for partitioning
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:26 +02:00
vyzo 28fe602a9b pass a ticket quality to mpool.SelectMessages -- temporary
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:26 +02:00
vyzo ca803d99fe nearly optimal message selection for a given ticket quality
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-11 16:14:20 +02:00
nikkolasg 37fe0dbed2 correct return argument 2020-08-11 13:00:23 +01:00
nikkolasg 7a7cce2538 use cache from drand 2020-08-11 12:58:27 +01:00
Łukasz Magiera 657b390193 Bump version 2020-08-11 12:11:59 +02:00
Łukasz Magiera fe83334ed9 Merge pull request #2978 from filecoin-project/fix/buildall
Fix buildall / Bump API version
2020-08-11 12:08:18 +02:00
Łukasz Magiera 55355c4165 Bump API version 2020-08-11 10:22:58 +02:00
Łukasz Magiera 878b8c7678 Fix buildall 2020-08-11 10:22:49 +02:00
Łukasz Magiera f25611d768 Merge pull request #2974 from filecoin-project/asr/spelling
fix spelling
2020-08-11 10:17:26 +02:00
Łukasz Magiera 90b5e47fa5 Merge pull request #2976 from yaohcn/space-check
add space check in StorageFindSector
2020-08-11 10:06:33 +02:00
yaohcn 6b0f607f4b add space check in StorageFindSector 2020-08-11 15:27:03 +08:00
Aayush Rajasekaran 5e54219be9 fix spelling 2020-08-11 01:10:12 -04:00
Łukasz Magiera 957d83f069 Merge pull request #2955 from filecoin-project/refactor/paych-collect
Refactor: move paych collect inside manager
2020-08-11 01:42:10 +02:00
Łukasz Magiera c8a5e31d65 Merge pull request #2966 from filecoin-project/feat/slightly-nicer-chain-list
more informative chain list
2020-08-11 01:40:28 +02:00
whyrusleeping 347ed154b8 more informative chain list 2020-08-10 16:22:02 -07:00
Dirk McCormick 51444c7f18 refactor: replace custom paych pubsub with existing impl 2020-08-10 17:53:10 -04:00
Łukasz Magiera 6d85d379ba Merge remote-tracking branch 'origin/master' into next 2020-08-10 23:09:00 +02:00
Łukasz Magiera a86caaa11d Merge pull request #2947 from filecoin-project/feat/paych-merge-pending-add-funds
Payment channels manager: merge queued add funds
2020-08-10 22:32:21 +02:00
Aayush Rajasekaran 532c32a741 Add new BlockMsgsForTipset() 2020-08-10 15:55:44 -04:00
vyzo 45db0abb59 Merge pull request #2957 from filecoin-project/gomod/update-pubsub
update go-libp2p-pubsub@v0.3.4
2020-08-10 22:13:22 +03:00
vyzo 110ccfc88f gomod: update go-libp2p-pubsub@v0.3.4 2020-08-10 22:08:29 +03:00
Aayush Rajasekaran c72f853e09 Add a test around duplicate nonces 2020-08-10 14:28:02 -04:00
Dirk McCormick a6100b7e46 refactor: move collect inside paych manager 2020-08-10 13:21:25 -04:00
Łukasz Magiera fb0afbf3b0 Merge pull request #2949 from filecoin-project/feat/import-storage-repos
Import storage repos into lotus
2020-08-10 18:30:34 +02:00
Łukasz Magiera 624731cb80 More gomod fixing 2020-08-10 18:03:54 +02:00
Łukasz Magiera 641eb3e2cf Merge storage-fsm subtree 2020-08-10 17:40:27 +02:00
Łukasz Magiera 85d8133f4a Fix gomods 2020-08-10 17:31:14 +02:00
Dirk McCormick 0edf65855a feat: paychmgr - merge queued add funds 2020-08-10 11:26:13 -04:00
Łukasz Magiera 0eaf44eb31 Merge sector-storage subtree 2020-08-10 17:25:46 +02:00
Łukasz Magiera bc381fc053 stmgr: Allow changing gas values in WaitMsg 2020-08-10 14:55:52 +02:00
Łukasz Magiera 0d1174cb81 Merge pull request #2924 from filecoin-project/feat/mpool-cfg-overesitm
Add GasLimitOverestimation to mpool config
2020-08-10 11:33:05 +02:00
Jakub Sztandera 3710f33e14 Don't reject messages that don't pass RBF, ignore them
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 03:17:40 +02:00
Jakub Sztandera 5ea9df1824 Use 25% overesitm
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 02:22:37 +02:00
Jakub Sztandera a826877ee3 Reduce overesitm to 10%, remove pledgeSectors test rate limit
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 00:37:24 +02:00
Jakub Sztandera ea92f5f1ff Handle error
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 00:30:00 +02:00
Jakub Sztandera 46fd9d5e80 Quiet down pending messages, fix GasLimit estimation, reduce fee cap
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 00:29:59 +02:00
Jakub Sztandera b41a0ea197 Print number of prioris
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 00:29:59 +02:00
Jakub Sztandera ed2778f785 Make MpoolPushMessage message wait for the first message to be done
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-09 00:29:59 +02:00
vyzo bcb33d75d0 Merge pull request #2918 from filecoin-project/feat/mpool-tests
Some more mpool tests
2020-08-08 22:03:07 +03:00
Jakub Sztandera ae1ae58dd7 Add bash function for accessing API
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-08 17:10:09 +02:00
Jakub Sztandera 5f157affdd Add GasLimitOverestimation to mpool config
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-08 17:09:47 +02:00
Jakub Sztandera 44551124e2 Merge pull request #2923 from filecoin-project/feat/mpool-more-timings
also log chain creation timings
2020-08-08 16:13:15 +02:00
vyzo 9bc5d9489d also log chain creation timings 2020-08-08 17:07:37 +03:00
vyzo d04d947cb7 Merge pull request #2922 from filecoin-project/feat/mpool-timings
Add timings to various components of message selection
2020-08-08 17:01:13 +03:00
vyzo b469277046 use structured logging for timings 2020-08-08 16:59:08 +03:00
vyzo 809e7d5390 add timings to various components of message selection 2020-08-08 16:51:30 +03:00
vyzo 4cdb5f7b81 add unit test for priority message selection 2020-08-08 11:22:47 +03:00
vyzo 2d9f2c7e72 add unit test for message skipping in chain creation 2020-08-08 11:16:50 +03:00
Łukasz Magiera be1e7d33d5 Merge pull request #39 from filecoin-project/next
Next Staging Branch
2020-08-06 01:21:00 +02:00
Łukasz Magiera 967d887503 Merge pull request #63 from filecoin-project/fix/bugfixes
Fix a bunch sealing issues
2020-08-06 01:19:25 +02:00
Łukasz Magiera be1231fef4 Merge pull request #60 from filecoin-project/next
Next Staging Branch
2020-08-05 23:39:09 +02:00
Łukasz Magiera b7dca7fb4e Merge pull request #90 from filecoin-project/feat/fetch-reserve-space
remote: Fetch storage reservation
2020-08-05 23:37:00 +02:00
Łukasz Magiera 77e4adb556 gofmt 2020-08-05 22:11:53 +02:00
Łukasz Magiera deec7a2658 Merge remote-tracking branch 'origin/next' into feat/fetch-reserve-space 2020-08-05 19:39:33 +02:00
Łukasz Magiera 7c3197d9b0 Merge pull request #91 from yaohcn/fix-2806
fix 2806
2020-08-05 19:38:49 +02:00
yaohcn de3d3b48f7 fix 2806 2020-08-05 20:36:49 +08:00
Łukasz Magiera 9d9ea4e633 Fix a bunch sealing issues 2020-08-05 03:30:58 +02:00
Łukasz Magiera b8526edd5e Merge pull request #46 from chunqizhi/wenchu
Add case: Removed in fsm.go to avoid "unexpected sector update state: Removed"
2020-08-05 00:16:12 +02:00
Łukasz Magiera b58eba0d99 remote: Fetch storage reservation 2020-08-04 16:34:29 +02:00
Łukasz Magiera ad9a691e0a Merge pull request #89 from filecoin-project/fix/locking
Fix some locking issues
2020-08-04 00:37:49 +02:00
Łukasz Magiera 3cab915fd2 mock: Make it possible to unfail sectors 2020-08-03 20:49:04 +02:00
Łukasz Magiera ed251d9f82 Fix some locking issues 2020-08-03 14:18:11 +02:00
Whyrusleeping 898a72d078 Merge pull request #88 from filecoin-project/fix/readpiece-nounseal
Try to not unseal in ReadPiece when don't need to
2020-07-30 20:00:49 -07:00
Łukasz Magiera 7153e1dd05 Fix tests 2020-07-30 22:38:05 +02:00
Łukasz Magiera 3d2084ab93 Try to not unseal in ReadPiece when don't need to 2020-07-30 22:03:43 +02:00
Łukasz Magiera 12e79a1661 Merge pull request #61 from filecoin-project/fix/addpiece-math
Fixes to math in AddPiece
2020-07-30 14:39:17 +02:00
Łukasz Magiera d423ae90d8 Fixes to math in AddPiece 2020-07-30 14:22:05 +02:00
Łukasz Magiera 8a74e06161 Merge pull request #60 from filecoin-project/daviddias-patch-1
docs: add note to use lotus issue tracker
2020-07-30 14:21:13 +02:00
Łukasz Magiera d57f0e6460 Merge pull request #56 from yaohcn/sealing-ctx
add sealing context
2020-07-30 14:18:47 +02:00
Łukasz Magiera 33dfb9a9cc Merge pull request #84 from jackoelv/patch-1
Update local.go
2020-07-30 12:20:03 +02:00
Łukasz Magiera 48d1782e71 Merge pull request #87 from filecoin-project/daviddias-patch-1
Update README.md
2020-07-30 12:16:36 +02:00
Łukasz Magiera 15ca665c21 Typo 2020-07-30 12:16:04 +02:00
Łukasz Magiera 8e6525e6dd Merge pull request #86 from filecoin-project/asr/specs-update
Update go-bitfield and specs-actors
2020-07-30 12:13:05 +02:00
David Dias 224a60fb23 Update README.md 2020-07-30 08:33:52 +02:00
David Dias 6e73e4b68e docs: add note to use lotus issue tracker 2020-07-30 08:29:23 +02:00
Aayush Rajasekaran 3ee28c3b6d Update go-bitfield and specs-actors 2020-07-30 01:00:24 -04:00
Aayush Rajasekaran 32ef4ecbea Merge pull request #59 from filecoin-project/feat/separate-pc-deposit-func
Separate precommit deposit estimation func
2020-07-28 15:05:13 -04:00
Łukasz Magiera 33f96f051f Separate precommit deposit estimation func 2020-07-28 20:50:42 +02:00
jackoelv 366de97ab5 Update local.go
StorageBestAlloc returns a sorted slice of storage paths. if no break, It would alloc the worst-last path but not the first-best path.
2020-07-28 18:20:58 +08:00
Łukasz Magiera add7f0b4b0 Merge pull request #82 from filecoin-project/feat/sched-diag
Fix requestQueue iteration, diag methods
2020-07-27 15:17:25 +02:00
Łukasz Magiera 9377cb376d gofmt 2020-07-27 13:21:36 +02:00
Łukasz Magiera 510897a497 container/heap doesn't provide sorted array 2020-07-27 13:20:18 +02:00
Łukasz Magiera 9fd91bb70a sched: function to dump scheduler state 2020-07-27 12:17:50 +02:00
Łukasz Magiera 57868bafa6 Merge pull request #81 from xjrwfilecoin/calibration
modify workerRequest
2020-07-27 12:15:08 +02:00
ocean 7aa1ccf726 modify workerRequest 2020-07-27 14:21:29 +08:00
Łukasz Magiera 0eb4296519 Merge pull request #80 from filecoin-project/feat/remote-improvements
Remote store improvements
2020-07-25 23:36:16 +02:00
Łukasz Magiera 295300ff46 stores: Fix remote fetch move 2020-07-24 19:53:51 +02:00
Łukasz Magiera 94e20ffee5 remote: Fetch into temp files 2020-07-24 16:54:00 +02:00
Łukasz Magiera ff9ffddd57 remote: Limit parallel fetches 2020-07-24 16:43:46 +02:00
Łukasz Magiera ed2e57dde6 Merge pull request #77 from yaohcn/timeout-ctx
add RPC timeout
2020-07-23 22:09:50 +02:00
Łukasz Magiera 7fafaf81c0 Merge pull request #78 from filecoin-project/feat/mock-post
mock: More accurate WindowPost
2020-07-23 21:56:51 +02:00
Łukasz Magiera 3791008b01 mock: Fix tests 2020-07-23 19:46:51 +02:00
Łukasz Magiera b2fe2c0e3b mock: More accurate WindowPost 2020-07-23 19:00:20 +02:00
yaohcn fafecdfd17 add RPC timeout 2020-07-23 20:34:27 +08:00
yaohcn 977fefeb1b add sealing context 2020-07-23 19:55:06 +08:00
Łukasz Magiera 7c19c5b229 Merge pull request #76 from filecoin-project/feat/jobs-api
Add api to get active tasks
2020-07-22 23:37:12 +02:00
Łukasz Magiera c7da20e53c Add api to get active tasks 2020-07-21 20:01:25 +02:00
Łukasz Magiera 2cfe2fe3c3 Merge pull request #52 from filecoin-project/fix/update-gas
Use estimated gas for commit
2020-07-20 21:00:00 +02:00
Jakub Sztandera 5fd49d4d6a Use estimated gas for commit
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-07-20 20:34:59 +02:00
Łukasz Magiera f83d828b24 Merge remote-tracking branch 'origin/master' into next 2020-07-20 19:52:07 +02:00
Łukasz Magiera 5cc2358376 Merge pull request #51 from filecoin-project/asr/maxdeals
Enforce max deals per sector
2020-07-20 19:35:38 +02:00
Łukasz Magiera a06ded53e9 Merge pull request #47 from TroyWind/fix-precommit-failed-state
fix precommit1 failed state
2020-07-20 19:24:58 +02:00
Aayush Rajasekaran 2d46edace9 enforce max deals per sector 2020-07-20 12:43:19 -04:00
Łukasz Magiera a109ef9cbe Merge pull request #67 from filecoin-project/feat/windows
Window based scheduling
2020-07-17 23:35:54 +02:00
Łukasz Magiera d575c3a5f7 Merge pull request #48 from filecoin-project/feat/actors-miner-refactor
Updates for refactored miner actor
2020-07-17 14:55:41 +02:00
Łukasz Magiera 3932b81401 Use specs-actors master 2020-07-17 14:36:38 +02:00
Łukasz Magiera f1b3837186 fix worker setup/cleanup raciness 2020-07-17 12:59:12 +02:00
Łukasz Magiera 3c9fa8609a Merge remote-tracking branch 'origin/next' into feat/windows 2020-07-17 11:55:19 +02:00
Łukasz Magiera 908d47305b fix race in runWorker 2020-07-17 01:46:59 +02:00
Łukasz Magiera bf315e63d7 sched: working tests 2020-07-17 01:33:40 +02:00
Łukasz Magiera cab0c74e08 more sched test debugging 2020-07-17 01:26:55 +02:00
Łukasz Magiera 2e557573f4 gofmt 2020-07-16 23:41:15 +02:00
Łukasz Magiera be6b88f406 Some sched tests 2020-07-16 23:41:04 +02:00
Łukasz Magiera 0a6c939a73 Drop unused SectorInfo fields 2020-07-16 23:40:54 +02:00
Łukasz Magiera a846ac9b39 Merge pull request #72 from ribasushi/chore/pre-update-more-deps
Bump fil-commcid and filecoin-ffi deps
2020-07-16 23:06:53 +02:00
Peter Rabbitson d244749f1a Bump fil-commcid and filecoin-ffi deps
Propagates correct on-chain commX CIDs
2020-07-16 23:00:22 +02:00
Łukasz Magiera 16ab71d302 Merge branch 'next' into feat/windows 2020-07-16 19:32:34 +02:00
Łukasz Magiera e0d64c5ac6 Merge pull request #73 from filecoin-project/fix/proofs-rand
Correctly turn randomness into fr32 values
2020-07-16 18:29:22 +02:00
Łukasz Magiera 4f8015b58a Correctly turn randomness into fr32 values 2020-07-16 18:18:43 +02:00
Łukasz Magiera b79b3d0c00 Merge pull request #50 from filecoin-project/fix/update-gas
Allow lotus to decide gas limit and gas price
2020-07-15 21:47:33 +02:00
Jakub Sztandera 7e92e888bf Update gas limits, allows lotus to determine limit and price
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-07-15 21:12:02 +02:00
Łukasz Magiera 328439a8bf gofmt 2020-07-15 16:53:17 +02:00
Łukasz Magiera 041d70a7ff Updates for refactored miner actor 2020-07-15 16:51:02 +02:00
刘林欣 d4c8be92b0 fix precommit1 failed state 2020-07-15 09:41:35 +08:00
chunqizhi 3e226b5aaa Add case: Removed in fsm.go 2020-07-14 16:41:19 +08:00
Łukasz Magiera 1794862d73 Merge pull request #44 from filecoin-project/asr/mutex
Packing deals improvements
2020-07-13 12:58:10 +02:00
Łukasz Magiera 937eba4785 Merge pull request #70 from filecoin-project/asr/refactor
extract GetRequiredPadding
2020-07-13 12:52:43 +02:00
Łukasz Magiera fcb6255161 Merge pull request #45 from filecoin-project/asr/temp
Increase gas limit
2020-07-13 12:15:20 +02:00
Aayush Rajasekaran 6e92d6a6f0 Increase gas limit 2020-07-12 00:50:02 -04:00
Aayush Rajasekaran a92d59317c Acquire lock before allocating pieces to sectors 2020-07-11 22:33:04 -04:00
Aayush Rajasekaran 1d67dcfa3c extract GetRequiredPadding 2020-07-11 22:32:25 -04:00
Łukasz Magiera 045e597787 remove open windows when dropping workers 2020-07-11 01:21:48 +02:00
Łukasz Magiera a99a7fc484 Merge remote-tracking branch 'origin/master' into next 2020-07-10 10:37:27 +02:00
Łukasz Magiera f0dae546b5 Merge pull request #68 from filecoin-project/fix/darwin
Fix build on osx
2020-07-09 20:46:11 +02:00
Łukasz Magiera d1a18c15e6 Fix build on osx 2020-07-09 20:43:19 +02:00
Łukasz Magiera 7f115954fd sched: More fixes 2020-07-09 19:17:15 +02:00
Łukasz Magiera 5c5fe09990 post-rebase fixes 2020-07-09 15:18:45 +02:00
Łukasz Magiera 45c1b268f1 sched: Remove unused worker field 2020-07-09 15:10:06 +02:00
Łukasz Magiera 903731adaf sched: Fix tests 2020-07-09 15:10:06 +02:00
Łukasz Magiera da96f06202 sched: implement runWorker 2020-07-09 15:10:06 +02:00
Łukasz Magiera ac7dc28cfb sched: WIP Windows 2020-07-09 15:10:06 +02:00
Sami Mäkelä 0784e57082 handling verified price here 2020-07-09 13:36:22 +03:00
Łukasz Magiera a445979f1a Merge pull request #64 from chunqizhi/wenchu
Modity addCachePathsForSectorSize func to support 2KiB sector size devnet locally also
2020-07-09 08:43:16 +02:00
Łukasz Magiera e3b9ba01c2 Merge pull request #66 from filecoin-project/fix/es
Fixes / changes for fast-retrieval support
2020-07-08 21:51:34 +02:00
Łukasz Magiera 9af64c9b21 ffiwrapper: Fix UnsealPiece 2020-07-08 19:51:26 +02:00
Łukasz Magiera 56570a2200 mock: Implemet ReleaseUnsealed correctly 2020-07-08 17:39:58 +02:00
Łukasz Magiera c0a242a1eb fsutil: FileSize util 2020-07-08 17:09:35 +02:00
Łukasz Magiera 0bc41d562d Move statfs to fsutil 2020-07-08 16:58:18 +02:00
Łukasz Magiera 77cf6e49a0 Merge pull request #65 from filecoin-project/feat/local-space-alloc
Better storage reservation logic
2020-07-08 01:27:59 +02:00
Łukasz Magiera bc5e298e2b Merge pull request #43 from filecoin-project/asr/timer
Add a timer to auto-start sector sealing
2020-07-07 21:42:29 +02:00
Aayush Rajasekaran b838ed4e85 Add a timer to auto-start sector sealing 2020-07-07 15:19:27 -04:00
Łukasz Magiera ce8ec242f9 Merge pull request #63 from filecoin-project/feat/keep-unsealed
Unsealed copy changes
2020-07-07 02:15:36 +02:00
Łukasz Magiera ce2a500a06 Merge pull request #42 from filecoin-project/feat/fast-ret
Fast-retrieval copy plumbing
2020-07-07 02:15:01 +02:00
Łukasz Magiera ec9db30863 Add docstring to Sectorinfo.unsealedRanges 2020-07-07 02:14:25 +02:00
Łukasz Magiera 63ba9bd018 gofmt 2020-07-06 19:19:24 +02:00
Łukasz Magiera 63c62c49ce Fix tests 2020-07-06 19:19:13 +02:00
Łukasz Magiera 7279a80dfa localstorage: don't double count reserved storage 2020-07-06 18:56:46 +02:00
Łukasz Magiera 8099621cd0 stores: Allow reserving local storage 2020-07-06 18:36:44 +02:00
Łukasz Magiera c5a96fdd08 Change PathType to string 2020-07-06 16:13:42 +02:00
chunqizhi 7b9ab5e292 Fix an error in addCachePathsForSectorSize func 2020-07-06 17:49:05 +08:00
chunqizhi 837aba777f Modity addCachePathsForSectorSize func to support 2KiB sector size devnet locally also 2020-07-06 15:08:13 +08:00
Łukasz Magiera 0fd142153a mod tidy 2020-07-03 22:24:47 +02:00
Łukasz Magiera 636bf90f84 Don't error in ReleaseUnsealed 2020-07-03 22:23:36 +02:00
Łukasz Magiera 31d9abfc8c Implement FinalizeSector keepUnsealed 2020-07-03 21:52:31 +02:00
Łukasz Magiera 0503592af7 Fast-retrieval copy plumbing 2020-07-02 22:09:59 +02:00
Łukasz Magiera 171e0d0e4b Merge pull request #32 from filecoin-project/feat/cc-upgrade
CC upgrade
2020-07-02 00:12:41 +02:00
Łukasz Magiera 59ec727191 gofmt 2020-07-01 16:34:05 +02:00
Łukasz Magiera 495b4ba841 Fix precommit deposit math 2020-07-01 16:33:59 +02:00
Łukasz Magiera 3030e3a74f mod tidy, gofmt 2020-07-01 15:32:24 +02:00
Łukasz Magiera e2691f3b3d Basic CC Upgrade logic 2020-07-01 15:30:25 +02:00
Łukasz Magiera dd6398dbcb Merge pull request #40 from filecoin-project/feat/specs-actors-v0.7.0
Specs actors v0.7.0
2020-07-01 15:11:52 +02:00
Łukasz Magiera a2de752a33 Merge remote-tracking branch 'origin/master' into next 2020-07-01 11:21:05 +02:00
Łukasz Magiera 4c1968f62a Merge pull request #61 from filecoin-project/feat/ffi-0.30.1
Fileconi-FFI 0.30.1
2020-06-30 20:03:18 +02:00
Łukasz Magiera a53fff7608 Fix tests 2020-06-30 19:38:41 +02:00
Łukasz Magiera 6d02ac0290 mod tidy 2020-06-30 19:30:06 +02:00
Łukasz Magiera cff68a14d8 Adjust resource table for filecoin-ffi 0.30.1 2020-06-30 19:26:56 +02:00
Łukasz Magiera c1ac986f20 Update FFI 2020-06-30 19:05:47 +02:00
Łukasz Magiera afab9395b9 gofmt 2020-06-26 18:01:50 +02:00
Łukasz Magiera 408c9a7b33 Set precommit deposit correctly 2020-06-26 17:58:29 +02:00
Łukasz Magiera 9aec1e9484 Update specs-actors to v0.7.0 2020-06-26 17:29:08 +02:00
Łukasz Magiera c059934fe8 Merge pull request #38 from filecoin-project/asr/multiple-deals
Pack multiple deals into a sector
2020-06-26 13:02:27 +02:00
Łukasz Magiera 76ce3b9d94 Merge pull request #59 from filecoin-project/feat/gencommd-align-pieces
ffiwrapper: Insert alignment between pieces
2020-06-26 13:00:03 +02:00
Łukasz Magiera a8997dc35c ffiwrapper: Insert alignment between pieces 2020-06-25 21:57:26 +02:00
Aayush Rajasekaran a3c686d317 Try to pack deals into existing unsealed sectors before creating new ones 2020-06-25 13:47:14 -04:00
Aayush Rajasekaran 81a2792e37 Move sector number calculation into newSector 2020-06-25 13:36:04 -04:00
Aayush Rajasekaran ff8894f2ec Maintain a map of UnsealedSectorInfos 2020-06-25 13:36:04 -04:00
Aayush Rajasekaran 020f3a173a Squash Sealing's AllocatePiece and SealPiece into one method 2020-06-25 13:36:04 -04:00
Aayush Rajasekaran 73f5c68674 Non-CC sectors start with no pieces, can be added using addPiece() 2020-06-25 13:33:23 -04:00
Aayush Rajasekaran 7f75cd71da Resolve proof type when creating new sector 2020-06-25 13:33:23 -04:00
Aayush Rajasekaran eb17b2f371 Add a state for waiting on deals, and events for new deals and start packing 2020-06-25 13:33:23 -04:00
Aayush Rajasekaran db863a4de7 Add new event for start of CC sectors 2020-06-25 13:33:23 -04:00
Aayush Rajasekaran 5ad33896cc Do not allocate pieces that are bigger than a sector 2020-06-25 13:33:23 -04:00
Łukasz Magiera 379a4655b0 Merge pull request #36 from filecoin-project/feat/deal-sechd-prio
Give sector with deals priority in sealing
2020-06-25 18:08:32 +02:00
Łukasz Magiera b1b7c4257b Use sector-storage master 2020-06-25 17:46:35 +02:00
Łukasz Magiera 98ef8e4ef2 Merge pull request #58 from filecoin-project/feat/sched-prio
sched: Support external priority
2020-06-25 17:43:33 +02:00
Łukasz Magiera ddd1f21e5d sched: Support external priority 2020-06-25 16:45:25 +02:00
Łukasz Magiera a381a4174e Give sector with deals priority in sealing 2020-06-24 23:55:51 +02:00
Łukasz Magiera de544b5316 Merge pull request #56 from filecoin-project/feat/shed-sel-cmp-timeout
sched: Also handle timeout on selector Cmp
2020-06-24 00:46:36 +02:00
Łukasz Magiera cea46d8c8c sched: Also handle timeout on selector Cmp 2020-06-24 00:43:58 +02:00
Łukasz Magiera 72a1ed2fa3 Merge pull request #54 from hayeah/rpc-timeout
add RPC timeout to maybeSchedRequest
2020-06-24 00:33:00 +02:00
Łukasz Magiera 1cb2b0ac1c Merge pull request #55 from filecoin-project/fix/finsector-mv-none
fix: Don't try to move removed unsealed sector files
2020-06-24 00:19:33 +02:00
Łukasz Magiera 57bda914f9 fix: Don't try to move removed unsealed sector files 2020-06-24 00:04:02 +02:00
Łukasz Magiera fe71d5b42d Merge pull request #34 from filecoin-project/feat/cc-upgrade-1
Update storage interfaces, support removing sectors
2020-06-23 23:30:10 +02:00
Łukasz Magiera 8a3b7c575f Use sector-storage master 2020-06-23 23:15:29 +02:00
Łukasz Magiera 47d9335658 Merge pull request #53 from filecoin-project/feat/remove-sector
Update specs-storage, sector removing support
2020-06-23 23:05:24 +02:00
Howard Yeh be4112ee68 add RPC timeout to maybeSchedRequest 2020-06-23 17:42:47 +08:00
Łukasz Magiera 628c590c00 Drop unused faulty state logic 2020-06-22 18:55:53 +02:00
Łukasz Magiera 24fd125223 Implement a way to remove sectors 2020-06-22 18:55:53 +02:00
Łukasz Magiera d8c81e712e Upgrade sector-storage 2020-06-22 18:55:53 +02:00
Łukasz Magiera cc8670b956 Merge pull request #33 from filecoin-project/fix/missing-pc1
Handle missing on-chain precommit in WaitSeed
2020-06-22 18:51:31 +02:00
Łukasz Magiera 07cf84cbc7 Update specs-storage, sector removing support 2020-06-22 17:06:09 +02:00
Łukasz Magiera ffbfa84591 Merge pull request #52 from yaohcn/finalize-not-sched-unseal
finalize not sched on unsealed worker
2020-06-22 13:36:32 +02:00
Łukasz Magiera b6e250303e Handle missing on-chain precommit in WaitSeed 2020-06-22 13:09:31 +02:00
yaohcn 92a6ba8a57 finalize not sched on unsealed worker 2020-06-19 09:43:19 +08:00
Łukasz Magiera d9de9b7cb4 Merge pull request #51 from filecoin-project/fix/cache-check-paths
Fix/cache check paths
2020-06-18 09:32:00 +02:00
Whyrusleeping ad297f28b8 Merge pull request #50 from filecoin-project/fix/log-err
actually log the stat error in question
2020-06-17 20:00:23 -07:00
Jeromy 5d7d633595 check appropriate paths per sector size 2020-06-17 19:35:05 -07:00
Jeromy 1436e21761 actually log the stat error in question 2020-06-17 19:22:03 -07:00
Łukasz Magiera 4380106d3e Merge pull request #31 from filecoin-project/fix/handle-missng-pc-msg
checkCommit: handle missing precommit in handlePreCommitWait
2020-06-17 20:37:54 +02:00
Łukasz Magiera ce0b99ee9d checkCommit: handle missing precommit in handlePreCommitWait 2020-06-17 20:35:47 +02:00
Łukasz Magiera 77fc23c4d1 Merge pull request #30 from filecoin-project/fix/no-precommit-recover
checkCommit: handle missing precommits
2020-06-17 20:02:48 +02:00
Łukasz Magiera b2d14380b4 checkCommit: handle missing precommits 2020-06-17 17:19:36 +02:00
Łukasz Magiera 42c9e08595 Merge pull request #46 from filecoin-project/feat/faults-sealed-size
faults: Check sealed sector file size
2020-06-15 21:20:01 +02:00
Łukasz Magiera cb2dfb2e11 Merge pull request #49 from filecoin-project/fix/unseal-close-correct
ffiwrapper: Close the correct end of the pipe in unseal
2020-06-15 21:11:57 +02:00
Łukasz Magiera 0fea67f662 Merge pull request #48 from filecoin-project/feat/log-and-ignore-falloc
Log and ignore if fallocate is not supported
2020-06-15 21:05:12 +02:00
Jakub Sztandera e82d2ee8ee Log and ignore if fallocate is not supported
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-06-15 20:19:42 +02:00
Łukasz Magiera e530ff93c4 ffiwrapper: Close the correct end of the pipe in unseal 2020-06-15 19:59:20 +02:00
Łukasz Magiera 494c3bc487 Merge pull request #27 from filecoin-project/deps/specs-actors-v0.6
specs-actors v0.6
2020-06-15 18:27:49 +02:00
Łukasz Magiera bd2ff4e909 specs-actors v0.6 2020-06-15 18:26:01 +02:00
Łukasz Magiera 728a47ab99 Merge pull request #47 from filecoin-project/deps/actors-v0.6.0
specs-actors v0.6
2020-06-15 17:48:52 +02:00
Łukasz Magiera f3026a9ee6 mod tidy 2020-06-15 17:45:37 +02:00
Łukasz Magiera 3d1225bf34 gofmt 2020-06-15 16:28:57 +02:00
Łukasz Magiera b6ef7d5910 Merge pull request #26 from storswift/master
Fix a mistake in checkPrecommit
2020-06-15 15:08:35 +02:00
Łukasz Magiera f67bbbc457 specs-actors v0.6 2020-06-15 14:32:17 +02:00
Łukasz Magiera 14c615dead faults: Check sealed sector file size 2020-06-15 12:54:12 +02:00
marco-storswift 0092bff922 fixed #25
ticketEpoch := epoch - SealRandomnessLookback in the func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.SealRandomness, abi.ChainEpoch, error) {
2020-06-12 14:48:33 +08:00
Łukasz Magiera 41f6d62a51 Merge pull request #45 from filecoin-project/fix/double-runlock
local store: Fix double RUnlock
2020-06-10 14:27:46 +02:00
Łukasz Magiera 40712b1026 local store: Fix double RUnlock 2020-06-10 14:08:03 +02:00
Łukasz Magiera 252c2b0c96 Merge pull request #44 from filecoin-project/feat/v27
v27 parameters
2020-06-10 01:15:55 +02:00
Łukasz Magiera 52782b6def ffiwrapper: Fix AddPiece with multireaders 2020-06-09 22:10:14 +02:00
Łukasz Magiera 57adda40f9 ffiwrapper: Test FD leaks 2020-06-09 12:24:03 +02:00
Łukasz Magiera edb4a1ee9e Fix addpiece and unsealRange 2020-06-09 12:06:21 +02:00
Łukasz Magiera 9dfe8851f8 vet fixes 2020-06-09 11:14:25 +02:00
Łukasz Magiera 3cd79b6fec wip fixing addpiece 2020-06-09 11:13:23 +02:00
Łukasz Magiera 796af1351c v27 parameters 2020-06-09 01:02:44 +02:00
Łukasz Magiera bccaf69712 Merge pull request #43 from filecoin-project/feat/better-fault-checks
A bunch of PoSt improvements
2020-06-08 22:32:46 +02:00
Łukasz Magiera 1902049972 mock: Update interface 2020-06-08 20:30:48 +02:00
Łukasz Magiera 375a6b4d38 verifier: Handle sector unlocking correctly 2020-06-08 19:57:34 +02:00
Łukasz Magiera 8e489cdbdb verifier: Skip sectors which can't be acquired 2020-06-08 19:36:41 +02:00
Łukasz Magiera 8c58fcb1cc verifier: update interfaces 2020-06-08 19:22:15 +02:00
Łukasz Magiera 547bf93f4a roprov: Use TryLock 2020-06-08 18:57:56 +02:00
Łukasz Magiera 1a5af8cafd Improve fault checker 2020-06-08 18:47:59 +02:00
Łukasz Magiera 4b9317d1f0 Merge pull request #42 from filecoin-project/feat/allow-commit1-anywhere
Allow Commit1 anywhere
2020-06-05 21:27:46 +02:00
Łukasz Magiera f92ef92193 Make ctxCond nicer 2020-06-05 20:04:59 +02:00
Łukasz Magiera 958f74340b mock: Fix concurrent map writes in AddPiece 2020-06-05 18:43:47 +02:00
Łukasz Magiera c06dc750da Address review 2020-06-05 16:52:59 +02:00
Łukasz Magiera aa405b2176 Merge pull request #24 from filecoin-project/feat/improvements
A bunch of improvements for more reliable sealing
2020-06-05 10:23:04 +02:00
Łukasz Magiera 13176e8b53 Cleanup PathType usages 2020-06-04 23:30:20 +02:00
Łukasz Magiera 05d703e53b Fix testworker 2020-06-04 21:19:15 +02:00
Łukasz Magiera b3cde66bd2 Recover from half-successful FinalizeSector 2020-06-04 21:15:15 +02:00
Łukasz Magiera aac3c448a4 Drop AcquireSector locks 2020-06-04 21:00:16 +02:00
Łukasz Magiera 8ad1af106d Retry precommit2 once before redoing precommit1 2020-06-04 17:30:36 +02:00
Łukasz Magiera b5674f12f0 Allow FinalizeSector on all nodes 2020-06-03 23:45:05 +02:00
Łukasz Magiera 1f5aa7fb7d Auto-retry failed finalize 2020-06-03 23:42:17 +02:00
Łukasz Magiera 7fc7221348 Use correct SealRandomnessLookbackLimit 2020-06-03 22:57:44 +02:00
Łukasz Magiera a39bc94c58 Integrate index locks into manager 2020-06-03 22:00:43 +02:00
Łukasz Magiera d9d3ccf6c6 index: Implement basic global sector locking system 2020-06-03 21:21:27 +02:00
Łukasz Magiera 1467fe4226 Fix tests 2020-06-03 12:50:56 +02:00
Łukasz Magiera 222f3d876c Fix handling of re-precommit 2020-06-02 23:45:28 +02:00
Łukasz Magiera 9b92e145e7 Try to re-precommit on consecutive failed commit proof compute 2020-06-02 22:30:40 +02:00
Łukasz Magiera 9df0cdf193 Merge pull request #34 from filecoin-project/feat/unseal
Unseal support
2020-05-29 19:52:41 +02:00
Łukasz Magiera 9e7eb3feef Remove dead commented code 2020-05-29 19:40:49 +02:00
Łukasz Magiera 8b9dbc22e5 fr32: Fix tests 2020-05-29 19:06:44 +02:00
Łukasz Magiera 2184f21dd2 make unseal actually work in lotus 2020-05-29 18:57:44 +02:00
Łukasz Magiera 3b698db127 fr32: real PadWriter 2020-05-29 17:21:21 +02:00
Łukasz Magiera 2a70ff3cf3 wireup fr32 padding to the unsealed file 2020-05-29 01:33:00 +02:00
Łukasz Magiera 55867ab48b fr32: io.Reader utils 2020-05-29 00:17:29 +02:00
Łukasz Magiera d38296a553 fr32: More testing 2020-05-28 19:49:25 +02:00
Łukasz Magiera 4db8351348 fr32 utils 2020-05-28 19:15:15 +02:00
Whyrusleeping cdada6e889 Merge pull request #23 from filecoin-project/feat/batch-verify-porep-handling
handle poreps being batch verified
2020-05-27 22:06:23 -07:00
Jeromy 4d4f8c1f9c handle poreps being batch verified 2020-05-27 17:10:50 -07:00
Whyrusleeping f49b328e17 Merge pull request #20 from filecoin-project/feat/pre-commit-wait-state
add a new state for precommit wait
2020-05-27 11:35:32 -07:00
Łukasz Magiera e3d3887a0b Address review 2020-05-26 21:08:51 +02:00
Łukasz Magiera ffaeb89347 Merge remote-tracking branch 'origin/master' into feat/unseal 2020-05-26 19:05:35 +02:00
Łukasz Magiera 8586b98c1a Merge pull request #40 from filecoin-project/deps/update-ffi
update to latest filecoin-ffi
2020-05-26 18:37:25 +02:00
Łukasz Magiera 9690e84722 mod tidy 2020-05-26 18:36:19 +02:00
Łukasz Magiera 65f04da920 mock: Update interface 2020-05-26 16:39:25 +02:00
Łukasz Magiera 6fe92ff13c go fmt 2020-05-26 10:25:29 +02:00
Łukasz Magiera 793d332002 Move UnpaddedByteIndex from FFI wrapper 2020-05-26 10:25:17 +02:00
Łukasz Magiera e06cfd24cf mock: Update unseal method 2020-05-26 10:19:42 +02:00
Jeromy a59ca7536a update to latest filecoin-ffi 2020-05-21 18:19:46 -07:00
Whyrusleeping 83fd743db8 Merge pull request #21 from filecoin-project/deps/update-ffi
update to latest filecoin-ffi
2020-05-21 18:05:18 -07:00
Jeromy fad9412c04 update to latest filecoin-ffi 2020-05-21 18:03:34 -07:00
Łukasz Magiera 8898eb8206 Merge remote-tracking branch 'origin/master' into feat/unseal 2020-05-20 22:29:05 +02:00
Łukasz Magiera 33673a30c7 Wire up unsealing logic, track primary sector copies 2020-05-20 18:36:46 +02:00
Łukasz Magiera 21f02924c1 Merge pull request #39 from jsign/jsign/ffx
mock: produce more valid PoSt proof
2020-05-20 16:30:55 +02:00
Ignacio Hagopian 806f7b33aa produce more valid post proof
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
2020-05-20 11:16:45 -03:00
Whyrusleeping ca37a9086f Merge pull request #38 from jsign/jsign/postfake
mock: add faked post
2020-05-19 17:50:31 -07:00
Ignacio Hagopian f9e495ac49 mock: add faked post
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
2020-05-19 21:27:21 -03:00
Łukasz Magiera 8f70192bf3 Missing stuff 2020-05-19 18:11:56 +02:00
Łukasz Magiera 05bc399afc Update testworker 2020-05-19 18:09:48 +02:00
Łukasz Magiera 78c0b8f985 ffiwrapper: Test unsealing 2020-05-19 01:03:49 +02:00
Jeromy 06bcde9c2d add a new state for precommit wait 2020-05-18 15:49:21 -07:00
Łukasz Magiera 86f3c0916e ffiwrapper: UnsealPiece 2020-05-19 00:08:11 +02:00
Łukasz Magiera a9631587f0 Merge pull request #33 from filecoin-project/feat/sched-sequential-ids
sched: Take sector numbers into accout when scheduling work
2020-05-18 15:31:36 +02:00
Łukasz Magiera f577c2120c Partial Files, use for sealing 2020-05-18 15:22:35 +02:00
Łukasz Magiera e620df4c43 Merge pull request #37 from filecoin-project/feat/veryverysimplefaultchecks
Very simple fault check function
2020-05-16 23:22:31 +02:00
Łukasz Magiera 450b0b8acb very simple fault check function 2020-05-16 23:08:24 +02:00
Łukasz Magiera 4065c94c1f Scaffolding for UnsealRange 2020-05-16 01:10:04 +02:00
Łukasz Magiera 920c43f589 Merge pull request #36 from filecoin-project/fix/less-commit2-mem
resources: relax memory requirements for commit2
2020-05-15 20:17:56 +02:00
Ignacio Corderi 744fc321e9 Merge pull request #19 from filecoin-project/icorderi/18
feat: Remove unused deal state from api.StateMarketStorageDeal signature

This is a breaking change on the SealingAPI
The StateMarketStorageDeal method now returns a tuple instead of a triple.

Fixes #18
2020-05-15 15:10:31 -03:00
Ignacio Corderi e2150fd66e feat: remove unused return argument from storage deal
This is a breaking change on the `SealingAPI`
- The `StateMarketStorageDeal` method now returns a tuple instead of a triple.
2020-05-15 13:31:32 -03:00
Łukasz Magiera 20817dc51d resources: relax memory requirements for commit2 2020-05-15 14:33:04 +02:00
Łukasz Magiera 617d34b9de sched: Take sector numbers into accout when scheduling work 2020-05-14 01:58:01 +02:00
Łukasz Magiera 4051533cc4 Merge pull request #32 from filecoin-project/fix/pc1-fail-cleanup
Cleanup before retrying precommit1
2020-05-13 20:52:32 +02:00
Łukasz Magiera 2bc21be319 Cleanup before retrying precommit1 2020-05-13 20:45:14 +02:00
Łukasz Magiera ebc27d314b Merge pull request #31 from filecoin-project/feat/64g
Add entries for 64G sectors
2020-05-09 02:51:26 +02:00
Łukasz Magiera 845502f522 Add entries for 64G sectors 2020-05-09 02:50:08 +02:00
Łukasz Magiera 4980cb4c92 Merge pull request #16 from filecoin-project/feat/v26-parameters
use v26 parameters + update sector-storage to drop lotus transitive dep
2020-05-08 23:23:39 +02:00
laser b565215d58 update sector-storage + go mod tidy 2020-05-08 14:14:41 -07:00
laser 32d092b293 v26 groth parameters 2020-05-08 14:13:37 -07:00
Łukasz Magiera a74812ba12 Merge pull request #30 from filecoin-project/feat/v26-proofs
update filecoin-ffi (and related) to v26 proofs
2020-05-08 22:34:01 +02:00
laser b24920c606 update to v26 proofs 2020-05-08 13:08:02 -07:00
Łukasz Magiera c395e40963 Merge pull request #29 from filecoin-project/feat/heartbeat
Improve storage selection logic
2020-05-08 21:24:01 +02:00
Łukasz Magiera 164e2214c3 Merge pull request #28 from filecoin-project/feat/basic-tests
Add some basic tests
2020-05-08 20:27:19 +02:00
Łukasz Magiera 170cc0e275 Add some basic tests 2020-05-08 20:01:42 +02:00
Łukasz Magiera e721b8910c stores: use heartbeat info in selecting alloc storage 2020-05-08 19:02:18 +02:00
Łukasz Magiera fc637552b7 stores: Simple health reporting 2020-05-08 18:08:48 +02:00
Łukasz Magiera 8c47b13d9e Merge pull request #27 from filecoin-project/fix/unseal
Fix unseal; some improvements
2020-05-08 02:05:08 +02:00
Łukasz Magiera ced1d6e087 Priority queue for tasks 2020-05-08 02:03:21 +02:00
Łukasz Magiera 1bbfb7cffd Fix ffiwrapper unseal 2020-05-08 00:23:07 +02:00
Łukasz Magiera 10f7750d80 v26 resource table 2020-05-08 00:22:37 +02:00
Łukasz Magiera e4a9a16161 Merge pull request #24 from filecoin-project/feat/worker-closing
sched: Handle closing workers better
2020-05-01 20:11:53 +02:00
Łukasz Magiera 780596477c gofmt 2020-05-01 20:04:21 +02:00
Łukasz Magiera cb0bb31d06 sched: Handle closing workers 2020-05-01 20:00:17 +02:00
Erin Swenson-Healey a03f325ffa Merge pull request #23 from filecoin-project/bugs/remove-lotus-dependency
remove lotus from dependency graph
2020-05-01 09:36:38 -07:00
laser a4ee6e27b9 ignore unused field 2020-05-01 09:31:34 -07:00
laser 593d2fce21 ignore build artifacts 2020-05-01 09:18:57 -07:00
laser f0569bd3c4 remove lotus from dependency graph 2020-05-01 09:18:00 -07:00
Łukasz Magiera 1da6937a0f sched: Try scheduling on newly connected workers 2020-05-01 17:29:27 +02:00
Łukasz Magiera 83b1b94034 Merge pull request #20 from filecoin-project/feat/overallocate
Refactor scheduling logic
2020-04-29 20:06:15 +02:00
Łukasz Magiera 7f1c9c89e7 remote store: Handle parallel fetches 2020-04-29 17:58:55 +02:00
Łukasz Magiera dd23715942 sched: add missing check for non-multicore thread availability 2020-04-29 17:04:40 +02:00
Łukasz Magiera 38cf04b888 sched: prefer workers with lower utilization 2020-04-29 16:04:05 +02:00
Łukasz Magiera 9777ddd2b7 stores: nicer error when sector was lost 2020-04-29 16:03:44 +02:00
Łukasz Magiera a0af4d4d2b index: hold rlock in StorageList 2020-04-29 14:13:21 +02:00
Łukasz Magiera e970fa09b0 Merge pull request #21 from filecoin-project/anorth/specs-actors
Upgrade to specs-actors v0.3.0
2020-04-29 10:21:30 +02:00
anorth 5ab39592cf Upgrade to specs-actors v0.3.0 2020-04-29 13:36:31 +10:00
Łukasz Magiera 5f1a27d52b sched: Address review 2020-04-28 12:34:07 +02:00
Łukasz Magiera d57877af31 sched: Fix error handling in assignWorker 2020-04-27 22:59:17 +02:00
Łukasz Magiera d399312786 sched: virtual resource pool for prefetching sector data 2020-04-27 22:50:30 +02:00
Łukasz Magiera 8c4dc60e75 move scheduling logic to a separate struct 2020-04-27 20:37:36 +02:00
Łukasz Magiera 01487d5ad3 Merge pull request #14 from filecoin-project/anorth/specs-actors
Upgrade to specs-actors v0.2.0
2020-04-27 20:20:14 +02:00
Łukasz Magiera 5bea676ce3 worker: Fetch task type 2020-04-27 14:55:37 +02:00
Łukasz Magiera f59d6b971b sched: Nicer handling of multicore tasks 2020-04-27 14:38:24 +02:00
Łukasz Magiera 2ef195583f Add Makefile 2020-04-27 13:43:59 +02:00
Łukasz Magiera c19a254498 Merge pull request #19 from filecoin-project/anorth/specs-actors
Upgrade to specs-actors v0.2.0
2020-04-25 12:23:15 +02:00
anorth 14256e22d3 Upgrade to specs-actors v0.2.0 2020-04-25 12:37:12 +10:00
anorth 368d07ad9c Upgrade to specs-actors v0.2.0 2020-04-25 12:32:51 +10:00
Łukasz Magiera 9404c859cb Merge pull request #18 from filecoin-project/feat/no-ffi-workerinfo
Move WorkerInfo to not require importing ffi
2020-04-24 00:23:24 +02:00
Łukasz Magiera 9eb049a833 move WorkerInfo to not require importing ffi 2020-04-24 00:20:53 +02:00
Whyrusleeping ec2b62c042 Merge pull request #12 from filecoin-project/feat/commit-collateral
Set pledge collateral in commit message
2020-04-23 09:17:48 -07:00
Łukasz Magiera f3bea4aa8b Set pledge collateral in commit message 2020-04-23 13:42:51 +02:00
Łukasz Magiera 1283a89a95 Merge pull request #11 from filecoin-project/anorth/tickets
Compute seal ticket internally, remove node ticket fn
2020-04-23 13:18:48 +02:00
anorth 29460c440d Compute seal ticket internally, remove node ticket fn 2020-04-23 10:13:02 +10:00
Łukasz Magiera 5963a2c82e Merge pull request #9 from filecoin-project/anorth/specs-actors
Update to specs-actors v1.0.0
2020-04-22 11:15:33 +02:00
Łukasz Magiera 6a3320b113 Merge pull request #16 from damonlau27/master
prefer remote worker
2020-04-22 10:51:39 +02:00
Łukasz Magiera 9230b22ea4 Merge pull request #15 from filecoin-project/anorth/specs-actors
Update to specs-actors v1.0.0
2020-04-22 10:48:02 +02:00
damonlau27 c1888035ac prefer remote worker 2020-04-22 16:18:02 +08:00
anorth f784a9098f Update to specs-actors v1.0.0 2020-04-22 15:51:19 +10:00
anorth a875473670 Update to specs-actors v1.0.0 2020-04-22 15:49:28 +10:00
Łukasz Magiera 1515cffb5d Merge pull request #8 from filecoin-project/fix/rand-entropy
Add correct entropy to randomness
2020-04-20 20:32:20 +02:00
Łukasz Magiera 7da71113a7 Add correct entropy to randomness 2020-04-20 20:21:11 +02:00
Łukasz Magiera e75536581a Merge pull request #12 from filecoin-project/fix/mock-winpost
mock: fix winning post challenge generation
2020-04-18 00:54:59 +02:00
Łukasz Magiera 16d40dfd15 mock: fix winning post 2020-04-18 00:52:42 +02:00
Łukasz Magiera 2dd3cc4875 Merge pull request #11 from filecoin-project/feat/separate-genwinchg
Move GenerateWinningPoStSectorChallenge to Verifier
2020-04-17 22:46:21 +02:00
Łukasz Magiera 9209a5f186 Merge pull request #6 from filecoin-project/feat/update-actors
Update specs-actors, windowed post updates
2020-04-17 22:45:56 +02:00
Łukasz Magiera fda71dbf53 Fix tests 2020-04-17 22:16:52 +02:00
Łukasz Magiera f2744cf099 policy: Round up expiration to nearest ProvingPeriod 2020-04-17 21:47:44 +02:00
Łukasz Magiera 6850784b1e Move GenerateWinningPoStSectorChallenge to Verifier 2020-04-17 16:00:21 +02:00
Łukasz Magiera afc45d4b6e mod tidy 2020-04-15 20:00:41 +02:00
Łukasz Magiera c19538f834 Update specs-actors 2020-04-15 20:00:29 +02:00
Łukasz Magiera 069c3b2468 Merge pull request #5 from filecoin-project/feat/v25
Update to v25 proof parameters
2020-04-13 22:09:47 +02:00
Łukasz Magiera 26b8ff722d Update Deps 2020-04-13 22:00:04 +02:00
Whyrusleeping 61616264b1 Merge pull request #10 from filecoin-project/feat/v25
Update proofs to v25 parameters, win PoSt
2020-04-10 17:02:42 -07:00
Łukasz Magiera 9d548f7432 Use FFI master 2020-04-11 01:28:57 +02:00
Łukasz Magiera 4c010a03af Update Deps 2020-04-10 23:16:48 +02:00
Łukasz Magiera 92e77fbba5 Update FFI 2020-04-10 23:12:11 +02:00
Łukasz Magiera c0d619cd86 gofmt 2020-04-10 23:01:42 +02:00
Łukasz Magiera cd464ef916 Drop SectorSizeForRegisteredProof 2020-04-10 23:01:35 +02:00
Łukasz Magiera 65efbfce12 Fix tests with v25 params 2020-04-10 21:13:47 +02:00
Łukasz Magiera e854090bdd v25 2020-04-10 20:46:53 +02:00
Łukasz Magiera 8fc0fd3221 Merge pull request #4 from filecoin-project/feat/dynamic-worker-address
we should always load worker address from the chain
2020-04-09 20:49:38 +02:00
laser 7b387ba4b2 fix error message 2020-04-09 10:46:44 -07:00
laser 5f3a3c76dd we should always load worker address from the chain 2020-04-09 10:34:07 -07:00
Erin Swenson-Healey 1c35692235 Merge pull request #3 from filecoin-project/feat/pre-commit-expiration-policy
initialize FSM with pre-commit expiry policy
2020-04-08 08:39:57 -07:00
laser f2649af5a1 rename pdi ("peace with deal info") -> p ("piece") 2020-04-08 07:56:35 -07:00
laser 1dfca2ff76 drop unused method brought in via rebase 2020-04-08 07:52:47 -07:00
laser 0cd4e0413f renaming PieceWithOptionalDealInfo -> Piece, drop PieceWithDealInfo 2020-04-08 07:52:20 -07:00
laser 5f3990d1bc remove unused, intermediate literal 2020-04-08 07:39:47 -07:00
laser c9dd3b3238 fix typo ("of" instead of "or") 2020-04-08 07:39:47 -07:00
laser 1f1e291cd1 use pre-commit policy to set pre-commit sector expiry epoch 2020-04-08 07:39:47 -07:00
laser de07fe8aaf persist deal schedule to piece data for pre-commit sector expiry 2020-04-08 07:39:47 -07:00
Erin Swenson-Healey 5326cb55b3 Merge pull request #2 from filecoin-project/feat/ticket-fn-takes-token
ticket-acquiring function takes tipset identifier
2020-04-08 07:39:38 -07:00
laser 55e54593cc fix(ticketfn): getting a ticket should take tipset identifier 2020-04-07 13:26:43 -07:00
laser 7c7b9b6a63 remove now-unused ChainReadObj 2020-04-07 13:20:52 -07:00
Łukasz Magiera 25993479b1 Merge pull request #1 from filecoin-project/feat/extract-lotus-goodies
extract "sealing" package into storage-fsm project
2020-04-07 18:32:48 +02:00
laser 32cf7ec677 need parameters.json for vk and groth parameter downloading (circleci) 2020-04-06 17:40:12 -07:00
laser d4d58047b0 add licenses and basic readme scaffolding 2020-04-06 17:38:48 -07:00
laser 8f682303ca configure CI, move types around, prepare for consumption by lotus 2020-04-06 17:29:52 -07:00
laser 52afe582e1 Merge branch 'testnet/3' of /tmp/lotus into feat/extract-lotus-goodies 2020-04-06 16:20:09 -07:00
Erin Swenson-Healey a2933084ca Initial commit 2020-04-06 16:16:49 -07:00
laser 8006f12dea SectorID -> SectorNumber 2020-04-06 15:31:33 -07:00
laser b7be24d775 revert name change 2020-04-06 14:05:26 -07:00
laser 0fc5ebf5b1 update CBOR encoders/decoders 2020-04-06 13:35:29 -07:00
laser b592a67892 move to types 2020-04-06 13:31:49 -07:00
laser f2cce14390 reorder imports 2020-04-06 13:27:14 -07:00
laser 70615df273 miscellaneous fixes post-rebase 2020-04-06 13:23:37 -07:00
laser 9b29210dce remove all lotus types from sealing package in preparation for extraction
events adapter

implement StateWaitMsg and StateComputeDataCommitment

implement StateGetSectorPreCommitOnChainInfo

implement ChainHead and SendMsg

implement remaining methods
2020-04-06 12:57:55 -07:00
Łukasz Magiera a6d0938385 Merge pull request #9 from filecoin-project/docs/architecture
readme: Add a section about architecture
2020-04-06 21:50:14 +02:00
Łukasz Magiera 0bc12be059 readme: Add a section about architecture 2020-04-06 21:44:45 +02:00
Łukasz Magiera c29cb87d2f fsm: Get correct interactive randomness if it lands on a nullblock 2020-04-04 04:57:05 +02:00
Łukasz Magiera dcfd0943d5 fsm: Handle invalid Commits 2020-04-04 03:50:05 +02:00
Łukasz Magiera 25bd37364c fsm: Update cbor-gen 2020-04-03 21:34:20 +02:00
Łukasz Magiera 4a6c5c25b0 fsm: Implement handlers for Commit errors 2020-04-03 19:45:48 +02:00
Łukasz Magiera 8c824dfaf7 sealing fsm: Separate precommit 1/2 2020-04-03 18:54:15 +02:00
Łukasz Magiera 5977db8833 fsm: Fix tests after changisg SectorState to a string 2020-04-03 18:36:48 +02:00
Łukasz Magiera abb433aa42 Change api.SectorState to a string 2020-04-03 18:29:31 +02:00
Łukasz Magiera 2c98869d96 Merge pull request #7 from filecoin-project/chores/address-pr-nit
bit shift 2 instead of 1 as per PR feedback
2020-04-02 01:56:33 +02:00
Łukasz Magiera 0cf0240cb5 Merge pull request #8 from filecoin-project/chores/add-various-docs
add README + basic CircleCI configuration
2020-04-02 01:55:41 +02:00
laser 9339232946 shift by multiple of 10 2020-04-01 16:26:47 -07:00
laser b17b226220 one line gofmt 2020-04-01 16:22:32 -07:00
laser 431a15c14a nolint the existing linting errors 2020-04-01 16:18:20 -07:00
laser ffc966a9ad fix gofmt issue which ci caught 2020-04-01 16:14:04 -07:00
laser 58922b7e76 golangci-lint needs libfilcrypto 2020-04-01 16:13:20 -07:00
laser 5874d90719 ensure submodules are initialized 2020-04-01 16:11:32 -07:00
laser c694853ddb ci: check out code before running linters 2020-04-01 16:08:59 -07:00
laser fdc2e4a67a ci: run tests on build 2020-04-01 16:07:34 -07:00
laser fcaaae705d circleci: add shell config
- download groth parameters and keys
- perform go mod tidy check
2020-04-01 15:51:50 -07:00
laser ba291a9254 add CircleCI badge 2020-04-01 15:20:17 -07:00
laser feb97789c5 add README.md 2020-04-01 15:14:08 -07:00
laser c99952d8cd shift 2 2020-04-01 14:24:09 -07:00
Erin Swenson-Healey 7c07e3406e Merge pull request #6 from filecoin-project/feat/relax-testing-sector-constraints
loosen constraints on 8MiB and 2KiB sectors (for testing)
2020-04-01 12:09:56 -07:00
laser 0730ece757 loosen constraints on 8MiB and 2KiB sectors (for testing) 2020-04-01 11:56:32 -07:00
Łukasz Magiera c8928ff5d9 Extract sector-storage 2020-03-28 01:32:39 +01:00
Łukasz Magiera c4b928d441 Revert specs-actors version 2020-03-28 00:33:38 +01:00
Łukasz Magiera afebab334e Update imports; Add build scripts 2020-03-28 00:21:36 +01:00
Łukasz Magiera bbbe16531b Repo setup 2020-03-28 00:02:52 +01:00
Łukasz Magiera 089c769373 sectorstorage: Untangle from lotus deps 2020-03-27 22:35:33 +01:00
Łukasz Magiera 9be406482b sectorstorage: Untangle from lotus deps 2020-03-27 22:35:33 +01:00
Łukasz Magiera 353ecbc62d sectorstorage: Address review 2020-03-27 18:45:32 +01:00
Łukasz Magiera ed6202d202 Cleanup after dropping sectorbuilder 2020-03-26 20:35:16 +01:00
Łukasz Magiera 617e3135c1 Cleanup after dropping sectorbuilder 2020-03-26 20:35:16 +01:00
Łukasz Magiera 2dfa38f572 Merge sectorbuilder into sectorstorage 2020-03-26 03:51:06 +01:00
Łukasz Magiera e8e90300f0 Merge sectorbuilder into sectorstorage 2020-03-26 03:51:06 +01:00
Łukasz Magiera 3081a1b9c7 Fix sealing sectors with multiple pieces 2020-03-26 02:18:13 +01:00
Łukasz Magiera 0ce42d520a stores: Mute serve-stat debug log 2020-03-25 22:23:01 +01:00
Łukasz Magiera db93e784ab workers: gofmt 2020-03-25 21:20:24 +01:00
Łukasz Magiera 8c63b25704 stores: 'None' file type 2020-03-25 21:19:58 +01:00
Łukasz Magiera f22942b3c8 sectorstorage: Move sealed sectors to storage in FinalizeSector 2020-03-25 19:21:53 +01:00
Łukasz Magiera a975f018c5 Merge remote-tracking branch 'origin/testnet/3' into feat/new-workers 2020-03-25 01:02:23 +01:00
Łukasz Magiera 817e699738 sectorstorage: wire up closing logic 2020-03-25 00:52:55 +01:00
Łukasz Magiera d8f357b01c workers: More review related fixes 2020-03-25 00:37:40 +01:00
Łukasz Magiera cd892105f6 sectorstorage: Remove unsealed sector in FinalizeSector 2020-03-24 21:28:07 +01:00
Łukasz Magiera 2900bb099f storageminer: Config for local worker task types 2020-03-24 20:38:00 +01:00
Łukasz Magiera bb4983ee39 Merge remote-tracking branch 'origin/testnet/3' into feat/new-workers 2020-03-24 19:09:02 +01:00
Łukasz Magiera dce6d8e4ae workers: Address review 2020-03-24 19:01:04 +01:00
Aayush Rajasekaran 01828ef885 Re: #1412: Add a non-blocking version of StateWaitMsg
- This commit adds a new method called StateSearchMsg
- We can probably overhaul StateWaitMsg onto this new method at a later point in time
2020-03-24 06:43:15 -04:00
Łukasz Magiera 290b7ebd26 storageminer: More storage stats in storage list 2020-03-23 23:43:38 +01:00
Łukasz Magiera 6842b4cb46 sectorstorage: Enable sealing on the local worker by default 2020-03-23 17:28:40 +01:00
Łukasz Magiera 40060e3525 sectorstorage: Fix remote sector deletion 2020-03-23 16:40:36 +01:00
Łukasz Magiera 68e279b399 workers: Basic monitoring tools 2020-03-23 15:56:22 +01:00
Łukasz Magiera 15e9d6ba5a sector index: Don't add duplicate storage URLs 2020-03-23 13:12:43 +01:00
Łukasz Magiera a9443774a9 Rename agvmgr+sealmgr to sectorstorage 2020-03-23 12:47:10 +01:00
Łukasz Magiera e40c5d441d Rename agvmgr+sealmgr to sectorstorage 2020-03-23 12:47:10 +01:00
Łukasz Magiera 88ad4858ec gofmt 2020-03-22 22:39:27 +01:00
Łukasz Magiera 2fc1114ad2 sealing: Improve sector log 2020-03-22 21:44:27 +01:00
Jeromy ea4c93a044 update and rerun cbor gen 2020-03-21 14:17:01 -07:00
Łukasz Magiera 80c774ec49 storageminer: Fix preseal meta import for genesis miners 2020-03-20 01:20:01 +01:00
Łukasz Magiera 0b4979d20a workers: get sectors back to miner process after precommit 2020-03-19 20:17:58 +01:00
Łukasz Magiera dadcfb8101 Merge remote-tracking branch 'origin/testnet/3' into feat/new-workers 2020-03-19 03:28:55 +01:00
whyrusleeping e035f05564 change gas limit to be a normal int64 2020-03-18 13:45:37 -07:00
Łukasz Magiera 0a3d61435e Fix tests after specs-storage changes 2020-03-18 02:08:11 +01:00
Łukasz Magiera 6ce8cda0a3 Use new specs-storage interface 2020-03-17 21:19:52 +01:00
whyrusleeping d255b7d6e9 Merge branch 'master' into testnet/3 2020-03-07 16:46:12 -08:00
Łukasz Magiera 9476452c49 sealing: Fix noop plan loop 2020-03-07 00:03:57 +01:00
Aayush Rajasekaran 2fec889a11 Unify MethodCall and ReplayResults into SimulationResult
- Call and Replay now return the same type, which includes both Message and MessageReceipt
2020-03-06 11:10:40 -08:00
Łukasz Magiera dbca774e17 libs: Use go-statemachine 2020-03-06 20:01:03 +01:00
Łukasz Magiera d5a4051c7f libs: Use zerocomm from sectorbuilder 2020-03-06 19:50:41 +01:00
Łukasz Magiera 732ea1b882 sectorbuilder type updates 2020-03-06 06:38:59 +01:00
Łukasz Magiera 0e195410b5 sealmgr: Implement all sealing steps 2020-03-05 19:19:32 +01:00
Łukasz Magiera 63e3ee222b Merge remote-tracking branch 'origin/testnet/3' into feat/4stage-seal 2020-03-04 04:01:13 +01:00
Łukasz Magiera b31c8a56f7 Storage Manager refactor 2020-03-03 23:19:22 +01:00
whyrusleeping ed6c957001 more misc fixes 2020-03-01 17:09:38 -08:00
whyrusleeping 94073cfb5a progress is made incrementally 2020-02-28 14:00:34 -08:00
whyrusleeping cacb797d16 pass on proper sector types 2020-02-28 12:52:14 -08:00
whyrusleeping 47901c3fb7 fixing miner logic to make more tests pass 2020-02-28 11:31:28 -08:00
Łukasz Magiera c45a376dd6 Regen cbor marshalers 2020-02-28 00:34:48 +01:00
whyrusleeping 9e77a046a1 make it all build finally 2020-02-27 13:45:31 -08:00
Łukasz Magiera 628d90353d Merge branch 'feat/update-sectorbuilder' of github.com:filecoin-project/go-lotus into feat/update-sectorbuilder 2020-02-27 01:56:15 +01:00
Łukasz Magiera cec0b3c15f zerocomm: 'Fix' the test 2020-02-27 01:56:09 +01:00
whyrusleeping 300264bee1 more fixes for random garbage 2020-02-26 16:42:39 -08:00
Łukasz Magiera d1c15a2666 Some test fixes 2020-02-26 10:05:22 +01:00
Łukasz Magiera 5649f5a87f types: Drop some redundant alias types 2020-02-25 22:09:22 +01:00
Łukasz Magiera 9c5d2fff1a actors: Remove addrass aliases 2020-02-25 21:54:58 +01:00
Łukasz Magiera fc4fa38c9b actors: drop a bunch of type aliases 2020-02-25 21:35:15 +01:00
Łukasz Magiera 2f22fa416d post-upstream-merge fixes 2020-02-24 18:45:25 +01:00
Łukasz Magiera c8b9846705 Merge branch 'testnet/3' into feat/specs-actors 2020-02-24 18:32:02 +01:00
Łukasz Magiera 1dc80d4c04 Fix Sealing in TestAPIDealFlow 2020-02-23 21:33:10 +01:00
Łukasz Magiera ed8569eb99 More unified randomness handling 2020-02-23 21:00:47 +01:00
Łukasz Magiera 4b4368a898 Deal flow fixes 2020-02-23 16:50:36 +01:00
Łukasz Magiera d04c304c93 Implement committed capacity sectors 2020-02-23 01:47:47 +01:00
Łukasz Magiera da236a26fc Generate zero CommP table 2020-02-22 15:06:38 +01:00
Łukasz Magiera 65b91a95d2 get chain to runnable state 2020-02-22 14:10:46 +01:00
Łukasz Magiera 9b40fa6c76 gofmt; mod tidy 2020-02-21 20:28:20 +01:00
Łukasz Magiera 70263b6fba storageminer: Update api interfaces 2020-02-21 18:43:44 +01:00
Łukasz Magiera e5b838bac8 update specs-actors 2020-02-21 17:57:40 +01:00
Łukasz Magiera 888267520d Merge remote-tracking branch 'origin/master' into testnet/3 2020-02-19 22:10:14 +01:00
whyrusleeping b82d26aee7 working towards a working genesis generator 2020-02-17 23:15:30 -08:00
Aayush Rajasekaran 15722b4bb9 Re: #1250: API methods should receive TipSetKeys, not TipSets, as input 2020-02-17 19:53:43 -05:00
Łukasz Magiera 175b0e88a3 gofmt 2020-02-14 22:38:30 +01:00
Łukasz Magiera 944ba527f3 use specs-actors birfields 2020-02-14 01:24:24 +01:00
Łukasz Magiera 8a5a5022ce Update cbor-gen 2020-02-13 02:37:28 +01:00
Łukasz Magiera 5a24c2dc5d Fix client market impl, gofmt 2020-02-13 01:15:33 +01:00
Łukasz Magiera 8bf95879f7 cbor-gen fixes 2020-02-13 01:10:07 +01:00
Łukasz Magiera 939610a930 Propagate spec actor types more 2020-02-12 08:44:20 +01:00
Łukasz Magiera bcea739cff genesis: Change template types 2020-02-12 01:58:55 +01:00
Łukasz Magiera 0279e8a34a genesis: Cleanup the structure 2020-02-11 21:48:03 +01:00
Łukasz Magiera 835ca2801c wip gengen fixing 2020-02-11 04:31:28 +01:00
Łukasz Magiera f5c78e67b0 stmgr: Update stmgr utils 2020-02-11 03:33:27 +01:00
Łukasz Magiera cd31b6721c Fix compilation after dep updates 2020-02-11 02:11:58 +01:00
Łukasz Magiera 0225142b90 specs-actors: Fis some test compilation errors 2020-02-10 20:16:36 +01:00
Łukasz Magiera fb495e98b4 specs-actors: Fix most compilation errors 2020-02-09 07:06:32 +01:00
Łukasz Magiera 68eb35e0f4 gofmt 2020-02-08 03:18:37 +01:00
Łukasz Magiera 9b5968f170 Spec Actors integration 2020-02-08 03:18:32 +01:00
Łukasz Magiera 17eb1f8ae1 Merge pull request #1223 from filecoin-project/fix/squash-forks
squash forks and use correct amt library everywhere
2020-02-06 20:14:55 +01:00
whyrusleeping 572cf16a51 squash forks and use correct amt library everywhere 2020-02-04 18:26:42 -08:00
Łukasz Magiera 4d19bebc03 storageminer: Work around broken fastPledgeCommitment 2020-02-04 21:46:31 +01:00
Łukasz Magiera 2d6f0cc589 sealing: fix finalize with cache only 2020-02-02 20:36:15 +01:00
Łukasz Magiera bd766ab3cd sealing: more logging in pledge sector flow 2020-01-31 20:22:31 +01:00
Łukasz Magiera edfbe71b0f fix pledgeReader with small sectors 2020-01-31 20:07:20 +01:00
Łukasz Magiera 52ff34c13e Fix tests 2020-01-31 02:27:38 +01:00
Łukasz Magiera b001a73da1 Update sectorbuilder 2020-01-31 02:18:48 +01:00
Łukasz Magiera 591ea245bc Merge remote-tracking branch 'origin/master' into feat/new-sb-fs 2020-01-30 07:46:47 +01:00
Łukasz Magiera c63fc61a52 sealing: Fix pledgeReader 2020-01-30 07:41:30 +01:00
Łukasz Magiera 8c2bdf984c Merge branch 'master' into feat/new-sb-fs 2020-01-30 07:39:52 +01:00
Łukasz Magiera 90b855094e Fix fast pledge math 2020-01-30 02:01:10 +01:00
Łukasz Magiera c4e9a77be4 actually call finalizeSector 2020-01-29 23:37:31 +01:00
Łukasz Magiera 4ce9d005dd sealing: FinalizeSector step 2020-01-29 22:25:06 +01:00
Whyrusleeping cb318cf2e9 Merge pull request #1158 from filecoin-project/feat/par-pledge
sealing: Parallel CommP calc in pledge sector
2020-01-29 12:15:22 -08:00
Łukasz Magiera 731660c76f test fastPledgeCommitment 2020-01-29 21:01:20 +01:00
Łukasz Magiera 367062aee4 sealing: round parts in fastPledgeCommitment 2020-01-29 20:12:27 +01:00
Łukasz Magiera 73839692d9 initial sectorbuilder FS refactor integration 2020-01-29 00:08:02 +01:00
laser debf107b54 write basic test affirming state change 2020-01-28 12:39:07 -08:00
laser e62515c042 planCommitting must handle SectorCommitFailed
The SectorCommitFailed struct can be created from within Sealing#handleCommitting, and is created if actors.SerializeParams(params) produces an error or if m.api.MpoolPushMessage(ctx.Context(), msg) produces an error.
2020-01-28 11:46:26 -08:00
Łukasz Magiera f6b12a33a2 sealing: Parallel CommP calc in pledge sector 2020-01-25 12:15:28 +01:00
Łukasz Magiera 248a362c3e sealing: docstrings for sanity-checks 2020-01-24 21:15:02 +01:00
Łukasz Magiera 0dfbb7d83e Merge remote-tracking branch 'origin/master' into feat/sector-recovery 2020-01-24 01:53:58 +01:00
Łukasz Magiera db5f1d2235 sealing: PreCommitFailed can go to SealFailed 2020-01-23 18:45:57 +01:00
Łukasz Magiera 75670290fe sealing: Handlef for PreCommitFailed 2020-01-23 18:34:04 +01:00
Łukasz Magiera ddf5cce6dd storageminer: Use tabwriter in sectors list 2020-01-23 17:15:45 +01:00
Łukasz Magiera 943197e65c sealing: Don't infinite-loop on fatal errors 2020-01-23 17:11:58 +01:00
Łukasz Magiera 54289225e8 sealing: Errors are hard 2020-01-23 17:02:55 +01:00
Łukasz Magiera 82343460dd sealing: Error types that can actually be checked 2020-01-23 16:57:50 +01:00
Łukasz Magiera 74095b25c5 sealing: Actually call handleSealFailed 2020-01-23 16:47:33 +01:00
Łukasz Magiera 2715ff763f sealing: implement handler for sealFailed 2020-01-23 16:38:10 +01:00
Łukasz Magiera 3ec83f2318 storageminer: log flag for sector status 2020-01-23 15:18:05 +01:00
Łukasz Magiera 9d0d15d51c sealing: Check ticket expiration 2020-01-23 15:05:44 +01:00
Łukasz Magiera 2aa9b16dbc sealing: check deal expiration 2020-01-23 13:17:45 +01:00
Łukasz Magiera 08a5030b46 sealing: Nonzero exit on commit isn't fatal 2020-01-23 11:02:20 +01:00
Łukasz Magiera c80099173e sealing: Not getting seal ticket isn't fatal 2020-01-22 22:16:45 +01:00
Łukasz Magiera ee34cf612f sealing: Wire up sector event log 2020-01-22 21:29:19 +01:00
Łukasz Magiera 7463ee72d0 sealing: wire up checkPieces and checkSeal 2020-01-22 20:47:29 +01:00
Łukasz Magiera 032b2d877c sealing: Fix planOne for global events 2020-01-22 19:30:56 +01:00
Łukasz Magiera 3a2047dcd7 sealing: Add Log field to SectorInfo 2020-01-22 03:41:39 +01:00
Łukasz Magiera 85d40a318b Merge branch 'master' into feat/sector-recovery 2020-01-22 03:27:11 +01:00
Łukasz Magiera a77c19a60d Fix master build 2020-01-21 19:51:17 +01:00
Łukasz Magiera 793bf7f579 Update cbor-gen, error on unknown fields 2020-01-21 17:28:55 +01:00
Łukasz Magiera 7c6a884980 cobr-gen: Soft struct-map unmarshaling 2020-01-21 17:05:10 +01:00
Łukasz Magiera f121570d60 sealing: Some state renaming 2020-01-20 23:04:46 +01:00
Łukasz Magiera 93453ed683 sealing: WIP SectorInfo sanity checks 2020-01-20 23:04:27 +01:00
dtynn 7566d75aeb small fixes 2020-01-20 16:23:56 +08:00
Łukasz Magiera 49461b2e68 Merge branch 'master' into feat/event-states 2020-01-18 14:40:59 +01:00
Łukasz Magiera a3747f8c71 Merge branch 'master' into feat/event-states 2020-01-16 03:59:14 +01:00
Łukasz Magiera 347e788eb6 sealing: gofmt 2020-01-16 03:54:57 +01:00
Łukasz Magiera 6413108dc9 sealing: Handle events based on current state 2020-01-16 03:53:59 +01:00
Łukasz Magiera e3b05e51b1 sealing: Handle seed changes more correctly 2020-01-16 02:25:49 +01:00
Łukasz Magiera 72ca563a1d sealing: More cleanup 2020-01-15 21:53:14 +01:00
Łukasz Magiera 03f31d74f1 Move miner sealing logic into a separate package 2020-01-15 21:49:11 +01:00
299 changed files with 23636 additions and 2972 deletions
+15 -6
View File
@@ -17,18 +17,27 @@ A brief description of the problem you encountered while proving (sealing) a sec
Including what commands you ran, and a description of your setup, is very helpful.
**Sectors list**
The output of `./lotus-miner sectors list`.
**Sectors status**
The output of `./lotus-miner sectors status --log <sectorId>` for the failed sector(s).
The output of `lotus-miner sectors status --log <sectorId>` for the failed sector(s).
**Lotus miner logs**
Please go through the logs of your miner, and include screenshots of any error-like messages you find.
Alternatively please upload full log files and share a link here
**Lotus miner diagnostic info**
Please collect the following diagnostic information, and share a link here
* lotus-miner diagnostic info `lotus-miner info all > allinfo`
** Code modifications **
If you have modified parts of lotus, please describe which areas were modified,
and the scope of those modifications
**Version**
The output of `./lotus --version`.
The output of `lotus --version`.
+143 -2
View File
@@ -1,7 +1,148 @@
# lotus changelog
# Lotus changelog
## 0.5.0 / 2020-08-2020
This version of Lotus will be used for the incentivized testnet Space Race competition,
and can be considered mainnet-ready code. It includes some protocol
changes, upgrades of core dependencies, and various bugfixes and UX/performance improvements.
# Highlights
Among the highlights included in this release are:
- Gas changes: We implemented EIP-1559 and introduced real gas values.
- Deal-making: We now support "Committed Capacity" sectors, "fast-retrieval" deals,
and the packing of multiple deals into a single sector.
- Renamed features: We renamed some of the binaries, environment variables, and default
paths associated with a Lotus node.
## Gas changes
We made some significant changes to the mechanics of gas in this release.
#### Network fee
We implemented something similar to
[Ethereum's EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md).
The `Message` structure had three changes:
- The `GasPrice` field has been removed
- A new `GasFeeCap` field has been added, which controls the maximum cost
the sender incurs for the message
- A new `GasPremium` field has been added, which controls the reward a miner
earns for including the message
A sender will never be charged more than `GasFeeCap * GasLimit`.
A miner will typically earn `GasPremium * GasLimit` as a reward.
The `Blockheader` structure has one new field, called `ParentBaseFee`.
Informally speaking,the `ParentBaseFee`
is increased when blocks are densely packed with messages, and decreased otherwise.
The `ParentBaseFee` is used when calculating how much a sender burns when executing a message. _Burning_ simply refers to sending attoFIL to a dedicated, unreachable account.
A message causes `ParentBaseFee * GasUsed` attoFIL to be burnt.
#### Real gas values
This release also includes our first "real" gas costs for primitive operations.
The costs were designed to account for both the _time_ that message execution takes,
as well as the _space_ a message adds to the state tree.
## Deal-making changes
There are three key changes to the deal-making process.
#### Committed Capacity sectors
Miners can now pledge "Committed Capacity" (CC) sectors, which are explicitly
stated as containing junk data, and must not include any deals. Miners can do this
to increase their storage power, and win block rewards from this pledged storage.
They can mark these sectors as "upgradable" with `lotus-miner sectors mark-for-upgrade`.
If the miner receives and accepts one or more storage deals, the sector that includes
those deals will _replace_ the CC sector. This is intended to maximize the amount of useful
storage on the Filecoin network.
#### Fast-retrieval deals
Clients can now include a `fast-retrieval` flag when proposing deals with storage miners.
If set to true, the miner will include an extra copy of the deal data. This
data can be quickly served in a retrieval deal, since it will not need to be unsealed.
#### Multiple deals per sector
Miners can now pack multiple deals into a single sector, so long as all the deals
fit into the sector capacity. This should increase the packing efficiency of miners.
## Renamed features
To improve the user experience, we updated several names to mainatin
standard prefixing, and to better reflect the meaning of the features being referenced.
In particular, the Lotus miner binary is now called `lotus-miner`, the default
path for miner data is now `~/.lotusminer`, and the environment variable
that sets the path for miner data is now `$LOTUS_MINER_PATH`. A full list of renamed
features can be found [here](https://github.com/filecoin-project/lotus/issues/2304).
# Changelog
#### Downstream upgrades
- Upgrades markets to v0.5.6 (https://github.com/filecoin-project/lotus/pull/3058)
- Upgrades specs-actors to v0.9.3 (https://github.com/filecoin-project/lotus/pull/3151)
#### Core protocol
- Introduces gas values, replacing placeholders (https://github.com/filecoin-project/lotus/pull/2343)
- Implements EIP-1559, introducing a network base fee, message gas fee cap, and message gas fee premium (https://github.com/filecoin-project/lotus/pull/2874)
- Implements Poisson Sortition for elections (https://github.com/filecoin-project/lotus/pull/2084)
#### Deal-making lifecycle
- Introduces "Committed Capacity" sectors (https://github.com/filecoin-project/lotus/pull/2220)
- Introduces "fast-retrieval" flag for deals (https://github.com/filecoin-project/lotus/pull/2323
- Supports packing multiple deals into one sector (https://github.com/filecoin-project/storage-fsm/pull/38)
#### Enhancements
- Optimized message pool selection logic (https://github.com/filecoin-project/lotus/pull/2838)
- Window-based scheduling of sealing tasks (https://github.com/filecoin-project/sector-storage/pull/67)
- Faster window PoSt (https://github.com/filecoin-project/lotus/pull/2209/files)
- Refactors the payment channel manager (https://github.com/filecoin-project/lotus/pull/2640)
- Refactors blocksync (https://github.com/filecoin-project/lotus/pull/2715/files)
#### UX
- Provide status updates for data-transfer (https://github.com/filecoin-project/lotus/pull/3162, https://github.com/filecoin-project/lotus/pull/3191)
- Miners can customise asks (https://github.com/filecoin-project/lotus/pull/2046)
- Miners can toggle auto-acceptance of deals (https://github.com/filecoin-project/lotus/pull/1994)
- Miners can maintain a blocklist of piece CIDs (https://github.com/filecoin-project/lotus/pull/2069)
# Contributors
The following contributors had 10 or more commits go into this release.
We are grateful for every contribution!
| Contributor | Commits | Lines ± |
|--------------------|---------|---------------|
| magik6k | 361 | +13197/-6136 |
| Kubuxu | 227 | +5670/-2587 |
| arajasek | 120 | +2916/-1264 |
| whyrusleeping | 112 | +3979/-1089 |
| vyzo | 99 | +3343/-1305 |
| dirkmc | 68 | +8732/-3621 |
| laser | 45 | +1489/-501 |
| hannahhoward | 43 | +2654/-990 |
| frrist | 37 | +6630/-4338 |
| schomatis | 28 | +3016/-1368 |
| placer14 | 27 | +824/-350 |
| raulk | 25 | +28718/-29849 |
| mrsmkl | 22 | +560/-368 |
| travisperson | 18 | +1354/-314 |
| nonsense | 16 | +2956/-2842 |
| ingar | 13 | +331/-123 |
| daviddias | 11 | +311/-11 |
| Stebalien | 11 | +1204/-980 |
| RobQuistNL | 10 | +69/-74 |
## 0.1.0 / 2019-12-11
We are very excited to release **lotus** 0.1.0. This is our testnet release. To install lotus and join the testnet, please visit [docs.lotu.sh](docs.lotu.sh). Please file bug reports as [issues](https://github.com/filecoin-project/lotus/issues).
We are very excited to release **lotus** 0.1.0. This is our testnet release. To install lotus and join the testnet, please visit [lotu.sh](lotu.sh). Please file bug reports as [issues](https://github.com/filecoin-project/lotus/issues).
A huge thank you to all contributors for this testnet release!
+2 -1
View File
@@ -148,7 +148,7 @@ BINS+=lotus-fountain
lotus-chainwatch:
rm -f lotus-chainwatch
go build -o lotus-chainwatch ./cmd/lotus-chainwatch
go build $(GOFLAGS) -o lotus-chainwatch ./cmd/lotus-chainwatch
.PHONY: lotus-chainwatch
BINS+=lotus-chainwatch
@@ -272,6 +272,7 @@ dist-clean:
type-gen:
go run ./gen/main.go
go generate ./...
method-gen:
(cd ./lotuspond/front/src/chain && go run ./methodgen.go)
+10 -2
View File
@@ -1,16 +1,24 @@
<p align="center">
<a href="https://docs.lotu.sh/" title="Lotus Docs">
<a href="https://lotu.sh/" title="Lotus Docs">
<img src="documentation/images/lotus_logo_h.png" alt="Project Lotus Logo" width="244" />
</a>
</p>
<h1 align="center">Project Lotus - 莲</h1>
<p align="center">
<a href="https://circleci.com/gh/filecoin-project/lotus"><img src="https://circleci.com/gh/filecoin-project/lotus.svg?style=svg"></a>
<a href="https://codecov.io/gh/filecoin-project/lotus"><img src="https://codecov.io/gh/filecoin-project/lotus/branch/master/graph/badge.svg"></a>
<a href="https://goreportcard.com/report/github.com/filecoin-project/lotus"><img src="https://goreportcard.com/badge/github.com/filecoin-project/lotus" /></a>
<a href=""><img src="https://img.shields.io/badge/golang-%3E%3D1.14.7-blue.svg" /></a>
<br>
</p>
Lotus is an implementation of the Filecoin Distributed Storage Network. For more details about Filecoin, check out the [Filecoin Spec](https://spec.filecoin.io).
## Building & Documentation
For instructions on how to build lotus from source, please visit [https://docs.lotu.sh](https://docs.lotu.sh) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
For instructions on how to build lotus from source, please visit [https://lotu.sh](https://lotu.sh) or read the source [here](https://github.com/filecoin-project/lotus/tree/master/documentation).
## Reporting a Vulnerability
+7 -2
View File
@@ -4,11 +4,10 @@ import (
"context"
"fmt"
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/lotus/build"
)
@@ -28,6 +27,7 @@ type Common interface {
NetDisconnect(context.Context, peer.ID) error
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
NetPubsubScores(context.Context) ([]PubsubScore, error)
NetAutoNatStatus(context.Context) (NatInfo, error)
// MethodGroup: Common
@@ -65,3 +65,8 @@ type Version struct {
func (v Version) String() string {
return fmt.Sprintf("%s+api%s", v.Version, v.APIVersion.String())
}
type NatInfo struct {
Reachability network.Reachability
PublicAddr string
}
+56 -25
View File
@@ -21,6 +21,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/chain/types"
marketevents "github.com/filecoin-project/lotus/markets/loggers"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
@@ -39,8 +40,11 @@ type FullNode interface {
// ChainHead returns the current head of the chain.
ChainHead(context.Context) (*types.TipSet, error)
// ChainGetRandomness is used to sample the chain for randomness.
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
// ChainGetRandomnessFromTickets is used to sample the chain for randomness.
ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
// ChainGetRandomnessFromBeacon is used to sample the beacon for randomness.
ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
// ChainGetBlock returns the block specified by the given CID.
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
@@ -122,12 +126,15 @@ type FullNode interface {
// It fails if message fails to execute.
GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error)
// GasEsitmateGasPremium estimates what gas price should be used for a
// GasEstimateGasPremium estimates what gas price should be used for a
// message to have high likelihood of inclusion in `nblocksincl` epochs.
GasEsitmateGasPremium(_ context.Context, nblocksincl uint64,
GasEstimateGasPremium(_ context.Context, nblocksincl uint64,
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
// GasEstimateMessageGas estimates gas values for unset message gas fields
GasEstimateMessageGas(context.Context, *types.Message, *MessageSendSpec, types.TipSetKey) (*types.Message, error)
// MethodGroup: Sync
// The Sync method group contains methods for interacting with and
// observing the lotus sync service.
@@ -159,20 +166,27 @@ type FullNode interface {
MpoolPending(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
// MpoolSelect returns a list of pending messages for inclusion in the next block
MpoolSelect(context.Context, types.TipSetKey) ([]*types.SignedMessage, error)
MpoolSelect(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error)
// MpoolPush pushes a signed message to mempool.
MpoolPush(context.Context, *types.SignedMessage) (cid.Cid, error)
// MpoolPushMessage atomically assigns a nonce, signs, and pushes a message
// to mempool.
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
// maxFee is only used when GasFeeCap/GasPremium fields aren't specified
//
// When maxFee is set to 0, MpoolPushMessage will guess appropriate fee
// based on current chain conditions
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
// MpoolGetNonce gets next nonce for the specified sender.
// Note that this method may not be atomic. Use MpoolPushMessage instead.
MpoolGetNonce(context.Context, address.Address) (uint64, error)
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
// MpoolClear clears pending messages from the mpool
MpoolClear(context.Context, bool) error
// MpoolGetConfig returns (a copy of) the current mpool config
MpoolGetConfig(context.Context) (*types.MpoolConfig, error)
// MpoolSetConfig sets the mpool config to (a copy of) the supplied config
@@ -237,14 +251,20 @@ type FullNode interface {
ClientMinerQueryOffer(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (QueryOffer, error)
// ClientRetrieve initiates the retrieval of a file, as specified in the order.
ClientRetrieve(ctx context.Context, order RetrievalOrder, ref *FileRef) error
// ClientRetrieveWithEvents initiates the retrieval of a file, as specified in the order, and provides a channel
// of status updates.
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error)
// ClientCalcCommP calculates the CommP for a specified file, based on the sector size of the provided miner.
ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*CommPRet, 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.
ClientGenCar(ctx context.Context, ref FileRef, outpath string) error
// ClientDealSize calculates real deal data size
ClientDealSize(ctx context.Context, root cid.Cid) (DataSize, error)
// ClientListTransfers returns the status of all ongoing transfers of data
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
// ClientUnimport removes references to the specified file from filestore
//ClientUnimport(path string)
@@ -290,11 +310,11 @@ type FullNode interface {
// StateMinerPartitions loads miner partitions for the specified miner/deadline
StateMinerPartitions(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error)
// StateMinerFaults returns a bitfield indicating the faulty sectors of the given miner
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error)
StateMinerFaults(context.Context, address.Address, types.TipSetKey) (abi.BitField, error)
// StateAllMinerFaults returns all non-expired Faults that occur within lookback epochs of the given tipset
StateAllMinerFaults(ctx context.Context, lookback abi.ChainEpoch, ts types.TipSetKey) ([]*Fault, error)
// StateMinerRecoveries returns a bitfield indicating the recovering sectors of the given miner
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error)
StateMinerRecoveries(context.Context, address.Address, types.TipSetKey) (abi.BitField, error)
// StateMinerInitialPledgeCollateral returns the precommit deposit for the specified miner's sector
StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
// StateMinerInitialPledgeCollateral returns the initial pledge collateral for the specified miner's sector
@@ -311,7 +331,6 @@ type FullNode interface {
StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*SectorExpiration, error)
// StateSectorPartition finds deadline/partition with the specified sector
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*SectorLocation, error)
StatePledgeCollateral(context.Context, types.TipSetKey) (types.BigInt, error)
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
@@ -352,7 +371,7 @@ type FullNode interface {
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
// MethodGroup: Msig
// The Msig methods are used to interact with multisig wallets on the
@@ -462,9 +481,12 @@ type DealInfo struct {
Duration uint64
DealID abi.DealID
CreationTime time.Time
}
type MsgLookup struct {
Message cid.Cid // Can be different than requested, in case it was replaced, but only gas values changed
Receipt types.MessageReceipt
ReturnDec interface{}
TipSet types.TipSetKey
@@ -507,14 +529,14 @@ type PaychStatus struct {
}
type ChannelInfo struct {
Channel address.Address
ChannelMessage cid.Cid
Channel address.Address
WaitSentinel cid.Cid
}
type PaymentInfo struct {
Channel address.Address
ChannelMessage *cid.Cid
Vouchers []*paych.SignedVoucher
Channel address.Address
WaitSentinel cid.Cid
Vouchers []*paych.SignedVoucher
}
type VoucherSpec struct {
@@ -601,14 +623,15 @@ type MethodCall struct {
}
type StartDealParams struct {
Data *storagemarket.DataRef
Wallet address.Address
Miner address.Address
EpochPrice types.BigInt
MinBlocksDuration uint64
DealStartEpoch abi.ChainEpoch
FastRetrieval bool
VerifiedDeal bool
Data *storagemarket.DataRef
Wallet address.Address
Miner address.Address
EpochPrice types.BigInt
MinBlocksDuration uint64
ProviderCollateral big.Int
DealStartEpoch abi.ChainEpoch
FastRetrieval bool
VerifiedDeal bool
}
type IpldObject struct {
@@ -665,6 +688,14 @@ type DealCollateralBounds struct {
Max abi.TokenAmount
}
type CirculatingSupply struct {
FilVested abi.TokenAmount
FilMined abi.TokenAmount
FilBurnt abi.TokenAmount
FilLocked abi.TokenAmount
FilCirculating abi.TokenAmount
}
type MiningBaseInfo struct {
MinerPower types.BigInt
NetworkPower types.BigInt
+5 -3
View File
@@ -12,9 +12,9 @@ import (
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/sector-storage/fsutil"
"github.com/filecoin-project/sector-storage/stores"
"github.com/filecoin-project/sector-storage/storiface"
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
"github.com/filecoin-project/specs-actors/actors/abi"
)
@@ -79,6 +79,8 @@ type StorageMiner interface {
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error)
MarketSetRetrievalAsk(ctx context.Context, rask *retrievalmarket.Ask) error
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
DealsList(ctx context.Context) ([]storagemarket.StorageDeal, error)
+5 -3
View File
@@ -6,9 +6,9 @@ import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/sector-storage/sealtasks"
"github.com/filecoin-project/sector-storage/stores"
"github.com/filecoin-project/sector-storage/storiface"
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-storage/storage"
@@ -23,6 +23,8 @@ type WorkerAPI interface {
Paths(context.Context) ([]stores.StoragePath, error)
Info(context.Context) (storiface.WorkerInfo, error)
AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error)
storage.Sealer
MoveStorage(ctx context.Context, sector abi.SectorID) error
+127 -79
View File
@@ -15,10 +15,11 @@ import (
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/go-multistore"
"github.com/filecoin-project/sector-storage/fsutil"
"github.com/filecoin-project/sector-storage/sealtasks"
"github.com/filecoin-project/sector-storage/stores"
"github.com/filecoin-project/sector-storage/storiface"
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
marketevents "github.com/filecoin-project/lotus/markets/loggers"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
@@ -48,6 +49,7 @@ type CommonStruct struct {
NetDisconnect func(context.Context, peer.ID) error `perm:"write"`
NetFindPeer func(context.Context, peer.ID) (peer.AddrInfo, error) `perm:"read"`
NetPubsubScores func(context.Context) ([]api.PubsubScore, error) `perm:"read"`
NetAutoNatStatus func(context.Context) (api.NatInfo, error) `perm:"read"`
ID func(context.Context) (peer.ID, error) `perm:"read"`
Version func(context.Context) (api.Version, error) `perm:"read"`
@@ -65,31 +67,33 @@ type FullNodeStruct struct {
CommonStruct
Internal struct {
ChainNotify func(context.Context) (<-chan []*api.HeadChange, error) `perm:"read"`
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainGetRandomness func(context.Context, types.TipSetKey, crypto.DomainSeparationTag, abi.ChainEpoch, []byte) (abi.Randomness, error) `perm:"read"`
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
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"`
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"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"`
ChainGetNode func(ctx context.Context, p string) (*api.IpldObject, error) `perm:"read"`
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"`
ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"`
ChainNotify func(context.Context) (<-chan []*api.HeadChange, error) `perm:"read"`
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainGetRandomnessFromTickets func(context.Context, types.TipSetKey, crypto.DomainSeparationTag, abi.ChainEpoch, []byte) (abi.Randomness, error) `perm:"read"`
ChainGetRandomnessFromBeacon func(context.Context, types.TipSetKey, crypto.DomainSeparationTag, abi.ChainEpoch, []byte) (abi.Randomness, error) `perm:"read"`
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
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"`
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"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"`
ChainGetNode func(ctx context.Context, p string) (*api.IpldObject, error) `perm:"read"`
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"`
ChainExport func(context.Context, types.TipSetKey) (<-chan []byte, error) `perm:"read"`
BeaconGetEntry func(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
GasEsitmateGasPremium func(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
GasEstimateGasLimit func(context.Context, *types.Message, types.TipSetKey) (int64, error) `perm:"read"`
GasEstimateFeeCap func(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
GasEstimateGasPremium func(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
GasEstimateGasLimit func(context.Context, *types.Message, types.TipSetKey) (int64, error) `perm:"read"`
GasEstimateFeeCap func(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
GasEstimateMessageGas func(context.Context, *types.Message, *api.MessageSendSpec, types.TipSetKey) (*types.Message, error) `perm:"read"`
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
@@ -97,14 +101,18 @@ type FullNodeStruct struct {
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
MpoolGetConfig func(context.Context) (*types.MpoolConfig, error) `perm:"read"`
MpoolSetConfig func(context.Context, *types.MpoolConfig) error `perm:"write"`
MpoolSelect func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
MpoolPushMessage func(context.Context, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
MpoolGetConfig func(context.Context) (*types.MpoolConfig, error) `perm:"read"`
MpoolSetConfig func(context.Context, *types.MpoolConfig) error `perm:"write"`
MpoolSelect func(context.Context, types.TipSetKey, float64) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPending func(context.Context, types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
MpoolClear func(context.Context, bool) error `perm:"write"`
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
MpoolPushMessage func(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
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"`
@@ -122,20 +130,23 @@ type FullNodeStruct struct {
WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"`
WalletDelete func(context.Context, address.Address) error `perm:"write"`
ClientImport func(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) `perm:"admin"`
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
ClientRemoveImport func(ctx context.Context, importID multistore.StoreID) error `perm:"admin"`
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
ClientFindData func(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
ClientMinerQueryOffer func(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) `perm:"read"`
ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
ClientCalcCommP func(ctx context.Context, inpath string, miner address.Address) (*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"`
ClientImport func(ctx context.Context, ref api.FileRef) (*api.ImportRes, error) `perm:"admin"`
ClientListImports func(ctx context.Context) ([]api.Import, error) `perm:"write"`
ClientRemoveImport func(ctx context.Context, importID multistore.StoreID) error `perm:"admin"`
ClientHasLocal func(ctx context.Context, root cid.Cid) (bool, error) `perm:"write"`
ClientFindData func(ctx context.Context, root cid.Cid, piece *cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
ClientMinerQueryOffer func(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) `perm:"read"`
ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
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"`
ClientCalcCommP func(ctx context.Context, inpath string) (*api.CommPRet, error) `perm:"read"`
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
ClientDealSize func(ctx context.Context, root cid.Cid) (api.DataSize, error) `perm:"read"`
ClientListDataTransfers func(ctx context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
ClientDataTransferUpdates func(ctx context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
@@ -145,9 +156,9 @@ type FullNodeStruct struct {
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error) `perm:"read"`
StateMinerPartitions func(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error) `perm:"read"`
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) `perm:"read"`
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (abi.BitField, error) `perm:"read"`
StateAllMinerFaults func(context.Context, abi.ChainEpoch, types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
StateMinerRecoveries func(context.Context, address.Address, types.TipSetKey) (*abi.BitField, error) `perm:"read"`
StateMinerRecoveries func(context.Context, address.Address, types.TipSetKey) (abi.BitField, error) `perm:"read"`
StateMinerPreCommitDepositForPower func(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) `perm:"read"`
StateMinerInitialPledgeCollateral func(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) `perm:"read"`
StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
@@ -159,7 +170,6 @@ type FullNodeStruct struct {
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
StatePledgeCollateral func(context.Context, types.TipSetKey) (types.BigInt, error) `perm:"read"`
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
StateListMiners func(context.Context, types.TipSetKey) ([]address.Address, error) `perm:"read"`
@@ -177,7 +187,7 @@ type FullNodeStruct struct {
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*verifreg.DataCap, error) `perm:"read"`
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
StateCirculatingSupply func(context.Context, types.TipSetKey) (abi.TokenAmount, error) `perm:"read"`
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
MsigCreate func(context.Context, uint64, []address.Address, abi.ChainEpoch, types.BigInt, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"`
@@ -230,6 +240,8 @@ type StorageMinerStruct struct {
MarketGetAsk func(ctx context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
MarketSetRetrievalAsk func(ctx context.Context, rask *retrievalmarket.Ask) error `perm:"admin"`
MarketGetRetrievalAsk func(ctx context.Context) (*retrievalmarket.Ask, error) `perm:"read"`
MarketListDataTransfers func(ctx context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
MarketDataTransferUpdates func(ctx context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
PledgeSector func(context.Context) error `perm:"write"`
@@ -257,7 +269,7 @@ type StorageMinerStruct struct {
StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin"`
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"`
StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"`
StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, abi.RegisteredSealProof, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"`
StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
@@ -296,6 +308,7 @@ type WorkerStruct struct {
Paths func(context.Context) ([]stores.StoragePath, error) `perm:"admin"`
Info func(context.Context) (storiface.WorkerInfo, error) `perm:"admin"`
AddPiece func(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error) `perm:"admin"`
SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"`
SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"`
SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"`
@@ -327,6 +340,7 @@ func (c *CommonStruct) AuthNew(ctx context.Context, perms []auth.Permission) ([]
func (c *CommonStruct) NetPubsubScores(ctx context.Context) ([]api.PubsubScore, error) {
return c.Internal.NetPubsubScores(ctx)
}
func (c *CommonStruct) NetConnectedness(ctx context.Context, pid peer.ID) (network.Connectedness, error) {
return c.Internal.NetConnectedness(ctx, pid)
}
@@ -351,6 +365,10 @@ func (c *CommonStruct) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInf
return c.Internal.NetFindPeer(ctx, p)
}
func (c *CommonStruct) NetAutoNatStatus(ctx context.Context) (api.NatInfo, error) {
return c.Internal.NetAutoNatStatus(ctx)
}
// ID implements API.ID
func (c *CommonStruct) ID(ctx context.Context) (peer.ID, error) {
return c.Internal.ID(ctx)
@@ -419,11 +437,15 @@ func (c *FullNodeStruct) ClientRetrieve(ctx context.Context, order api.Retrieval
return c.Internal.ClientRetrieve(ctx, order, ref)
}
func (c *FullNodeStruct) ClientRetrieveWithEvents(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) {
return c.Internal.ClientRetrieveWithEvents(ctx, order, ref)
}
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) {
return c.Internal.ClientQueryAsk(ctx, p, miner)
}
func (c *FullNodeStruct) ClientCalcCommP(ctx context.Context, inpath string, miner address.Address) (*api.CommPRet, error) {
return c.Internal.ClientCalcCommP(ctx, inpath, miner)
func (c *FullNodeStruct) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) {
return c.Internal.ClientCalcCommP(ctx, inpath)
}
func (c *FullNodeStruct) ClientGenCar(ctx context.Context, ref api.FileRef, outpath string) error {
@@ -434,17 +456,27 @@ func (c *FullNodeStruct) ClientDealSize(ctx context.Context, root cid.Cid) (api.
return c.Internal.ClientDealSize(ctx, root)
}
func (c *FullNodeStruct) GasEsitmateGasPremium(ctx context.Context, nblocksincl uint64,
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
return c.Internal.GasEsitmateGasPremium(ctx, nblocksincl, sender, gaslimit, tsk)
func (c *FullNodeStruct) ClientListDataTransfers(ctx context.Context) ([]api.DataTransferChannel, error) {
return c.Internal.ClientListDataTransfers(ctx)
}
func (c *FullNodeStruct) GasEstimateFeeCap(ctx context.Context, msg *types.Message,
maxqueueblks int64, tsk types.TipSetKey) (types.BigInt, error) {
func (c *FullNodeStruct) ClientDataTransferUpdates(ctx context.Context) (<-chan api.DataTransferChannel, error) {
return c.Internal.ClientDataTransferUpdates(ctx)
}
func (c *FullNodeStruct) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
return c.Internal.GasEstimateGasPremium(ctx, nblocksincl, sender, gaslimit, tsk)
}
func (c *FullNodeStruct) GasEstimateFeeCap(ctx context.Context, msg *types.Message, maxqueueblks int64, tsk types.TipSetKey) (types.BigInt, error) {
return c.Internal.GasEstimateFeeCap(ctx, msg, maxqueueblks, tsk)
}
func (c *FullNodeStruct) GasEstimateGasLimit(ctx context.Context, msg *types.Message,
tsk types.TipSetKey) (int64, error) {
func (c *FullNodeStruct) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
return c.Internal.GasEstimateMessageGas(ctx, msg, spec, tsk)
}
func (c *FullNodeStruct) GasEstimateGasLimit(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (int64, error) {
return c.Internal.GasEstimateGasLimit(ctx, msg, tsk)
}
@@ -456,20 +488,24 @@ func (c *FullNodeStruct) MpoolSetConfig(ctx context.Context, cfg *types.MpoolCon
return c.Internal.MpoolSetConfig(ctx, cfg)
}
func (c *FullNodeStruct) MpoolSelect(ctx context.Context, tsk types.TipSetKey) ([]*types.SignedMessage, error) {
return c.Internal.MpoolSelect(ctx, tsk)
func (c *FullNodeStruct) MpoolSelect(ctx context.Context, tsk types.TipSetKey, tq float64) ([]*types.SignedMessage, error) {
return c.Internal.MpoolSelect(ctx, tsk, tq)
}
func (c *FullNodeStruct) MpoolPending(ctx context.Context, tsk types.TipSetKey) ([]*types.SignedMessage, error) {
return c.Internal.MpoolPending(ctx, tsk)
}
func (c *FullNodeStruct) MpoolClear(ctx context.Context, local bool) error {
return c.Internal.MpoolClear(ctx, local)
}
func (c *FullNodeStruct) MpoolPush(ctx context.Context, smsg *types.SignedMessage) (cid.Cid, error) {
return c.Internal.MpoolPush(ctx, smsg)
}
func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
return c.Internal.MpoolPushMessage(ctx, msg)
func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
return c.Internal.MpoolPushMessage(ctx, msg, spec)
}
func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) {
@@ -488,8 +524,12 @@ func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
return c.Internal.ChainHead(ctx)
}
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
return c.Internal.ChainGetRandomness(ctx, tsk, personalization, randEpoch, entropy)
func (c *FullNodeStruct) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
return c.Internal.ChainGetRandomnessFromTickets(ctx, tsk, personalization, randEpoch, entropy)
}
func (c *FullNodeStruct) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
return c.Internal.ChainGetRandomnessFromBeacon(ctx, tsk, personalization, randEpoch, entropy)
}
func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error) {
@@ -668,7 +708,7 @@ func (c *FullNodeStruct) StateMinerPartitions(ctx context.Context, m address.Add
return c.Internal.StateMinerPartitions(ctx, m, dlIdx, tsk)
}
func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*abi.BitField, error) {
func (c *FullNodeStruct) StateMinerFaults(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.BitField, error) {
return c.Internal.StateMinerFaults(ctx, actor, tsk)
}
@@ -676,7 +716,7 @@ func (c *FullNodeStruct) StateAllMinerFaults(ctx context.Context, cutoff abi.Cha
return c.Internal.StateAllMinerFaults(ctx, cutoff, endTsk)
}
func (c *FullNodeStruct) StateMinerRecoveries(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*abi.BitField, error) {
func (c *FullNodeStruct) StateMinerRecoveries(ctx context.Context, actor address.Address, tsk types.TipSetKey) (abi.BitField, error) {
return c.Internal.StateMinerRecoveries(ctx, actor, tsk)
}
@@ -724,10 +764,6 @@ func (c *FullNodeStruct) StateReadState(ctx context.Context, addr address.Addres
return c.Internal.StateReadState(ctx, addr, tsk)
}
func (c *FullNodeStruct) StatePledgeCollateral(ctx context.Context, tsk types.TipSetKey) (types.BigInt, error) {
return c.Internal.StatePledgeCollateral(ctx, tsk)
}
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64) (*api.MsgLookup, error) {
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
}
@@ -792,7 +828,7 @@ func (c *FullNodeStruct) StateDealProviderCollateralBounds(ctx context.Context,
return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
}
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
return c.Internal.StateCirculatingSupply(ctx, tsk)
}
@@ -836,8 +872,8 @@ func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address,
return c.Internal.PaychGet(ctx, from, to, amt)
}
func (c *FullNodeStruct) PaychGetWaitReady(ctx context.Context, mcid cid.Cid) (address.Address, error) {
return c.Internal.PaychGetWaitReady(ctx, mcid)
func (c *FullNodeStruct) PaychGetWaitReady(ctx context.Context, sentinel cid.Cid) (address.Address, error) {
return c.Internal.PaychGetWaitReady(ctx, sentinel)
}
func (c *FullNodeStruct) PaychList(ctx context.Context) ([]address.Address, error) {
@@ -980,8 +1016,8 @@ func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId st
return c.Internal.StorageDropSector(ctx, storageId, s, ft)
}
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, allowFetch bool) ([]stores.SectorStorageInfo, error) {
return c.Internal.StorageFindSector(ctx, si, types, allowFetch)
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, spt abi.RegisteredSealProof, allowFetch bool) ([]stores.SectorStorageInfo, error) {
return c.Internal.StorageFindSector(ctx, si, types, spt, allowFetch)
}
func (c *StorageMinerStruct) StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) {
@@ -1052,6 +1088,14 @@ func (c *StorageMinerStruct) MarketGetRetrievalAsk(ctx context.Context) (*retrie
return c.Internal.MarketGetRetrievalAsk(ctx)
}
func (c *StorageMinerStruct) MarketListDataTransfers(ctx context.Context) ([]api.DataTransferChannel, error) {
return c.Internal.MarketListDataTransfers(ctx)
}
func (c *StorageMinerStruct) MarketDataTransferUpdates(ctx context.Context) (<-chan api.DataTransferChannel, error) {
return c.Internal.MarketDataTransferUpdates(ctx)
}
func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error {
return c.Internal.DealsImportData(ctx, dealPropCid, file)
}
@@ -1138,6 +1182,10 @@ func (w *WorkerStruct) Info(ctx context.Context) (storiface.WorkerInfo, error) {
return w.Internal.Info(ctx)
}
func (w *WorkerStruct) AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error) {
return w.Internal.AddPiece(ctx, sector, pieceSizes, newPieceSize, pieceData)
}
func (w *WorkerStruct) SealPreCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) {
return w.Internal.SealPreCommit1(ctx, sector, ticket, pieces)
}
+12 -30
View File
@@ -41,26 +41,20 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
return err
}
// t.ChannelMessage (cid.Cid) (struct)
if len("ChannelMessage") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"ChannelMessage\" was too long")
// t.WaitSentinel (cid.Cid) (struct)
if len("WaitSentinel") > cbg.MaxLength {
return xerrors.Errorf("Value in field \"WaitSentinel\" was too long")
}
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("ChannelMessage"))); err != nil {
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len("WaitSentinel"))); err != nil {
return err
}
if _, err := io.WriteString(w, string("ChannelMessage")); err != nil {
if _, err := io.WriteString(w, string("WaitSentinel")); err != nil {
return err
}
if t.ChannelMessage == nil {
if _, err := w.Write(cbg.CborNull); err != nil {
return err
}
} else {
if err := cbg.WriteCidBuf(scratch, w, *t.ChannelMessage); err != nil {
return xerrors.Errorf("failed to write cid field t.ChannelMessage: %w", err)
}
if err := cbg.WriteCidBuf(scratch, w, t.WaitSentinel); err != nil {
return xerrors.Errorf("failed to write cid field t.WaitSentinel: %w", err)
}
// t.Vouchers ([]*paych.SignedVoucher) (slice)
@@ -133,29 +127,17 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
}
}
// t.ChannelMessage (cid.Cid) (struct)
case "ChannelMessage":
// t.WaitSentinel (cid.Cid) (struct)
case "WaitSentinel":
{
pb, err := br.PeekByte()
c, err := cbg.ReadCid(br)
if err != nil {
return err
return xerrors.Errorf("failed to read cid field t.WaitSentinel: %w", err)
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
return err
}
} else {
c, err := cbg.ReadCid(br)
if err != nil {
return xerrors.Errorf("failed to read cid field t.ChannelMessage: %w", err)
}
t.ChannelMessage = &c
}
t.WaitSentinel = c
}
// t.Vouchers ([]*paych.SignedVoucher) (slice)
+23 -1
View File
@@ -2,11 +2,15 @@ package client
import (
"net/http"
"net/url"
"path"
"time"
"github.com/filecoin-project/go-jsonrpc"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apistruct"
"github.com/filecoin-project/lotus/lib/rpcenc"
)
// NewCommonRPC creates a new http jsonrpc client.
@@ -35,7 +39,7 @@ func NewFullNodeRPC(addr string, requestHeader http.Header) (api.FullNode, jsonr
}
// NewStorageMinerRPC creates a new http jsonrpc client for miner
func NewStorageMinerRPC(addr string, requestHeader http.Header) (api.StorageMiner, jsonrpc.ClientCloser, error) {
func NewStorageMinerRPC(addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) {
var res apistruct.StorageMinerStruct
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
[]interface{}{
@@ -43,18 +47,36 @@ func NewStorageMinerRPC(addr string, requestHeader http.Header) (api.StorageMine
&res.Internal,
},
requestHeader,
opts...,
)
return &res, closer, err
}
func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
u, err := url.Parse(addr)
if err != nil {
return nil, nil, err
}
switch u.Scheme {
case "ws":
u.Scheme = "http"
case "wss":
u.Scheme = "https"
}
///rpc/v0 -> /rpc/streams/v0/push
u.Path = path.Join(u.Path, "../streams/v0/push")
var res apistruct.WorkerStruct
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
[]interface{}{
&res.Internal,
},
requestHeader,
rpcenc.ReaderParamEncoder(u.String()),
jsonrpc.WithNoReconnect(),
jsonrpc.WithTimeout(30*time.Second),
)
return &res, closer, err
+56
View File
@@ -0,0 +1,56 @@
package test
import (
"context"
"fmt"
"sync/atomic"
"testing"
"time"
"github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/specs-actors/actors/abi"
)
type BlockMiner struct {
ctx context.Context
t *testing.T
miner TestStorageNode
blocktime time.Duration
mine int64
nulls int64
done chan struct{}
}
func NewBlockMiner(ctx context.Context, t *testing.T, miner TestStorageNode, blocktime time.Duration) *BlockMiner {
return &BlockMiner{
ctx: ctx,
t: t,
miner: miner,
blocktime: blocktime,
mine: int64(1),
done: make(chan struct{}),
}
}
func (bm *BlockMiner) MineBlocks() {
time.Sleep(time.Second)
go func() {
defer close(bm.done)
for atomic.LoadInt64(&bm.mine) == 1 {
time.Sleep(bm.blocktime)
nulls := atomic.SwapInt64(&bm.nulls, 0)
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
InjectNulls: abi.ChainEpoch(nulls),
Done: func(bool, error) {},
}); err != nil {
bm.t.Error(err)
}
}
}()
}
func (bm *BlockMiner) Stop() {
atomic.AddInt64(&bm.mine, -1)
fmt.Println("shutting down mining")
<-bm.done
}
+1 -1
View File
@@ -20,7 +20,7 @@ func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
+10 -8
View File
@@ -22,8 +22,8 @@ import (
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/lotus/miner"
sealing "github.com/filecoin-project/storage-fsm"
dag "github.com/ipfs/go-merkledag"
dstest "github.com/ipfs/go-merkledag/test"
unixfile "github.com/ipfs/go-unixfs/file"
@@ -47,7 +47,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@@ -84,7 +84,7 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@@ -148,7 +148,7 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@@ -203,7 +203,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@@ -398,9 +398,11 @@ func testRetrieval(t *testing.T, ctx context.Context, err error, client *impl.Fu
Path: filepath.Join(rpath, "ret"),
IsCAR: carExport,
}
err = client.ClientRetrieve(ctx, offers[0].Order(caddr), ref)
if err != nil {
t.Fatalf("%+v", err)
updates, err := client.ClientRetrieveWithEvents(ctx, offers[0].Order(caddr), ref)
for update := range updates {
if update.Err != "" {
t.Fatalf("%v", err)
}
}
rdata, err := ioutil.ReadFile(filepath.Join(rpath, "ret"))
+2 -2
View File
@@ -24,7 +24,7 @@ var log = logging.Logger("apitest")
func (ts *testSuite) testMining(t *testing.T) {
ctx := context.Background()
apis, sn := ts.makeNodes(t, 1, oneMiner)
apis, sn := ts.makeNodes(t, 1, OneMiner)
api := apis[0]
newHeads, err := api.ChainNotify(ctx)
@@ -55,7 +55,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
}()
ctx := context.Background()
apis, sn := ts.makeNodes(t, 1, oneMiner)
apis, sn := ts.makeNodes(t, 1, OneMiner)
api := apis[0]
newHeads, err := api.ChainNotify(ctx)
+8 -79
View File
@@ -23,14 +23,13 @@ import (
"github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/miner"
)
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 2, oneMiner)
n, sn := b(t, 2, OneMiner)
paymentCreator := n[0]
paymentReceiver := n[1]
@@ -51,8 +50,8 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
}
// start mining blocks
bm := newBlockMiner(ctx, t, miner, blocktime)
bm.mineBlocks()
bm := NewBlockMiner(ctx, t, miner, blocktime)
bm.MineBlocks()
// send some funds to register the receiver
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
@@ -60,7 +59,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
t.Fatal(err)
}
sendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18))
SendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18))
// setup the payment channel
createrAddr, err := paymentCreator.WalletDefaultAddress(ctx)
@@ -74,7 +73,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
t.Fatal(err)
}
channel, err := paymentCreator.PaychGetWaitReady(ctx, channelInfo.ChannelMessage)
channel, err := paymentCreator.PaychGetWaitReady(ctx, channelInfo.WaitSentinel)
if err != nil {
t.Fatal(err)
}
@@ -201,10 +200,10 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
}
// shut down mining
bm.stop()
bm.Stop()
}
func waitForBlocks(ctx context.Context, t *testing.T, bm *blockMiner, paymentReceiver TestNode, receiverAddr address.Address, count int) {
func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentReceiver TestNode, receiverAddr address.Address, count int) {
// We need to add null blocks in batches, if we add too many the chain can't sync
batchSize := 60
for i := 0; i < count; i += batchSize {
@@ -221,7 +220,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *blockMiner, paymentRec
To: builtin.BurntFundsActorAddr,
From: receiverAddr,
Value: types.NewInt(0),
})
}, nil)
if err != nil {
t.Fatal(err)
}
@@ -249,73 +248,3 @@ func waitForMessage(ctx context.Context, t *testing.T, paymentCreator TestNode,
fmt.Println("Confirmed", desc)
return res
}
type blockMiner struct {
ctx context.Context
t *testing.T
miner TestStorageNode
blocktime time.Duration
mine int64
nulls int64
done chan struct{}
}
func newBlockMiner(ctx context.Context, t *testing.T, miner TestStorageNode, blocktime time.Duration) *blockMiner {
return &blockMiner{
ctx: ctx,
t: t,
miner: miner,
blocktime: blocktime,
mine: int64(1),
done: make(chan struct{}),
}
}
func (bm *blockMiner) mineBlocks() {
time.Sleep(time.Second)
go func() {
defer close(bm.done)
for atomic.LoadInt64(&bm.mine) == 1 {
time.Sleep(bm.blocktime)
nulls := atomic.SwapInt64(&bm.nulls, 0)
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
InjectNulls: abi.ChainEpoch(nulls),
Done: func(bool, error) {},
}); err != nil {
bm.t.Error(err)
}
}
}()
}
func (bm *blockMiner) stop() {
atomic.AddInt64(&bm.mine, -1)
fmt.Println("shutting down mining")
<-bm.done
}
func sendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) {
senderAddr, err := sender.WalletDefaultAddress(ctx)
if err != nil {
t.Fatal(err)
}
msg := &types.Message{
From: senderAddr,
To: addr,
Value: amount,
}
sm, err := sender.MpoolPushMessage(ctx, msg)
if err != nil {
t.Fatal(err)
}
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1)
if err != nil {
t.Fatal(err)
}
if res.Receipt.ExitCode != 0 {
t.Fatal("did not successfully send money")
}
}
+12 -4
View File
@@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -14,10 +16,16 @@ import (
type TestNode struct {
api.FullNode
// ListenAddr is the address on which an API server is listening, if an
// API server is created for this Node
ListenAddr multiaddr.Multiaddr
}
type TestStorageNode struct {
api.StorageMiner
// ListenAddr is the address on which an API server is listening, if an
// API server is created for this Node
ListenAddr multiaddr.Multiaddr
MineOne func(context.Context, miner.MineReq) error
}
@@ -54,11 +62,11 @@ func TestApis(t *testing.T, b APIBuilder) {
t.Run("testMiningReal", ts.testMiningReal)
}
var oneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
var OneMiner = []StorageMiner{{Full: 0, Preseal: PresealGenesis}}
func (ts *testSuite) testVersion(t *testing.T) {
ctx := context.Background()
apis, _ := ts.makeNodes(t, 1, oneMiner)
apis, _ := ts.makeNodes(t, 1, OneMiner)
api := apis[0]
v, err := api.Version(ctx)
@@ -70,7 +78,7 @@ func (ts *testSuite) testVersion(t *testing.T) {
func (ts *testSuite) testID(t *testing.T) {
ctx := context.Background()
apis, _ := ts.makeNodes(t, 1, oneMiner)
apis, _ := ts.makeNodes(t, 1, OneMiner)
api := apis[0]
id, err := api.ID(ctx)
@@ -82,7 +90,7 @@ func (ts *testSuite) testID(t *testing.T) {
func (ts *testSuite) testConnectTwo(t *testing.T) {
ctx := context.Background()
apis, _ := ts.makeNodes(t, 2, oneMiner)
apis, _ := ts.makeNodes(t, 2, OneMiner)
p, err := apis[0].NetPeers(ctx)
if err != nil {
+36
View File
@@ -0,0 +1,36 @@
package test
import (
"context"
"testing"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
)
func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) {
senderAddr, err := sender.WalletDefaultAddress(ctx)
if err != nil {
t.Fatal(err)
}
msg := &types.Message{
From: senderAddr,
To: addr,
Value: amount,
}
sm, err := sender.MpoolPushMessage(ctx, msg, nil)
if err != nil {
t.Fatal(err)
}
res, err := sender.StateWaitMsg(ctx, sm.Cid(), 1)
if err != nil {
t.Fatal(err)
}
if res.Receipt.ExitCode != 0 {
t.Fatal("did not successfully send money")
}
}
+5 -10
View File
@@ -12,10 +12,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/sector-storage/mock"
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/specs-actors/actors/abi"
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
sealing "github.com/filecoin-project/storage-fsm"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
@@ -28,7 +28,7 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
@@ -44,16 +44,11 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
mine := true
done := make(chan struct{})
blockNotif := make(chan struct{}, 1)
go func() {
defer close(done)
for mine {
build.Clock.Sleep(blocktime)
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, error) {
select {
case blockNotif <- struct{}{}:
default:
}
}}); err != nil {
t.Error(err)
@@ -61,7 +56,7 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
}
}()
pledgeSectors(t, ctx, miner, nSectors, 0, blockNotif)
pledgeSectors(t, ctx, miner, nSectors, 0, nil)
mine = false
<-done
@@ -118,7 +113,7 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, 1, oneMiner)
n, sn := b(t, 1, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
+83 -9
View File
@@ -2,9 +2,14 @@ package api
import (
"encoding/json"
"fmt"
"github.com/filecoin-project/go-address"
datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
pubsub "github.com/libp2p/go-libp2p-pubsub"
@@ -45,11 +50,12 @@ type PubsubScore struct {
}
type MinerInfo struct {
Owner address.Address // Must be an ID-address.
Worker address.Address // Must be an ID-address.
NewWorker address.Address // Must be an ID-address.
Owner address.Address // Must be an ID-address.
Worker address.Address // Must be an ID-address.
NewWorker address.Address // Must be an ID-address.
ControlAddresses []address.Address // Must be an ID-addresses.
WorkerChangeEpoch abi.ChainEpoch
PeerId peer.ID
PeerId *peer.ID
Multiaddrs []abi.Multiaddrs
SealProofType abi.RegisteredSealProof
SectorSize abi.SectorSize
@@ -57,12 +63,20 @@ type MinerInfo struct {
}
func NewApiMinerInfo(info *miner.MinerInfo) MinerInfo {
var pid *peer.ID
if peerID, err := peer.IDFromBytes(info.PeerId); err == nil {
pid = &peerID
}
mi := MinerInfo{
Owner: info.Owner,
Worker: info.Worker,
NewWorker: address.Undef,
WorkerChangeEpoch: -1,
PeerId: peer.ID(info.PeerId),
Owner: info.Owner,
Worker: info.Worker,
ControlAddresses: info.ControlAddresses,
NewWorker: address.Undef,
WorkerChangeEpoch: -1,
PeerId: pid,
Multiaddrs: info.Multiaddrs,
SealProofType: info.SealProofType,
SectorSize: info.SectorSize,
@@ -76,3 +90,63 @@ func NewApiMinerInfo(info *miner.MinerInfo) MinerInfo {
return mi
}
type MessageSendSpec struct {
MaxFee abi.TokenAmount
}
var DefaultMessageSendSpec = MessageSendSpec{
MaxFee: big.Zero(),
}
func (ms *MessageSendSpec) Get() MessageSendSpec {
if ms == nil {
return DefaultMessageSendSpec
}
return *ms
}
type DataTransferChannel struct {
TransferID datatransfer.TransferID
Status datatransfer.Status
BaseCID cid.Cid
IsInitiator bool
IsSender bool
Voucher string
Message string
OtherPeer peer.ID
Transferred uint64
}
// NewDataTransferChannel constructs an API DataTransferChannel type from full channel state snapshot and a host id
func NewDataTransferChannel(hostID peer.ID, channelState datatransfer.ChannelState) DataTransferChannel {
channel := DataTransferChannel{
TransferID: channelState.TransferID(),
Status: channelState.Status(),
BaseCID: channelState.BaseCID(),
IsSender: channelState.Sender() == hostID,
Message: channelState.Message(),
}
stringer, ok := channelState.Voucher().(fmt.Stringer)
if ok {
channel.Voucher = stringer.String()
} else {
voucherJSON, err := json.Marshal(channelState.Voucher())
if err != nil {
channel.Voucher = fmt.Errorf("Voucher Serialization: %w", err).Error()
} else {
channel.Voucher = string(voucherJSON)
}
}
if channel.IsSender {
channel.IsInitiator = !channelState.IsPull()
channel.Transferred = channelState.Sent()
channel.OtherPeer = channelState.Recipient()
} else {
channel.IsInitiator = channelState.IsPull()
channel.Transferred = channelState.Received()
channel.OtherPeer = channelState.Sender()
}
return channel
}
+6 -12
View File
@@ -1,12 +1,6 @@
/dns4/bootstrap-0-sin.fil-test.net/tcp/1347/p2p/12D3KooWPdUquftaQvoQEtEdsRBAhwD6jopbF2oweVTzR59VbHEd
/ip4/86.109.15.57/tcp/1347/p2p/12D3KooWPdUquftaQvoQEtEdsRBAhwD6jopbF2oweVTzR59VbHEd
/dns4/bootstrap-0-dfw.fil-test.net/tcp/1347/p2p/12D3KooWQSCkHCzosEyrh8FgYfLejKgEPM5VB6qWzZE3yDAuXn8d
/ip4/139.178.84.45/tcp/1347/p2p/12D3KooWQSCkHCzosEyrh8FgYfLejKgEPM5VB6qWzZE3yDAuXn8d
/dns4/bootstrap-0-fra.fil-test.net/tcp/1347/p2p/12D3KooWEXN2eQmoyqnNjde9PBAQfQLHN67jcEdWU6JougWrgXJK
/ip4/136.144.49.17/tcp/1347/p2p/12D3KooWEXN2eQmoyqnNjde9PBAQfQLHN67jcEdWU6JougWrgXJK
/dns4/bootstrap-1-sin.fil-test.net/tcp/1347/p2p/12D3KooWLmJkZd33mJhjg5RrpJ6NFep9SNLXWc4uVngV4TXKwzYw
/ip4/86.109.15.123/tcp/1347/p2p/12D3KooWLmJkZd33mJhjg5RrpJ6NFep9SNLXWc4uVngV4TXKwzYw
/dns4/bootstrap-1-dfw.fil-test.net/tcp/1347/p2p/12D3KooWGXLHjiz6pTRu7x2pkgTVCoxcCiVxcNLpMnWcJ3JiNEy5
/ip4/139.178.86.3/tcp/1347/p2p/12D3KooWGXLHjiz6pTRu7x2pkgTVCoxcCiVxcNLpMnWcJ3JiNEy5
/dns4/bootstrap-1-fra.fil-test.net/tcp/1347/p2p/12D3KooW9szZmKttS9A1FafH3Zc2pxKwwmvCWCGKkRP4KmbhhC4R
/ip4/136.144.49.131/tcp/1347/p2p/12D3KooW9szZmKttS9A1FafH3Zc2pxKwwmvCWCGKkRP4KmbhhC4R
/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
+15 -1
View File
@@ -2,7 +2,7 @@ package build
import "github.com/filecoin-project/lotus/node/modules/dtypes"
var DrandNetwork = DrandMainnet
var DrandNetwork = DrandIncentinet
func DrandConfig() dtypes.DrandConfig {
return DrandConfigs[DrandNetwork]
@@ -15,6 +15,7 @@ const (
DrandTestnet
DrandDevnet
DrandLocalnet
DrandIncentinet
)
var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
@@ -55,4 +56,17 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
},
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
},
DrandIncentinet: {
Servers: []string{
"https://pl-eu.incentinet.drand.sh",
"https://pl-us.incentinet.drand.sh",
"https://pl-sin.incentinet.drand.sh",
},
Relays: []string{
"/dnsaddr/pl-eu.incentinet.drand.sh/",
"/dnsaddr/pl-us.incentinet.drand.sh/",
"/dnsaddr/pl-sin.incentinet.drand.sh/",
},
ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`,
},
}
Binary file not shown.
+3
View File
@@ -89,11 +89,14 @@ const VerifSigCacheSize = 32000
// TODO: If this is gonna stay, it should move to specs-actors
const BlockMessageLimit = 10000
const BlockGasLimit = 10_000_000_000
const BlockGasTarget = BlockGasLimit / 2
const BaseFeeMaxChangeDenom = 8 // 12.5%
const InitialBaseFee = 100e6
const MinimumBaseFee = 100
const PackingEfficiencyNum = 4
const PackingEfficiencyDenom = 5
// Actor consts
// TODO: Pull from actors when its made not private
+3
View File
@@ -66,4 +66,7 @@ var (
// Actor consts
// TODO: Pull from actors when its made not private
MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
PackingEfficiencyNum int64 = 4
PackingEfficiencyDenom int64 = 5
)
+1 -1
View File
@@ -13,7 +13,7 @@ import (
)
func init() {
power.ConsensusMinerMinPower = big.NewInt(1024 << 30)
power.ConsensusMinerMinPower = big.NewInt(10 << 40)
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg32GiBV1: {},
abi.RegisteredSealProof_StackedDrg64GiBV1: {},
+91 -91
View File
@@ -1,152 +1,152 @@
{
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
"cid": "QmeDRyxek34F1H6xJY6AkFdWvPsy5F6dKTrebV3ZtWT4ky",
"digest": "f5827f2d8801c62c831e0f972f6dc8bb",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
"cid": "QmVxjFRyhmyQaZEtCh7nk2abc7LhFkzhnRX4rcHqCCpikR",
"digest": "7610b9f82bfc88405b7a832b651ce2f6",
"sector_size": 2048
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
"cid": "QmUw1ZmG4BBbX19MsbH3zAEGKUc42iFJc5ZAyomDHeJTsA",
"digest": "398fecdb4b2de445125852bc3c080b35",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.vk": {
"cid": "QmcS5JZs8X3TdtkEBpHAdUYjdNDqcL7fWQFtQz69mpnu2X",
"digest": "0e0958009936b9d5e515ec97b8cb792d",
"sector_size": 2048
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
"cid": "QmUeNKp9YZpiAFm81RV5KuxH1FDGJx2DuwcbU2XNSZLLSv",
"digest": "2b6d2972ac9e862e8134d98fb695b0c5",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.params": {
"cid": "QmUiRx71uxfmUE8V3H9sWAsAXoM88KR4eo1ByvvcFNeTLR",
"digest": "1a7d4a9c8a502a497ed92a54366af33f",
"sector_size": 536870912
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
"cid": "QmQaQmTXX995Akd66ggtJY5bNx6Gkxk8P34JTdMMq8393G",
"digest": "3688c9eb256b7b17f411dad78d5ef74a",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0cfb4f178bbb71cf2ecfcd42accce558b27199ab4fb59cb78f2483fe21ef36d9.vk": {
"cid": "QmfCeddjFpWtavzfEzZpJfzSajGNwfL4RjFXWAvA9TSnTV",
"digest": "4dae975de4f011f101f5a2f86d1daaba",
"sector_size": 536870912
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
"cid": "QmfEYTMSkwGJTumQx26iKXGNKiYh3mmAC4SkdybZpJCj5p",
"digest": "09bff16aed893349d94485cfae366a9c",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.params": {
"cid": "QmcSTqDcFVLGGVYz1njhUZ7B6fkKtBumsLUwx4nkh22TzS",
"digest": "82c88066be968bb550a05e30ff6c2413",
"sector_size": 2048
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
"cid": "QmP4ThPieSUJyRanjibWpT5R5cCMzMAU4j8Y7kBn7CSW1Q",
"digest": "142f2f7e8f1b1779290315cabfd2c803",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-3ea05428c9d11689f23529cde32fd30aabd50f7d2c93657c1d3650bca3e8ea9e.vk": {
"cid": "QmSTCXF2ipGA3f6muVo6kHc2URSx6PzZxGUqu7uykaH5KU",
"digest": "ffd79788d614d27919ae5bd2d94eacb6",
"sector_size": 2048
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
"cid": "QmcAixrHsz29DgvtZiMc2kQjvPRvWxYUp36QYmRDZbmREm",
"digest": "8f987f64d434365562180b96ec12e299",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.params": {
"cid": "QmU9SBzJNrcjRFDiFc4GcApqdApN6z9X7MpUr66mJ2kAJP",
"digest": "700171ecf7334e3199437c930676af82",
"sector_size": 8388608
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
"cid": "QmT4iFnbL6r4txS5PXsiV7NTzbhCxHy54PvdkJJGV2VFXb",
"digest": "94b6c24ac01924f4feeecedd16b5d77d",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-50c7368dea9593ed0989e70974d28024efa9d156d585b7eea1be22b2e753f331.vk": {
"cid": "QmbmUMa3TbbW3X5kFhExs6WgC4KeWT18YivaVmXDkB6ANG",
"digest": "79ebb55f56fda427743e35053edad8fc",
"sector_size": 8388608
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
"cid": "QmbjFst6SFCK1KsTQrfwPdxf3VTNa1raed574tEZZ9PoyQ",
"digest": "2c245fe8179839dd6c6cdea207c67ae8",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.params": {
"cid": "QmdNEL2RtqL52GQNuj8uz6mVj5Z34NVnbaJ1yMyh1oXtBx",
"digest": "c49499bb76a0762884896f9683403f55",
"sector_size": 8388608
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
"cid": "QmQJKmvZN1a5cQ1Nw6CDyXs3nuRPzvyU5NvCFMUL2BfcZC",
"digest": "56ae47bfda53bb8d22981ed8d8d27d72",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-5294475db5237a2e83c3e52fd6c2b03859a1831d45ed08c4f35dbf9a803165a9.vk": {
"cid": "QmUiVYCQUgr6Y13pZFr8acWpSM4xvTXUdcvGmxyuHbKhsc",
"digest": "34d4feeacd9abf788d69ef1bb4d8fd00",
"sector_size": 8388608
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
"cid": "QmQCABxeTpdvXTyjDyk7nPBxkQzCh7MXfGztWnSXEPKMLW",
"digest": "7e6b2eb5ecbb11ac651ad66ebbb2075a",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.params": {
"cid": "QmVgCsJFRXKLuuUhT3aMYwKVGNA9rDeR6DCrs7cAe8riBT",
"digest": "827359440349fe8f5a016e7598993b79",
"sector_size": 536870912
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
"cid": "QmPBweyugh5Sx4umk8ULhgEGbjY8xmWLfU6M7EMpc8Mad6",
"digest": "94a8d9e25a9ab9674d339833664eba25",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-7d739b8cf60f1b0709eeebee7730e297683552e4b69cab6984ec0285663c5781.vk": {
"cid": "QmfA31fbCWojSmhSGvvfxmxaYCpMoXP95zEQ9sLvBGHNaN",
"digest": "bd2cd62f65c1ab84f19ca27e97b7c731",
"sector_size": 536870912
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
"cid": "QmY5yax1E9KymBnCeHksE9Zi8NieZbmwcpoDGoabkeeb9h",
"digest": "c909ea9e3fe25ab9b391a64593afdbba",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.params": {
"cid": "QmaUmfcJt6pozn8ndq1JVBzLRjRJdHMTPd4foa8iw5sjBZ",
"digest": "2cf49eb26f1fee94c85781a390ddb4c8",
"sector_size": 34359738368
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
"cid": "QmXnPo4yH5mwMguwrvqgRfduSttbmPrXtbBfbwU21wQWHt",
"digest": "caf900461e988bbf86dbcaca087b7864",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-0377ded656c6f524f1618760bffe4e0a1c51d5a70c4509eedae8a27555733edc.vk": {
"cid": "QmR9i9KL3vhhAqTBGj1bPPC7LvkptxrH9RvxJxLN1vvsBE",
"digest": "0f8ec542485568fa3468c066e9fed82b",
"sector_size": 34359738368
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
"cid": "QmZtzzPWwmZEgR7MSMvXRbt9KVK8k4XZ5RLWHybHJW9SdE",
"digest": "a2844f0703f186d143a06146a04577d8",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.params": {
"cid": "Qmdtczp7p4wrbDofmHdGhiixn9irAcN77mV9AEHZBaTt1i",
"digest": "d84f79a16fe40e9e25a36e2107bb1ba0",
"sector_size": 34359738368
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
"cid": "QmWxEA7EdQCUJTzjNpxg5XTF45D2uVyYnN1QRUb5TRYU8M",
"digest": "2306247a1e616dbe07f01b88196c2044",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-0-559e581f022bb4e4ec6e719e563bf0e026ad6de42e56c18714a2c692b1b88d7e.vk": {
"cid": "QmZCvxKcKP97vDAk8Nxs9R1fWtqpjQrAhhfXPoCi1nkDoF",
"digest": "fc02943678dd119e69e7fab8420e8819",
"sector_size": 34359738368
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": {
"cid": "QmP676KwuvyF9Y64uJnXvLtvD1xcuWQ6wD23RzYtQ6dd4f",
"digest": "215b1c667a4f46a1d0178338df568615",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.params": {
"cid": "QmeAN4vuANhXsF8xP2Lx5j2L6yMSdogLzpcvqCJThRGK1V",
"digest": "3810b7780ac0e299b22ae70f1f94c9bc",
"sector_size": 68719476736
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": {
"cid": "QmPvPwbJtcSGyqB1rQJhSF5yvFbX9ZBSsHVej5F8JUyHUJ",
"digest": "0c9c423b28b1455fcbc329a1045fd4dd",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-2627e4006b67f99cef990c0a47d5426cb7ab0a0ad58fc1061547bf2d28b09def.vk": {
"cid": "QmWV8rqZLxs1oQN9jxNWmnT1YdgLwCcscv94VARrhHf1T7",
"digest": "59d2bf1857adc59a4f08fcf2afaa916b",
"sector_size": 68719476736
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": {
"cid": "QmUxPQfvckzm1t6MFRdDZ1fDK5UJzAjK7pTZ97cwyachdr",
"digest": "965132f51ae445b0e6d32692b7561995",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.params": {
"cid": "QmVkrXc1SLcpgcudK5J25HH93QvR9tNsVhVTYHm5UymXAz",
"digest": "2170a91ad5bae22ea61f2ea766630322",
"sector_size": 68719476736
},
"v27-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": {
"cid": "QmTxq2EBnQWb5R8tS4MHdchj4vNfLYGoSXxwJFvs5xgW4K",
"digest": "fc8c3d26e0e56373ad96cb41520d55a6",
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-8-2-b62098629d07946e9028127e70295ed996fe3ed25b0f9f88eb610a0ab4385a3c.vk": {
"cid": "QmbfQjPD7EpzjhWGmvWAsyN2mAZ4PcYhsf3ujuhU9CSuBm",
"digest": "6d3789148fb6466d07ee1e24d6292fd6",
"sector_size": 68719476736
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": {
"cid": "QmRjgZHERgqGoRagR788Kh6ybi26csVYa8mqbqhmZm57Jx",
"digest": "cfc7b0897d1eee48c586f7beb89e67f7",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.params": {
"cid": "QmWceMgnWYLopMuM4AoGMvGEau7tNe5UK83XFjH5V9B17h",
"digest": "434fb1338ecfaf0f59256f30dde4968f",
"sector_size": 2048
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": {
"cid": "QmNjvnvFP7KgovHUddULoB19fBHT81iz7NcUbzEHZUUPsm",
"digest": "fb59bd061c987eac7068008c44de346b",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-032d3138d22506ec0082ed72b2dcba18df18477904e35bafee82b3793b06832f.vk": {
"cid": "QmamahpFCstMUqHi2qGtVoDnRrsXhid86qsfvoyCTKJqHr",
"digest": "dc1ade9929ade1708238f155343044ac",
"sector_size": 2048
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": {
"cid": "QmTpRPBA4dt8fgGpcVzi4L1KA1U2eBHCE8WVmS2GUygMvT",
"digest": "36d465915b0afbf96bd08e7915e00952",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.params": {
"cid": "QmYBpTt7LWNAWr1JXThV5VxX7wsQFLd1PHrGYVbrU1EZjC",
"digest": "6c77597eb91ab936c1cef4cf19eba1b3",
"sector_size": 536870912
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": {
"cid": "QmRzDyVfQCLsxspoVsed5bcQRsG6KiktngJfcNBL3TJPZe",
"digest": "99d16df0eb6a7e227a4f4570c4f6b6f1",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-6babf46ce344ae495d558e7770a585b2382d54f225af8ed0397b8be7c3fcd472.vk": {
"cid": "QmWionkqH2B6TXivzBSQeSyBxojaiAFbzhjtwYRrfwd8nH",
"digest": "065179da19fbe515507267677f02823e",
"sector_size": 536870912
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": {
"cid": "QmV8ZjTSGzDUWmFvsq9NSyPBR7eDDUcvCPNgj2yE7HMAFu",
"digest": "34f3ddf1d1c9f41c0cd73b91e8b4bc27",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.params": {
"cid": "QmPXAPPuQtuQz7Zz3MHMAMEtsYwqM1o9H1csPLeiMUQwZH",
"digest": "09e612e4eeb7a0eb95679a88404f960c",
"sector_size": 8388608
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": {
"cid": "QmTa3VbjTiqJWU6r4WKayaQrUaaBsrpp5UDqYvPDd2C5hs",
"digest": "ec62d59651daa5631d3d1e9c782dd940",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-0-0-sha256_hasher-ecd683648512ab1765faa2a5f14bab48f676e633467f0aa8aad4b55dcb0652bb.vk": {
"cid": "QmYCuipFyvVW1GojdMrjK1JnMobXtT4zRCZs1CGxjizs99",
"digest": "b687beb9adbd9dabe265a7e3620813e4",
"sector_size": 8388608
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": {
"cid": "Qmf8ngfArxrv9tFWDqBcNegdBMymvuakwyHKd1pbW3pbsb",
"digest": "a16d6f4c6424fb280236739f84b24f97",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.params": {
"cid": "QmengpM684XLQfG8754ToonszgEg2bQeAGUan5uXTHUQzJ",
"digest": "6a388072a518cf46ebd661f5cc46900a",
"sector_size": 34359738368
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": {
"cid": "QmfQgVFerArJ6Jupwyc9tKjLD9n1J9ajLHBdpY465tRM7M",
"digest": "7a139d82b8a02e35279d657e197f5c1f",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-0-sha256_hasher-82a357d2f2ca81dc61bb45f4a762807aedee1b0a53fd6c4e77b46a01bfef7820.vk": {
"cid": "Qmf93EMrADXAK6CyiSfE8xx45fkMfR3uzKEPCvZC1n2kzb",
"digest": "0c7b4aac1c40fdb7eb82bc355b41addf",
"sector_size": 34359738368
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": {
"cid": "QmfDha8271nXJn14Aq3qQeghjMBWbs6HNSGa6VuzCVk4TW",
"digest": "5d3cd3f107a3bea8a96d1189efd2965c",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.params": {
"cid": "QmS7ye6Ri2MfFzCkcUJ7FQ6zxDKuJ6J6B8k5PN7wzSR9sX",
"digest": "1801f8a6e1b00bceb00cc27314bb5ce3",
"sector_size": 68719476736
},
"v27-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": {
"cid": "QmRVtTtiFzHJTHurYzaCvetGAchux9cktixT4aGHthN6Zt",
"digest": "62c366405404e60f171e661492740b1c",
"v28-stacked-proof-of-replication-merkletree-poseidon_hasher-8-8-2-sha256_hasher-96f1b4a04c5c51e4759bbf224bbc2ef5a42c7100f16ec0637123f16a845ddfb2.vk": {
"cid": "QmehSmC6BhrgRZakPDta2ewoH9nosNzdjCqQRXsNFNUkLN",
"digest": "a89884252c04c298d0b3c81bfd884164",
"sector_size": 68719476736
}
}
}
+2 -2
View File
@@ -25,7 +25,7 @@ func buildType() string {
}
// BuildVersion is the local build version, set by build system
const BuildVersion = "0.4.3"
const BuildVersion = "0.4.6"
func UserVersion() string {
return BuildVersion + buildType() + CurrentCommit
@@ -53,7 +53,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool {
}
// APIVersion is a semver version of the rpc api exposed
var APIVersion Version = newVer(0, 9, 0)
var APIVersion Version = newVer(0, 11, 0)
//nolint:varcheck,deadcode
const (
+4
View File
@@ -171,6 +171,10 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
// TODO handle genesis better
return nil
}
if be := db.getCachedValue(curr.Round); be != nil {
// return no error if the value is in the cache already
return nil
}
b := &dchain.Beacon{
PreviousSig: prev.Data,
Round: curr.Round,
+4 -6
View File
@@ -7,7 +7,7 @@ import (
"io"
"github.com/filecoin-project/lotus/chain/types"
cid "github.com/ipfs/go-cid"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
)
@@ -625,16 +625,14 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) error {
{
pb, err := br.PeekByte()
b, err := br.ReadByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
} else {
t.Messages = new(CompactedMessages)
if err := t.Messages.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.Messages pointer: %w", err)
+1 -1
View File
@@ -393,7 +393,7 @@ func (client *BlockSync) sendRequestToPeer(
&res)
if err != nil {
client.peerTracker.logFailure(peer, build.Clock.Since(connectionStart))
return nil, err
return nil, xerrors.Errorf("failed to read blocksync response: %w", err)
}
// FIXME: Move all this together at the top using a defer as done elsewhere.
+11 -4
View File
@@ -1,6 +1,7 @@
package state
import (
"bytes"
"github.com/filecoin-project/specs-actors/actors/util/adt"
typegen "github.com/whyrusleeping/cbor-gen"
)
@@ -39,8 +40,11 @@ func DiffAdtArray(preArr, curArr *adt.Array, out AdtArrayDiff) error {
return nil
}
if err := out.Modify(uint64(i), prevVal, curVal); err != nil {
return err
// no modification
if !bytes.Equal(prevVal.Raw, curVal.Raw) {
if err := out.Modify(uint64(i), prevVal, curVal); err != nil {
return err
}
}
return curArr.Delete(uint64(i))
@@ -90,8 +94,11 @@ func DiffAdtMap(preMap, curMap *adt.Map, out AdtMapDiff) error {
return nil
}
if err := out.Modify(key, prevVal, curVal); err != nil {
return err
// no modification
if !bytes.Equal(prevVal.Raw, curVal.Raw) {
if err := out.Modify(key, prevVal, curVal); err != nil {
return err
}
}
return curMap.Delete(k)
+168 -20
View File
@@ -40,7 +40,7 @@ func TestDiffAdtArray(t *testing.T) {
require.NoError(t, arrB.Set(5, runtime.CBORBytes{8})) // add
require.NoError(t, arrB.Set(6, runtime.CBORBytes{9})) // add
changes := new(TestAdtDiff)
changes := new(TestDiffArray)
assert.NoError(t, DiffAdtArray(arrA, arrB, changes))
assert.NotNil(t, changes)
@@ -71,38 +71,186 @@ func TestDiffAdtArray(t *testing.T) {
assert.EqualValues(t, []byte{1}, changes.Removed[1].val)
}
type adtDiffResult struct {
key uint64
val runtime.CBORBytes
func TestDiffAdtMap(t *testing.T) {
ctxstoreA := newContextStore()
ctxstoreB := newContextStore()
mapA := adt.MakeEmptyMap(ctxstoreA)
mapB := adt.MakeEmptyMap(ctxstoreB)
require.NoError(t, mapA.Put(adt.UIntKey(0), runtime.CBORBytes([]byte{0}))) // delete
require.NoError(t, mapA.Put(adt.UIntKey(1), runtime.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(adt.UIntKey(1), runtime.CBORBytes([]byte{1})))
require.NoError(t, mapA.Put(adt.UIntKey(2), runtime.CBORBytes([]byte{1}))) // delete
require.NoError(t, mapA.Put(adt.UIntKey(3), runtime.CBORBytes([]byte{0}))) // noop
require.NoError(t, mapB.Put(adt.UIntKey(3), runtime.CBORBytes([]byte{0})))
require.NoError(t, mapA.Put(adt.UIntKey(4), runtime.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(adt.UIntKey(4), runtime.CBORBytes([]byte{6})))
require.NoError(t, mapB.Put(adt.UIntKey(5), runtime.CBORBytes{8})) // add
require.NoError(t, mapB.Put(adt.UIntKey(6), runtime.CBORBytes{9})) // add
changes := new(TestDiffMap)
assert.NoError(t, DiffAdtMap(mapA, mapB, changes))
assert.NotNil(t, changes)
assert.Equal(t, 2, len(changes.Added))
// keys 5 and 6 were added
assert.EqualValues(t, uint64(6), changes.Added[0].key)
assert.EqualValues(t, []byte{9}, changes.Added[0].val)
assert.EqualValues(t, uint64(5), changes.Added[1].key)
assert.EqualValues(t, []byte{8}, changes.Added[1].val)
assert.Equal(t, 2, len(changes.Modified))
// keys 1 and 4 were modified
assert.EqualValues(t, uint64(1), changes.Modified[0].From.key)
assert.EqualValues(t, []byte{0}, changes.Modified[0].From.val)
assert.EqualValues(t, uint64(1), changes.Modified[0].To.key)
assert.EqualValues(t, []byte{1}, changes.Modified[0].To.val)
assert.EqualValues(t, uint64(4), changes.Modified[1].From.key)
assert.EqualValues(t, []byte{0}, changes.Modified[1].From.val)
assert.EqualValues(t, uint64(4), changes.Modified[1].To.key)
assert.EqualValues(t, []byte{6}, changes.Modified[1].To.val)
assert.Equal(t, 2, len(changes.Removed))
// keys 0 and 2 were deleted
assert.EqualValues(t, uint64(0), changes.Removed[0].key)
assert.EqualValues(t, []byte{0}, changes.Removed[0].val)
assert.EqualValues(t, uint64(2), changes.Removed[1].key)
assert.EqualValues(t, []byte{1}, changes.Removed[1].val)
}
type TestAdtDiff struct {
Added []adtDiffResult
Modified []TestAdtDiffModified
Removed []adtDiffResult
type TestDiffMap struct {
Added []adtMapDiffResult
Modified []TestAdtMapDiffModified
Removed []adtMapDiffResult
}
var _ AdtArrayDiff = &TestAdtDiff{}
var _ AdtMapDiff = &TestDiffMap{}
type TestAdtDiffModified struct {
From adtDiffResult
To adtDiffResult
func (t *TestDiffMap) AsKey(key string) (adt.Keyer, error) {
k, err := adt.ParseUIntKey(key)
if err != nil {
return nil, err
}
return adt.UIntKey(k), nil
}
func (t *TestAdtDiff) Add(key uint64, val *typegen.Deferred) error {
func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error {
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
}
t.Added = append(t.Added, adtDiffResult{
k, err := adt.ParseUIntKey(key)
if err != nil {
return err
}
t.Added = append(t.Added, adtMapDiffResult{
key: k,
val: *v,
})
return nil
}
func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error {
vFrom := new(runtime.CBORBytes)
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
if err != nil {
return err
}
vTo := new(runtime.CBORBytes)
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
if err != nil {
return err
}
k, err := adt.ParseUIntKey(key)
if err != nil {
return err
}
if !bytes.Equal(*vFrom, *vTo) {
t.Modified = append(t.Modified, TestAdtMapDiffModified{
From: adtMapDiffResult{
key: k,
val: *vFrom,
},
To: adtMapDiffResult{
key: k,
val: *vTo,
},
})
}
return nil
}
func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
}
k, err := adt.ParseUIntKey(key)
if err != nil {
return err
}
t.Removed = append(t.Removed, adtMapDiffResult{
key: k,
val: *v,
})
return nil
}
type adtMapDiffResult struct {
key uint64
val runtime.CBORBytes
}
type TestAdtMapDiffModified struct {
From adtMapDiffResult
To adtMapDiffResult
}
type adtArrayDiffResult struct {
key uint64
val runtime.CBORBytes
}
type TestDiffArray struct {
Added []adtArrayDiffResult
Modified []TestAdtArrayDiffModified
Removed []adtArrayDiffResult
}
var _ AdtArrayDiff = &TestDiffArray{}
type TestAdtArrayDiffModified struct {
From adtArrayDiffResult
To adtArrayDiffResult
}
func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
}
t.Added = append(t.Added, adtArrayDiffResult{
key: key,
val: *v,
})
return nil
}
func (t *TestAdtDiff) Modify(key uint64, from, to *typegen.Deferred) error {
func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error {
vFrom := new(runtime.CBORBytes)
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
if err != nil {
@@ -116,12 +264,12 @@ func (t *TestAdtDiff) Modify(key uint64, from, to *typegen.Deferred) error {
}
if !bytes.Equal(*vFrom, *vTo) {
t.Modified = append(t.Modified, TestAdtDiffModified{
From: adtDiffResult{
t.Modified = append(t.Modified, TestAdtArrayDiffModified{
From: adtArrayDiffResult{
key: key,
val: *vFrom,
},
To: adtDiffResult{
To: adtArrayDiffResult{
key: key,
val: *vTo,
},
@@ -130,13 +278,13 @@ func (t *TestAdtDiff) Modify(key uint64, from, to *typegen.Deferred) error {
return nil
}
func (t *TestAdtDiff) Remove(key uint64, val *typegen.Deferred) error {
func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error {
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
}
t.Removed = append(t.Removed, adtDiffResult{
t.Removed = append(t.Removed, adtArrayDiffResult{
key: key,
val: *v,
})
+161 -5
View File
@@ -3,19 +3,18 @@ package state
import (
"bytes"
"context"
"github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
typegen "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
typegen "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/chain/types"
@@ -407,6 +406,21 @@ func (sp *StatePredicates) AvailableBalanceChangedForAddresses(getAddrs func() [
type DiffMinerActorStateFunc func(ctx context.Context, oldState *miner.State, newState *miner.State) (changed bool, user UserData, err error)
func (sp *StatePredicates) OnInitActorChange(diffInitActorState DiffInitActorStateFunc) DiffTipSetKeyFunc {
return sp.OnActorStateChanged(builtin.InitActorAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
var oldState init_.State
if err := sp.cst.Get(ctx, oldActorStateHead, &oldState); err != nil {
return false, nil, err
}
var newState init_.State
if err := sp.cst.Get(ctx, newActorStateHead, &newState); err != nil {
return false, nil, err
}
return diffInitActorState(ctx, &oldState, &newState)
})
}
func (sp *StatePredicates) OnMinerActorChange(minerAddr address.Address, diffMinerActorState DiffMinerActorStateFunc) DiffTipSetKeyFunc {
return sp.OnActorStateChanged(minerAddr, func(ctx context.Context, oldActorStateHead, newActorStateHead cid.Cid) (changed bool, user UserData, err error) {
var oldState miner.State
@@ -628,3 +642,145 @@ func (sp *StatePredicates) OnToSendAmountChanges() DiffPaymentChannelStateFunc {
}, nil
}
}
type AddressPair struct {
ID address.Address
PK address.Address
}
type InitActorAddressChanges struct {
Added []AddressPair
Modified []AddressChange
Removed []AddressPair
}
type AddressChange struct {
From AddressPair
To AddressPair
}
type DiffInitActorStateFunc func(ctx context.Context, oldState *init_.State, newState *init_.State) (changed bool, user UserData, err error)
func (i *InitActorAddressChanges) AsKey(key string) (adt.Keyer, error) {
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return nil, err
}
return adt.AddrKey(addr), nil
}
func (i *InitActorAddressChanges) Add(key string, val *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
id := new(typegen.CborInt)
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return err
}
idAddr, err := address.NewIDAddress(uint64(*id))
if err != nil {
return err
}
i.Added = append(i.Added, AddressPair{
ID: idAddr,
PK: pkAddr,
})
return nil
}
func (i *InitActorAddressChanges) Modify(key string, from, to *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
fromID := new(typegen.CborInt)
if err := fromID.UnmarshalCBOR(bytes.NewReader(from.Raw)); err != nil {
return err
}
fromIDAddr, err := address.NewIDAddress(uint64(*fromID))
if err != nil {
return err
}
toID := new(typegen.CborInt)
if err := toID.UnmarshalCBOR(bytes.NewReader(to.Raw)); err != nil {
return err
}
toIDAddr, err := address.NewIDAddress(uint64(*toID))
if err != nil {
return err
}
i.Modified = append(i.Modified, AddressChange{
From: AddressPair{
ID: fromIDAddr,
PK: pkAddr,
},
To: AddressPair{
ID: toIDAddr,
PK: pkAddr,
},
})
return nil
}
func (i *InitActorAddressChanges) Remove(key string, val *typegen.Deferred) error {
pkAddr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
id := new(typegen.CborInt)
if err := id.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return err
}
idAddr, err := address.NewIDAddress(uint64(*id))
if err != nil {
return err
}
i.Removed = append(i.Removed, AddressPair{
ID: idAddr,
PK: pkAddr,
})
return nil
}
func (sp *StatePredicates) OnAddressMapChange() DiffInitActorStateFunc {
return func(ctx context.Context, oldState, newState *init_.State) (changed bool, user UserData, err error) {
ctxStore := &contextStore{
ctx: ctx,
cst: sp.cst,
}
addressChanges := &InitActorAddressChanges{
Added: []AddressPair{},
Modified: []AddressChange{},
Removed: []AddressPair{},
}
if oldState.AddressMap.Equals(newState.AddressMap) {
return false, nil, nil
}
oldAddrs, err := adt.AsMap(ctxStore, oldState.AddressMap)
if err != nil {
return false, nil, err
}
newAddrs, err := adt.AsMap(ctxStore, newState.AddressMap)
if err != nil {
return false, nil, err
}
if err := DiffAdtMap(oldAddrs, newAddrs, addressChanges); err != nil {
return false, nil, err
}
if len(addressChanges.Added)+len(addressChanges.Removed)+len(addressChanges.Modified) == 0 {
return false, nil, nil
}
return true, addressChanges, nil
}
}
+7 -10
View File
@@ -537,26 +537,23 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, o
emptyMap, err := adt.MakeEmptyMap(store).Root()
require.NoError(t, err)
emptyDeadline, err := store.Put(context.TODO(), &miner.Deadline{
Partitions: emptyArrayCid,
ExpirationsEpochs: emptyArrayCid,
PostSubmissions: abi.NewBitField(),
EarlyTerminations: abi.NewBitField(),
LiveSectors: 0,
})
emptyDeadline, err := store.Put(store.Context(), miner.ConstructDeadline(emptyArrayCid))
require.NoError(t, err)
emptyVestingFunds := miner.ConstructVestingFunds()
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
emptyDeadlines := miner.ConstructDeadlines(emptyDeadline)
emptyDeadlinesCid, err := store.Put(context.Background(), emptyDeadlines)
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
require.NoError(t, err)
minerInfo := emptyMap
emptyBitfield := bitfield.NewFromSet(nil)
emptyBitfieldCid, err := store.Put(context.Background(), emptyBitfield)
emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
require.NoError(t, err)
state, err := miner.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid)
state, err := miner.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
require.NoError(t, err)
return state
+60 -22
View File
@@ -34,11 +34,11 @@ import (
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/genesis"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/lotus/lib/sigs"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/sector-storage/ffiwrapper"
)
var log = logging.Logger("gen")
@@ -92,10 +92,8 @@ func (m mybs) Get(c cid.Cid) (block.Block, error) {
return b, nil
}
var rootkey, _ = address.NewIDAddress(80)
var rootkeyMultisig = genesis.MultisigMeta{
Signers: []address.Address{rootkey},
Signers: []address.Address{remAccTestKey},
Threshold: 1,
VestingDuration: 0,
VestingStart: 0,
@@ -107,6 +105,18 @@ var DefaultVerifregRootkeyActor = genesis.Actor{
Meta: rootkeyMultisig.ActorMeta(),
}
var remAccTestKey, _ = address.NewFromString("t1ceb34gnsc6qk5dt6n7xg6ycwzasjhbxm3iylkiy")
var remAccMeta = genesis.MultisigMeta{
Signers: []address.Address{remAccTestKey},
Threshold: 1,
}
var DefaultRemainderAccountActor = genesis.Actor{
Type: genesis.TMultisig,
Balance: big.NewInt(0),
Meta: remAccMeta.ActorMeta(),
}
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
@@ -210,9 +220,10 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
*genm1,
*genm2,
},
VerifregRootKey: DefaultVerifregRootkeyActor,
NetworkName: "",
Timestamp: uint64(build.Clock.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()),
VerifregRootKey: DefaultVerifregRootkeyActor,
RemainderAccount: DefaultRemainderAccountActor,
NetworkName: "",
Timestamp: uint64(build.Clock.Now().Add(-500 * time.Duration(build.BlockDelaySecs) * time.Second).Unix()),
}
genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl)
@@ -272,6 +283,10 @@ func NewGenerator() (*ChainGen, error) {
return NewGeneratorWithSectors(1)
}
func (cg *ChainGen) StateManager() *stmgr.StateManager {
return cg.sm
}
func (cg *ChainGen) SetStateManager(sm *stmgr.StateManager) {
cg.sm = sm
}
@@ -300,7 +315,8 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) {
func CarWalkFunc(nd format.Node) (out []*format.Link, err error) {
for _, link := range nd.Links() {
if link.Cid.Prefix().Codec == cid.FilCommitmentSealed || link.Cid.Prefix().Codec == cid.FilCommitmentUnsealed {
pref := link.Cid.Prefix()
if pref.Codec == cid.FilCommitmentSealed || pref.Codec == cid.FilCommitmentUnsealed {
continue
}
out = append(out, link)
@@ -383,15 +399,32 @@ func (cg *ChainGen) SetWinningPoStProver(m address.Address, wpp WinningPoStProve
}
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address) (*MinedTipSet, error) {
var blks []*types.FullBlock
msgs, err := cg.GetMessages(cg)
ms, err := cg.GetMessages(cg)
if err != nil {
return nil, xerrors.Errorf("get random messages: %w", err)
}
msgs := make([][]*types.SignedMessage, len(miners))
for i := range msgs {
msgs[i] = ms
}
fts, err := cg.NextTipSetFromMinersWithMessages(base, miners, msgs)
if err != nil {
return nil, err
}
return &MinedTipSet{
TipSet: fts,
Messages: ms,
}, nil
}
func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners []address.Address, msgs [][]*types.SignedMessage) (*store.FullTipSet, error) {
var blks []*types.FullBlock
for round := base.Height() + 1; len(blks) == 0; round++ {
for _, m := range miners {
for mi, m := range miners {
bvals, et, ticket, err := cg.nextBlockProof(context.TODO(), base, m, round)
if err != nil {
return nil, xerrors.Errorf("next block proof: %w", err)
@@ -404,7 +437,7 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
return nil, err
}
fblk, err := cg.makeBlock(base, m, ticket, et, bvals, round, wpost, msgs)
fblk, err := cg.makeBlock(base, m, ticket, et, bvals, round, wpost, msgs[mi])
if err != nil {
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
}
@@ -418,12 +451,7 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
}
}
fts := store.NewFullTipSet(blks)
return &MinedTipSet{
TipSet: fts,
Messages: msgs,
}, nil
return store.NewFullTipSet(blks), nil
}
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
@@ -516,7 +544,8 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
}
type MiningCheckAPI interface {
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error)
@@ -530,13 +559,22 @@ type mca struct {
bcn beacon.RandomBeacon
}
func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
func (mca mca) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
pts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
return mca.sm.ChainStore().GetChainRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (mca mca) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
pts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return mca.sm.ChainStore().GetBeaconRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
+41
View File
@@ -0,0 +1,41 @@
package genesis
import (
"encoding/hex"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"github.com/multiformats/go-multihash"
)
const genesisMultihashString = "1220107d821c25dc0735200249df94a8bebc9c8e489744f86a4ca8919e81f19dcd72"
const genesisBlockHex = "a5684461746574696d6573323031372d30352d30352030313a32373a3531674e6574776f726b6846696c65636f696e65546f6b656e6846696c65636f696e6c546f6b656e416d6f756e7473a36b546f74616c537570706c796d322c3030302c3030302c303030664d696e6572736d312c3430302c3030302c3030306c50726f746f636f6c4c616273a36b446576656c6f706d656e746b3330302c3030302c3030306b46756e6472616973696e676b3230302c3030302c3030306a466f756e646174696f6e6b3130302c3030302c303030674d657373616765784854686973206973207468652047656e6573697320426c6f636b206f66207468652046696c65636f696e20446563656e7472616c697a65642053746f72616765204e6574776f726b2e"
var cidBuilder = cid.V1Builder{Codec: cid.DagCBOR, MhType: multihash.SHA2_256}
func expectedCid() cid.Cid {
mh, err := multihash.FromHexString(genesisMultihashString)
if err != nil {
panic(err)
}
return cid.NewCidV1(cidBuilder.Codec, mh)
}
func getGenesisBlock() (blocks.Block, error) {
genesisBlockData, err := hex.DecodeString(genesisBlockHex)
if err != nil {
return nil, err
}
genesisCid, err := cidBuilder.Sum(genesisBlockData)
if err != nil {
return nil, err
}
block, err := blocks.NewBlockWithCid(genesisBlockData, genesisCid)
if err != nil {
return nil, err
}
return block, nil
}
+188 -81
View File
@@ -2,7 +2,9 @@ package genesis
import (
"context"
"crypto/rand"
"encoding/json"
"fmt"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
@@ -117,11 +119,6 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
return nil, nil, xerrors.Errorf("making new state tree: %w", err)
}
emptyobject, err := cst.Put(context.TODO(), []struct{}{})
if err != nil {
return nil, nil, xerrors.Errorf("failed putting empty object: %w", err)
}
// Create system actor
sysact, err := SetupSystemActor(bs)
@@ -134,7 +131,7 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
// Create init actor
initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey)
idStart, initact, keyIDs, err := SetupInitActor(bs, template.NetworkName, template.Accounts, template.VerifregRootKey)
if err != nil {
return nil, nil, xerrors.Errorf("setup init actor: %w", err)
}
@@ -190,31 +187,47 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
return nil, nil, xerrors.Errorf("set market actor: %w", err)
}
burntRoot, err := cst.Put(ctx, &account.State{
Address: builtin.BurntFundsActorAddr,
})
if err != nil {
return nil, nil, xerrors.Errorf("failed to setup burnt funds actor state: %w", err)
}
// Setup burnt-funds
err = state.SetActor(builtin.BurntFundsActorAddr, &types.Actor{
Code: builtin.AccountActorCodeID,
Balance: types.NewInt(0),
Head: emptyobject,
Head: burntRoot,
})
if err != nil {
return nil, nil, xerrors.Errorf("set burnt funds account actor: %w", err)
}
// Create accounts
for id, info := range template.Accounts {
if info.Type != genesis.TAccount && info.Type != genesis.TMultisig {
for _, info := range template.Accounts {
switch info.Type {
case genesis.TAccount:
if err := createAccountActor(ctx, cst, state, info, keyIDs); err != nil {
return nil, nil, xerrors.Errorf("failed to create account actor: %w", err)
}
case genesis.TMultisig:
ida, err := address.NewIDAddress(uint64(idStart))
if err != nil {
return nil, nil, err
}
idStart++
if err := createMultisigAccount(ctx, bs, cst, state, ida, info, keyIDs); err != nil {
return nil, nil, err
}
default:
return nil, nil, xerrors.New("unsupported account type")
}
ida, err := address.NewIDAddress(uint64(AccountStart + id))
if err != nil {
return nil, nil, err
}
if err = createAccount(ctx, bs, cst, state, ida, info); err != nil {
return nil, nil, err
}
}
vregroot, err := address.NewIDAddress(80)
@@ -222,8 +235,8 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
return nil, nil, err
}
if err = createAccount(ctx, bs, cst, state, vregroot, template.VerifregRootKey); err != nil {
return nil, nil, err
if err = createMultisigAccount(ctx, bs, cst, state, vregroot, template.VerifregRootKey, keyIDs); err != nil {
return nil, nil, xerrors.Errorf("failed to set up verified registry signer: %w", err)
}
// Setup the first verifier as ID-address 81
@@ -258,63 +271,132 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
Balance: types.NewInt(0),
Head: verifierState,
})
if err != nil {
return nil, nil, xerrors.Errorf("setting account from actmap: %w", err)
}
totalFilAllocated := big.Zero()
// flush as ForEach works on the HAMT
if _, err := state.Flush(ctx); err != nil {
return nil, nil, err
}
err = state.ForEach(func(addr address.Address, act *types.Actor) error {
totalFilAllocated = big.Add(totalFilAllocated, act.Balance)
return nil
})
if err != nil {
return nil, nil, xerrors.Errorf("summing account balances in state tree: %w", err)
}
totalFil := big.Mul(big.NewInt(int64(build.FilBase)), big.NewInt(int64(build.FilecoinPrecision)))
remainingFil := big.Sub(totalFil, totalFilAllocated)
if remainingFil.Sign() < 0 {
return nil, nil, xerrors.Errorf("somehow overallocated filecoin (allocated = %s)", types.FIL(totalFilAllocated))
}
remAccKey, err := address.NewIDAddress(90)
if err != nil {
return nil, nil, err
}
template.RemainderAccount.Balance = remainingFil
if err := createMultisigAccount(ctx, bs, cst, state, remAccKey, template.RemainderAccount, keyIDs); err != nil {
return nil, nil, xerrors.Errorf("failed to set up remainder account: %w", err)
}
return state, keyIDs, nil
}
func createAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor) error {
if info.Type == genesis.TAccount {
var ainfo genesis.AccountMeta
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
return xerrors.Errorf("unmarshaling account meta: %w", err)
}
st, err := cst.Put(ctx, &account.State{Address: ainfo.Owner})
if err != nil {
return err
}
err = state.SetActor(ida, &types.Actor{
Code: builtin.AccountActorCodeID,
Balance: info.Balance,
Head: st,
})
if err != nil {
return xerrors.Errorf("setting account from actmap: %w", err)
}
} else if info.Type == genesis.TMultisig {
var ainfo genesis.MultisigMeta
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
return xerrors.Errorf("unmarshaling account meta: %w", err)
}
pending, err := adt.MakeEmptyMap(adt.WrapStore(ctx, cst)).Root()
if err != nil {
return xerrors.Errorf("failed to create empty map: %v", err)
}
st, err := cst.Put(ctx, &multisig.State{
Signers: ainfo.Signers,
NumApprovalsThreshold: uint64(ainfo.Threshold),
StartEpoch: abi.ChainEpoch(ainfo.VestingStart),
UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration),
PendingTxns: pending,
InitialBalance: info.Balance,
})
if err != nil {
return err
}
err = state.SetActor(ida, &types.Actor{
Code: builtin.MultisigActorCodeID,
Balance: info.Balance,
Head: st,
})
if err != nil {
return xerrors.Errorf("setting account from actmap: %w", err)
}
func createAccountActor(ctx context.Context, cst cbor.IpldStore, state *state.StateTree, info genesis.Actor, keyIDs map[address.Address]address.Address) error {
var ainfo genesis.AccountMeta
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
return xerrors.Errorf("unmarshaling account meta: %w", err)
}
st, err := cst.Put(ctx, &account.State{Address: ainfo.Owner})
if err != nil {
return err
}
ida, ok := keyIDs[ainfo.Owner]
if !ok {
return fmt.Errorf("no registered ID for account actor: %s", ainfo.Owner)
}
err = state.SetActor(ida, &types.Actor{
Code: builtin.AccountActorCodeID,
Balance: info.Balance,
Head: st,
})
if err != nil {
return xerrors.Errorf("setting account from actmap: %w", err)
}
return nil
}
func createMultisigAccount(ctx context.Context, bs bstore.Blockstore, cst cbor.IpldStore, state *state.StateTree, ida address.Address, info genesis.Actor, keyIDs map[address.Address]address.Address) error {
if info.Type != genesis.TMultisig {
return fmt.Errorf("can only call createMultisigAccount with multisig Actor info")
}
var ainfo genesis.MultisigMeta
if err := json.Unmarshal(info.Meta, &ainfo); err != nil {
return xerrors.Errorf("unmarshaling account meta: %w", err)
}
pending, err := adt.MakeEmptyMap(adt.WrapStore(ctx, cst)).Root()
if err != nil {
return xerrors.Errorf("failed to create empty map: %v", err)
}
var signers []address.Address
for _, e := range ainfo.Signers {
idAddress, ok := keyIDs[e]
if !ok {
return fmt.Errorf("no registered key ID for signer: %s", e)
}
// Check if actor already exists
_, err := state.GetActor(e)
if err == nil {
signers = append(signers, idAddress)
continue
}
st, err := cst.Put(ctx, &account.State{Address: e})
if err != nil {
return err
}
err = state.SetActor(idAddress, &types.Actor{
Code: builtin.AccountActorCodeID,
Balance: types.NewInt(0),
Head: st,
})
if err != nil {
return xerrors.Errorf("setting account from actmap: %w", err)
}
signers = append(signers, idAddress)
}
st, err := cst.Put(ctx, &multisig.State{
Signers: signers,
NumApprovalsThreshold: uint64(ainfo.Threshold),
StartEpoch: abi.ChainEpoch(ainfo.VestingStart),
UnlockDuration: abi.ChainEpoch(ainfo.VestingDuration),
PendingTxns: pending,
InitialBalance: info.Balance,
})
if err != nil {
return err
}
err = state.SetActor(ida, &types.Actor{
Code: builtin.MultisigActorCodeID,
Balance: info.Balance,
Head: st,
})
if err != nil {
return xerrors.Errorf("setting account from actmap: %w", err)
}
return nil
}
@@ -323,24 +405,25 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
var sum abi.PaddedPieceSize
vmopt := vm.VMOpts{
StateBase: stateroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
VestedCalc: nil,
BaseFee: types.NewInt(0),
StateBase: stateroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
CircSupplyCalc: nil,
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(&vmopt)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
}
for _, m := range template.Miners {
for mi, m := range template.Miners {
for si, s := range m.Sectors {
if s.Deal.Provider != m.ID {
return cid.Undef, xerrors.Errorf("Sector %d in miner %d in template had mismatch in provider and miner ID: %s != %s", si, mi, s.Deal.Provider, m.ID)
}
// Add the miner to the market actor's balance table
_, err = doExec(ctx, vm, builtin.StorageMarketActorAddr, m.Owner, builtin.MethodsMarket.AddBalance, mustEnc(adt.Empty))
for _, s := range m.Sectors {
amt := s.Deal.PieceSize
verifNeeds[keyIDs[s.Deal.Client]] += amt
sum += amt
@@ -430,14 +513,38 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
log.Infof("Empty Genesis root: %s", emptyroot)
tickBuf := make([]byte, 32)
_, _ = rand.Read(tickBuf)
genesisticket := &types.Ticket{
VRFProof: []byte("vrf proof0000000vrf proof0000000"),
VRFProof: tickBuf,
}
filecoinGenesisCid, err := cid.Decode("bafyreiaqpwbbyjo4a42saasj36kkrpv4tsherf2e7bvezkert2a7dhonoi")
if err != nil {
return nil, xerrors.Errorf("failed to decode filecoin genesis block CID: %w", err)
}
if !expectedCid().Equals(filecoinGenesisCid) {
return nil, xerrors.Errorf("expectedCid != filecoinGenesisCid")
}
gblk, err := getGenesisBlock()
if err != nil {
return nil, xerrors.Errorf("failed to construct filecoin genesis block: %w", err)
}
if !filecoinGenesisCid.Equals(gblk.Cid()) {
return nil, xerrors.Errorf("filecoinGenesisCid != gblk.Cid")
}
if err := bs.Put(gblk); err != nil {
return nil, xerrors.Errorf("failed writing filecoin genesis block to blockstore: %w", err)
}
b := &types.BlockHeader{
Miner: builtin.SystemActorAddr,
Ticket: genesisticket,
Parents: []cid.Cid{},
Parents: []cid.Cid{filecoinGenesisCid},
Height: 0,
ParentWeight: types.NewInt(0),
ParentStateRoot: stateroot,
+22 -12
View File
@@ -14,7 +14,7 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
@@ -57,18 +57,18 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
}
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner) (cid.Cid, error) {
vc := func(context.Context, abi.ChainEpoch) (abi.TokenAmount, error) {
csc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) {
return big.Zero(), nil
}
vmopt := &vm.VMOpts{
StateBase: sroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
VestedCalc: vc,
BaseFee: types.NewInt(0),
StateBase: sroot,
Epoch: 0,
Rand: &fakeRand{},
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
CircSupplyCalc: csc,
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(vmopt)
@@ -137,7 +137,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
params := mustEnc(&minerInfos[i].maddr)
_, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err)
}
}
@@ -149,7 +149,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
ret, err := doExecValue(ctx, vm, builtin.StorageMarketActorAddr, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
if err != nil {
return xerrors.Errorf("failed to create genesis miner: %w", err)
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
}
var ids market.PublishStorageDealsReturn
if err := ids.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
@@ -262,6 +262,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
return cid.Undef, xerrors.Errorf("getting current total power: %w", err)
}
pcd := miner.PreCommitDepositForPower(epochReward.ThisEpochRewardSmoothed, tpow.QualityAdjPowerSmoothed, sectorWeight)
pledge := miner.InitialPledgeForPower(
sectorWeight,
epochReward.ThisEpochBaselinePower,
@@ -271,6 +273,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
circSupply(ctx, vm, minerInfos[i].maddr),
)
pledge = big.Add(pcd, pledge)
fmt.Println(types.FIL(pledge))
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin.MethodsMiner.PreCommitSector, mustEnc(params))
if err != nil {
@@ -318,7 +322,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
// TODO: copied from actors test harness, deduplicate or remove from here
type fakeRand struct{}
func (fr *fakeRand) GetRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (fr *fakeRand) GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out)
return out, nil
}
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out)
return out, nil
+65 -14
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/builtin"
@@ -19,9 +20,9 @@ import (
bstore "github.com/filecoin-project/lotus/lib/blockstore"
)
func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor) (*types.Actor, map[address.Address]address.Address, error) {
func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesis.Actor, rootVerifier genesis.Actor) (int64, *types.Actor, map[address.Address]address.Address, error) {
if len(initialActors) > MaxAccounts {
return nil, nil, xerrors.New("too many initial actors")
return 0, nil, nil, xerrors.New("too many initial actors")
}
var ias init_.State
@@ -32,55 +33,105 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
amap := adt.MakeEmptyMap(store)
keyToId := map[address.Address]address.Address{}
counter := int64(AccountStart)
for i, a := range initialActors {
for _, a := range initialActors {
if a.Type == genesis.TMultisig {
var ainfo genesis.MultisigMeta
if err := json.Unmarshal(a.Meta, &ainfo); err != nil {
return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
}
for _, e := range ainfo.Signers {
if _, ok := keyToId[e]; ok {
continue
}
fmt.Printf("init set %s t0%d\n", e, counter)
value := cbg.CborInt(counter)
if err := amap.Put(adt.AddrKey(e), &value); err != nil {
return 0, nil, nil, err
}
counter = counter + 1
var err error
keyToId[e], err = address.NewIDAddress(uint64(value))
if err != nil {
return 0, nil, nil, err
}
}
// Need to add actors for all multisigs too
continue
}
if a.Type != genesis.TAccount {
return nil, nil, xerrors.Errorf("unsupported account type: %s", a.Type) // TODO: Support msig (skip here)
return 0, nil, nil, xerrors.Errorf("unsupported account type: %s", a.Type)
}
var ainfo genesis.AccountMeta
if err := json.Unmarshal(a.Meta, &ainfo); err != nil {
return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
}
fmt.Printf("init set %s t0%d\n", ainfo.Owner, AccountStart+int64(i))
fmt.Printf("init set %s t0%d\n", ainfo.Owner, counter)
value := cbg.CborInt(AccountStart + int64(i))
value := cbg.CborInt(counter)
if err := amap.Put(adt.AddrKey(ainfo.Owner), &value); err != nil {
return nil, nil, err
return 0, nil, nil, err
}
counter = counter + 1
var err error
keyToId[ainfo.Owner], err = address.NewIDAddress(uint64(value))
if err != nil {
return nil, nil, err
return 0, nil, nil, err
}
}
if rootVerifier.Type == genesis.TAccount {
var ainfo genesis.AccountMeta
if err := json.Unmarshal(rootVerifier.Meta, &ainfo); err != nil {
return nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
}
value := cbg.CborInt(80)
if err := amap.Put(adt.AddrKey(ainfo.Owner), &value); err != nil {
return nil, nil, err
return 0, nil, nil, err
}
} else if rootVerifier.Type == genesis.TMultisig {
var ainfo genesis.MultisigMeta
if err := json.Unmarshal(rootVerifier.Meta, &ainfo); err != nil {
return 0, nil, nil, xerrors.Errorf("unmarshaling account meta: %w", err)
}
for _, e := range ainfo.Signers {
if _, ok := keyToId[e]; ok {
continue
}
fmt.Printf("init set %s t0%d\n", e, counter)
value := cbg.CborInt(counter)
if err := amap.Put(adt.AddrKey(e), &value); err != nil {
return 0, nil, nil, err
}
counter = counter + 1
var err error
keyToId[e], err = address.NewIDAddress(uint64(value))
if err != nil {
return 0, nil, nil, err
}
}
}
amapaddr, err := amap.Root()
if err != nil {
return nil, nil, err
return 0, nil, nil, err
}
ias.AddressMap = amapaddr
statecid, err := store.Put(store.Context(), &ias)
if err != nil {
return nil, nil, err
return 0, nil, nil, err
}
act := &types.Actor{
@@ -88,5 +139,5 @@ func SetupInitActor(bs bstore.Blockstore, netname string, initialActors []genesi
Head: statecid,
}
return act, keyToId, nil
return counter, act, keyToId, nil
}
+1 -1
View File
@@ -28,7 +28,7 @@ func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method abi
func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value types.BigInt, method abi.MethodNum, params []byte) ([]byte, error) {
act, err := vm.StateTree().GetActor(from)
if err != nil {
return nil, xerrors.Errorf("doExec failed to get from actor: %w", err)
return nil, xerrors.Errorf("doExec failed to get from actor (%s): %w", from, err)
}
ret, err := vm.ApplyImplicitMessage(ctx, &types.Message{
+18 -11
View File
@@ -14,7 +14,6 @@ import (
"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"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/events/state"
@@ -52,7 +51,7 @@ func StartFundManager(lc fx.Lifecycle, api API) *FundMgr {
match := func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) {
return dealDiffFn(ctx, oldTs.Key(), newTs.Key())
}
return ev.StateChanged(fm.checkFunc, fm.stateChanged, fm.revert, int(build.MessageConfidence), events.NoTimeout, match)
return ev.StateChanged(fm.checkFunc, fm.stateChanged, fm.revert, 0, events.NoTimeout, match)
},
})
return fm
@@ -60,7 +59,7 @@ func StartFundManager(lc fx.Lifecycle, api API) *FundMgr {
type fundMgrAPI interface {
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error)
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
}
@@ -92,6 +91,10 @@ func (fm *FundMgr) stateChanged(ts *types.TipSet, ts2 *types.TipSet, states even
// overwrite our in memory cache with new values from chain (chain is canonical)
fm.lk.Lock()
for addr, balanceChange := range changedBalances {
if fm.available[addr].Int != nil {
log.Infof("State balance change recorded, prev: %s, new: %s", fm.available[addr].String(), balanceChange.To.String())
}
fm.available[addr] = balanceChange.To
}
fm.lk.Unlock()
@@ -116,15 +119,17 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
return cid.Undef, err
}
fm.lk.Lock()
bal, err := fm.api.StateMarketBalance(ctx, addr, types.EmptyTSK)
if err != nil {
fm.lk.Unlock()
return cid.Undef, err
}
stateAvail := types.BigSub(bal.Escrow, bal.Locked)
avail, ok := fm.available[idAddr]
if !ok {
bal, err := fm.api.StateMarketBalance(ctx, addr, types.EmptyTSK)
if err != nil {
fm.lk.Unlock()
return cid.Undef, err
}
avail = types.BigSub(bal.Escrow, bal.Locked)
avail = stateAvail
}
toAdd := types.BigSub(amt, avail)
@@ -134,6 +139,8 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
fm.available[idAddr] = big.Add(avail, toAdd)
fm.lk.Unlock()
log.Infof("Funds operation w/ Expected Balance: %s, In State: %s, Requested: %s, Adding: %s", avail.String(), stateAvail.String(), amt.String(), toAdd.String())
if toAdd.LessThanEqual(big.Zero()) {
return cid.Undef, nil
}
@@ -149,7 +156,7 @@ func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Add
Value: toAdd,
Method: builtin.MethodsMarket.AddBalance,
Params: params,
})
}, nil)
if err != nil {
return cid.Undef, err
}
+1 -1
View File
@@ -36,7 +36,7 @@ func (fapi *fakeAPI) StateMarketBalance(context.Context, address.Address, types.
return fapi.returnedBalance, fapi.returnedBalanceErr
}
func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*types.SignedMessage, error) {
func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
fapi.receivedMessage = msg
return &types.SignedMessage{
Message: *msg,
+102
View File
@@ -0,0 +1,102 @@
package messagepool
import (
"math"
"sync"
)
var noWinnersProbCache []float64
var noWinnersProbOnce sync.Once
func noWinnersProb() []float64 {
noWinnersProbOnce.Do(func() {
poissPdf := func(x float64) float64 {
const Mu = 5
lg, _ := math.Lgamma(x + 1)
result := math.Exp((math.Log(Mu) * x) - lg - Mu)
return result
}
out := make([]float64, 0, MaxBlocks)
for i := 0; i < MaxBlocks; i++ {
out = append(out, poissPdf(float64(i)))
}
noWinnersProbCache = out
})
return noWinnersProbCache
}
var noWinnersProbAssumingCache []float64
var noWinnersProbAssumingOnce sync.Once
func noWinnersProbAssumingMoreThanOne() []float64 {
noWinnersProbAssumingOnce.Do(func() {
cond := math.Log(-1 + math.Exp(5))
poissPdf := func(x float64) float64 {
const Mu = 5
lg, _ := math.Lgamma(x + 1)
result := math.Exp((math.Log(Mu) * x) - lg - cond)
return result
}
out := make([]float64, 0, MaxBlocks)
for i := 0; i < MaxBlocks; i++ {
out = append(out, poissPdf(float64(i+1)))
}
noWinnersProbAssumingCache = out
})
return noWinnersProbAssumingCache
}
func binomialCoefficient(n, k float64) float64 {
if k > n {
return math.NaN()
}
r := 1.0
for d := 1.0; d <= k; d++ {
r *= n
r /= d
n -= 1
}
return r
}
func (mp *MessagePool) blockProbabilities(tq float64) []float64 {
noWinners := noWinnersProbAssumingMoreThanOne()
p := 1 - tq
binoPdf := func(x, trials float64) float64 {
// based on https://github.com/atgjack/prob
if x > trials {
return 0
}
if p == 0 {
if x == 0 {
return 1.0
}
return 0.0
}
if p == 1 {
if x == trials {
return 1.0
}
return 0.0
}
coef := binomialCoefficient(trials, x)
pow := math.Pow(p, x) * math.Pow(1-p, trials-x)
if math.IsInf(coef, 0) {
return 0
}
return coef * pow
}
out := make([]float64, 0, MaxBlocks)
for place := 0; place < MaxBlocks; place++ {
var pPlace float64
for otherWinners, pCase := range noWinners {
pPlace += pCase * binoPdf(float64(place), float64(otherWinners))
}
out = append(out, pPlace)
}
return out
}
+43
View File
@@ -0,0 +1,43 @@
package messagepool
import (
"math"
"math/rand"
"testing"
"time"
)
func TestBlockProbability(t *testing.T) {
mp := &MessagePool{}
bp := mp.blockProbabilities(1 - 0.15)
t.Logf("%+v\n", bp)
for i := 0; i < len(bp)-1; i++ {
if bp[i] < bp[i+1] {
t.Fatalf("expected decreasing block probabilities for this quality: %d %f %f",
i, bp[i], bp[i+1])
}
}
}
func TestWinnerProba(t *testing.T) {
rand.Seed(time.Now().UnixNano())
const N = 1000000
winnerProba := noWinnersProb()
sum := 0
for i := 0; i < N; i++ {
minersRand := rand.Float64()
j := 0
for ; j < MaxBlocks; j++ {
minersRand -= winnerProba[j]
if minersRand < 0 {
break
}
}
sum += j
}
if avg := float64(sum) / N; math.Abs(avg-5) > 0.01 {
t.Fatalf("avg too far off: %f", avg)
}
}
+25 -6
View File
@@ -2,6 +2,7 @@ package messagepool
import (
"encoding/json"
"fmt"
"time"
"github.com/filecoin-project/lotus/chain/types"
@@ -14,6 +15,7 @@ var (
MemPoolSizeLimitHiDefault = 30000
MemPoolSizeLimitLoDefault = 20000
PruneCooldownDefault = time.Minute
GasLimitOverestimation = 1.25
ConfigKey = datastore.NewKey("/mpool/config")
)
@@ -51,23 +53,40 @@ func (mp *MessagePool) GetConfig() *types.MpoolConfig {
return mp.cfg.Clone()
}
func (mp *MessagePool) SetConfig(cfg *types.MpoolConfig) {
func validateConfg(cfg *types.MpoolConfig) error {
if cfg.ReplaceByFeeRatio < ReplaceByFeeRatioDefault {
return fmt.Errorf("'ReplaceByFeeRatio' is less than required %f < %f",
cfg.ReplaceByFeeRatio, ReplaceByFeeRatioDefault)
}
if cfg.GasLimitOverestimation < 1 {
return fmt.Errorf("'GasLimitOverestimation' cannot be less than 1")
}
return nil
}
func (mp *MessagePool) SetConfig(cfg *types.MpoolConfig) error {
if err := validateConfg(cfg); err != nil {
return err
}
cfg = cfg.Clone()
mp.cfgLk.Lock()
mp.cfg = cfg
mp.rbfNum = types.NewInt(uint64((cfg.ReplaceByFeeRatio - 1) * RbfDenom))
err := saveConfig(cfg, mp.ds)
if err != nil {
log.Warnf("error persisting mpool config: %s", err)
}
mp.cfgLk.Unlock()
return nil
}
func DefaultConfig() *types.MpoolConfig {
return &types.MpoolConfig{
SizeLimitHigh: MemPoolSizeLimitHiDefault,
SizeLimitLow: MemPoolSizeLimitLoDefault,
ReplaceByFeeRatio: ReplaceByFeeRatioDefault,
PruneCooldown: PruneCooldownDefault,
SizeLimitHigh: MemPoolSizeLimitHiDefault,
SizeLimitLow: MemPoolSizeLimitLoDefault,
ReplaceByFeeRatio: ReplaceByFeeRatioDefault,
PruneCooldown: PruneCooldownDefault,
GasLimitOverestimation: GasLimitOverestimation,
}
}
+181 -150
View File
@@ -12,6 +12,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/hashicorp/go-multierror"
lru "github.com/hashicorp/golang-lru"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
@@ -20,14 +21,12 @@ import (
logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
lps "github.com/whyrusleeping/pubsub"
"go.uber.org/multierr"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/lib/sigs"
@@ -40,10 +39,13 @@ var log = logging.Logger("messagepool")
const futureDebug = false
const repubMsgLimit = 5
var rbfNumBig = types.NewInt(uint64((ReplaceByFeeRatioDefault - 1) * RbfDenom))
var rbfDenomBig = types.NewInt(RbfDenom)
const RbfDenom = 256
var RepublishInterval = pubsub.TimeCacheDuration + time.Duration(5*build.BlockDelaySecs+build.PropagationDelaySecs)*time.Second
var (
ErrMessageTooBig = errors.New("message too big")
@@ -55,7 +57,10 @@ var (
ErrInvalidToAddr = errors.New("message had invalid to address")
ErrBroadcastAnyway = errors.New("broadcasting message despite validation fail")
ErrBroadcastAnyway = errors.New("broadcasting message despite validation fail")
ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium")
ErrTryAgain = errors.New("state inconsistency while pushing message; please try again")
)
const (
@@ -69,8 +74,14 @@ type MessagePool struct {
ds dtypes.MetadataDS
closer chan struct{}
repubTk *clock.Ticker
addSema chan struct{}
closer chan struct{}
repubTk *clock.Ticker
repubTrigger chan struct{}
republished map[cid.Cid]struct{}
localAddrs map[address.Address]struct{}
@@ -82,8 +93,6 @@ type MessagePool struct {
cfgLk sync.Mutex
cfg *types.MpoolConfig
rbfNum, rbfDenom types.BigInt
api Provider
minGasPrice types.BigInt
@@ -127,7 +136,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool) (bool, error) {
if m.Cid() != exms.Cid() {
// check if RBF passes
minPrice := exms.Message.GasPremium
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, mp.rbfNum), mp.rbfDenom))
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNumBig), rbfDenomBig))
minPrice = types.BigAdd(minPrice, types.NewInt(1))
if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 {
log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium,
@@ -135,8 +144,9 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool) (bool, error) {
} else {
log.Info("add with duplicate nonce")
return false, xerrors.Errorf("message from %s with nonce %d already in mpool,"+
" increase GasPremium to %s from %s to trigger replace by fee",
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPremium)
" increase GasPremium to %s from %s to trigger replace by fee: %w",
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPremium,
ErrRBFTooLowPremium)
}
}
}
@@ -145,69 +155,6 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool) (bool, error) {
return !has, nil
}
type Provider interface {
SubscribeHeadChanges(func(rev, app []*types.TipSet) error) *types.TipSet
PutMessage(m types.ChainMsg) (cid.Cid, error)
PubSubPublish(string, []byte) error
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
StateAccountKey(context.Context, address.Address, *types.TipSet) (address.Address, error)
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error)
}
type mpoolProvider struct {
sm *stmgr.StateManager
ps *pubsub.PubSub
}
func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
return &mpoolProvider{sm: sm, ps: ps}
}
func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
mpp.sm.ChainStore().SubscribeHeadChanges(cb)
return mpp.sm.ChainStore().GetHeaviestTipSet()
}
func (mpp *mpoolProvider) PutMessage(m types.ChainMsg) (cid.Cid, error) {
return mpp.sm.ChainStore().PutMessage(m)
}
func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
return mpp.ps.Publish(k, v)
}
func (mpp *mpoolProvider) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
var act types.Actor
return &act, mpp.sm.WithParentState(ts, mpp.sm.WithActor(addr, stmgr.GetActor(&act)))
}
func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
return mpp.sm.ResolveToKeyAddress(ctx, addr, ts)
}
func (mpp *mpoolProvider) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return mpp.sm.ChainStore().MessagesForBlock(h)
}
func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
return mpp.sm.ChainStore().MessagesForTipset(ts)
}
func (mpp *mpoolProvider) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
return mpp.sm.ChainStore().LoadTipSet(tsk)
}
func (mpp *mpoolProvider) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
baseFee, err := mpp.sm.ChainStore().ComputeBaseFee(ctx, ts)
if err != nil {
return types.NewInt(0), xerrors.Errorf("computing base fee at %s: %w", ts, err)
}
return baseFee, nil
}
func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*MessagePool, error) {
cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
verifcache, _ := lru.New2Q(build.VerifSigCacheSize)
@@ -221,8 +168,10 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
mp := &MessagePool{
ds: ds,
addSema: make(chan struct{}, 1),
closer: make(chan struct{}),
repubTk: build.Clock.Ticker(time.Duration(build.BlockDelaySecs) * time.Second),
repubTk: build.Clock.Ticker(RepublishInterval),
repubTrigger: make(chan struct{}, 1),
localAddrs: make(map[address.Address]struct{}),
pending: make(map[address.Address]*msgSet),
minGasPrice: types.NewInt(0),
@@ -235,8 +184,6 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
api: api,
netName: netName,
cfg: cfg,
rbfNum: types.NewInt(uint64((cfg.ReplaceByFeeRatio - 1) * RbfDenom)),
rbfDenom: types.NewInt(RbfDenom),
}
// enable initial prunes
@@ -280,63 +227,12 @@ func (mp *MessagePool) runLoop() {
for {
select {
case <-mp.repubTk.C:
mp.lk.Lock()
msgsForAddr := make(map[address.Address][]*types.SignedMessage)
for a := range mp.localAddrs {
msgsForAddr[a] = mp.pendingFor(a)
if err := mp.republishPendingMessages(); err != nil {
log.Errorf("error while republishing messages: %s", err)
}
mp.lk.Unlock()
var errout error
outputMsgs := []*types.SignedMessage{}
for a, msgs := range msgsForAddr {
a, err := mp.api.StateGetActor(a, nil)
if err != nil {
errout = multierr.Append(errout, xerrors.Errorf("could not get actor state: %w", err))
continue
}
curNonce := a.Nonce
for _, m := range msgs {
if m.Message.Nonce < curNonce {
continue
}
if m.Message.Nonce != curNonce {
break
}
outputMsgs = append(outputMsgs, m)
curNonce++
}
}
if len(outputMsgs) != 0 {
log.Infow("republishing local messages", "n", len(outputMsgs))
}
if len(outputMsgs) > repubMsgLimit {
outputMsgs = outputMsgs[:repubMsgLimit]
}
for _, msg := range outputMsgs {
msgb, err := msg.Serialize()
if err != nil {
errout = multierr.Append(errout, xerrors.Errorf("could not serialize: %w", err))
continue
}
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
if err != nil {
errout = multierr.Append(errout, xerrors.Errorf("could not publish: %w", err))
continue
}
}
if errout != nil {
log.Errorf("errors while republishing: %+v", errout)
case <-mp.repubTrigger:
if err := mp.republishPendingMessages(); err != nil {
log.Errorf("error while republishing messages: %s", err)
}
case <-mp.pruneTrigger:
if err := mp.pruneExcessMessages(); err != nil {
@@ -347,7 +243,6 @@ func (mp *MessagePool) runLoop() {
return
}
}
}
func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error {
@@ -370,8 +265,20 @@ func (mp *MessagePool) verifyMsgBeforePush(m *types.SignedMessage, epoch abi.Cha
}
func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
err := mp.checkMessage(m)
if err != nil {
return cid.Undef, err
}
// serialize push access to reduce lock contention
mp.addSema <- struct{}{}
defer func() {
<-mp.addSema
}()
mp.curTsLk.Lock()
epoch := mp.curTs.Height()
curTs := mp.curTs
epoch := curTs.Height()
mp.curTsLk.Unlock()
if err := mp.verifyMsgBeforePush(m, epoch); err != nil {
return cid.Undef, err
@@ -382,9 +289,17 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
return cid.Undef, err
}
if err := mp.Add(m); err != nil {
mp.curTsLk.Lock()
if mp.curTs != curTs {
mp.curTsLk.Unlock()
return cid.Undef, ErrTryAgain
}
if err := mp.addTs(m, mp.curTs); err != nil {
mp.curTsLk.Unlock()
return cid.Undef, err
}
mp.curTsLk.Unlock()
mp.lk.Lock()
if err := mp.addLocal(m, msgb); err != nil {
@@ -396,7 +311,7 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
return m.Cid(), mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
}
func (mp *MessagePool) Add(m *types.SignedMessage) error {
func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
// big messages are bad, anti DOS
if m.Size() > 32*1024 {
return xerrors.Errorf("mpool message too large (%dB): %w", m.Size(), ErrMessageTooBig)
@@ -415,6 +330,21 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
return err
}
return nil
}
func (mp *MessagePool) Add(m *types.SignedMessage) error {
err := mp.checkMessage(m)
if err != nil {
return err
}
// serialize push access to reduce lock contention
mp.addSema <- struct{}{}
defer func() {
<-mp.addSema
}()
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
return mp.addTs(m, mp.curTs)
@@ -517,7 +447,7 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage) error {
incr, err := mset.add(m, mp)
if err != nil {
log.Info(err)
return err // TODO(review): this error return was dropped at some point, was it on purpose?
return err
}
if incr {
@@ -613,31 +543,64 @@ func (mp *MessagePool) getStateBalance(addr address.Address, ts *types.TipSet) (
}
func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address, cb func(address.Address, uint64) (*types.SignedMessage, error)) (*types.SignedMessage, error) {
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
// serialize push access to reduce lock contention
mp.addSema <- struct{}{}
defer func() {
<-mp.addSema
}()
mp.curTsLk.Lock()
mp.lk.Lock()
defer mp.lk.Unlock()
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
}
// 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
}
if err := mp.verifyMsgBeforePush(msg, mp.curTs.Height()); err != nil {
return nil, err
}
@@ -746,6 +709,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
repubTrigger := false
rmsgs := make(map[address.Address]map[uint64]*types.SignedMessage)
add := func(m *types.SignedMessage) {
s, ok := rmsgs[m.Message.From]
@@ -770,40 +734,70 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
mp.Remove(from, nonce)
}
maybeRepub := func(cid cid.Cid) {
if !repubTrigger {
mp.lk.Lock()
_, republished := mp.republished[cid]
mp.lk.Unlock()
if republished {
repubTrigger = true
}
}
}
var merr error
for _, ts := range revert {
pts, err := mp.api.LoadTipSet(ts.Parents())
if err != nil {
return err
}
msgs, err := mp.MessagesForBlocks(ts.Blocks())
if err != nil {
return err
log.Errorf("error loading reverted tipset parent: %s", err)
merr = multierror.Append(merr, err)
continue
}
mp.curTs = pts
msgs, err := mp.MessagesForBlocks(ts.Blocks())
if err != nil {
log.Errorf("error retrieving messages for reverted block: %s", err)
merr = multierror.Append(merr, err)
continue
}
for _, msg := range msgs {
add(msg)
}
}
for _, ts := range apply {
mp.curTs = ts
for _, b := range ts.Blocks() {
bmsgs, smsgs, err := mp.api.MessagesForBlock(b)
if err != nil {
return xerrors.Errorf("failed to get messages for apply block %s(height %d) (msgroot = %s): %w", b.Cid(), b.Height, b.Messages, err)
xerr := xerrors.Errorf("failed to get messages for apply block %s(height %d) (msgroot = %s): %w", b.Cid(), b.Height, b.Messages, err)
log.Errorf("error retrieving messages for block: %s", xerr)
merr = multierror.Append(merr, xerr)
continue
}
for _, msg := range smsgs {
rm(msg.Message.From, msg.Message.Nonce)
maybeRepub(msg.Cid())
}
for _, msg := range bmsgs {
rm(msg.From, msg.Nonce)
maybeRepub(msg.Cid())
}
}
}
mp.curTs = ts
if repubTrigger {
select {
case mp.repubTrigger <- struct{}{}:
default:
}
}
for _, s := range rmsgs {
@@ -879,7 +873,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
}
}
return nil
return merr
}
type statBucket struct {
@@ -979,3 +973,40 @@ func (mp *MessagePool) loadLocal() error {
return nil
}
func (mp *MessagePool) Clear(local bool) {
mp.lk.Lock()
defer mp.lk.Unlock()
// remove everything if local is true, including removing local messages from
// the datastore
if local {
for a := range mp.localAddrs {
mset, ok := mp.pending[a]
if !ok {
continue
}
for _, m := range mset.msgs {
err := mp.localMsgs.Delete(datastore.NewKey(string(m.Cid().Bytes())))
if err != nil {
log.Warnf("error deleting local message: %s", err)
}
}
}
mp.pending = make(map[address.Address]*msgSet)
mp.republished = nil
return
}
// remove everything except the local messages
for a := range mp.pending {
_, isLocal := mp.localAddrs[a]
if isLocal {
continue
}
delete(mp.pending, a)
}
}
+76
View File
@@ -0,0 +1,76 @@
package messagepool
import (
"context"
"github.com/ipfs/go-cid"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
)
type Provider interface {
SubscribeHeadChanges(func(rev, app []*types.TipSet) error) *types.TipSet
PutMessage(m types.ChainMsg) (cid.Cid, error)
PubSubPublish(string, []byte) error
StateGetActor(address.Address, *types.TipSet) (*types.Actor, error)
StateAccountKey(context.Context, address.Address, *types.TipSet) (address.Address, error)
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error)
}
type mpoolProvider struct {
sm *stmgr.StateManager
ps *pubsub.PubSub
}
func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
return &mpoolProvider{sm: sm, ps: ps}
}
func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
mpp.sm.ChainStore().SubscribeHeadChanges(cb)
return mpp.sm.ChainStore().GetHeaviestTipSet()
}
func (mpp *mpoolProvider) PutMessage(m types.ChainMsg) (cid.Cid, error) {
return mpp.sm.ChainStore().PutMessage(m)
}
func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
return mpp.ps.Publish(k, v)
}
func (mpp *mpoolProvider) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
var act types.Actor
return &act, mpp.sm.WithParentState(ts, mpp.sm.WithActor(addr, stmgr.GetActor(&act)))
}
func (mpp *mpoolProvider) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
return mpp.sm.ResolveToKeyAddress(ctx, addr, ts)
}
func (mpp *mpoolProvider) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return mpp.sm.ChainStore().MessagesForBlock(h)
}
func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
return mpp.sm.ChainStore().MessagesForTipset(ts)
}
func (mpp *mpoolProvider) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
return mpp.sm.ChainStore().LoadTipSet(tsk)
}
func (mpp *mpoolProvider) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
baseFee, err := mpp.sm.ChainStore().ComputeBaseFee(ctx, ts)
if err != nil {
return types.NewInt(0), xerrors.Errorf("computing base fee at %s: %w", ts, err)
}
return baseFee, nil
}
+148
View File
@@ -0,0 +1,148 @@
package messagepool
import (
"context"
"sort"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
)
const repubMsgLimit = 30
func (mp *MessagePool) republishPendingMessages() error {
mp.curTsLk.Lock()
ts := mp.curTs
baseFee, err := mp.api.ChainComputeBaseFee(context.TODO(), ts)
if err != nil {
mp.curTsLk.Unlock()
return xerrors.Errorf("computing basefee: %w", err)
}
pending := make(map[address.Address]map[uint64]*types.SignedMessage)
mp.lk.Lock()
mp.republished = nil // clear this to avoid races triggering an early republish
for actor := range mp.localAddrs {
mset, ok := mp.pending[actor]
if !ok {
continue
}
if len(mset.msgs) == 0 {
continue
}
// we need to copy this while holding the lock to avoid races with concurrent modification
pend := make(map[uint64]*types.SignedMessage, len(mset.msgs))
for nonce, m := range mset.msgs {
pend[nonce] = m
}
pending[actor] = pend
}
mp.lk.Unlock()
mp.curTsLk.Unlock()
if len(pending) == 0 {
return nil
}
var chains []*msgChain
for actor, mset := range pending {
next := mp.createMessageChains(actor, mset, baseFee, ts)
chains = append(chains, next...)
}
if len(chains) == 0 {
return nil
}
sort.Slice(chains, func(i, j int) bool {
return chains[i].Before(chains[j])
})
// we don't republish negative performing chains; this is an error that will be screamed
// at the user
if chains[0].gasPerf < 0 {
return xerrors.Errorf("skipping republish: all message chains have negative gas performance; best gas performance: %f", chains[0].gasPerf)
}
gasLimit := int64(build.BlockGasLimit)
minGas := int64(gasguess.MinGas)
var msgs []*types.SignedMessage
for i := 0; i < len(chains); {
chain := chains[i]
// we can exceed this if we have picked (some) longer chain already
if len(msgs) > repubMsgLimit {
break
}
// there is not enough gas for any message
if gasLimit <= minGas {
break
}
// we don't republish negative performing chains, as they won't be included in
// a block anyway
if chain.gasPerf < 0 {
break
}
// has the chain been invalidated?
if !chain.valid {
i++
continue
}
// does it fit in a block?
if chain.gasLimit <= gasLimit {
gasLimit -= chain.gasLimit
msgs = append(msgs, chain.msgs...)
i++
continue
}
// we can't fit the current chain but there is gas to spare
// trim it and push it down
chain.Trim(gasLimit, mp, baseFee, ts, false)
for j := i; j < len(chains)-1; j++ {
if chains[j].Before(chains[j+1]) {
break
}
chains[j], chains[j+1] = chains[j+1], chains[j]
}
}
count := 0
log.Infof("republishing %d messages", len(msgs))
for _, m := range msgs {
mb, err := m.Serialize()
if err != nil {
return xerrors.Errorf("cannot serialize message: %w", err)
}
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), mb)
if err != nil {
return xerrors.Errorf("cannot publish: %w", err)
}
count++
}
// track most recently republished messages
republished := make(map[cid.Cid]struct{})
for _, m := range msgs[:count] {
republished[m.Cid()] = struct{}{}
}
mp.lk.Lock()
// update the republished set so that we can trigger early republish from head changes
mp.republished = republished
mp.lk.Unlock()
return nil
}
+364 -35
View File
@@ -19,26 +19,289 @@ import (
var bigBlockGasLimit = big.NewInt(build.BlockGasLimit)
const MaxBlocks = 15
type msgChain struct {
msgs []*types.SignedMessage
gasReward *big.Int
gasLimit int64
gasPerf float64
valid bool
next *msgChain
msgs []*types.SignedMessage
gasReward *big.Int
gasLimit int64
gasPerf float64
effPerf float64
bp float64
parentOffset float64
valid bool
merged bool
next *msgChain
prev *msgChain
}
func (mp *MessagePool) SelectMessages(ts *types.TipSet) ([]*types.SignedMessage, error) {
func (mp *MessagePool) SelectMessages(ts *types.TipSet, tq float64) ([]*types.SignedMessage, error) {
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
mp.lk.Lock()
defer mp.lk.Unlock()
return mp.selectMessages(mp.curTs, ts)
// if the ticket quality is high enough that the first block has higher probability
// than any other block, then we don't bother with optimal selection because the
// first block will always have higher effective performance
if tq > 0.84 {
return mp.selectMessagesGreedy(mp.curTs, ts)
}
return mp.selectMessagesOptimal(mp.curTs, ts, tq)
}
func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedMessage, error) {
func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64) ([]*types.SignedMessage, error) {
start := time.Now()
baseFee, err := mp.api.ChainComputeBaseFee(context.TODO(), ts)
if err != nil {
return nil, xerrors.Errorf("computing basefee: %w", err)
}
// 0. Load messages from the target tipset; if it is the same as the current tipset in
// the mpool, then this is just the pending messages
pending, err := mp.getPendingMessages(curTs, ts)
if err != nil {
return nil, err
}
if len(pending) == 0 {
return nil, nil
}
// defer only here so if we have no pending messages we don't spam
defer func() {
log.Infow("message selection done", "took", time.Since(start))
}()
// 0b. Select all priority messages that fit in the block
minGas := int64(gasguess.MinGas)
result, gasLimit := mp.selectPriorityMessages(pending, baseFee, ts)
// have we filled the block?
if gasLimit < minGas {
return result, nil
}
// 1. Create a list of dependent message chains with maximal gas reward per limit consumed
startChains := time.Now()
var chains []*msgChain
for actor, mset := range pending {
next := mp.createMessageChains(actor, mset, baseFee, ts)
chains = append(chains, next...)
}
if dt := time.Since(startChains); dt > time.Millisecond {
log.Infow("create message chains done", "took", dt)
}
// 2. Sort the chains
sort.Slice(chains, func(i, j int) bool {
return chains[i].Before(chains[j])
})
if len(chains) != 0 && chains[0].gasPerf < 0 {
log.Warnw("all messages in mpool have non-positive gas performance", "bestGasPerf", chains[0].gasPerf)
return nil, nil
}
// 3. Parition chains into blocks (without trimming)
// we use the full blockGasLimit (as opposed to the residual gas limit from the
// priority message selection) as we have to account for what other miners are doing
nextChain := 0
partitions := make([][]*msgChain, MaxBlocks)
for i := 0; i < MaxBlocks && nextChain < len(chains); i++ {
gasLimit := int64(build.BlockGasLimit)
for nextChain < len(chains) {
chain := chains[nextChain]
nextChain++
partitions[i] = append(partitions[i], chain)
gasLimit -= chain.gasLimit
if gasLimit < minGas {
break
}
}
}
// 4. Compute effective performance for each chain, based on the partition they fall into
// The effective performance is the gasPerf of the chain * block probability
blockProb := mp.blockProbabilities(tq)
effChains := 0
for i := 0; i < MaxBlocks; i++ {
for _, chain := range partitions[i] {
chain.SetEffectivePerf(blockProb[i])
}
effChains += len(partitions[i])
}
// nullify the effective performance of chains that don't fit in any partition
for _, chain := range chains[effChains:] {
chain.SetNullEffectivePerf()
}
// 5. Resort the chains based on effective performance
sort.Slice(chains, func(i, j int) bool {
return chains[i].BeforeEffective(chains[j])
})
// 6. Merge the head chains to produce the list of messages selected for inclusion
// subject to the residual gas limit
// When a chain is merged in, all its previous dependent chains *must* also be
// merged in or we'll have a broken block
startMerge := time.Now()
last := len(chains)
for i, chain := range chains {
// did we run out of performing chains?
if chain.gasPerf < 0 {
break
}
// has it already been merged?
if chain.merged {
continue
}
// compute the dependencies that must be merged and the gas limit including deps
chainGasLimit := chain.gasLimit
var chainDeps []*msgChain
for curChain := chain.prev; curChain != nil && !curChain.merged; curChain = curChain.prev {
chainDeps = append(chainDeps, curChain)
chainGasLimit += curChain.gasLimit
}
// does it all fit in the block?
if chainGasLimit <= gasLimit {
// include it together with all dependencies
for i := len(chainDeps) - 1; i >= 0; i-- {
curChain := chainDeps[i]
curChain.merged = true
result = append(result, curChain.msgs...)
}
chain.merged = true
// adjust the effective pefromance for all subsequent chains
if next := chain.next; next != nil && next.effPerf > 0 {
next.effPerf += next.parentOffset
for next = next.next; next != nil && next.effPerf > 0; next = next.next {
next.setEffPerf()
}
}
result = append(result, chain.msgs...)
gasLimit -= chainGasLimit
// resort to account for already merged chains and effective performance adjustments
sort.Slice(chains[i+1:], func(i, j int) bool {
return chains[i].BeforeEffective(chains[j])
})
continue
}
// we can't fit this chain and its dependencies because of block gasLimit -- we are
// at the edge
last = i
break
}
if dt := time.Since(startMerge); dt > time.Millisecond {
log.Infow("merge message chains done", "took", dt)
}
// 7. We have reached the edge of what can fit wholesale; if we still hae available
// gasLimit to pack some more chains, then trim the last chain and push it down.
// Trimming invalidaates subsequent dependent chains so that they can't be selected
// as their dependency cannot be (fully) included.
// We do this in a loop because the blocker might have been inordinately large and
// we might have to do it multiple times to satisfy tail packing
startTail := time.Now()
tailLoop:
for gasLimit >= minGas && last < len(chains) {
// trim if necessary
if chains[last].gasLimit > gasLimit {
chains[last].Trim(gasLimit, mp, baseFee, ts, false)
}
// push down if it hasn't been invalidated
if chains[last].valid {
for i := last; i < len(chains)-1; i++ {
if chains[i].BeforeEffective(chains[i+1]) {
break
}
chains[i], chains[i+1] = chains[i+1], chains[i]
}
}
// select the next (valid and fitting) chain and its dependencies for inclusion
for i, chain := range chains[last:] {
// has the chain been invalidated?
if !chain.valid {
continue
}
// has it already been merged?
if chain.merged {
continue
}
// if gasPerf < 0 we have no more profitable chains
if chain.gasPerf < 0 {
break tailLoop
}
// compute the dependencies that must be merged and the gas limit including deps
chainGasLimit := chain.gasLimit
depGasLimit := int64(0)
var chainDeps []*msgChain
for curChain := chain.prev; curChain != nil && !curChain.merged; curChain = curChain.prev {
chainDeps = append(chainDeps, curChain)
chainGasLimit += curChain.gasLimit
depGasLimit += curChain.gasLimit
}
// does it all fit in the bock
if chainGasLimit <= gasLimit {
// include it together with all dependencies
for i := len(chainDeps) - 1; i >= 0; i-- {
curChain := chainDeps[i]
curChain.merged = true
result = append(result, curChain.msgs...)
}
chain.merged = true
result = append(result, chain.msgs...)
gasLimit -= chainGasLimit
continue
}
// it doesn't all fit; now we have to take into account the dependent chains before
// making a decision about trimming or invalidating.
// if the dependencies exceed the gas limit, then we must invalidate the chain
// as it can never be included.
// Otherwise we can just trim and continue
if depGasLimit > gasLimit {
chain.Invalidate()
last += i + 1
continue tailLoop
}
// dependencies fit, just trim it
chain.Trim(gasLimit-depGasLimit, mp, baseFee, ts, false)
last += i
continue tailLoop
}
// the merge loop ended after processing all the chains and we we probably have still
// gas to spare; end the loop.
break
}
if dt := time.Since(startTail); dt > time.Millisecond {
log.Infow("pack tail chains done", "took", dt)
}
return result, nil
}
func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.SignedMessage, error) {
start := time.Now()
baseFee, err := mp.api.ChainComputeBaseFee(context.TODO(), ts)
@@ -59,7 +322,7 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
// defer only here so if we have no pending messages we don't spam
defer func() {
log.Infof("message selection took %s", time.Since(start))
log.Infow("message selection done", "took", time.Since(start))
}()
// 0b. Select all priority messages that fit in the block
@@ -72,11 +335,15 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
}
// 1. Create a list of dependent message chains with maximal gas reward per limit consumed
startChains := time.Now()
var chains []*msgChain
for actor, mset := range pending {
next := mp.createMessageChains(actor, mset, baseFee, ts)
chains = append(chains, next...)
}
if dt := time.Since(startChains); dt > time.Millisecond {
log.Infow("create message chains done", "took", dt)
}
// 2. Sort the chains
sort.Slice(chains, func(i, j int) bool {
@@ -90,24 +357,28 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
// 3. Merge the head chains to produce the list of messages selected for inclusion, subject to
// the block gas limit.
startMerge := time.Now()
last := len(chains)
for i, chain := range chains {
// does it fit in the block?
if chain.gasLimit <= gasLimit && chain.gasPerf >= 0 {
gasLimit -= chain.gasLimit
result = append(result, chain.msgs...)
continue
}
// did we run out of performing chains?
if chain.gasPerf < 0 {
break
}
// does it fit in the block?
if chain.gasLimit <= gasLimit {
gasLimit -= chain.gasLimit
result = append(result, chain.msgs...)
continue
}
// we can't fit this chain because of block gasLimit -- we are at the edge
last = i
break
}
if dt := time.Since(startMerge); dt > time.Millisecond {
log.Infow("merge message chains done", "took", dt)
}
// 4. We have reached the edge of what we can fit wholesale; if we still have available gasLimit
// to pack some more chains, then trim the last chain and push it down.
@@ -115,6 +386,7 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
// dependency cannot be (fully) included.
// We do this in a loop because the blocker might have been inordinately large and we might
// have to do it multiple times to satisfy tail packing.
startTail := time.Now()
tailLoop:
for gasLimit >= minGas && last < len(chains) {
// trim
@@ -132,36 +404,47 @@ tailLoop:
// select the next (valid and fitting) chain for inclusion
for i, chain := range chains[last:] {
// has the chain been invalidated
// has the chain been invalidated?
if !chain.valid {
continue
}
// does it fit in the bock?
if chain.gasLimit <= gasLimit && chain.gasPerf >= 0 {
gasLimit -= chain.gasLimit
result = append(result, chain.msgs...)
continue
}
// if gasPerf < 0 we have no more profitable chains
if chain.gasPerf < 0 {
break tailLoop
}
// does it fit in the bock?
if chain.gasLimit <= gasLimit {
gasLimit -= chain.gasLimit
result = append(result, chain.msgs...)
continue
}
// this chain needs to be trimmed
last += i
continue tailLoop
}
// the merge loop ended after processing all the chains and we probably still have gas to spare
// -- mark the end.
last = len(chains)
// the merge loop ended after processing all the chains and we probably still have
// gas to spare; end the loop
break
}
if dt := time.Since(startTail); dt > time.Millisecond {
log.Infow("pack tail chains done", "took", dt)
}
return result, nil
}
func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[uint64]*types.SignedMessage, baseFee types.BigInt, ts *types.TipSet) ([]*types.SignedMessage, int64) {
start := time.Now()
defer func() {
if dt := time.Since(start); dt > time.Millisecond {
log.Infow("select priority messages done", "took", dt)
}
}()
result := make([]*types.SignedMessage, 0, mp.cfg.SizeLimitLow)
gasLimit := int64(build.BlockGasLimit)
minGas := int64(gasguess.MinGas)
@@ -242,8 +525,15 @@ tailLoop:
}
func (mp *MessagePool) getPendingMessages(curTs, ts *types.TipSet) (map[address.Address]map[uint64]*types.SignedMessage, error) {
start := time.Now()
result := make(map[address.Address]map[uint64]*types.SignedMessage)
haveCids := make(map[cid.Cid]struct{})
defer func() {
if dt := time.Since(start); dt > time.Millisecond {
log.Infow("get pending messages done", "took", dt)
}
}()
// are we in sync?
inSync := false
@@ -345,11 +635,11 @@ func (mp *MessagePool) getPendingMessages(curTs, ts *types.TipSet) (map[address.
}
func (mp *MessagePool) getGasReward(msg *types.SignedMessage, baseFee types.BigInt, ts *types.TipSet) *big.Int {
gasReward := abig.Mul(msg.Message.GasPremium, types.NewInt(uint64(msg.Message.GasLimit)))
maxReward := types.BigSub(msg.Message.GasFeeCap, baseFee)
if types.BigCmp(maxReward, gasReward) < 0 {
gasReward = maxReward
maxPremium := types.BigSub(msg.Message.GasFeeCap, baseFee)
if types.BigCmp(maxPremium, msg.Message.GasPremium) < 0 {
maxPremium = msg.Message.GasPremium
}
gasReward := abig.Mul(maxPremium, types.NewInt(uint64(msg.Message.GasLimit)))
return gasReward.Int
}
@@ -431,7 +721,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
}
// check we have a sane set of messages to construct the chains
if i > 0 {
if i > skip {
msgs = msgs[skip:i]
} else {
return nil
@@ -515,6 +805,10 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
chains[i].next = chains[i+1]
}
for i := len(chains) - 1; i > 0; i-- {
chains[i].prev = chains[i-1]
}
return chains
}
@@ -531,8 +825,12 @@ func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt,
mc.gasLimit -= mc.msgs[i].Message.GasLimit
if mc.gasLimit > 0 {
mc.gasPerf = mp.getGasPerf(mc.gasReward, mc.gasLimit)
if mc.bp != 0 {
mc.setEffPerf()
}
} else {
mc.gasPerf = 0
mc.effPerf = 0
}
i--
}
@@ -545,16 +843,47 @@ func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt,
}
if mc.next != nil {
mc.next.invalidate()
mc.next.Invalidate()
mc.next = nil
}
}
func (mc *msgChain) invalidate() {
func (mc *msgChain) Invalidate() {
mc.valid = false
mc.msgs = nil
if mc.next != nil {
mc.next.invalidate()
mc.next.Invalidate()
mc.next = nil
}
}
func (mc *msgChain) SetEffectivePerf(bp float64) {
mc.bp = bp
mc.setEffPerf()
}
func (mc *msgChain) setEffPerf() {
effPerf := mc.gasPerf * mc.bp
if effPerf > 0 && mc.prev != nil {
effPerfWithParent := (effPerf*float64(mc.gasLimit) + mc.prev.effPerf*float64(mc.prev.gasLimit)) / float64(mc.gasLimit+mc.prev.gasLimit)
mc.parentOffset = effPerf - effPerfWithParent
effPerf = effPerfWithParent
}
mc.effPerf = effPerf
}
func (mc *msgChain) SetNullEffectivePerf() {
if mc.gasPerf < 0 {
mc.effPerf = mc.gasPerf
} else {
mc.effPerf = 0
}
}
func (mc *msgChain) BeforeEffective(other *msgChain) bool {
// move merged chains to the front so we can discard them earlier
return (mc.merged && !other.merged) || mc.effPerf > other.effPerf ||
(mc.effPerf == other.effPerf && mc.gasPerf > other.gasPerf) ||
(mc.effPerf == other.effPerf && mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0)
}
+596 -13
View File
@@ -2,6 +2,9 @@ package messagepool
import (
"context"
"math"
"math/big"
"math/rand"
"testing"
"github.com/filecoin-project/go-address"
@@ -12,10 +15,12 @@ import (
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
logging "github.com/ipfs/go-log"
)
func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, gasLimit int64, gasPrice uint64) *types.SignedMessage {
@@ -59,7 +64,7 @@ func TestMessageChains(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeBLS)
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -69,7 +74,7 @@ func TestMessageChains(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeBLS)
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -77,7 +82,7 @@ func TestMessageChains(t *testing.T) {
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
gasLimit := gasguess.Costs[gasguess.CostKey{builtin.StorageMarketActorCodeID, 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
@@ -286,7 +291,9 @@ func TestMessageChains(t *testing.T) {
}
func TestBasicMessageSelection(t *testing.T) {
func TestMessageChainSkipping(t *testing.T) {
// regression test for chain skip bug
mp, tma := makeTestMpool()
// the actors
@@ -295,7 +302,7 @@ func TestBasicMessageSelection(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeBLS)
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -305,7 +312,77 @@ func TestBasicMessageSelection(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeBLS)
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
baseFee := types.NewInt(0)
tma.setBalance(a1, 1) // in FIL
tma.setStateNonce(a1, 10)
mset := make(map[uint64]*types.SignedMessage)
for i := 0; i < 20; i++ {
bias := (20 - i) / 3
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3+bias))
mset[uint64(i)] = m
}
chains := mp.createMessageChains(a1, mset, baseFee, ts)
if len(chains) != 4 {
t.Fatalf("expected 4 chains, got %d", len(chains))
}
for i, chain := range chains {
var expectedLen int
switch {
case i == 0:
expectedLen = 2
case i > 2:
expectedLen = 2
default:
expectedLen = 3
}
if len(chain.msgs) != expectedLen {
t.Fatalf("expected %d message in chain %d but got %d", expectedLen, i, len(chain.msgs))
}
}
nextNonce := 10
for _, chain := range chains {
for _, m := range chain.msgs {
if m.Message.Nonce != uint64(nextNonce) {
t.Fatalf("expected nonce %d but got %d", nextNonce, m.Message.Nonce)
}
nextNonce++
}
}
}
func TestBasicMessageSelection(t *testing.T) {
mp, tma := makeTestMpool()
// the actors
w1, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
w2, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -314,7 +391,7 @@ func TestBasicMessageSelection(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{builtin.StorageMarketActorCodeID, 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -331,7 +408,7 @@ func TestBasicMessageSelection(t *testing.T) {
mustAdd(t, mp, m)
}
msgs, err := mp.SelectMessages(ts)
msgs, err := mp.SelectMessages(ts, 1.0)
if err != nil {
t.Fatal(err)
}
@@ -399,7 +476,7 @@ func TestBasicMessageSelection(t *testing.T) {
tma.setStateNonce(a1, 10)
tma.setStateNonce(a2, 10)
msgs, err = mp.SelectMessages(ts3)
msgs, err = mp.SelectMessages(ts3, 1.0)
if err != nil {
t.Fatal(err)
}
@@ -439,7 +516,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeBLS)
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -449,7 +526,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeBLS)
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -458,7 +535,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{builtin.StorageMarketActorCodeID, 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -473,7 +550,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
mustAdd(t, mp, m)
}
msgs, err := mp.SelectMessages(ts)
msgs, err := mp.SelectMessages(ts, 1.0)
if err != nil {
t.Fatal(err)
}
@@ -492,3 +569,509 @@ func TestMessageSelectionTrimming(t *testing.T) {
}
}
func TestPriorityMessageSelection(t *testing.T) {
mp, tma := makeTestMpool()
// the actors
w1, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
w2, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
mp.cfg.PriorityAddrs = []address.Address{a1}
nMessages := 10
for i := 0; i < nMessages; i++ {
bias := (nMessages - i) / 3
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3+bias))
mustAdd(t, mp, m)
m = makeTestMessage(w2, a2, a1, uint64(i), gasLimit, uint64(1+i%3+bias))
mustAdd(t, mp, m)
}
msgs, err := mp.SelectMessages(ts, 1.0)
if err != nil {
t.Fatal(err)
}
if len(msgs) != 20 {
t.Fatalf("expected 20 messages but got %d", len(msgs))
}
// messages from a1 must be first
nextNonce := uint64(0)
for i := 0; i < 10; i++ {
m := msgs[i]
if m.Message.From != a1 {
t.Fatal("expected messages from a1 before messages from a2")
}
if m.Message.Nonce != nextNonce {
t.Fatalf("expected nonce %d but got %d", nextNonce, m.Message.Nonce)
}
nextNonce++
}
nextNonce = 0
for i := 10; i < 20; i++ {
m := msgs[i]
if m.Message.From != a2 {
t.Fatal("expected messages from a2 after messages from a1")
}
if m.Message.Nonce != nextNonce {
t.Fatalf("expected nonce %d but got %d", nextNonce, m.Message.Nonce)
}
nextNonce++
}
}
func TestOptimalMessageSelection1(t *testing.T) {
// this test uses just a single actor sending messages with a low tq
// the chain depenent merging algorithm should pick messages from the actor
// from the start
mp, tma := makeTestMpool()
// the actors
w1, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
w2, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
nMessages := int(10 * build.BlockGasLimit / gasLimit)
for i := 0; i < nMessages; i++ {
bias := (nMessages - i) / 3
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1+i%3+bias))
mustAdd(t, mp, m)
}
msgs, err := mp.SelectMessages(ts, 0.25)
if err != nil {
t.Fatal(err)
}
expectedMsgs := int(build.BlockGasLimit / gasLimit)
if len(msgs) != expectedMsgs {
t.Fatalf("expected %d messages, but got %d", expectedMsgs, len(msgs))
}
nextNonce := uint64(0)
for _, m := range msgs {
if m.Message.From != a1 {
t.Fatal("expected message from a1")
}
if m.Message.Nonce != nextNonce {
t.Fatalf("expected nonce %d but got %d", nextNonce, m.Message.Nonce)
}
nextNonce++
}
}
func TestOptimalMessageSelection2(t *testing.T) {
// this test uses two actors sending messages to each other, with the first
// actor paying (much) higher gas premium than the second.
// We select with a low ticket quality; the chain depenent merging algorithm should pick
// messages from the second actor from the start
mp, tma := makeTestMpool()
// the actors
w1, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
w2, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
nMessages := int(5 * build.BlockGasLimit / gasLimit)
for i := 0; i < nMessages; i++ {
bias := (nMessages - i) / 3
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(200000+i%3+bias))
mustAdd(t, mp, m)
m = makeTestMessage(w2, a2, a1, uint64(i), gasLimit, uint64(190000+i%3+bias))
mustAdd(t, mp, m)
}
msgs, err := mp.SelectMessages(ts, 0.1)
if err != nil {
t.Fatal(err)
}
expectedMsgs := int(build.BlockGasLimit / gasLimit)
if len(msgs) != expectedMsgs {
t.Fatalf("expected %d messages, but got %d", expectedMsgs, len(msgs))
}
var nFrom1, nFrom2 int
var nextNonce1, nextNonce2 uint64
for _, m := range msgs {
if m.Message.From == a1 {
if m.Message.Nonce != nextNonce1 {
t.Fatalf("expected nonce %d but got %d", nextNonce1, m.Message.Nonce)
}
nextNonce1++
nFrom1++
} else {
if m.Message.Nonce != nextNonce2 {
t.Fatalf("expected nonce %d but got %d", nextNonce2, m.Message.Nonce)
}
nextNonce2++
nFrom2++
}
}
if nFrom1 > nFrom2 {
t.Fatalf("expected more messages from a2 than a1; nFrom1=%d nFrom2=%d", nFrom1, nFrom2)
}
}
func TestOptimalMessageSelection3(t *testing.T) {
// this test uses 10 actors sending a block of messages to each other, with the the first
// actors paying higher gas premium than the subsequent actors.
// We select with a low ticket quality; the chain depenent merging algorithm should pick
// messages from the median actor from the start
mp, tma := makeTestMpool()
nActors := 10
// the actors
var actors []address.Address
var wallets []*wallet.Wallet
for i := 0; i < nActors; i++ {
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a, err := w.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
actors = append(actors, a)
wallets = append(wallets, w)
}
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
for _, a := range actors {
tma.setBalance(a, 1) // in FIL
}
nMessages := int(build.BlockGasLimit/gasLimit) + 1
for i := 0; i < nMessages; i++ {
for j := 0; j < nActors; j++ {
premium := 500000 + 10000*(nActors-j) + (nMessages+2-i)/(30*nActors) + i%3
m := makeTestMessage(wallets[j], actors[j], actors[j%nActors], uint64(i), gasLimit, uint64(premium))
mustAdd(t, mp, m)
}
}
msgs, err := mp.SelectMessages(ts, 0.1)
if err != nil {
t.Fatal(err)
}
expectedMsgs := int(build.BlockGasLimit / gasLimit)
if len(msgs) != expectedMsgs {
t.Fatalf("expected %d messages, but got %d", expectedMsgs, len(msgs))
}
whoIs := func(a address.Address) int {
for i, aa := range actors {
if a == aa {
return i
}
}
return -1
}
nonces := make([]uint64, nActors)
for _, m := range msgs {
who := whoIs(m.Message.From)
if who < 3 {
t.Fatalf("got message from %dth actor", who)
}
nextNonce := nonces[who]
if m.Message.Nonce != nextNonce {
t.Fatalf("expected nonce %d but got %d", nextNonce, m.Message.Nonce)
}
nonces[who]++
}
}
func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium func() uint64) (float64, float64, float64) {
// in this test we use 300 actors and send 10 blocks of messages.
// actors send with an randomly distributed premium dictated by the getPremium function.
// a number of miners select with varying ticket quality and we compare the
// capacity and rewards of greedy selection -vs- optimal selection
mp, tma := makeTestMpool()
nActors := 300
// the actors
var actors []address.Address
var wallets []*wallet.Wallet
for i := 0; i < nActors; i++ {
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
a, err := w.GenerateKey(crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
actors = append(actors, a)
wallets = append(wallets, w)
}
block := mock.MkBlock(nil, 1, 1)
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
baseFee := types.NewInt(0)
for _, a := range actors {
tma.setBalance(a, 1) // in FIL
}
nMessages := 10 * int(build.BlockGasLimit/gasLimit)
t.Log("nMessages", nMessages)
nonces := make([]uint64, nActors)
for i := 0; i < nMessages; i++ {
from := rng.Intn(nActors)
to := rng.Intn(nActors)
nonce := nonces[from]
nonces[from]++
premium := getPremium()
m := makeTestMessage(wallets[from], actors[from], actors[to], nonce, gasLimit, premium)
mustAdd(t, mp, m)
}
logging.SetLogLevel("messagepool", "error")
// 1. greedy selection
greedyMsgs, err := mp.selectMessagesGreedy(ts, ts)
if err != nil {
t.Fatal(err)
}
totalGreedyCapacity := 0.0
totalGreedyReward := 0.0
totalOptimalCapacity := 0.0
totalOptimalReward := 0.0
totalBestTQReward := 0.0
const runs = 1
for i := 0; i < runs; i++ {
// 2. optimal selection
minersRand := rng.Float64()
winerProba := noWinnersProb()
i := 0
for ; i < MaxBlocks && minersRand > 0; i++ {
minersRand -= winerProba[i]
}
nMiners := i - 1
if nMiners < 1 {
nMiners = 1
}
optMsgs := make(map[cid.Cid]*types.SignedMessage)
bestTq := 0.0
var bestMsgs []*types.SignedMessage
for j := 0; j < nMiners; j++ {
tq := rng.Float64()
msgs, err := mp.SelectMessages(ts, tq)
if err != nil {
t.Fatal(err)
}
if tq > bestTq {
bestMsgs = msgs
}
for _, m := range msgs {
optMsgs[m.Cid()] = m
}
}
totalGreedyCapacity += float64(len(greedyMsgs))
totalOptimalCapacity += float64(len(optMsgs))
boost := float64(len(optMsgs)) / float64(len(greedyMsgs))
t.Logf("nMiners: %d", nMiners)
t.Logf("greedy capacity %d, optimal capacity %d (x %.1f )", len(greedyMsgs),
len(optMsgs), boost)
if len(greedyMsgs) > len(optMsgs) {
t.Errorf("greedy capacity higher than optimal capacity; wtf")
}
greedyReward := big.NewInt(0)
for _, m := range greedyMsgs {
greedyReward.Add(greedyReward, mp.getGasReward(m, baseFee, ts))
}
optReward := big.NewInt(0)
for _, m := range optMsgs {
optReward.Add(optReward, mp.getGasReward(m, baseFee, ts))
}
bestTqReward := big.NewInt(0)
for _, m := range bestMsgs {
bestTqReward.Add(bestTqReward, mp.getGasReward(m, baseFee, ts))
}
totalBestTQReward += float64(bestTqReward.Uint64())
nMinersBig := big.NewInt(int64(nMiners))
greedyAvgReward, _ := new(big.Rat).SetFrac(greedyReward, nMinersBig).Float64()
totalGreedyReward += greedyAvgReward
optimalAvgReward, _ := new(big.Rat).SetFrac(optReward, nMinersBig).Float64()
totalOptimalReward += optimalAvgReward
boost = optimalAvgReward / greedyAvgReward
t.Logf("greedy reward: %.0f, optimal reward: %.0f (x %.1f )", greedyAvgReward,
optimalAvgReward, boost)
}
capacityBoost := totalOptimalCapacity / totalGreedyCapacity
rewardBoost := totalOptimalReward / totalGreedyReward
t.Logf("Average capacity boost: %f", capacityBoost)
t.Logf("Average reward boost: %f", rewardBoost)
t.Logf("Average best tq reward: %f", totalBestTQReward/runs/1e12)
logging.SetLogLevel("messagepool", "info")
return capacityBoost, rewardBoost, totalBestTQReward / runs / 1e12
}
func makeExpPremiumDistribution(rng *rand.Rand) func() uint64 {
return func() uint64 {
premium := 20000*math.Exp(-3.*rng.Float64()) + 5000
return uint64(premium)
}
}
func makeZipfPremiumDistribution(rng *rand.Rand) func() uint64 {
zipf := rand.NewZipf(rng, 1.001, 1, 40000)
return func() uint64 {
return zipf.Uint64() + 10000
}
}
func TestCompetitiveMessageSelectionExp(t *testing.T) {
var capacityBoost, rewardBoost, tqReward float64
seeds := []int64{1947, 1976, 2020, 2100, 10000, 143324, 432432, 131, 32, 45}
for _, seed := range seeds {
t.Log("running competitive message selection with Exponential premium distribution and seed", seed)
rng := rand.New(rand.NewSource(seed))
cb, rb, tqR := testCompetitiveMessageSelection(t, rng, makeExpPremiumDistribution(rng))
capacityBoost += cb
rewardBoost += rb
tqReward += tqR
}
capacityBoost /= float64(len(seeds))
rewardBoost /= float64(len(seeds))
tqReward /= float64(len(seeds))
t.Logf("Average capacity boost across all seeds: %f", capacityBoost)
t.Logf("Average reward boost across all seeds: %f", rewardBoost)
t.Logf("Average reward of best ticket across all seeds: %f", tqReward)
}
func TestCompetitiveMessageSelectionZipf(t *testing.T) {
var capacityBoost, rewardBoost, tqReward float64
seeds := []int64{1947, 1976, 2020, 2100, 10000, 143324, 432432, 131, 32, 45}
for _, seed := range seeds {
t.Log("running competitive message selection with Zipf premium distribution and seed", seed)
rng := rand.New(rand.NewSource(seed))
cb, rb, tqR := testCompetitiveMessageSelection(t, rng, makeZipfPremiumDistribution(rng))
capacityBoost += cb
rewardBoost += rb
tqReward += tqR
}
tqReward /= float64(len(seeds))
capacityBoost /= float64(len(seeds))
rewardBoost /= float64(len(seeds))
t.Logf("Average capacity boost across all seeds: %f", capacityBoost)
t.Logf("Average reward boost across all seeds: %f", rewardBoost)
t.Logf("Average reward of best ticket across all seeds: %f", tqReward)
}
+18 -3
View File
@@ -170,7 +170,10 @@ func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
return address.Undef, xerrors.Errorf("loading init actor state: %w", err)
}
a, err := ias.ResolveAddress(&AdtStore{st.Store}, addr)
a, found, err := ias.ResolveAddress(&AdtStore{st.Store}, addr)
if err == nil && !found {
err = types.ErrActorNotFound
}
if err != nil {
return address.Undef, xerrors.Errorf("resolve address %s: %w", addr, err)
}
@@ -189,7 +192,7 @@ func (st *StateTree) GetActor(addr address.Address) (*types.Actor, error) {
// Transform `addr` to its ID format.
iaddr, err := st.LookupID(addr)
if err != nil {
if xerrors.Is(err, init_.ErrAddressNotFound) {
if xerrors.Is(err, types.ErrActorNotFound) {
return nil, xerrors.Errorf("resolution lookup failed (%s): %w", addr, err)
}
return nil, xerrors.Errorf("address resolution: %w", err)
@@ -224,7 +227,7 @@ func (st *StateTree) DeleteActor(addr address.Address) error {
iaddr, err := st.LookupID(addr)
if err != nil {
if xerrors.Is(err, init_.ErrAddressNotFound) {
if xerrors.Is(err, types.ErrActorNotFound) {
return xerrors.Errorf("resolution lookup failed (%s): %w", addr, err)
}
return xerrors.Errorf("address resolution: %w", err)
@@ -333,3 +336,15 @@ func (st *StateTree) MutateActor(addr address.Address, f func(*types.Actor) erro
return st.SetActor(addr, act)
}
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 {
addr, err := address.NewFromBytes([]byte(k))
if err != nil {
return xerrors.Errorf("invalid address (%x) found in state tree key: %w", []byte(k), err)
}
return f(addr, &act)
})
}
+19 -16
View File
@@ -23,13 +23,13 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
defer span.End()
vmopt := &vm.VMOpts{
StateBase: bstate,
Epoch: bheight,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: types.NewInt(0),
StateBase: bstate,
Epoch: bheight,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: types.NewInt(0),
}
vmi, err := vm.NewVM(vmopt)
@@ -108,7 +108,10 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
ts = sm.cs.GetHeaviestTipSet()
}
state := ts.ParentState()
state, _, err := sm.TipSetState(ctx, ts)
if err != nil {
return nil, xerrors.Errorf("computing tipset state: %w", err)
}
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
@@ -121,13 +124,13 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
}
vmopt := &vm.VMOpts{
StateBase: state,
Epoch: ts.Height(),
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
StateBase: state,
Epoch: ts.Height() + 1,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {
@@ -193,7 +196,7 @@ func (sm *StateManager) Replay(ctx context.Context, ts *types.TipSet, mcid cid.C
var outm *types.Message
var outr *vm.ApplyRet
_, _, err := sm.computeTipSetState(ctx, ts.Blocks(), func(c cid.Cid, m *types.Message, ret *vm.ApplyRet) error {
_, _, err := sm.computeTipSetState(ctx, ts, func(c cid.Cid, m *types.Message, ret *vm.ApplyRet) error {
if c == mcid {
outm = m
outr = ret
+358 -104
View File
@@ -5,6 +5,8 @@ import (
"fmt"
"sync"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/go-address"
@@ -42,7 +44,7 @@ type StateManager struct {
stlk sync.Mutex
genesisMsigLk sync.Mutex
newVM func(*vm.VMOpts) (*vm.VM, error)
genesisMsigs []multisig.State
genInfo *genesisInfo
}
func NewStateManager(cs *store.ChainStore) *StateManager {
@@ -111,7 +113,7 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c
return ts.Blocks()[0].ParentStateRoot, ts.Blocks()[0].ParentMessageReceipts, nil
}
st, rec, err = sm.computeTipSetState(ctx, ts.Blocks(), nil)
st, rec, err = sm.computeTipSetState(ctx, ts, nil)
if err != nil {
return cid.Undef, cid.Undef, err
}
@@ -121,7 +123,7 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c
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.Blocks(), func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
st, _, err := sm.computeTipSetState(ctx, ts, func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
ir := &api.InvocResult{
Msg: msg,
MsgRct: &ret.MessageReceipt,
@@ -141,25 +143,18 @@ func (sm *StateManager) ExecutionTrace(ctx context.Context, ts *types.TipSet) (c
return st, trace, nil
}
type BlockMessages struct {
Miner address.Address
BlsMessages []types.ChainMsg
SecpkMessages []types.ChainMsg
WinCount int64
}
type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount) (cid.Cid, cid.Cid, 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) (cid.Cid, cid.Cid, error) {
vmopt := &vm.VMOpts{
StateBase: pstate,
Epoch: epoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: baseFee,
StateBase: pstate,
Epoch: epoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: baseFee,
}
vmi, err := sm.newVM(vmopt)
@@ -311,10 +306,12 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
return st, rectroot, nil
}
func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.BlockHeader, cb ExecCallback) (cid.Cid, cid.Cid, error) {
func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet, cb ExecCallback) (cid.Cid, cid.Cid, error) {
ctx, span := trace.StartSpan(ctx, "computeTipSetState")
defer span.End()
blks := ts.Blocks()
for i := 0; i < len(blks); i++ {
for j := i + 1; j < len(blks); j++ {
if blks[i].Miner == blks[j].Miner {
@@ -327,7 +324,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
var parentEpoch abi.ChainEpoch
pstate := blks[0].ParentStateRoot
if len(blks[0].Parents) > 0 {
if blks[0].Height > 0 {
parent, err := sm.cs.GetBlock(blks[0].Parents[0])
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("getting parent block: %w", err)
@@ -343,30 +340,11 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
r := store.NewChainRand(sm.cs, cids, blks[0].Height)
var blkmsgs []BlockMessages
for _, b := range blks {
bms, sms, err := sm.cs.MessagesForBlock(b)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get messages for block: %w", err)
}
bm := BlockMessages{
Miner: b.Miner,
BlsMessages: make([]types.ChainMsg, 0, len(bms)),
SecpkMessages: make([]types.ChainMsg, 0, len(sms)),
WinCount: b.ElectionProof.WinCount,
}
for _, m := range bms {
bm.BlsMessages = append(bm.BlsMessages, m)
}
for _, m := range sms {
bm.SecpkMessages = append(bm.SecpkMessages, m)
}
blkmsgs = append(blkmsgs, bm)
blkmsgs, err := sm.cs.BlockMsgsForTipset(ts)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("getting block messages for tipset: %w", err)
}
baseFee := blks[0].ParentBaseFee
return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, cb, baseFee)
@@ -441,7 +419,7 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
return nil, fmt.Errorf("failed to load message: %w", err)
}
r, err := sm.tipsetExecutedMessage(ts, msg, m.VMMessage())
r, _, err := sm.tipsetExecutedMessage(ts, msg, m.VMMessage())
if err != nil {
return nil, err
}
@@ -450,7 +428,7 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
return r, nil
}
_, r, err = sm.searchBackForMsg(ctx, ts, m)
_, r, _, err = sm.searchBackForMsg(ctx, ts, m)
if err != nil {
return nil, fmt.Errorf("failed to look back through chain for message: %w", err)
}
@@ -461,44 +439,45 @@ func (sm *StateManager) GetReceipt(ctx context.Context, msg cid.Cid, ts *types.T
// WaitForMessage blocks until a message appears on chain. It looks backwards in the chain to see if this has already
// happened. It guarantees that the message has been on chain for at least confidence epochs without being reverted
// before returning.
func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64) (*types.TipSet, *types.MessageReceipt, error) {
func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confidence uint64) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
msg, err := sm.cs.GetCMessage(mcid)
if err != nil {
return nil, nil, fmt.Errorf("failed to load message: %w", err)
return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err)
}
tsub := sm.cs.SubHeadChanges(ctx)
head, ok := <-tsub
if !ok {
return nil, nil, fmt.Errorf("SubHeadChanges stream was invalid")
return nil, nil, cid.Undef, fmt.Errorf("SubHeadChanges stream was invalid")
}
if len(head) != 1 {
return nil, nil, fmt.Errorf("SubHeadChanges first entry should have been one item")
return nil, nil, cid.Undef, fmt.Errorf("SubHeadChanges first entry should have been one item")
}
if head[0].Type != store.HCCurrent {
return nil, nil, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type)
return nil, nil, cid.Undef, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type)
}
r, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage())
r, foundMsg, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage())
if err != nil {
return nil, nil, err
return nil, nil, cid.Undef, err
}
if r != nil {
return head[0].Val, r, nil
return head[0].Val, r, foundMsg, nil
}
var backTs *types.TipSet
var backRcp *types.MessageReceipt
var backFm cid.Cid
backSearchWait := make(chan struct{})
go func() {
fts, r, err := sm.searchBackForMsg(ctx, head[0].Val, msg)
fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head[0].Val, msg)
if err != nil {
log.Warnf("failed to look back through chain for message: %w", err)
return
@@ -506,11 +485,13 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
backTs = fts
backRcp = r
backFm = foundMsg
close(backSearchWait)
}()
var candidateTs *types.TipSet
var candidateRcp *types.MessageReceipt
var candidateFm cid.Cid
heightOfHead := head[0].Val.Height()
reverts := map[types.TipSetKey]bool{}
@@ -518,7 +499,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
select {
case notif, ok := <-tsub:
if !ok {
return nil, nil, ctx.Err()
return nil, nil, cid.Undef, ctx.Err()
}
for _, val := range notif {
switch val.Type {
@@ -526,24 +507,26 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
if val.Val.Equals(candidateTs) {
candidateTs = nil
candidateRcp = nil
candidateFm = cid.Undef
}
if backSearchWait != nil {
reverts[val.Val.Key()] = true
}
case store.HCApply:
if candidateTs != nil && val.Val.Height() >= candidateTs.Height()+abi.ChainEpoch(confidence) {
return candidateTs, candidateRcp, nil
return candidateTs, candidateRcp, candidateFm, nil
}
r, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage())
r, foundMsg, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage())
if err != nil {
return nil, nil, err
return nil, nil, cid.Undef, err
}
if r != nil {
if confidence == 0 {
return val.Val, r, err
return val.Val, r, foundMsg, err
}
candidateTs = val.Val
candidateRcp = r
candidateFm = foundMsg
}
heightOfHead = val.Val.Height()
}
@@ -553,111 +536,112 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
if backTs != nil && !reverts[backTs.Key()] {
// if head is at or past confidence interval, return immediately
if heightOfHead >= backTs.Height()+abi.ChainEpoch(confidence) {
return backTs, backRcp, nil
return backTs, backRcp, backFm, nil
}
// wait for confidence interval
candidateTs = backTs
candidateRcp = backRcp
candidateFm = backFm
}
reverts = nil
backSearchWait = nil
case <-ctx.Done():
return nil, nil, ctx.Err()
return nil, nil, cid.Undef, ctx.Err()
}
}
}
func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid) (*types.TipSet, *types.MessageReceipt, error) {
func (sm *StateManager) SearchForMessage(ctx context.Context, mcid cid.Cid) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) {
msg, err := sm.cs.GetCMessage(mcid)
if err != nil {
return nil, nil, fmt.Errorf("failed to load message: %w", err)
return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err)
}
head := sm.cs.GetHeaviestTipSet()
r, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage())
r, foundMsg, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage())
if err != nil {
return nil, nil, err
return nil, nil, cid.Undef, err
}
if r != nil {
return head, r, nil
return head, r, foundMsg, nil
}
fts, r, err := sm.searchBackForMsg(ctx, head, msg)
fts, r, foundMsg, err := sm.searchBackForMsg(ctx, head, msg)
if err != nil {
log.Warnf("failed to look back through chain for message %s", mcid)
return nil, nil, err
return nil, nil, cid.Undef, err
}
if fts == nil {
return nil, nil, nil
return nil, nil, cid.Undef, nil
}
return fts, r, nil
return fts, r, foundMsg, nil
}
func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg) (*types.TipSet, *types.MessageReceipt, error) {
func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet, m types.ChainMsg) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) {
cur := from
for {
if cur.Height() == 0 {
// it ain't here!
return nil, nil, nil
return nil, nil, cid.Undef, nil
}
select {
case <-ctx.Done():
return nil, nil, nil
return nil, nil, cid.Undef, nil
default:
}
var act types.Actor
err := sm.WithParentState(cur, sm.WithActor(m.VMMessage().From, GetActor(&act)))
if err != nil {
return nil, nil, err
return nil, nil, cid.Undef, err
}
// we either have no messages from the sender, or the latest message we found has a lower nonce than the one being searched for,
// either way, no reason to lookback, it ain't there
if act.Nonce == 0 || act.Nonce < m.VMMessage().Nonce {
return nil, nil, nil
return nil, nil, cid.Undef, nil
}
ts, err := sm.cs.LoadTipSet(cur.Parents())
if err != nil {
return nil, nil, fmt.Errorf("failed to load tipset during msg wait searchback: %w", err)
return nil, nil, cid.Undef, fmt.Errorf("failed to load tipset during msg wait searchback: %w", err)
}
r, err := sm.tipsetExecutedMessage(ts, m.Cid(), m.VMMessage())
r, foundMsg, err := sm.tipsetExecutedMessage(ts, m.Cid(), m.VMMessage())
if err != nil {
return nil, nil, fmt.Errorf("checking for message execution during lookback: %w", err)
return nil, nil, cid.Undef, fmt.Errorf("checking for message execution during lookback: %w", err)
}
if r != nil {
return ts, r, nil
return ts, r, foundMsg, nil
}
cur = ts
}
}
func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message) (*types.MessageReceipt, error) {
func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message) (*types.MessageReceipt, cid.Cid, error) {
// The genesis block did not execute any messages
if ts.Height() == 0 {
return nil, nil
return nil, cid.Undef, nil
}
pts, err := sm.cs.LoadTipSet(ts.Parents())
if err != nil {
return nil, err
return nil, cid.Undef, err
}
cm, err := sm.cs.MessagesForTipset(pts)
if err != nil {
return nil, err
return nil, cid.Undef, err
}
for ii := range cm {
@@ -667,21 +651,30 @@ func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm
if m.VMMessage().From == vmm.From { // cheaper to just check origin first
if m.VMMessage().Nonce == vmm.Nonce {
if m.Cid() == msg {
return sm.cs.GetParentReceipt(ts.Blocks()[0], i)
if m.VMMessage().EqualCall(vmm) {
if m.Cid() != msg {
log.Warnw("found message with equal nonce and call params but different CID",
"wanted", msg, "found", m.Cid(), "nonce", vmm.Nonce, "from", vmm.From)
}
pr, err := sm.cs.GetParentReceipt(ts.Blocks()[0], i)
if err != nil {
return nil, cid.Undef, err
}
return pr, m.Cid(), nil
}
// this should be that message
return nil, xerrors.Errorf("found message with equal nonce as the one we are looking for (F:%s n %d, TS: %s n%d)",
return nil, cid.Undef, xerrors.Errorf("found message with equal nonce as the one we are looking for (F:%s n %d, TS: %s n%d)",
msg, vmm.Nonce, m.Cid(), m.VMMessage().Nonce)
}
if m.VMMessage().Nonce < vmm.Nonce {
return nil, nil // don't bother looking further
return nil, cid.Undef, nil // don't bother looking further
}
}
}
return nil, nil
return nil, cid.Undef, nil
}
func (sm *StateManager) ListAllActors(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
@@ -782,12 +775,24 @@ func (sm *StateManager) SetVMConstructor(nvm func(*vm.VMOpts) (*vm.VM, error)) {
sm.newVM = nvm
}
type GenesisMsigEntry struct {
totalFunds abi.TokenAmount
unitVest abi.TokenAmount
type genesisInfo struct {
genesisMsigs []multisig.State
// info about the Accounts in the genesis state
genesisActors []genesisActor
genesisPledge abi.TokenAmount
genesisMarketFunds abi.TokenAmount
}
func (sm *StateManager) setupGenesisMsigs(ctx context.Context) error {
type genesisActor struct {
addr address.Address
initBal abi.TokenAmount
}
// sets up information about the actors in the genesis state
func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
gi := genesisInfo{}
gb, err := sm.cs.GetGenesis()
if err != nil {
return xerrors.Errorf("getting genesis block: %w", err)
@@ -803,6 +808,22 @@ func (sm *StateManager) setupGenesisMsigs(ctx context.Context) error {
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)
}
gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree)
if err != nil {
return xerrors.Errorf("setting up genesis market funds: %w", err)
}
gi.genesisPledge, err = getFilPowerLocked(ctx, sTree)
if err != nil {
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)
@@ -829,40 +850,273 @@ func (sm *StateManager) setupGenesisMsigs(ctx context.Context) error {
totalsByEpoch[s.UnlockDuration] = s.InitialBalance
}
} else if act.Code == builtin.AccountActorCodeID {
// should exclude burnt funds actor and "remainder account actor"
// should only ever be "faucet" accounts in testnets
kaddr, err := address.NewFromBytes([]byte(k))
if err != nil {
return xerrors.Errorf("decoding 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,
})
}
}
return nil
})
if err != nil {
return xerrors.Errorf("error setting up composite genesis multisigs: %w", err)
return xerrors.Errorf("error setting up genesis infos: %w", err)
}
sm.genesisMsigs = make([]multisig.State, 0, len(totalsByEpoch))
gi.genesisMsigs = make([]multisig.State, 0, len(totalsByEpoch))
for k, v := range totalsByEpoch {
ns := multisig.State{
InitialBalance: v,
UnlockDuration: k,
PendingTxns: cid.Undef,
}
sm.genesisMsigs = append(sm.genesisMsigs, ns)
gi.genesisMsigs = append(gi.genesisMsigs, ns)
}
sm.genInfo = &gi
return nil
}
func (sm *StateManager) GetVestedFunds(ctx context.Context, height abi.ChainEpoch) (abi.TokenAmount, error) {
sm.genesisMsigLk.Lock()
defer sm.genesisMsigLk.Unlock()
if sm.genesisMsigs == nil {
err := sm.setupGenesisMsigs(ctx)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to setup genesis msig entries: %w", err)
}
// 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 {
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)
}
gi.genesisMarketFunds, err = getFilMarketLocked(ctx, sTree)
if err != nil {
return xerrors.Errorf("setting up genesis market funds: %w", err)
}
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 * builtin.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)
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years
sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay)
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
gi.genesisMsigs = make([]multisig.State, 0, len(totalsByEpoch))
for k, v := range totalsByEpoch {
ns := multisig.State{
InitialBalance: v,
UnlockDuration: k,
PendingTxns: cid.Undef,
}
gi.genesisMsigs = append(gi.genesisMsigs, ns)
}
sm.genInfo = &gi
return nil
}
// GetVestedFunds returns all funds that have "left" actors that are in the genesis state:
// - For Multisigs, it counts the actual amounts that have vested at the given epoch
// - 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.genesisMsigs {
for _, v := range sm.genInfo.genesisMsigs {
au := big.Sub(v.InitialBalance, v.AmountLocked(height))
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 {
act, err := st.GetActor(v.addr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to get actor: %w", err)
}
diff := big.Sub(v.initBal, act.Balance)
if diff.GreaterThan(big.Zero()) {
vf = big.Add(vf, diff)
}
}
vf = big.Add(vf, sm.genInfo.genesisPledge)
vf = big.Add(vf, sm.genInfo.genesisMarketFunds)
return vf, nil
}
func GetFilMined(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
ractor, err := st.GetActor(builtin.RewardActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load reward actor state: %w", err)
}
var rst reward.State
if err := st.Store.Get(ctx, ractor.Head, &rst); err != nil {
return big.Zero(), xerrors.Errorf("failed to load reward state: %w", err)
}
return rst.TotalMined, nil
}
func getFilMarketLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
mactor, err := st.GetActor(builtin.StorageMarketActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load market actor: %w", err)
}
var mst market.State
if err := st.Store.Get(ctx, mactor.Head, &mst); err != nil {
return big.Zero(), xerrors.Errorf("failed to load market state: %w", err)
}
fml := types.BigAdd(mst.TotalClientLockedCollateral, mst.TotalProviderLockedCollateral)
fml = types.BigAdd(fml, mst.TotalClientStorageFee)
return fml, nil
}
func getFilPowerLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
pactor, err := st.GetActor(builtin.StoragePowerActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load power actor: %w", err)
}
var pst power.State
if err := st.Store.Get(ctx, pactor.Head, &pst); err != nil {
return big.Zero(), xerrors.Errorf("failed to load power state: %w", err)
}
return pst.TotalPledgeCollateral, nil
}
func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
filMarketLocked, err := getFilMarketLocked(ctx, st)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to get filMarketLocked: %w", err)
}
filPowerLocked, err := getFilPowerLocked(ctx, st)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to get filPowerLocked: %w", err)
}
return types.BigAdd(filMarketLocked, filPowerLocked), nil
}
func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
burnt, err := st.GetActor(builtin.BurntFundsActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err)
}
return burnt.Balance, nil
}
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 err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to setup genesis information: %w", err)
}
}
filVested, err := sm.GetFilVested(ctx, height, st)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filVested: %w", err)
}
filMined, err := GetFilMined(ctx, st)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filMined: %w", err)
}
filBurnt, err := GetFilBurnt(ctx, st)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filBurnt: %w", err)
}
filLocked, err := sm.GetFilLocked(ctx, st)
if err != nil {
return api.CirculatingSupply{}, xerrors.Errorf("failed to calculate filLocked: %w", err)
}
ret := types.BigAdd(filVested, filMined)
ret = types.BigSub(ret, filBurnt)
ret = types.BigSub(ret, filLocked)
if ret.LessThan(big.Zero()) {
ret = big.Zero()
}
return api.CirculatingSupply{
FilVested: filVested,
FilMined: filMined,
FilBurnt: filBurnt,
FilLocked: filLocked,
FilCirculating: ret,
}, nil
}
func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
csi, err := sm.GetCirculatingSupplyDetailed(ctx, height, st)
if err != nil {
return big.Zero(), err
}
return csi.FilCirculating, nil
}
+22 -72
View File
@@ -13,9 +13,8 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"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"
@@ -175,7 +174,7 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
}
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]abi.SectorInfo, error) {
var partsProving []*abi.BitField
var partsProving []abi.BitField
var mas *miner.State
var info *miner.MinerInfo
@@ -294,14 +293,8 @@ 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) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil {
return false, xerrors.Errorf("(get miner slashed) failed to load miner actor state")
}
var spas power.State
_, err = sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &spas, ts)
_, err := sm.LoadActorState(ctx, builtin.StoragePowerActorAddr, &spas, ts)
if err != nil {
return false, xerrors.Errorf("(get miner slashed) failed to load power actor state")
}
@@ -441,13 +434,13 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
r := store.NewChainRand(sm.cs, ts.Cids(), height)
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: height,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
StateBase: base,
Epoch: height,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {
@@ -593,40 +586,6 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBe
}, nil
}
func (sm *StateManager) CirculatingSupply(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) {
if ts == nil {
ts = sm.cs.GetHeaviestTipSet()
}
st, _, err := sm.TipSetState(ctx, ts)
if err != nil {
return big.Zero(), err
}
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
vmopt := &vm.VMOpts{
StateBase: st,
Epoch: ts.Height(),
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
if err != nil {
return big.Zero(), err
}
unsafeVM := &vm.UnsafeVM{VM: vmi}
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
GasLimit: 100e6,
From: builtin.SystemActorAddr,
}, builtin.SystemActorAddr, 0, 0, 0)
return rt.TotalFilCircSupply(), nil
}
type methodMeta struct {
Name string
@@ -694,29 +653,20 @@ func MinerHasMinPower(ctx context.Context, sm *StateManager, addr address.Addres
return ps.MinerNominalPowerMeetsConsensusMinimum(sm.ChainStore().Store(ctx), addr)
}
func GetCirculatingSupply(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi.TokenAmount, error) {
if ts == nil {
ts = sm.cs.GetHeaviestTipSet()
}
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
vmopt := &vm.VMOpts{
StateBase: ts.ParentState(),
Epoch: ts.Height(),
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
VestedCalc: sm.GetVestedFunds,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
func CheckTotalFIL(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi.TokenAmount, error) {
str, err := state.LoadStateTree(sm.ChainStore().Store(ctx), ts.ParentState())
if err != nil {
return abi.NewTokenAmount(0), err
return abi.TokenAmount{}, err
}
uvm := &vm.UnsafeVM{vmi}
sum := types.NewInt(0)
err = str.ForEach(func(a address.Address, act *types.Actor) error {
sum = types.BigAdd(sum, act.Balance)
return nil
})
if err != nil {
return abi.TokenAmount{}, err
}
rt := uvm.MakeRuntime(ctx, &types.Message{From: builtin.InitActorAddr, GasLimit: 10000000}, builtin.InitActorAddr, 0, 0, 0)
return rt.TotalFilCircSupply(), nil
return sum, nil
}
+31 -3
View File
@@ -7,11 +7,26 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
)
func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int) types.BigInt {
delta := gasLimitUsed/int64(noOfBlocks) - build.BlockGasTarget
// deta := 1/PackingEfficiency * gasLimitUsed/noOfBlocks - build.BlockGasTarget
// change := baseFee * deta / BlockGasTarget / BaseFeeMaxChangeDenom
// nextBaseFee = baseFee + change
// nextBaseFee = max(nextBaseFee, build.MinimumBaseFee)
delta := build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum)
delta -= build.BlockGasTarget
// cap change at 12.5% (BaseFeeMaxChangeDenom) by capping delta
if delta > build.BlockGasTarget {
delta = build.BlockGasTarget
}
if delta < -build.BlockGasTarget {
delta = -build.BlockGasTarget
}
change := big.Mul(baseFee, big.NewInt(delta))
change = big.Div(change, big.NewInt(build.BlockGasTarget))
@@ -26,17 +41,30 @@ func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int
func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) {
zero := abi.NewTokenAmount(0)
// totalLimit is sum of GasLimits of unique messages in a tipset
totalLimit := int64(0)
seen := make(map[cid.Cid]struct{})
for _, b := range ts.Blocks() {
msg1, msg2, err := cs.MessagesForBlock(b)
if err != nil {
return zero, xerrors.Errorf("error getting messages for: %s: %w", b.Cid(), err)
}
for _, m := range msg1 {
totalLimit += m.GasLimit
c := m.Cid()
if _, ok := seen[c]; !ok {
totalLimit += m.GasLimit
seen[c] = struct{}{}
}
}
for _, m := range msg2 {
totalLimit += m.Message.GasLimit
c := m.Cid()
if _, ok := seen[c]; !ok {
totalLimit += m.Message.GasLimit
seen[c] = struct{}{}
}
}
}
parentBaseFee := ts.Blocks()[0].ParentBaseFee
+3 -3
View File
@@ -18,10 +18,10 @@ func TestBaseFee(t *testing.T) {
}{
{100e6, 0, 1, 87.5e6},
{100e6, 0, 5, 87.5e6},
{100e6, build.BlockGasTarget, 1, 100e6},
{100e6, build.BlockGasTarget * 2, 2, 100e6},
{100e6, build.BlockGasTarget, 1, 103.125e6},
{100e6, build.BlockGasTarget * 2, 2, 103.125e6},
{100e6, build.BlockGasLimit * 2, 2, 112.5e6},
{100e6, build.BlockGasLimit * 1.5, 2, 106.25e6},
{100e6, build.BlockGasLimit * 1.5, 2, 110937500},
}
for _, test := range tests {
+16 -1
View File
@@ -2,6 +2,8 @@ package store
import (
"context"
"os"
"strconv"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
@@ -9,6 +11,19 @@ import (
"golang.org/x/xerrors"
)
var DefaultChainIndexCacheSize = 32 << 10
func init() {
if s := os.Getenv("LOTUS_CHAIN_INDEX_CACHE"); s != "" {
lcic, err := strconv.Atoi(s)
if err != nil {
log.Errorf("failed to parse 'LOTUS_CHAIN_INDEX_CACHE' env var: %s", err)
}
DefaultChainIndexCacheSize = lcic
}
}
type ChainIndex struct {
skipCache *lru.ARCCache
@@ -19,7 +34,7 @@ type ChainIndex struct {
type loadTipSetFunc func(types.TipSetKey) (*types.TipSet, error)
func NewChainIndex(lts loadTipSetFunc) *ChainIndex {
sc, _ := lru.NewARC(8192)
sc, _ := lru.NewARC(DefaultChainIndexCacheSize)
return &ChainIndex{
skipCache: sc,
loadTipSet: lts,
+129 -30
View File
@@ -7,6 +7,7 @@ import (
"encoding/json"
"io"
"os"
"strconv"
"sync"
"github.com/filecoin-project/specs-actors/actors/crypto"
@@ -47,6 +48,18 @@ var log = logging.Logger("chainstore")
var chainHeadKey = dstore.NewKey("head")
var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation")
var DefaultTipSetCacheSize = 8192
func init() {
if s := os.Getenv("LOTUS_CHAIN_TIPSET_CACHE"); s != "" {
tscs, err := strconv.Atoi(s)
if err != nil {
log.Errorf("failed to parse 'LOTUS_CHAIN_TIPSET_CACHE' env var: %s", err)
}
DefaultTipSetCacheSize = tscs
}
}
// ReorgNotifee represents a callback that gets called upon reorgs.
type ReorgNotifee func(rev, app []*types.TipSet) error
@@ -85,7 +98,7 @@ type ChainStore struct {
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls vm.SyscallBuilder) *ChainStore {
c, _ := lru.NewARC(2048)
tsc, _ := lru.NewARC(4096)
tsc, _ := lru.NewARC(DefaultTipSetCacheSize)
cs := &ChainStore{
bs: bs,
ds: ds,
@@ -707,9 +720,15 @@ func (cs *ChainStore) readAMTCids(root cid.Cid) ([]cid.Cid, error) {
return cids, nil
}
func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
type BlockMessages struct {
Miner address.Address
BlsMessages []types.ChainMsg
SecpkMessages []types.ChainMsg
WinCount int64
}
func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) {
applied := make(map[address.Address]uint64)
balances := make(map[address.Address]types.BigInt)
cst := cbor.NewCborStore(cs.bs)
st, err := state.LoadStateTree(cst, ts.Blocks()[0].ParentStateRoot)
@@ -725,43 +744,80 @@ func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, err
}
applied[a] = act.Nonce
balances[a] = act.Balance
}
return nil
}
var out []types.ChainMsg
selectMsg := func(m *types.Message) (bool, error) {
if err := preloadAddr(m.From); err != nil {
return false, err
}
if applied[m.From] != m.Nonce {
return false, nil
}
applied[m.From]++
return true, nil
}
var out []BlockMessages
for _, b := range ts.Blocks() {
bms, sms, err := cs.MessagesForBlock(b)
if err != nil {
return nil, xerrors.Errorf("failed to get messages for block: %w", err)
}
cmsgs := make([]types.ChainMsg, 0, len(bms)+len(sms))
for _, m := range bms {
cmsgs = append(cmsgs, m)
}
for _, sm := range sms {
cmsgs = append(cmsgs, sm)
bm := BlockMessages{
Miner: b.Miner,
BlsMessages: make([]types.ChainMsg, 0, len(bms)),
SecpkMessages: make([]types.ChainMsg, 0, len(sms)),
WinCount: b.ElectionProof.WinCount,
}
for _, cm := range cmsgs {
m := cm.VMMessage()
if err := preloadAddr(m.From); err != nil {
return nil, err
for _, bmsg := range bms {
b, err := selectMsg(bmsg.VMMessage())
if err != nil {
return nil, xerrors.Errorf("failed to decide whether to select message for block: %w", err)
}
if applied[m.From] != m.Nonce {
continue
if b {
bm.BlsMessages = append(bm.BlsMessages, bmsg)
}
applied[m.From]++
}
if balances[m.From].LessThan(m.RequiredFunds()) {
continue
for _, smsg := range sms {
b, err := selectMsg(smsg.VMMessage())
if err != nil {
return nil, xerrors.Errorf("failed to decide whether to select message for block: %w", err)
}
balances[m.From] = types.BigSub(balances[m.From], m.RequiredFunds())
out = append(out, cm)
if b {
bm.SecpkMessages = append(bm.SecpkMessages, smsg)
}
}
out = append(out, bm)
}
return out, nil
}
func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
bmsgs, err := cs.BlockMsgsForTipset(ts)
if err != nil {
return nil, err
}
var out []types.ChainMsg
for _, bm := range bmsgs {
for _, blsm := range bm.BlsMessages {
out = append(out, blsm)
}
for _, secm := range bm.SecpkMessages {
out = append(out, secm)
}
}
@@ -951,8 +1007,42 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha
return h.Sum(nil), nil
}
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
_, span := trace.StartSpan(ctx, "store.GetRandomness")
func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
_, span := trace.StartSpan(ctx, "store.GetBeaconRandomness")
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
ts, err := cs.LoadTipSet(types.NewTipSetKey(blks...))
if err != nil {
return nil, err
}
if round > ts.Height() {
return nil, xerrors.Errorf("cannot draw randomness from the future")
}
searchHeight := round
if searchHeight < 0 {
searchHeight = 0
}
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true)
if err != nil {
return nil, err
}
be, err := cs.GetLatestBeaconEntry(randTs)
if err != nil {
return nil, err
}
// if at (or just past -- for null epochs) appropriate epoch
// or at genesis (works for negative epochs)
return DrawRandomness(be.Data, pers, round, entropy)
}
func (cs *ChainStore) GetChainRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
_, span := trace.StartSpan(ctx, "store.GetChainRandomness")
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
@@ -1087,15 +1177,20 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, w io.Writer)
return xerrors.Errorf("unmarshaling block header (cid=%s): %w", blk, err)
}
for _, p := range b.Parents {
blocksToWalk = append(blocksToWalk, p)
}
cids, err := recurseLinks(cs.bs, b.Messages, []cid.Cid{b.Messages})
if err != nil {
return xerrors.Errorf("recursing messages failed: %w", err)
}
if b.Height > 0 {
for _, p := range b.Parents {
blocksToWalk = append(blocksToWalk, p)
}
} else {
// include the genesis block
cids = append(cids, b.Parents...)
}
out := cids
if b.Height == 0 {
@@ -1193,8 +1288,12 @@ func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight abi.ChainEpoch) vm.Ran
}
}
func (cr *chainRand) GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetRandomness(ctx, cr.blks, pers, round, entropy)
func (cr *chainRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetChainRandomness(ctx, cr.blks, pers, round, entropy)
}
func (cr *chainRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetBeaconRandomness(ctx, cr.blks, pers, round, entropy)
}
func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) {
+1 -1
View File
@@ -72,7 +72,7 @@ func BenchmarkGetRandomness(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := cs.GetRandomness(context.TODO(), last.Cids(), crypto.DomainSeparationTag_SealRandomness, 500, nil)
_, err := cs.GetChainRandomness(context.TODO(), last.Cids(), crypto.DomainSeparationTag_SealRandomness, 500, nil)
if err != nil {
b.Fatal(err)
}
+99 -20
View File
@@ -195,6 +195,8 @@ func fetchCids(
}
type BlockValidator struct {
self peer.ID
peers *lru.TwoQueueCache
killThresh int
@@ -211,9 +213,10 @@ type BlockValidator struct {
keycache map[string]address.Address
}
func NewBlockValidator(chain *store.ChainStore, stmgr *stmgr.StateManager, blacklist func(peer.ID)) *BlockValidator {
func NewBlockValidator(self peer.ID, chain *store.ChainStore, stmgr *stmgr.StateManager, blacklist func(peer.ID)) *BlockValidator {
p, _ := lru.New2Q(4096)
return &BlockValidator{
self: self,
peers: p,
killThresh: 10,
blacklist: blacklist,
@@ -243,6 +246,10 @@ func (bv *BlockValidator) flagPeer(p peer.ID) {
}
func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub.Message) pubsub.ValidationResult {
if pid == bv.self {
return bv.validateLocalBlock(ctx, msg)
}
// track validation time
begin := build.Clock.Now()
defer func() {
@@ -257,25 +264,10 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
bv.flagPeer(pid)
}
// make sure the block can be decoded
blk, err := types.DecodeBlockMsg(msg.GetData())
blk, what, err := bv.decodeAndCheckBlock(msg)
if err != nil {
log.Error("got invalid block over pubsub: ", err)
recordFailure("invalid")
return pubsub.ValidationReject
}
// check the message limit constraints
if len(blk.BlsMessages)+len(blk.SecpkMessages) > build.BlockMessageLimit {
log.Warnf("received block with too many messages over pubsub")
recordFailure("too_many_messages")
return pubsub.ValidationReject
}
// make sure we have a signature
if blk.Header.BlockSig == nil {
log.Warnf("received block without a signature over pubsub")
recordFailure("missing_signature")
recordFailure(what)
return pubsub.ValidationReject
}
@@ -332,6 +324,45 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
return pubsub.ValidationAccept
}
func (bv *BlockValidator) validateLocalBlock(ctx context.Context, msg *pubsub.Message) pubsub.ValidationResult {
stats.Record(ctx, metrics.BlockPublished.M(1))
blk, what, err := bv.decodeAndCheckBlock(msg)
if err != nil {
log.Errorf("got invalid local block: %s", err)
ctx, _ = tag.New(ctx, tag.Insert(metrics.FailureType, what))
stats.Record(ctx, metrics.BlockValidationFailure.M(1))
return pubsub.ValidationIgnore
}
if count := bv.recvBlocks.add(blk.Header.Cid()); count > 0 {
log.Warnf("local block has been seen %d times; ignoring", count)
return pubsub.ValidationIgnore
}
msg.ValidatorData = blk
stats.Record(ctx, metrics.BlockValidationSuccess.M(1))
return pubsub.ValidationAccept
}
func (bv *BlockValidator) decodeAndCheckBlock(msg *pubsub.Message) (*types.BlockMsg, string, error) {
blk, err := types.DecodeBlockMsg(msg.GetData())
if err != nil {
return nil, "invalid", xerrors.Errorf("error decoding block: %w", err)
}
if count := len(blk.BlsMessages) + len(blk.SecpkMessages); count > build.BlockMessageLimit {
return nil, "too_many_messages", fmt.Errorf("block contains too many messages (%d)", count)
}
// make sure we have a signature
if blk.Header.BlockSig == nil {
return nil, "missing_signature", fmt.Errorf("block without a signature")
}
return blk, "", nil
}
func (bv *BlockValidator) isChainNearSynced() bool {
ts := bv.chain.GetHeaviestTipSet()
timestamp := ts.MinTimestamp()
@@ -485,14 +516,19 @@ func (brc *blockReceiptCache) add(bcid cid.Cid) int {
}
type MessageValidator struct {
self peer.ID
mpool *messagepool.MessagePool
}
func NewMessageValidator(mp *messagepool.MessagePool) *MessageValidator {
return &MessageValidator{mp}
func NewMessageValidator(self peer.ID, mp *messagepool.MessagePool) *MessageValidator {
return &MessageValidator{self: self, mpool: mp}
}
func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub.Message) pubsub.ValidationResult {
if pid == mv.self {
return mv.validateLocalMessage(ctx, msg)
}
stats.Record(ctx, metrics.MessageReceived.M(1))
m, err := types.DecodeSignedMessage(msg.Message.GetData())
if err != nil {
@@ -511,6 +547,10 @@ func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubs
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
switch {
case xerrors.Is(err, messagepool.ErrBroadcastAnyway):
fallthrough
case xerrors.Is(err, messagepool.ErrRBFTooLowPremium):
fallthrough
case xerrors.Is(err, messagepool.ErrNonceTooLow):
return pubsub.ValidationIgnore
default:
return pubsub.ValidationReject
@@ -520,6 +560,45 @@ func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubs
return pubsub.ValidationAccept
}
func (mv *MessageValidator) validateLocalMessage(ctx context.Context, msg *pubsub.Message) pubsub.ValidationResult {
// do some lightweight validation
stats.Record(ctx, metrics.MessagePublished.M(1))
m, err := types.DecodeSignedMessage(msg.Message.GetData())
if err != nil {
log.Warnf("failed to decode local message: %s", err)
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
if m.Size() > 32*1024 {
log.Warnf("local message is too large! (%dB)", m.Size())
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
if m.Message.To == address.Undef {
log.Warn("local message has invalid destination address")
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
if !m.Message.Value.LessThan(types.TotalFilecoinInt) {
log.Warnf("local messages has too high value: %s", m.Message.Value)
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
if err := mv.mpool.VerifyMsgSig(m); err != nil {
log.Warnf("signature verification failed for local message: %s", err)
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
stats.Record(ctx, metrics.MessageValidationSuccess.M(1))
return pubsub.ValidationAccept
}
func HandleIncomingMessages(ctx context.Context, mpool *messagepool.MessagePool, msub *pubsub.Subscription) {
for {
_, err := msub.Next(ctx)
+1 -1
View File
@@ -24,7 +24,7 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
+121 -19
View File
@@ -3,6 +3,7 @@ package chain_test
import (
"context"
"fmt"
"github.com/ipfs/go-cid"
"os"
"testing"
"time"
@@ -172,7 +173,7 @@ func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bo
}
}
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool) *store.FullTipSet {
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool, msgs [][]*types.SignedMessage) *store.FullTipSet {
if miners == nil {
for i := range tu.g.Miners {
miners = append(miners, i)
@@ -186,20 +187,28 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int,
fmt.Println("Miner mining block: ", maddrs)
mts, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs)
require.NoError(tu.t, err)
if fail {
tu.pushTsExpectErr(to, mts.TipSet, true)
var nts *store.FullTipSet
var err error
if msgs != nil {
nts, err = tu.g.NextTipSetFromMinersWithMessages(blk.TipSet(), maddrs, msgs)
require.NoError(tu.t, err)
} else {
tu.pushFtsAndWait(to, mts.TipSet, wait)
mt, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs)
require.NoError(tu.t, err)
nts = mt.TipSet
}
return mts.TipSet
if fail {
tu.pushTsExpectErr(to, nts, true)
} else {
tu.pushFtsAndWait(to, nts, wait)
}
return nts
}
func (tu *syncTestUtil) mineNewBlock(src int, miners []int) {
mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false)
mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false, nil)
tu.g.CurTipset = mts
}
@@ -416,7 +425,7 @@ func TestSyncBadTimestamp(t *testing.T) {
fmt.Println("BASE: ", base.Cids())
tu.printHeads()
a1 := tu.mineOnBlock(base, 0, nil, false, true)
a1 := tu.mineOnBlock(base, 0, nil, false, true, nil)
tu.g.Timestamper = nil
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
@@ -425,7 +434,7 @@ func TestSyncBadTimestamp(t *testing.T) {
fmt.Println("After mine bad block!")
tu.printHeads()
a2 := tu.mineOnBlock(base, 0, nil, true, false)
a2 := tu.mineOnBlock(base, 0, nil, true, false, nil)
tu.waitUntilSync(0, client)
@@ -469,7 +478,7 @@ func TestSyncBadWinningPoSt(t *testing.T) {
tu.g.SetWinningPoStProver(tu.g.Miners[1], &badWpp{})
// now ensure that new blocks are not accepted
tu.mineOnBlock(base, client, nil, false, true)
tu.mineOnBlock(base, client, nil, false, true, nil)
}
func (tu *syncTestUtil) loadChainToNode(to int) {
@@ -514,16 +523,16 @@ func TestSyncFork(t *testing.T) {
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
// The two nodes fork at this point into 'a' and 'b'
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false)
a = tu.mineOnBlock(a, p1, []int{0}, true, false)
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
// chain B will now be heaviest
b := tu.mineOnBlock(base, p2, []int{1}, true, false)
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
@@ -538,6 +547,99 @@ func TestSyncFork(t *testing.T) {
phead()
}
// This test crafts a tipset with 2 blocks, A and B.
// A and B both include _different_ messages from sender X with nonce N (where N is the correct nonce for X).
// We can confirm that the state can be correctly computed, and that `MessagesForTipset` behaves as expected.
func TestDuplicateNonce(t *testing.T) {
H := 10
tu := prepSyncTest(t, H)
base := tu.g.CurTipset
// Produce a message from the banker to the rcvr
makeMsg := func(rcvr address.Address) *types.SignedMessage {
ba, err := tu.nds[0].StateGetActor(context.TODO(), tu.g.Banker(), base.TipSet().Key())
require.NoError(t, err)
msg := types.Message{
To: rcvr,
From: tu.g.Banker(),
Nonce: ba.Nonce,
Value: types.NewInt(1),
Method: 0,
GasLimit: 100_000_000,
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
}
sig, err := tu.g.Wallet().Sign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes())
require.NoError(t, err)
return &types.SignedMessage{
Message: msg,
Signature: *sig,
}
}
msgs := make([][]*types.SignedMessage, 2)
// Each miner includes a message from the banker with the same nonce, but to different addresses
for k, _ := range msgs {
msgs[k] = []*types.SignedMessage{makeMsg(tu.g.Miners[k])}
}
ts1 := tu.mineOnBlock(base, 0, []int{0, 1}, true, false, msgs)
tu.waitUntilSyncTarget(0, ts1.TipSet())
// mine another tipset
ts2 := tu.mineOnBlock(ts1, 0, []int{0, 1}, true, false, make([][]*types.SignedMessage, 2))
tu.waitUntilSyncTarget(0, ts2.TipSet())
var includedMsg cid.Cid
var skippedMsg cid.Cid
r0, err0 := tu.nds[0].StateGetReceipt(context.TODO(), msgs[0][0].Cid(), ts2.TipSet().Key())
r1, err1 := tu.nds[0].StateGetReceipt(context.TODO(), msgs[1][0].Cid(), ts2.TipSet().Key())
if err0 == nil {
require.Error(t, err1, "at least one of the StateGetReceipt calls should fail")
require.True(t, r0.ExitCode.IsSuccess())
includedMsg = msgs[0][0].Message.Cid()
skippedMsg = msgs[1][0].Message.Cid()
} else {
require.NoError(t, err1, "both the StateGetReceipt calls should not fail")
require.True(t, r1.ExitCode.IsSuccess())
includedMsg = msgs[1][0].Message.Cid()
skippedMsg = msgs[0][0].Message.Cid()
}
_, rslts, err := tu.g.StateManager().ExecutionTrace(context.TODO(), ts1.TipSet())
require.NoError(t, err)
found := false
for _, v := range rslts {
if v.Msg.Cid() == skippedMsg {
t.Fatal("skipped message should not be in exec trace")
}
if v.Msg.Cid() == includedMsg {
found = true
}
}
if !found {
t.Fatal("included message should be in exec trace")
}
mft, err := tu.g.ChainStore().MessagesForTipset(ts1.TipSet())
require.NoError(t, err)
require.True(t, len(mft) == 1, "only expecting one message for this tipset")
require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message")
}
func BenchmarkSyncBasic(b *testing.B) {
for i := 0; i < b.N; i++ {
runSyncBenchLength(b, 100)
+3 -2
View File
@@ -1,13 +1,14 @@
package types
import (
"errors"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
)
var ErrActorNotFound = init_.ErrAddressNotFound
var ErrActorNotFound = errors.New("actor not found")
type Actor struct {
// Identifies the type of actor (string coded as a CID), see `chain/actors/actors.go`.
+10
View File
@@ -22,6 +22,16 @@ type Ticket struct {
VRFProof []byte
}
func (t *Ticket) Quality() float64 {
ticketHash := blake2b.Sum256(t.VRFProof)
ticketNum := BigFromBytes(ticketHash[:]).Int
ticketDenu := big.NewInt(1)
ticketDenu.Lsh(ticketDenu, 256)
tv, _ := new(big.Rat).SetFrac(ticketNum, ticketDenu).Float64()
tq := 1 - tv
return tq
}
type BeaconEntry struct {
Round uint64
Data []byte
+1 -1
View File
@@ -81,7 +81,7 @@ func TestInteropBH(t *testing.T) {
}
posts := []abi.PoStProof{
{abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, []byte{0x07}},
{PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, ProofBytes: []byte{0x07}},
}
bh := &BlockHeader{
+16 -26
View File
@@ -9,7 +9,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
cid "github.com/ipfs/go-cid"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
)
@@ -180,16 +180,14 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
{
pb, err := br.PeekByte()
b, err := br.ReadByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
} else {
t.Ticket = new(Ticket)
if err := t.Ticket.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.Ticket pointer: %w", err)
@@ -201,16 +199,14 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
{
pb, err := br.PeekByte()
b, err := br.ReadByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
} else {
t.ElectionProof = new(ElectionProof)
if err := t.ElectionProof.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.ElectionProof pointer: %w", err)
@@ -378,16 +374,14 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
{
pb, err := br.PeekByte()
b, err := br.ReadByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
} else {
t.BLSAggregate = new(crypto.Signature)
if err := t.BLSAggregate.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.BLSAggregate pointer: %w", err)
@@ -413,16 +407,14 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
{
pb, err := br.PeekByte()
b, err := br.ReadByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
} else {
t.BlockSig = new(crypto.Signature)
if err := t.BlockSig.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.BlockSig pointer: %w", err)
@@ -1337,16 +1329,14 @@ func (t *BlockMsg) UnmarshalCBOR(r io.Reader) error {
{
pb, err := br.PeekByte()
b, err := br.ReadByte()
if err != nil {
return err
}
if pb == cbg.CborNull[0] {
var nbuf [1]byte
if _, err := br.Read(nbuf[:]); err != nil {
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
} else {
t.Header = new(BlockHeader)
if err := t.Header.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.Header pointer: %w", err)
+18
View File
@@ -1,6 +1,7 @@
package types
import (
"encoding"
"fmt"
"math/big"
"strings"
@@ -27,6 +28,20 @@ func (f FIL) Format(s fmt.State, ch rune) {
}
}
func (f FIL) MarshalText() (text []byte, err error) {
return []byte(f.String()), nil
}
func (f FIL) UnmarshalText(text []byte) error {
p, err := ParseFIL(string(text))
if err != nil {
return err
}
f.Int.Set(p.Int)
return nil
}
func ParseFIL(s string) (FIL, error) {
suffix := strings.TrimLeft(s, ".1234567890")
s = s[:len(s)-len(suffix)]
@@ -61,3 +76,6 @@ func ParseFIL(s string) (FIL, error) {
return FIL{r.Num()}, nil
}
var _ encoding.TextMarshaler = (*FIL)(nil)
var _ encoding.TextUnmarshaler = (*FIL)(nil)
+27
View File
@@ -118,6 +118,17 @@ func (m *Message) Equals(o *Message) bool {
return m.Cid() == o.Cid()
}
func (m *Message) EqualCall(o *Message) bool {
m1 := *m
m2 := *o
m1.GasLimit, m2.GasLimit = 0, 0
m1.GasFeeCap, m2.GasFeeCap = big.Zero(), big.Zero()
m1.GasPremium, m2.GasPremium = big.Zero(), big.Zero()
return (&m1).Equals(&m2)
}
func (m *Message) ValidForBlockInclusion(minGas int64) error {
if m.Version != 0 {
return xerrors.New("'Version' unsupported")
@@ -131,6 +142,10 @@ func (m *Message) ValidForBlockInclusion(minGas int64) error {
return xerrors.New("'From' address cannot be empty")
}
if m.Value.Int == nil {
return xerrors.New("'Value' cannot be nil")
}
if m.Value.LessThan(big.Zero()) {
return xerrors.New("'Value' field cannot be negative")
}
@@ -139,14 +154,26 @@ func (m *Message) ValidForBlockInclusion(minGas int64) error {
return xerrors.New("'Value' field cannot be greater than total filecoin supply")
}
if m.GasFeeCap.Int == nil {
return xerrors.New("'GasFeeCap' cannot be nil")
}
if m.GasFeeCap.LessThan(big.Zero()) {
return xerrors.New("'GasFeeCap' field cannot be negative")
}
if m.GasPremium.Int == nil {
return xerrors.New("'GasPremium' cannot be nil")
}
if m.GasPremium.LessThan(big.Zero()) {
return xerrors.New("'GasPremium' field cannot be negative")
}
if m.GasPremium.GreaterThan(m.GasFeeCap) {
return xerrors.New("'GasFeeCap' less than 'GasPremium'")
}
if m.GasLimit > build.BlockGasLimit {
return xerrors.New("'GasLimit' field cannot be greater than a block's gas limit")
}
+72
View File
@@ -0,0 +1,72 @@
package types
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
)
func TestEqualCall(t *testing.T) {
m1 := &Message{
To: builtin.StoragePowerActorAddr,
From: builtin.SystemActorAddr,
Nonce: 34,
Value: big.Zero(),
GasLimit: 123,
GasFeeCap: big.NewInt(234),
GasPremium: big.NewInt(234),
Method: 6,
Params: []byte("hai"),
}
m2 := &Message{
To: builtin.StoragePowerActorAddr,
From: builtin.SystemActorAddr,
Nonce: 34,
Value: big.Zero(),
GasLimit: 1236, // changed
GasFeeCap: big.NewInt(234),
GasPremium: big.NewInt(234),
Method: 6,
Params: []byte("hai"),
}
m3 := &Message{
To: builtin.StoragePowerActorAddr,
From: builtin.SystemActorAddr,
Nonce: 34,
Value: big.Zero(),
GasLimit: 123,
GasFeeCap: big.NewInt(4524), // changed
GasPremium: big.NewInt(234),
Method: 6,
Params: []byte("hai"),
}
m4 := &Message{
To: builtin.StoragePowerActorAddr,
From: builtin.SystemActorAddr,
Nonce: 34,
Value: big.Zero(),
GasLimit: 123,
GasFeeCap: big.NewInt(4524),
GasPremium: big.NewInt(234),
Method: 5, // changed
Params: []byte("hai"),
}
require.True(t, m1.EqualCall(m2))
require.True(t, m1.EqualCall(m3))
require.False(t, m1.EqualCall(m4))
}
+6 -5
View File
@@ -7,11 +7,12 @@ import (
)
type MpoolConfig struct {
PriorityAddrs []address.Address
SizeLimitHigh int
SizeLimitLow int
ReplaceByFeeRatio float64
PruneCooldown time.Duration
PriorityAddrs []address.Address
SizeLimitHigh int
SizeLimitLow int
ReplaceByFeeRatio float64
PruneCooldown time.Duration
GasLimitOverestimation float64
}
func (mc *MpoolConfig) Clone() *MpoolConfig {
+22 -13
View File
@@ -71,9 +71,9 @@ func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.Bloc
cs := store.NewChainStore(a.stateWrapper.bs, a.stateWrapper.ds, a.syscalls)
sm := stmgr.NewStateManager(cs)
var bms []stmgr.BlockMessages
var bms []store.BlockMessages
for _, b := range blocks {
bm := stmgr.BlockMessages{
bm := store.BlockMessages{
Miner: b.Miner,
WinCount: 1,
}
@@ -120,17 +120,26 @@ func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.Bloc
}
type randWrapper struct {
rnd vstate.RandomnessSource
rand vstate.RandomnessSource
}
func (w *randWrapper) GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return w.rnd.Randomness(ctx, pers, round, entropy)
// TODO: these should really be two different randomness sources
func (w *randWrapper) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return w.rand.Randomness(ctx, pers, round, entropy)
}
func (w *randWrapper) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return w.rand.Randomness(ctx, pers, round, entropy)
}
type vmRand struct {
}
func (*vmRand) GetRandomness(ctx context.Context, dst crypto.DomainSeparationTag, h abi.ChainEpoch, input []byte) ([]byte, error) {
func (*vmRand) GetChainRandomness(ctx context.Context, dst crypto.DomainSeparationTag, h abi.ChainEpoch, input []byte) ([]byte, error) {
panic("implement me")
}
func (*vmRand) GetBeaconRandomness(ctx context.Context, dst crypto.DomainSeparationTag, h abi.ChainEpoch, input []byte) ([]byte, error) {
panic("implement me")
}
@@ -139,13 +148,13 @@ func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes.
base := a.stateWrapper.Root()
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: epoch,
Rand: &vmRand{},
Bstore: a.stateWrapper.bs,
Syscalls: a.syscalls,
VestedCalc: nil,
BaseFee: abi.NewTokenAmount(100),
StateBase: base,
Epoch: epoch,
Rand: &vmRand{},
Bstore: a.stateWrapper.bs,
Syscalls: a.syscalls,
CircSupplyCalc: nil,
BaseFee: abi.NewTokenAmount(100),
}
lotusVM, err := vm.NewVM(vmopt)
+2 -2
View File
@@ -29,12 +29,12 @@ func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
return 0, gasLimit
}
// over = gasLimit/gasUsed - 1 - 0.3
// over = gasLimit/gasUsed - 1 - 0.1
// over = min(over, 1)
// gasToBurn = (gasLimit - gasUsed) * over
// so to factor out division from `over`
// over*gasUsed = min(gasLimit - (13*gasUsed)/10, gasUsed)
// over*gasUsed = min(gasLimit - (11*gasUsed)/10, gasUsed)
// gasToBurn = ((gasLimit - gasUsed)*over*gasUsed) / gasUsed
over := gasLimit - (gasOveruseNum*gasUsed)/gasOveruseDenom
if over < 0 {
+14 -60
View File
@@ -8,14 +8,10 @@ import (
gruntime "runtime"
"time"
samarket "github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
sainit "github.com/filecoin-project/specs-actors/actors/builtin/init"
sapower "github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
@@ -62,68 +58,18 @@ type Runtime struct {
}
func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount {
filVested, err := rt.vm.GetVestedFunds(rt.ctx)
cs, err := rt.vm.GetCircSupply(rt.ctx)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get vested funds for computing total supply: %s", err)
rt.Abortf(exitcode.ErrIllegalState, "failed to get total circ supply: %s", err)
}
rew, err := rt.state.GetActor(builtin.RewardActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
filMined := types.BigSub(types.FromFil(build.FilAllocStorageMining), rew.Balance)
if filMined.LessThan(big.Zero()) {
filMined = big.Zero()
}
burnt, err := rt.state.GetActor(builtin.BurntFundsActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
filBurned := burnt.Balance
market, err := rt.state.GetActor(builtin.StorageMarketActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
var mst samarket.State
if err := rt.cst.Get(rt.ctx, market.Head, &mst); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get market state: %s", err)
}
filMarketLocked := types.BigAdd(mst.TotalClientLockedCollateral, mst.TotalProviderLockedCollateral)
filMarketLocked = types.BigAdd(filMarketLocked, mst.TotalClientStorageFee)
power, err := rt.state.GetActor(builtin.StoragePowerActorAddr)
if err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get reward actor for computing total supply: %s", err)
}
var pst sapower.State
if err := rt.cst.Get(rt.ctx, power.Head, &pst); err != nil {
rt.Abortf(exitcode.ErrIllegalState, "failed to get storage power state: %s", err)
}
filLocked := types.BigAdd(filMarketLocked, pst.TotalPledgeCollateral)
ret := types.BigAdd(filVested, filMined)
ret = types.BigSub(ret, filBurned)
ret = types.BigSub(ret, filLocked)
if ret.LessThan(big.Zero()) {
ret = big.Zero()
}
return ret
return cs
}
func (rt *Runtime) ResolveAddress(addr address.Address) (ret address.Address, ok bool) {
r, err := rt.state.LookupID(addr)
if err != nil {
if xerrors.Is(err, sainit.ErrAddressNotFound) {
if xerrors.Is(err, types.ErrActorNotFound) {
return address.Undef, false
}
panic(aerrors.Fatalf("failed to resolve address %s: %s", addr, err))
@@ -232,8 +178,16 @@ func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool)
return act.Code, true
}
func (rt *Runtime) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetRandomness(rt.ctx, personalization, randEpoch, entropy)
func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy)
if err != nil {
panic(aerrors.Fatalf("could not get randomness: %s", err))
}
return res
}
func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy)
if err != nil {
panic(aerrors.Fatalf("could not get randomness: %s", err))
}
+1 -1
View File
@@ -23,7 +23,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
)
func init() {
+32 -32
View File
@@ -24,7 +24,6 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/account"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
@@ -141,30 +140,30 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin
return vm.VM.makeRuntime(ctx, msg, origin, originNonce, usedGas, nac)
}
type VestedCalculator func(context.Context, abi.ChainEpoch) (abi.TokenAmount, error)
type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error)
type VM struct {
cstate *state.StateTree
base cid.Cid
cst *cbor.BasicIpldStore
buf *bufbstore.BufferedBS
blockHeight abi.ChainEpoch
inv *Invoker
rand Rand
vc VestedCalculator
baseFee abi.TokenAmount
cstate *state.StateTree
base cid.Cid
cst *cbor.BasicIpldStore
buf *bufbstore.BufferedBS
blockHeight abi.ChainEpoch
inv *Invoker
rand Rand
circSupplyCalc CircSupplyCalculator
baseFee abi.TokenAmount
Syscalls SyscallBuilder
}
type VMOpts struct {
StateBase cid.Cid
Epoch abi.ChainEpoch
Rand Rand
Bstore bstore.Blockstore
Syscalls SyscallBuilder
VestedCalc VestedCalculator
BaseFee abi.TokenAmount
StateBase cid.Cid
Epoch abi.ChainEpoch
Rand Rand
Bstore bstore.Blockstore
Syscalls SyscallBuilder
CircSupplyCalc CircSupplyCalculator
BaseFee abi.TokenAmount
}
func NewVM(opts *VMOpts) (*VM, error) {
@@ -176,21 +175,22 @@ func NewVM(opts *VMOpts) (*VM, error) {
}
return &VM{
cstate: state,
base: opts.StateBase,
cst: cst,
buf: buf,
blockHeight: opts.Epoch,
inv: NewInvoker(),
rand: opts.Rand, // TODO: Probably should be a syscall
vc: opts.VestedCalc,
Syscalls: opts.Syscalls,
baseFee: opts.BaseFee,
cstate: state,
base: opts.StateBase,
cst: cst,
buf: buf,
blockHeight: opts.Epoch,
inv: NewInvoker(),
rand: opts.Rand, // TODO: Probably should be a syscall
circSupplyCalc: opts.CircSupplyCalc,
Syscalls: opts.Syscalls,
baseFee: opts.BaseFee,
}, nil
}
type Rand interface {
GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
}
type ApplyRet struct {
@@ -240,7 +240,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
_ = rt.chargeGasSafe(newGasCharge("OnGetActor", 0, 0))
toActor, err := st.GetActor(msg.To)
if err != nil {
if xerrors.Is(err, init_.ErrAddressNotFound) {
if xerrors.Is(err, types.ErrActorNotFound) {
a, err := TryCreateAccountActor(rt, msg.To)
if err != nil {
return nil, aerrors.Wrapf(err, "could not create account")
@@ -714,8 +714,8 @@ func (vm *VM) SetInvoker(i *Invoker) {
vm.inv = i
}
func (vm *VM) GetVestedFunds(ctx context.Context) (abi.TokenAmount, error) {
return vm.vc(ctx, vm.blockHeight)
func (vm *VM) GetCircSupply(ctx context.Context) (abi.TokenAmount, error) {
return vm.circSupplyCalc(ctx, vm.blockHeight, vm.cstate)
}
func (vm *VM) incrementNonce(addr address.Address) error {
+6 -5
View File
@@ -419,7 +419,8 @@ var chainListCmd = &cli.Command{
}
tss = otss
for i, ts := range tss {
fmt.Printf("%d: %d blocks\n", ts.Height(), len(ts.Blocks()))
pbf := ts.Blocks()[0].ParentBaseFee
fmt.Printf("%d: %d blocks (baseFee: %s -> maxFee: %s)\n", ts.Height(), len(ts.Blocks()), ts.Blocks()[0].ParentBaseFee, types.FIL(types.BigMul(pbf, types.NewInt(uint64(build.BlockGasLimit)))))
for _, b := range ts.Blocks() {
msgs, err := api.ChainGetBlockMessages(ctx, b.Cid())
@@ -445,7 +446,7 @@ var chainListCmd = &cli.Command{
avgpremium = big.Div(psum, big.NewInt(int64(lenmsgs)))
}
fmt.Printf("\t%s: \t%d msgs, gasLimit: %d / %d (%0.2f%%), avgPrice: %s\n", b.Miner, len(msgs.BlsMessages)+len(msgs.SecpkMessages), limitSum, build.BlockGasLimit, 100*float64(limitSum)/float64(build.BlockGasLimit), avgpremium)
fmt.Printf("\t%s: \t%d msgs, gasLimit: %d / %d (%0.2f%%), avgPremium: %s\n", b.Miner, len(msgs.BlsMessages)+len(msgs.SecpkMessages), limitSum, build.BlockGasLimit, 100*float64(limitSum)/float64(build.BlockGasLimit), avgpremium)
}
if i < len(tss)-1 {
msgs, err := api.ChainGetParentMessages(ctx, tss[i+1].Blocks()[0].Cid())
@@ -1006,7 +1007,7 @@ var slashConsensusFault = &cli.Command{
Params: enc,
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}
@@ -1030,9 +1031,9 @@ var chainGasPriceCmd = &cli.Command{
nb := []int{1, 2, 3, 5, 10, 20, 50, 100, 300}
for _, nblocks := range nb {
addr := builtin.SystemActorAddr // TODO: make real when used in GasEsitmateGasPremium
addr := builtin.SystemActorAddr // TODO: make real when used in GasEstimateGasPremium
est, err := api.GasEsitmateGasPremium(ctx, uint64(nblocks), addr, 10000, types.EmptyTSK)
est, err := api.GasEstimateGasPremium(ctx, uint64(nblocks), addr, 10000, types.EmptyTSK)
if err != nil {
return err
}
+234 -26
View File
@@ -3,6 +3,7 @@ package cli
import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"sort"
@@ -10,8 +11,11 @@ import (
"text/tabwriter"
"time"
tm "github.com/buger/goterm"
"github.com/docker/go-units"
"github.com/fatih/color"
datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-cidutil/cidenc"
"github.com/libp2p/go-libp2p-core/peer"
@@ -75,6 +79,7 @@ var clientCmd = &cli.Command{
WithCategory("util", clientCommPCmd),
WithCategory("util", clientCarGenCmd),
WithCategory("util", clientInfoCmd),
WithCategory("util", clientListTransfers),
},
}
@@ -173,7 +178,7 @@ var clientDropCmd = &cli.Command{
var clientCommPCmd = &cli.Command{
Name: "commP",
Usage: "Calculate the piece-cid (commP) of a CAR file",
ArgsUsage: "[inputFile minerAddress]",
ArgsUsage: "[inputFile]",
Flags: []cli.Flag{
&CidBaseFlag,
},
@@ -185,16 +190,11 @@ var clientCommPCmd = &cli.Command{
defer closer()
ctx := ReqContext(cctx)
if cctx.Args().Len() != 2 {
return fmt.Errorf("usage: commP <inputPath> <minerAddr>")
if cctx.Args().Len() != 1 {
return fmt.Errorf("usage: commP <inputPath>")
}
miner, err := address.NewFromString(cctx.Args().Get(1))
if err != nil {
return err
}
ret, err := api.ClientCalcCommP(ctx, cctx.Args().Get(0), miner)
ret, err := api.ClientCalcCommP(ctx, cctx.Args().Get(0))
if err != nil {
return err
}
@@ -315,6 +315,10 @@ var clientDealCmd = &cli.Command{
Usage: "indicate that the deal counts towards verified client total",
Value: false,
},
&cli.StringFlag{
Name: "provider-collateral",
Usage: "specify the requested provider collateral the miner should put up",
},
&CidBaseFlag,
},
Action: func(cctx *cli.Context) error {
@@ -355,6 +359,15 @@ var clientDealCmd = &cli.Command{
return err
}
var provCol big.Int
if pcs := cctx.String("provider-collateral"); pcs != "" {
pc, err := big.FromString(pcs)
if err != nil {
return fmt.Errorf("failed to parse provider-collateral: %w", err)
}
provCol = pc
}
if abi.ChainEpoch(dur) < build.MinDealDuration {
return xerrors.Errorf("minimum deal duration is %d blocks", build.MinDealDuration)
}
@@ -419,14 +432,15 @@ var clientDealCmd = &cli.Command{
}
proposal, err := api.ClientStartDeal(ctx, &lapi.StartDealParams{
Data: ref,
Wallet: a,
Miner: miner,
EpochPrice: types.BigInt(price),
MinBlocksDuration: uint64(dur),
DealStartEpoch: abi.ChainEpoch(cctx.Int64("start-epoch")),
FastRetrieval: cctx.Bool("fast-retrieval"),
VerifiedDeal: isVerified,
Data: ref,
Wallet: a,
Miner: miner,
EpochPrice: types.BigInt(price),
MinBlocksDuration: uint64(dur),
DealStartEpoch: abi.ChainEpoch(cctx.Int64("start-epoch")),
FastRetrieval: cctx.Bool("fast-retrieval"),
VerifiedDeal: isVerified,
ProviderCollateral: provCol,
})
if err != nil {
return err
@@ -540,7 +554,7 @@ func interactiveDeal(cctx *cli.Context) error {
continue
}
a, err := api.ClientQueryAsk(ctx, mi.PeerId, maddr)
a, err := api.ClientQueryAsk(ctx, *mi.PeerId, maddr)
if err != nil {
printErr(xerrors.Errorf("failed to query ask: %w", err))
state = "miner"
@@ -837,12 +851,33 @@ var clientRetrieveCmd = &cli.Command{
Path: cctx.Args().Get(1),
IsCAR: cctx.Bool("car"),
}
if err := fapi.ClientRetrieve(ctx, offer.Order(payer), ref); err != nil {
return xerrors.Errorf("Retrieval Failed: %w", err)
updates, err := fapi.ClientRetrieveWithEvents(ctx, offer.Order(payer), ref)
if err != nil {
return xerrors.Errorf("error setting up retrieval: %w", err)
}
fmt.Println("Success")
return nil
for {
select {
case evt, ok := <-updates:
if ok {
fmt.Printf("> Recv: %s, Paid %s, %s (%s)\n",
types.SizeStr(types.NewInt(evt.BytesReceived)),
types.FIL(evt.FundsSpent),
retrievalmarket.ClientEvents[evt.Event],
retrievalmarket.DealStatuses[evt.Status],
)
} else {
fmt.Println("Success")
return nil
}
if evt.Err != "" {
return xerrors.Errorf("retrieval failed: %s", evt.Err)
}
case <-ctx.Done():
return xerrors.Errorf("retrieval timed out")
}
}
},
}
@@ -895,11 +930,11 @@ var clientQueryAskCmd = &cli.Command{
return xerrors.Errorf("failed to get peerID for miner: %w", err)
}
if peer.ID(mi.PeerId) == peer.ID("SETME") {
if peer.ID(*mi.PeerId) == peer.ID("SETME") {
return fmt.Errorf("the miner hasn't initialized yet")
}
pid = peer.ID(mi.PeerId)
pid = peer.ID(*mi.PeerId)
}
ask, err := api.ClientQueryAsk(ctx, pid, maddr)
@@ -909,6 +944,7 @@ 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))))
size := cctx.Int64("size")
@@ -961,6 +997,10 @@ var clientListDeals = &cli.Command{
return err
}
sort.Slice(localDeals, func(i, j int) bool {
return localDeals[i].CreationTime.Before(localDeals[j].CreationTime)
})
var deals []deal
for _, v := range localDeals {
if v.DealID == 0 {
@@ -989,7 +1029,7 @@ var clientListDeals = &cli.Command{
if cctx.Bool("verbose") {
w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
fmt.Fprintf(w, "DealCid\tDealId\tProvider\tState\tOn Chain?\tSlashed?\tPieceCID\tSize\tPrice\tDuration\tMessage\n")
fmt.Fprintf(w, "Created\tDealCid\tDealId\tProvider\tState\tOn Chain?\tSlashed?\tPieceCID\tSize\tPrice\tDuration\tMessage\n")
for _, d := range deals {
onChain := "N"
if d.OnChainDealState.SectorStartEpoch != -1 {
@@ -1002,7 +1042,7 @@ var clientListDeals = &cli.Command{
}
price := types.FIL(types.BigMul(d.LocalDeal.PricePerEpoch, types.NewInt(d.LocalDeal.Duration)))
fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%s\n", d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, dealStateString(color, d.LocalDeal.State), onChain, slashed, d.LocalDeal.PieceCID, types.SizeStr(types.NewInt(d.LocalDeal.Size)), price, d.LocalDeal.Duration, d.LocalDeal.Message)
fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d\t%s\n", d.LocalDeal.CreationTime.Format(time.Stamp), d.LocalDeal.ProposalCid, d.LocalDeal.DealID, d.LocalDeal.Provider, dealStateString(color, d.LocalDeal.State), onChain, slashed, d.LocalDeal.PieceCID, types.SizeStr(types.NewInt(d.LocalDeal.Size)), price, d.LocalDeal.Duration, d.LocalDeal.Message)
}
return w.Flush()
} else {
@@ -1171,3 +1211,171 @@ var clientInfoCmd = &cli.Command{
return nil
},
}
var clientListTransfers = &cli.Command{
Name: "list-transfers",
Usage: "List ongoing data transfers for deals",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "color",
Usage: "use color in display output",
Value: true,
},
&cli.BoolFlag{
Name: "completed",
Usage: "show completed data transfers",
},
&cli.BoolFlag{
Name: "watch",
Usage: "watch deal updates in real-time, rather than a one time list",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
channels, err := api.ClientListDataTransfers(ctx)
if err != nil {
return err
}
completed := cctx.Bool("completed")
color := cctx.Bool("color")
watch := cctx.Bool("watch")
if watch {
channelUpdates, err := api.ClientDataTransferUpdates(ctx)
if err != nil {
return err
}
for {
tm.Clear() // Clear current screen
tm.MoveCursor(1, 1)
OutputDataTransferChannels(tm.Screen, channels, completed, color)
tm.Flush()
select {
case <-ctx.Done():
return nil
case channelUpdate := <-channelUpdates:
var found bool
for i, existing := range channels {
if existing.TransferID == channelUpdate.TransferID &&
existing.OtherPeer == channelUpdate.OtherPeer &&
existing.IsSender == channelUpdate.IsSender &&
existing.IsInitiator == channelUpdate.IsInitiator {
channels[i] = channelUpdate
found = true
break
}
}
if !found {
channels = append(channels, channelUpdate)
}
}
}
}
OutputDataTransferChannels(os.Stdout, channels, completed, color)
return nil
},
}
// OutputDataTransferChannels generates table output for a list of channels
func OutputDataTransferChannels(out io.Writer, channels []lapi.DataTransferChannel, completed bool, color bool) {
sort.Slice(channels, func(i, j int) bool {
return channels[i].TransferID < channels[j].TransferID
})
var receivingChannels, sendingChannels []lapi.DataTransferChannel
for _, channel := range channels {
if !completed && channel.Status == datatransfer.Completed {
continue
}
if channel.IsSender {
sendingChannels = append(sendingChannels, channel)
} else {
receivingChannels = append(receivingChannels, channel)
}
}
fmt.Fprintf(out, "Sending Channels\n\n")
w := tablewriter.New(tablewriter.Col("ID"),
tablewriter.Col("Status"),
tablewriter.Col("Sending To"),
tablewriter.Col("Root Cid"),
tablewriter.Col("Initiated?"),
tablewriter.Col("Transferred"),
tablewriter.Col("Voucher"),
tablewriter.NewLineCol("Message"))
for _, channel := range sendingChannels {
w.Write(toChannelOutput(color, "Sending To", channel))
}
w.Flush(out)
fmt.Fprintf(out, "\nReceiving Channels\n\n")
w = tablewriter.New(tablewriter.Col("ID"),
tablewriter.Col("Status"),
tablewriter.Col("Receiving From"),
tablewriter.Col("Root Cid"),
tablewriter.Col("Initiated?"),
tablewriter.Col("Transferred"),
tablewriter.Col("Voucher"),
tablewriter.NewLineCol("Message"))
for _, channel := range receivingChannels {
w.Write(toChannelOutput(color, "Receiving From", channel))
}
w.Flush(out)
}
func channelStatusString(useColor bool, status datatransfer.Status) string {
s := datatransfer.Statuses[status]
if !useColor {
return s
}
switch status {
case datatransfer.Failed, datatransfer.Cancelled:
return color.RedString(s)
case datatransfer.Completed:
return color.GreenString(s)
default:
return s
}
}
func toChannelOutput(useColor bool, otherPartyColumn string, channel lapi.DataTransferChannel) map[string]interface{} {
rootCid := channel.BaseCID.String()
rootCid = "..." + rootCid[len(rootCid)-8:]
otherParty := channel.OtherPeer.String()
otherParty = "..." + otherParty[len(otherParty)-8:]
initiated := "N"
if channel.IsInitiator {
initiated = "Y"
}
voucher := channel.Voucher
if len(voucher) > 40 {
voucher = "..." + voucher[len(voucher)-37:]
}
return map[string]interface{}{
"ID": channel.TransferID,
"Status": channelStatusString(useColor, channel.Status),
otherPartyColumn: otherParty,
"Root Cid": rootCid,
"Initiated?": initiated,
"Transferred": channel.Transferred,
"Voucher": voucher,
"Message": channel.Message,
}
}
+34 -5
View File
@@ -26,7 +26,7 @@ import (
var log = logging.Logger("cli")
const (
metadataTraceConetxt = "traceContext"
metadataTraceContext = "traceContext"
)
// custom CLI error
@@ -67,6 +67,19 @@ func (a APIInfo) AuthHeader() http.Header {
return nil
}
// The flag passed on the command line with the listen address of the API
// server (only used by the tests)
func flagForAPI(t repo.RepoType) string {
switch t {
case repo.FullNode:
return "api"
case repo.StorageMiner:
return "miner-api"
default:
panic(fmt.Sprintf("Unknown repo type: %v", t))
}
}
func flagForRepo(t repo.RepoType) string {
switch t {
case repo.FullNode:
@@ -102,6 +115,20 @@ func envForRepoDeprecation(t repo.RepoType) string {
}
func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) {
// Check if there was a flag passed with the listen address of the API
// server (only used by the tests)
apiFlag := flagForAPI(t)
if ctx.IsSet(apiFlag) {
strma := ctx.String(apiFlag)
strma = strings.TrimSpace(strma)
apima, err := multiaddr.NewMultiaddr(strma)
if err != nil {
return APIInfo{}, err
}
return APIInfo{Addr: apima}, nil
}
envKey := envForRepo(t)
env, ok := os.LookupEnv(envKey)
if !ok {
@@ -132,7 +159,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) {
p, err := homedir.Expand(ctx.String(repoFlag))
if err != nil {
return APIInfo{}, xerrors.Errorf("cound not expand home dir (%s): %w", repoFlag, err)
return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", repoFlag, err)
}
r, err := repo.NewFS(p)
@@ -198,17 +225,17 @@ func GetFullNodeAPI(ctx *cli.Context) (api.FullNode, jsonrpc.ClientCloser, error
return client.NewFullNodeRPC(addr, headers)
}
func GetStorageMinerAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) {
func GetStorageMinerAPI(ctx *cli.Context, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) {
addr, headers, err := GetRawAPI(ctx, repo.StorageMiner)
if err != nil {
return nil, nil, err
}
return client.NewStorageMinerRPC(addr, headers)
return client.NewStorageMinerRPC(addr, headers, opts...)
}
func DaemonContext(cctx *cli.Context) context.Context {
if mtCtx, ok := cctx.App.Metadata[metadataTraceConetxt]; ok {
if mtCtx, ok := cctx.App.Metadata[metadataTraceContext]; ok {
return mtCtx.(context.Context)
}
@@ -238,6 +265,7 @@ var CommonCommands = []*cli.Command{
logCmd,
waitApiCmd,
fetchParamCmd,
pprofCmd,
VersionCmd,
}
@@ -256,6 +284,7 @@ var Commands = []*cli.Command{
WithCategory("developer", fetchParamCmd),
WithCategory("network", netCmd),
WithCategory("network", syncCmd),
pprofCmd,
VersionCmd,
}
+79
View File
@@ -20,10 +20,12 @@ var mpoolCmd = &cli.Command{
Usage: "Manage message pool",
Subcommands: []*cli.Command{
mpoolPending,
mpoolClear,
mpoolSub,
mpoolStat,
mpoolReplaceCmd,
mpoolFindCmd,
mpoolConfig,
},
}
@@ -82,6 +84,38 @@ var mpoolPending = &cli.Command{
},
}
var mpoolClear = &cli.Command{
Name: "clear",
Usage: "Clear all pending messages from the mpool (USE WITH CARE)",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "local",
Usage: "also clear local messages",
},
&cli.BoolFlag{
Name: "really-do-it",
Usage: "must be specified for the action to take effect",
},
},
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
really := cctx.Bool("really-do-it")
if !really {
return fmt.Errorf("--really-do-it must be specified for this action to have an effect; you have been warned.")
}
local := cctx.Bool("local")
ctx := ReqContext(cctx)
return api.MpoolClear(ctx, local)
},
}
var mpoolSub = &cli.Command{
Name: "sub",
Usage: "Subscribe to mpool changes",
@@ -415,3 +449,48 @@ var mpoolFindCmd = &cli.Command{
return nil
},
}
var mpoolConfig = &cli.Command{
Name: "config",
Usage: "get or set current mpool configuration",
ArgsUsage: "[new-config]",
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() > 1 {
return cli.ShowCommandHelp(cctx, cctx.Command.Name)
}
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if cctx.Args().Len() == 0 {
cfg, err := api.MpoolGetConfig(ctx)
if err != nil {
return err
}
bytes, err := json.Marshal(cfg)
if err != nil {
return err
}
fmt.Println(string(bytes))
} else {
cfg := new(types.MpoolConfig)
bytes := []byte(cctx.Args().Get(0))
err := json.Unmarshal(bytes, cfg)
if err != nil {
return err
}
return api.MpoolSetConfig(ctx, cfg)
}
return nil
},
}
+12 -2
View File
@@ -12,6 +12,7 @@ import (
"text/tabwriter"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/go-address"
@@ -231,10 +232,10 @@ var msigInspectCmd = &cli.Command{
})
w := tabwriter.NewWriter(os.Stdout, 8, 4, 0, ' ', 0)
fmt.Fprintf(w, "ID\tState\tTo\tValue\tMethod\tParams\n")
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%s\t%s\t%d\t%x\n", txid, state(tx), 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, state(tx), 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)
@@ -355,6 +356,15 @@ var msigProposeCmd = &cli.Command{
from = defaddr
}
act, err := api.StateGetActor(ctx, msig, types.EmptyTSK)
if err != nil {
return fmt.Errorf("failed to look up multisig %s: %w", msig, err)
}
if act.Code != builtin.MultisigActorCodeID {
return fmt.Errorf("actor %s is not a multisig actor", msig)
}
msgCid, err := api.MsigPropose(ctx, msig, dest, types.BigInt(value), from, method, params)
if err != nil {
return err
+26
View File
@@ -24,6 +24,7 @@ var netCmd = &cli.Command{
NetId,
netFindPeer,
netScores,
NetReachability,
},
}
@@ -202,3 +203,28 @@ var netFindPeer = &cli.Command{
return nil
},
}
var NetReachability = &cli.Command{
Name: "reachability",
Usage: "Print information about reachability from the internet",
Action: func(cctx *cli.Context) error {
api, closer, err := GetAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
i, err := api.NetAutoNatStatus(ctx)
if err != nil {
return err
}
fmt.Println("AutoNAT status: ", i.Reachability.String())
if i.PublicAddr != "" {
fmt.Println("Public address: ", i.PublicAddr)
}
return nil
},
}
+13 -14
View File
@@ -5,9 +5,8 @@ import (
"encoding/base64"
"fmt"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/urfave/cli/v2"
@@ -66,12 +65,12 @@ var paychGetCmd = &cli.Command{
}
// Wait for the message to be confirmed
chAddr, err := api.PaychGetWaitReady(ctx, info.ChannelMessage)
chAddr, err := api.PaychGetWaitReady(ctx, info.WaitSentinel)
if err != nil {
return err
}
fmt.Println(chAddr)
fmt.Fprintln(cctx.App.Writer, chAddr)
return nil
},
}
@@ -94,7 +93,7 @@ var paychListCmd = &cli.Command{
}
for _, v := range chs {
fmt.Println(v.String())
fmt.Fprintln(cctx.App.Writer, v.String())
}
return nil
},
@@ -135,7 +134,7 @@ var paychSettleCmd = &cli.Command{
return fmt.Errorf("settle message execution failed (exit code %d)", mwait.Receipt.ExitCode)
}
fmt.Printf("Settled channel %s\n", ch)
fmt.Fprintf(cctx.App.Writer, "Settled channel %s\n", ch)
return nil
},
}
@@ -175,7 +174,7 @@ var paychCloseCmd = &cli.Command{
return fmt.Errorf("collect message execution failed (exit code %d)", mwait.Receipt.ExitCode)
}
fmt.Printf("Collected funds for channel %s\n", ch)
fmt.Fprintf(cctx.App.Writer, "Collected funds for channel %s\n", ch)
return nil
},
}
@@ -239,7 +238,7 @@ var paychVoucherCreateCmd = &cli.Command{
return err
}
fmt.Println(enc)
fmt.Fprintln(cctx.App.Writer, enc)
return nil
},
}
@@ -275,7 +274,7 @@ var paychVoucherCheckCmd = &cli.Command{
return err
}
fmt.Println("voucher is valid")
fmt.Fprintln(cctx.App.Writer, "voucher is valid")
return nil
},
}
@@ -356,9 +355,9 @@ var paychVoucherListCmd = &cli.Command{
return err
}
fmt.Printf("Lane %d, Nonce %d: %s; %s\n", v.Lane, v.Nonce, v.Amount.String(), enc)
fmt.Fprintf(cctx.App.Writer, "Lane %d, Nonce %d: %s; %s\n", v.Lane, v.Nonce, v.Amount.String(), enc)
} else {
fmt.Printf("Lane %d, Nonce %d: %s\n", v.Lane, v.Nonce, v.Amount.String())
fmt.Fprintf(cctx.App.Writer, "Lane %d, Nonce %d: %s\n", v.Lane, v.Nonce, v.Amount.String())
}
}
@@ -415,8 +414,8 @@ var paychVoucherBestSpendableCmd = &cli.Command{
return err
}
fmt.Println(enc)
fmt.Printf("Amount: %s\n", best.Amount)
fmt.Fprintln(cctx.App.Writer, enc)
fmt.Fprintf(cctx.App.Writer, "Amount: %s\n", best.Amount)
return nil
},
}
@@ -462,7 +461,7 @@ var paychVoucherSubmitCmd = &cli.Command{
return fmt.Errorf("message execution failed (exit code %d)", mwait.Receipt.ExitCode)
}
fmt.Println("channel updated successfully")
fmt.Fprintln(cctx.App.Writer, "channel updated successfully")
return nil
},
+228
View File
@@ -0,0 +1,228 @@
package cli
import (
"bytes"
"context"
"flag"
"os"
"strconv"
"strings"
"testing"
"time"
"github.com/filecoin-project/specs-actors/actors/abi/big"
saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/multiformats/go-multiaddr"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/specs-actors/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/lotus/api/test"
"github.com/filecoin-project/lotus/chain/wallet"
builder "github.com/filecoin-project/lotus/node/test"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
)
func init() {
power.ConsensusMinerMinPower = big.NewInt(2048)
saminer.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
abi.RegisteredSealProof_StackedDrg2KiBV1: {},
}
verifreg.MinVerifiedDealSize = big.NewInt(256)
}
// TestPaymentChannels does a basic test to exercise the payment channel CLI
// commands
func TestPaymentChannels(t *testing.T) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
blocktime := 5 * time.Millisecond
ctx := context.Background()
n, sn := builder.RPCMockSbBuilder(t, 2, test.OneMiner)
paymentCreator := n[0]
paymentReceiver := n[1]
miner := sn[0]
// Get everyone connected
addrs, err := paymentCreator.NetAddrsListen(ctx)
if err != nil {
t.Fatal(err)
}
if err := paymentReceiver.NetConnect(ctx, addrs); err != nil {
t.Fatal(err)
}
if err := miner.NetConnect(ctx, addrs); err != nil {
t.Fatal(err)
}
// Start mining blocks
bm := test.NewBlockMiner(ctx, t, miner, blocktime)
bm.MineBlocks()
// Send some funds to register the receiver
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
if err != nil {
t.Fatal(err)
}
test.SendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18))
// Get the creator's address
creatorAddr, err := paymentCreator.WalletDefaultAddress(ctx)
if err != nil {
t.Fatal(err)
}
// Create mock CLI
mockCLI := newMockCLI(t)
creatorCLI := mockCLI.client(paymentCreator.ListenAddr)
receiverCLI := mockCLI.client(paymentReceiver.ListenAddr)
// creator: paych get <creator> <receiver> <amount>
channelAmt := "100000"
cmd := []string{creatorAddr.String(), receiverAddr.String(), channelAmt}
chstr := creatorCLI.runCmd(paychGetCmd, cmd)
chAddr, err := address.NewFromString(chstr)
require.NoError(t, err)
// creator: paych voucher create <channel> <amount>
voucherAmt := 100
vamt := strconv.Itoa(voucherAmt)
cmd = []string{chAddr.String(), vamt}
voucher := creatorCLI.runCmd(paychVoucherCreateCmd, cmd)
// receiver: paych voucher add <channel> <voucher>
cmd = []string{chAddr.String(), voucher}
receiverCLI.runCmd(paychVoucherAddCmd, cmd)
// creator: paych settle <channel>
cmd = []string{chAddr.String()}
creatorCLI.runCmd(paychSettleCmd, cmd)
// Wait for the chain to reach the settle height
chState := getPaychState(ctx, t, paymentReceiver, chAddr)
waitForHeight(ctx, t, paymentReceiver, chState.SettlingAt)
// receiver: paych collect <channel>
cmd = []string{chAddr.String()}
receiverCLI.runCmd(paychCloseCmd, cmd)
}
type mockCLI struct {
t *testing.T
cctx *cli.Context
out *bytes.Buffer
}
func newMockCLI(t *testing.T) *mockCLI {
// Create a CLI App with an --api flag so that we can specify which node
// the command should be executed against
app := cli.NewApp()
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "api",
Hidden: true,
},
}
var out bytes.Buffer
app.Writer = &out
app.Setup()
cctx := cli.NewContext(app, &flag.FlagSet{}, nil)
return &mockCLI{t: t, cctx: cctx, out: &out}
}
func (c *mockCLI) client(addr multiaddr.Multiaddr) *mockCLIClient {
return &mockCLIClient{t: c.t, addr: addr, cctx: c.cctx, out: c.out}
}
// mockCLIClient runs commands against a particular node
type mockCLIClient struct {
t *testing.T
addr multiaddr.Multiaddr
cctx *cli.Context
out *bytes.Buffer
}
func (c *mockCLIClient) runCmd(cmd *cli.Command, input []string) string {
// prepend --api=<node api listener address>
apiFlag := "--api=" + c.addr.String()
input = append([]string{apiFlag}, input...)
fs := c.flagSet(cmd)
err := fs.Parse(input)
require.NoError(c.t, err)
err = cmd.Action(cli.NewContext(c.cctx.App, fs, c.cctx))
require.NoError(c.t, err)
// Get the output
str := strings.TrimSpace(c.out.String())
c.out.Reset()
return str
}
func (c *mockCLIClient) flagSet(cmd *cli.Command) *flag.FlagSet {
// Apply app level flags (so we can process --api flag)
fs := &flag.FlagSet{}
for _, f := range c.cctx.App.Flags {
err := f.Apply(fs)
if err != nil {
c.t.Fatal(err)
}
}
// Apply command level flags
for _, f := range cmd.Flags {
err := f.Apply(fs)
if err != nil {
c.t.Fatal(err)
}
}
return fs
}
// waitForHeight waits for the node to reach the given chain epoch
func waitForHeight(ctx context.Context, t *testing.T, node test.TestNode, height abi.ChainEpoch) {
atHeight := make(chan struct{})
chainEvents := events.NewEvents(ctx, node)
err := chainEvents.ChainAt(func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error {
close(atHeight)
return nil
}, nil, 1, height)
if err != nil {
t.Fatal(err)
}
select {
case <-atHeight:
case <-ctx.Done():
}
}
// getPaychState gets the state of the payment channel with the given address
func getPaychState(ctx context.Context, t *testing.T, node test.TestNode, chAddr address.Address) paych.State {
act, err := node.StateGetActor(ctx, chAddr, types.EmptyTSK)
require.NoError(t, err)
store := cbor.NewCborStore(apibstore.NewAPIBlockstore(node))
var chState paych.State
err = store.Get(ctx, act.Head, &chState)
require.NoError(t, err)
return chState
}
+58
View File
@@ -0,0 +1,58 @@
package cli
import (
"io"
"net/http"
"os"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/node/repo"
manet "github.com/multiformats/go-multiaddr-net"
)
var pprofCmd = &cli.Command{
Name: "pprof",
Hidden: true,
Subcommands: []*cli.Command{
PprofGoroutines,
},
}
var PprofGoroutines = &cli.Command{
Name: "goroutines",
Usage: "Get goroutine stacks",
Action: func(cctx *cli.Context) error {
ti, ok := cctx.App.Metadata["repoType"]
if !ok {
log.Errorf("unknown repo type, are you sure you want to use GetAPI?")
ti = repo.FullNode
}
t, ok := ti.(repo.RepoType)
if !ok {
log.Errorf("repoType type does not match the type of repo.RepoType")
}
ainfo, err := GetAPIInfo(cctx, t)
if err != nil {
return xerrors.Errorf("could not get API info: %w", err)
}
_, addr, err := manet.DialArgs(ainfo.Addr)
if err != nil {
return err
}
addr = "http://" + addr + "/debug/pprof/goroutine?debug=2"
r, err := http.Get(addr)
if err != nil {
return err
}
if _, err := io.Copy(os.Stdout, r.Body); err != nil {
return err
}
return r.Body.Close()
},
}
+6 -4
View File
@@ -8,13 +8,15 @@ import (
"fmt"
"reflect"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
)
var sendCmd = &cli.Command{
@@ -154,7 +156,7 @@ var sendCmd = &cli.Command{
}
fmt.Println(sm.Cid())
} else {
sm, err := api.MpoolPushMessage(ctx, msg)
sm, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}
+75 -31
View File
@@ -52,7 +52,6 @@ var stateCmd = &cli.Command{
statePowerCmd,
stateSectorsCmd,
stateActiveSectorsCmd,
statePledgeCollateralCmd,
stateListActorsCmd,
stateListMinersCmd,
stateCircSupplyCmd,
@@ -68,6 +67,7 @@ var stateCmd = &cli.Command{
stateWaitMsgCmd,
stateSearchMsgCmd,
stateMinerInfo,
stateMarketCmd,
},
}
@@ -105,6 +105,9 @@ var stateMinerInfo = &cli.Command{
fmt.Printf("Owner:\t%s\n", mi.Owner)
fmt.Printf("Worker:\t%s\n", mi.Worker)
for i, controlAddress := range mi.ControlAddresses {
fmt.Printf("Control %d: \t%s\n", i, controlAddress)
}
fmt.Printf("PeerID:\t%s\n", mi.PeerId)
fmt.Printf("SectorSize:\t%s (%d)\n", types.SizeStr(types.NewInt(uint64(mi.SectorSize))), mi.SectorSize)
fmt.Printf("Multiaddrs: \t")
@@ -386,33 +389,6 @@ var stateReplaySetCmd = &cli.Command{
},
}
var statePledgeCollateralCmd = &cli.Command{
Name: "pledge-collateral",
Usage: "Get minimum miner pledge collateral",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
ts, err := LoadTipSet(ctx, cctx, api)
if err != nil {
return err
}
coll, err := api.StatePledgeCollateral(ctx, ts.Key())
if err != nil {
return err
}
fmt.Println(types.FIL(coll))
return nil
},
}
var stateGetDealSetCmd = &cli.Command{
Name: "get-deal",
Usage: "View on-chain deal info",
@@ -589,10 +565,30 @@ var stateGetActorCmd = &cli.Command{
return err
}
var strtype string
switch a.Code {
case builtin.AccountActorCodeID:
strtype = "account"
case builtin.MultisigActorCodeID:
strtype = "multisig"
case builtin.CronActorCodeID:
strtype = "cron"
case builtin.InitActorCodeID:
strtype = "init"
case builtin.StorageMinerActorCodeID:
strtype = "miner"
case builtin.StorageMarketActorCodeID:
strtype = "market"
case builtin.StoragePowerActorCodeID:
strtype = "power"
default:
strtype = "unknown"
}
fmt.Printf("Address:\t%s\n", addr)
fmt.Printf("Balance:\t%s\n", types.FIL(a.Balance))
fmt.Printf("Nonce:\t\t%d\n", a.Nonce)
fmt.Printf("Code:\t\t%s\n", a.Code)
fmt.Printf("Code:\t\t%s (%s)\n", a.Code, strtype)
fmt.Printf("Head:\t\t%s\n", a.Head)
return nil
@@ -858,7 +854,7 @@ var stateComputeStateCmd = &cli.Command{
var msgs []*types.Message
if cctx.Bool("apply-mpool-messages") {
pmsgs, err := api.MpoolSelect(ctx, ts.Key())
pmsgs, err := api.MpoolSelect(ctx, ts.Key(), 1)
if err != nil {
return err
}
@@ -913,6 +909,7 @@ func printInternalExecutions(prefix string, trace []types.ExecutionTrace) {
var compStateTemplate = `
<html>
<head>
<meta charset="UTF-8">
<style>
html, body { font-family: monospace; }
a:link, a:visited { color: #004; }
@@ -1542,7 +1539,54 @@ var stateCircSupplyCmd = &cli.Command{
return err
}
fmt.Println(types.FIL(circ))
fmt.Println("Circulating supply: ", types.FIL(circ.FilCirculating))
fmt.Println("Mined: ", types.FIL(circ.FilMined))
fmt.Println("Vested: ", types.FIL(circ.FilVested))
fmt.Println("Burnt: ", types.FIL(circ.FilBurnt))
fmt.Println("Locked: ", types.FIL(circ.FilLocked))
return nil
},
}
var stateMarketCmd = &cli.Command{
Name: "market",
Usage: "Inspect the storage market actor",
Subcommands: []*cli.Command{
stateMarketBalanceCmd,
},
}
var stateMarketBalanceCmd = &cli.Command{
Name: "balance",
Usage: "Get the market balance (locked and escrowed) for a given account",
Action: func(cctx *cli.Context) error {
if !cctx.Args().Present() {
return ShowHelp(cctx, fmt.Errorf("must specify address to print market balance for"))
}
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
ts, err := LoadTipSet(ctx, cctx, api)
if err != nil {
return err
}
addr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
balance, err := api.StateMarketBalance(ctx, addr, ts.Key())
fmt.Printf("Escrow: %s\n", types.FIL(balance.Escrow))
fmt.Printf("Locked: %s\n", types.FIL(balance.Locked))
return nil
},
+1 -3
View File
@@ -79,7 +79,7 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
Value: types.NewInt(1),
}
smsg, err := api.MpoolPushMessage(ctx, msg)
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return err
}
@@ -88,6 +88,4 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
return nil
}
}
return nil
}
+1 -1
View File
@@ -25,7 +25,7 @@ import (
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/ipfs/go-datastore"
+4 -4
View File
@@ -21,9 +21,9 @@ import (
"github.com/filecoin-project/go-address"
paramfetch "github.com/filecoin-project/go-paramfetch"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/sector-storage/ffiwrapper/basicfs"
"github.com/filecoin-project/sector-storage/stores"
"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/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-storage/storage"
@@ -743,5 +743,5 @@ func bps(data abi.SectorSize, d time.Duration) string {
bdata := new(big.Int).SetUint64(uint64(data))
bdata = bdata.Mul(bdata, big.NewInt(time.Second.Nanoseconds()))
bps := bdata.Div(bdata, big.NewInt(d.Nanoseconds()))
return types.SizeStr(types.BigInt{bps}) + "/s"
return types.SizeStr(types.BigInt{Int: bps}) + "/s"
}
+1 -1
View File
@@ -14,7 +14,7 @@ func main() {
if err := logging.SetLogLevel("*", "info"); err != nil {
log.Fatal(err)
}
log.Info("Starting chainwatch")
log.Info("Starting chainwatch", " v", build.UserVersion())
app := &cli.App{
Name: "lotus-chainwatch",
+28 -15
View File
@@ -8,16 +8,15 @@ import (
"golang.org/x/sync/errgroup"
"golang.org/x/xerrors"
"github.com/ipfs/go-cid"
typegen "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/types"
cw_util "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/util"
"github.com/filecoin-project/specs-actors/actors/builtin"
_init "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/chain/types"
cw_util "github.com/filecoin-project/lotus/cmd/lotus-chainwatch/util"
"github.com/ipfs/go-cid"
typegen "github.com/whyrusleeping/cbor-gen"
)
func (p *Processor) setupCommonActors() error {
@@ -125,6 +124,11 @@ func (p *Processor) HandleCommonActorsChanges(ctx context.Context, actors map[ci
return grp.Wait()
}
type UpdateAddresses struct {
Old state.AddressPair
New state.AddressPair
}
func (p Processor) storeActorAddresses(ctx context.Context, actors map[cid.Cid]ActorTips) error {
start := time.Now()
defer func() {
@@ -209,7 +213,8 @@ create temp table iam (like id_address_map excluding constraints) on commit drop
// HACK until chain watch can handle reorgs we need to update this table when ID -> PubKey mappings change
if _, err := tx.Exec(`insert into id_address_map select * from iam on conflict (id) do update set address = EXCLUDED.address`); err != nil {
return xerrors.Errorf("actor put: %w", err)
log.Warnw("Failed to update id_address_map table, this is a known issue")
return nil
}
return tx.Commit()
@@ -226,20 +231,24 @@ func (p *Processor) storeActorHeads(actors map[cid.Cid]ActorTips) error {
return err
}
if _, err := tx.Exec(`
create temp table a (like actors excluding constraints) on commit drop;
create temp table a_tmp (like actors excluding constraints) on commit drop;
`); err != nil {
return xerrors.Errorf("prep temp: %w", err)
}
stmt, err := tx.Prepare(`copy a (id, code, head, nonce, balance, stateroot) from stdin `)
stmt, err := tx.Prepare(`copy a_tmp (id, code, head, nonce, balance, stateroot) from stdin `)
if err != nil {
return err
}
for code, actTips := range actors {
actorName := code.String()
if builtin.IsBuiltinActor(code) {
actorName = builtin.ActorNameByCode(code)
}
for _, actorInfo := range actTips {
for _, a := range actorInfo {
if _, err := stmt.Exec(a.addr.String(), code.String(), a.act.Head.String(), a.act.Nonce, a.act.Balance.String(), a.stateroot.String()); err != nil {
if _, err := stmt.Exec(a.addr.String(), actorName, a.act.Head.String(), a.act.Nonce, a.act.Balance.String(), a.stateroot.String()); err != nil {
return err
}
}
@@ -250,7 +259,7 @@ func (p *Processor) storeActorHeads(actors map[cid.Cid]ActorTips) error {
return err
}
if _, err := tx.Exec(`insert into actors select * from a on conflict do nothing `); err != nil {
if _, err := tx.Exec(`insert into actors select * from a_tmp on conflict do nothing `); err != nil {
return xerrors.Errorf("actor put: %w", err)
}
@@ -268,20 +277,24 @@ func (p *Processor) storeActorStates(actors map[cid.Cid]ActorTips) error {
return err
}
if _, err := tx.Exec(`
create temp table a (like actor_states excluding constraints) on commit drop;
create temp table as_tmp (like actor_states excluding constraints) on commit drop;
`); err != nil {
return xerrors.Errorf("prep temp: %w", err)
}
stmt, err := tx.Prepare(`copy a (head, code, state) from stdin `)
stmt, err := tx.Prepare(`copy as_tmp (head, code, state) from stdin `)
if err != nil {
return err
}
for code, actTips := range actors {
actorName := code.String()
if builtin.IsBuiltinActor(code) {
actorName = builtin.ActorNameByCode(code)
}
for _, actorInfo := range actTips {
for _, a := range actorInfo {
if _, err := stmt.Exec(a.act.Head.String(), code.String(), a.state); err != nil {
if _, err := stmt.Exec(a.act.Head.String(), actorName, a.state); err != nil {
return err
}
}
@@ -292,7 +305,7 @@ func (p *Processor) storeActorStates(actors map[cid.Cid]ActorTips) error {
return err
}
if _, err := tx.Exec(`insert into actor_states select * from a on conflict do nothing `); err != nil {
if _, err := tx.Exec(`insert into actor_states select * from as_tmp on conflict do nothing `); err != nil {
return xerrors.Errorf("actor put: %w", err)
}
+22 -13
View File
@@ -88,6 +88,8 @@ create table if not exists sector_info
verified_deal_weight text not null,
initial_pledge text not null,
expected_day_reward text not null,
expected_storage_pledge text not null,
constraint sector_info_pk
primary key (miner_id, sector_id, sealed_cid)
@@ -166,11 +168,11 @@ type SectorDealEvent struct {
}
type PartitionStatus struct {
Terminated *abi.BitField
Expired *abi.BitField
Faulted *abi.BitField
InRecovery *abi.BitField
Recovered *abi.BitField
Terminated abi.BitField
Expired abi.BitField
Faulted abi.BitField
InRecovery abi.BitField
Recovered abi.BitField
}
type minerActorInfo struct {
@@ -307,6 +309,7 @@ func (p *Processor) storeMinerPreCommitInfo(ctx context.Context, miners []minerA
}
stmt, err := tx.Prepare(`copy spi (miner_id, sector_id, sealed_cid, state_root, seal_rand_epoch, expiration_epoch, precommit_deposit, precommit_epoch, deal_weight, verified_deal_weight, is_replace_capacity, replace_sector_deadline, replace_sector_partition, replace_sector_number) from STDIN`)
if err != nil {
return xerrors.Errorf("Failed to prepare miner precommit info statement: %w", err)
}
@@ -319,7 +322,7 @@ func (p *Processor) storeMinerPreCommitInfo(ctx context.Context, miners []minerA
changes, err := p.getMinerPreCommitChanges(ctx, m)
if err != nil {
if strings.Contains(err.Error(), "address not found") {
if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) {
continue
} else {
return err
@@ -431,7 +434,7 @@ func (p *Processor) storeMinerSectorInfo(ctx context.Context, miners []minerActo
return xerrors.Errorf("Failed to create temp table for sector_: %w", err)
}
stmt, err := tx.Prepare(`copy si (miner_id, sector_id, sealed_cid, state_root, activation_epoch, expiration_epoch, deal_weight, verified_deal_weight, initial_pledge) from STDIN`)
stmt, err := tx.Prepare(`copy si (miner_id, sector_id, sealed_cid, state_root, activation_epoch, expiration_epoch, deal_weight, verified_deal_weight, initial_pledge, expected_day_reward, expected_storage_pledge) from STDIN`)
if err != nil {
return xerrors.Errorf("Failed to prepare miner sector info statement: %w", err)
}
@@ -439,7 +442,7 @@ func (p *Processor) storeMinerSectorInfo(ctx context.Context, miners []minerActo
for _, m := range miners {
changes, err := p.getMinerSectorChanges(ctx, m)
if err != nil {
if strings.Contains(err.Error(), "address not found") {
if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) {
continue
} else {
return err
@@ -463,6 +466,8 @@ func (p *Processor) storeMinerSectorInfo(ctx context.Context, miners []minerActo
added.DealWeight.String(),
added.VerifiedDealWeight.String(),
added.InitialPledge.String(),
added.ExpectedDayReward.String(),
added.ExpectedStoragePledge.String(),
); err != nil {
return err
}
@@ -518,7 +523,7 @@ func (p *Processor) getMinerPartitionsDifferences(ctx context.Context, miners []
m := m
grp.Go(func() error {
if err := p.diffMinerPartitions(ctx, m, events); err != nil {
if strings.Contains(err.Error(), "address not found") {
if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) {
return nil
}
return err
@@ -794,11 +799,11 @@ func (p *Processor) diffPartition(prevPart, curPart miner.Partition) (*Partition
return nil, err
}
expired := abi.NewBitField()
expired := bitfield.New()
var bf abi.BitField
if err := terminatedEarlyArr.ForEach(&bf, func(i int64) error {
// expired = all removals - termination
expirations, err := bitfield.SubtractBitField(allRemovedSectors, &bf)
expirations, err := bitfield.SubtractBitField(allRemovedSectors, bf)
if err != nil {
return err
}
@@ -873,17 +878,21 @@ func (p *Processor) storeMinersActorInfoState(ctx context.Context, miners []mine
for _, m := range miners {
mi, err := p.node.StateMinerInfo(ctx, m.common.addr, m.common.tsKey)
if err != nil {
if strings.Contains(err.Error(), "address not found") {
if strings.Contains(err.Error(), types.ErrActorNotFound.Error()) {
continue
} else {
return err
}
}
var pid string
if mi.PeerId != nil {
pid = mi.PeerId.String()
}
if _, err := stmt.Exec(
m.common.addr.String(),
mi.Owner.String(),
mi.Worker.String(),
mi.PeerId.String(),
pid,
mi.SectorSize.ShortString(),
); err != nil {
log.Errorw("failed to store miner state", "state", m.state, "info", m.state.Info, "error", err)
+1 -2
View File
@@ -30,11 +30,10 @@ func (p *Processor) subMpool(ctx context.Context) {
loop:
for {
time.Sleep(10 * time.Millisecond)
select {
case update := <-sub:
updates = append(updates, update)
default:
case <-time.After(10 * time.Millisecond):
break loop
}
}
+135
View File
@@ -0,0 +1,135 @@
package processor
import (
"bytes"
"context"
"time"
"golang.org/x/xerrors"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/util/smoothing"
)
type powerActorInfo struct {
common actorInfo
epochSmoothingEstimate *smoothing.FilterEstimate
}
func (p *Processor) setupPower() error {
tx, err := p.db.Begin()
if err != nil {
return err
}
if _, err := tx.Exec(`
create table if not exists power_smoothing_estimates
(
state_root text not null
constraint power_smoothing_estimates_pk
primary key,
position_estimate text not null,
velocity_estimate text not null
);
`); err != nil {
return err
}
return tx.Commit()
}
func (p *Processor) HandlePowerChanges(ctx context.Context, powerTips ActorTips) error {
powerChanges, err := p.processPowerActors(ctx, powerTips)
if err != nil {
return xerrors.Errorf("Failed to process power actors: %w", err)
}
if err := p.persistPowerActors(ctx, powerChanges); err != nil {
return err
}
return nil
}
func (p *Processor) processPowerActors(ctx context.Context, powerTips ActorTips) ([]powerActorInfo, error) {
start := time.Now()
defer func() {
log.Debugw("Processed Power Actors", "duration", time.Since(start).String())
}()
var out []powerActorInfo
for tipset, powers := range powerTips {
for _, act := range powers {
var pw powerActorInfo
pw.common = act
powerActor, err := p.node.StateGetActor(ctx, builtin.StoragePowerActorAddr, tipset)
if err != nil {
return nil, xerrors.Errorf("get power state (@ %s): %w", pw.common.stateroot.String(), err)
}
powerStateRaw, err := p.node.ChainReadObj(ctx, powerActor.Head)
if err != nil {
return nil, xerrors.Errorf("read state obj (@ %s): %w", pw.common.stateroot.String(), err)
}
var powerActorState power.State
if err := powerActorState.UnmarshalCBOR(bytes.NewReader(powerStateRaw)); err != nil {
return nil, xerrors.Errorf("unmarshal state (@ %s): %w", pw.common.stateroot.String(), err)
}
pw.epochSmoothingEstimate = powerActorState.ThisEpochQAPowerSmoothed
out = append(out, pw)
}
}
return out, nil
}
func (p *Processor) persistPowerActors(ctx context.Context, powers []powerActorInfo) error {
// NB: use errgroup when there is more than a single store operation
return p.storePowerSmoothingEstimates(powers)
}
func (p *Processor) storePowerSmoothingEstimates(powers []powerActorInfo) error {
tx, err := p.db.Begin()
if err != nil {
return xerrors.Errorf("begin power_smoothing_estimates tx: %w", err)
}
if _, err := tx.Exec(`create temp table rse (like power_smoothing_estimates) on commit drop`); err != nil {
return xerrors.Errorf("prep power_smoothing_estimates: %w", err)
}
stmt, err := tx.Prepare(`copy rse (state_root, position_estimate, velocity_estimate) from stdin;`)
if err != nil {
return xerrors.Errorf("prepare tmp power_smoothing_estimates: %w", err)
}
for _, powerState := range powers {
if _, err := stmt.Exec(
powerState.common.stateroot.String(),
powerState.epochSmoothingEstimate.PositionEstimate.String(),
powerState.epochSmoothingEstimate.VelocityEstimate.String(),
); err != nil {
return xerrors.Errorf("failed to store smoothing estimate: %w", err)
}
}
if err := stmt.Close(); err != nil {
return xerrors.Errorf("close prepared power_smoothing_estimates: %w", err)
}
if _, err := tx.Exec(`insert into power_smoothing_estimates select * from rse on conflict do nothing`); err != nil {
return xerrors.Errorf("insert power_smoothing_estimates from tmp: %w", err)
}
if err := tx.Commit(); err != nil {
return xerrors.Errorf("commit power_smoothing_estimates tx: %w", err)
}
return nil
}
+18 -3
View File
@@ -88,6 +88,10 @@ func (p *Processor) setupSchemas() error {
return err
}
if err := p.setupPower(); err != nil {
return err
}
return nil
}
@@ -166,6 +170,14 @@ func (p *Processor) Start(ctx context.Context) {
return nil
})
grp.Go(func() error {
if err := p.HandlePowerChanges(ctx, actorChanges[builtin.StoragePowerActorCodeID]); err != nil {
return xerrors.Errorf("Failed to handle power actor changes: %w", err)
}
log.Info("Processes Power Changes")
return nil
})
grp.Go(func() error {
if err := p.HandleMessageChanges(ctx, toProcess); err != nil {
return xerrors.Errorf("Failed to handle message changes: %w", err)
@@ -336,16 +348,19 @@ where rnk <= $1
}
var c string
if err := rows.Scan(&c); err != nil {
return nil, xerrors.Errorf("Failed to scan unprocessed blocks: %w", err)
log.Errorf("Failed to scan unprocessed blocks: %s", err.Error())
continue
}
ci, err := cid.Parse(c)
if err != nil {
return nil, xerrors.Errorf("Failed to parse unprocessed blocks: %w", err)
log.Errorf("Failed to parse unprocessed blocks: %s", err.Error())
continue
}
bh, err := p.node.ChainGetBlock(ctx, ci)
if err != nil {
// this is a pretty serious issue.
return nil, xerrors.Errorf("Failed to get block header %s: %w", ci.String(), err)
log.Errorf("Failed to get block header %s: %s", ci.String(), err.Error())
continue
}
out[ci] = bh
if bh.Height < minBlock {
+64 -1
View File
@@ -11,6 +11,7 @@ import (
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/util/smoothing"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
@@ -24,6 +25,8 @@ type rewardActorInfo struct {
// base reward in attofil for each block found during this epoch
baseBlockReward big.Int
epochSmoothingEstimate *smoothing.FilterEstimate
}
func (p *Processor) setupRewards() error {
@@ -53,6 +56,15 @@ create table if not exists chain_power
primary key,
baseline_power text not null
);
create table if not exists reward_smoothing_estimates
(
state_root text not null
constraint reward_smoothing_estimates_pk
primary key,
position_estimate text not null,
velocity_estimate text not null
);
`); err != nil {
return err
}
@@ -63,7 +75,7 @@ create table if not exists chain_power
func (p *Processor) HandleRewardChanges(ctx context.Context, rewardTips ActorTips, nullRounds []types.TipSetKey) error {
rewardChanges, err := p.processRewardActors(ctx, rewardTips, nullRounds)
if err != nil {
log.Fatalw("Failed to process reward actors", "error", err)
return xerrors.Errorf("Failed to process reward actors: %w", err)
}
if err := p.persistRewardActors(ctx, rewardChanges); err != nil {
@@ -103,6 +115,7 @@ func (p *Processor) processRewardActors(ctx context.Context, rewardTips ActorTip
rw.baseBlockReward = rewardActorState.ThisEpochReward
rw.baselinePower = rewardActorState.ThisEpochBaselinePower
rw.epochSmoothingEstimate = rewardActorState.ThisEpochRewardSmoothed
out = append(out, rw)
}
}
@@ -162,6 +175,13 @@ func (p *Processor) persistRewardActors(ctx context.Context, rewards []rewardAct
return nil
})
grp.Go(func() error {
if err := p.storeRewardSmoothingEstimates(rewards); err != nil {
return err
}
return nil
})
return grp.Wait()
}
@@ -243,3 +263,46 @@ func (p *Processor) storeBaseBlockReward(rewards []rewardActorInfo) error {
return nil
}
func (p *Processor) storeRewardSmoothingEstimates(rewards []rewardActorInfo) error {
tx, err := p.db.Begin()
if err != nil {
return xerrors.Errorf("begin reward_smoothing_estimates tx: %w", err)
}
if _, err := tx.Exec(`create temp table rse (like reward_smoothing_estimates) on commit drop`); err != nil {
return xerrors.Errorf("prep reward_smoothing_estimates: %w", err)
}
stmt, err := tx.Prepare(`copy rse (state_root, position_estimate, velocity_estimate) from stdin;`)
if err != nil {
return xerrors.Errorf("prepare tmp reward_smoothing_estimates: %w", err)
}
for _, rewardState := range rewards {
if rewardState.epochSmoothingEstimate == nil {
continue
}
if _, err := stmt.Exec(
rewardState.common.stateroot.String(),
rewardState.epochSmoothingEstimate.PositionEstimate.String(),
rewardState.epochSmoothingEstimate.VelocityEstimate.String(),
); err != nil {
return xerrors.Errorf("failed to store smoothing estimate: %w", err)
}
}
if err := stmt.Close(); err != nil {
return xerrors.Errorf("close prepared reward_smoothing_estimates: %w", err)
}
if _, err := tx.Exec(`insert into reward_smoothing_estimates select * from rse on conflict do nothing`); err != nil {
return xerrors.Errorf("insert reward_smoothing_estimates from tmp: %w", err)
}
if err := tx.Commit(); err != nil {
return xerrors.Errorf("commit reward_smoothing_estimates tx: %w", err)
}
return nil
}
+13 -4
View File
@@ -46,7 +46,11 @@ create table if not exists chain_economics
(
parent_state_root text not null
constraint chain_economics_pk primary key,
circulating_fil text not null
circulating_fil text not null,
vested_fil text not null,
mined_fil text not null,
burnt_fil text not null,
locked_fil text not null
);
create table if not exists block_cids
@@ -235,7 +239,7 @@ func (s *Syncer) unsyncedBlocks(ctx context.Context, head *types.TipSet, since t
log.Debugw("To visit", "toVisit", toVisit.Len(), "toSync", len(toSync), "current_height", bh.Height)
}
if len(bh.Parents) == 0 {
if bh.Height == 0 {
continue
}
@@ -283,11 +287,16 @@ func (s *Syncer) storeCirculatingSupply(ctx context.Context, tipset *types.TipSe
return err
}
ceInsert := `insert into chain_economics (parent_state_root, circulating_fil) values ('%s', '%s');`
ceInsert := `insert into chain_economics (parent_state_root, circulating_fil, vested_fil, mined_fil, burnt_fil, locked_fil)` +
`values ('%s', '%s', '%s', '%s', '%s', '%s');`
if _, err := s.db.Exec(fmt.Sprintf(ceInsert,
tipset.ParentState().String(),
supply.String(),
supply.FilCirculating.String(),
supply.FilVested.String(),
supply.FilMined.String(),
supply.FilBurnt.String(),
supply.FilLocked.String(),
)); err != nil {
return xerrors.Errorf("insert circulating supply for tipset (%s): %w", tipset.Key().String(), err)
}
+6 -12
View File
@@ -21,8 +21,9 @@ import (
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
@@ -279,7 +280,7 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
Value: types.BigInt(h.sendPerRequest),
From: h.from,
To: to,
})
}, nil)
if err != nil {
w.WriteHeader(400)
_, _ = w.Write([]byte(err.Error()))
@@ -339,18 +340,11 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
return
}
collateral, err := h.api.StatePledgeCollateral(r.Context(), types.EmptyTSK)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
return
}
smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{
Value: types.BigInt(h.sendPerRequest),
From: h.from,
To: owner,
})
}, nil)
if err != nil {
w.WriteHeader(400)
w.Write([]byte("pushfunds: " + err.Error()))
@@ -380,13 +374,13 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
createStorageMinerMsg := &types.Message{
To: builtin.StoragePowerActorAddr,
From: h.from,
Value: types.BigAdd(collateral, types.BigDiv(collateral, types.NewInt(100))),
Value: big.Zero(),
Method: builtin.MethodsPower.CreateMiner,
Params: params,
}
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg)
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg, nil)
if err != nil {
w.WriteHeader(400)
w.Write([]byte(err.Error()))
+1 -1
View File
@@ -29,7 +29,7 @@
<span>When creating miner, DO NOT REFRESH THE PAGE, wait for it to load. This can take more than 5min.</span>
</div>
<div class="Index-node">
<span>If you don't have an owner/worker address, you can create it by following <a target="_blank" href="https://docs.lotu.sh/en+mining#get-started-22083">these instructions</a>.</span>
<span>If you don't have an owner/worker address, you can create it by following <a target="_blank" href="https://lotu.sh/en+mining#get-started-22083">these instructions</a>.</span>
</div>
</div>
<div class="Index-footer">

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