Compare commits

...
416 Commits
Author SHA1 Message Date
Aayush Rajasekaran 60cae87bfa Merge pull request #3635 from filecoin-project/ntwk-0.6.0
Network Upgrade: 0.6.0
2020-09-07 19:29:35 -04:00
Aayush Rajasekaran eda33f7d11 Merge pull request #3634 from filecoin-project/fix/proper-epoch-breeze
use defined constant for fork height
2020-09-07 19:20:05 -04:00
whyrusleeping d1cf445327 use defined constant for fork height 2020-09-07 16:18:22 -07:00
Aayush Rajasekaran 8e3dd11f81 Merge pull request #3633 from filecoin-project/asr/changelog
Lotus version v.0.6.0
2020-09-07 19:16:47 -04:00
Aayush Rajasekaran 80a4beace6 Lotus version v.0.6.0 2020-09-07 19:14:17 -04:00
Aayush Rajasekaran 6dc821186e Merge pull request #3632 from filecoin-project/feat/faucet-fixins
Implement faucet funds reallocation logic
2020-09-07 19:13:39 -04:00
whyrusleeping 26ec0716b9 fix lint errors 2020-09-07 16:12:44 -07:00
whyrusleeping 97af576f6a Implement faucet funds reallocation logic
use all committed sectors instead of power

give all miners who had at least a sector on friday a base amount

include genesis miner in redistribution

drop back to 1,000,000
2020-09-07 16:06:13 -07:00
Aayush Rajasekaran 0e986df7e5 Merge pull request #3627 from filecoin-project/asr/specs-update-0.9.7
Update to specs 0.9.7 and markets 0.6.0
2020-09-07 18:00:56 -04:00
Aayush Rajasekaran 45011c0fad Use latest version if no upgrade height is specified 2020-09-07 17:43:14 -04:00
Jakub Sztandera ca919dddd6 Merge pull request #3628 from filecoin-project/fix/fork-treshold
Upgrade to correct fork treshold
2020-09-07 23:17:24 +02:00
Aayush Rajasekaran 6eea5dd109 Update to specs 0.9.7 and markets 0.6.0 2020-09-07 17:11:32 -04:00
Jakub Sztandera 46ee2eeded Upgrade to correct fork treshold
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 23:07:33 +02:00
Łukasz Magiera 3741186656 Merge pull request #3625 from filecoin-project/fix/temporary-allow-negative-chains
temporarily allow negative chains
2020-09-07 23:06:15 +02:00
Jakub Sztandera 704db225d1 Update the fork point
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:45:06 +02:00
Jakub Sztandera ce0e9594df Update to go-state-types
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:44:12 +02:00
Jakub Sztandera 835b7eb6f7 Make allowNegativeChains a function
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:44:12 +02:00
vyzo 172ff846fd decouple negative chain selection from base fee lower bound validation
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:44:12 +02:00
vyzo 97fddc45d9 temporarily allow negative perfoming chains
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:44:09 +02:00
Jakub Sztandera 8a018ce3ba Merge pull request #3623 from filecoin-project/feat/base-fee-tamping
introduce logic to perform base fee tamping around the upgrade time
2020-09-07 22:43:34 +02:00
Jakub Sztandera baaec9db87 Fix testground build
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:31:39 +02:00
whyrusleeping 5d5c964d06 set correct upgrade height
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:31:39 +02:00
whyrusleeping 502d3fb335 set values for test networks
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:31:39 +02:00
whyrusleeping 5654322f54 introduce logic to perform base fee tamping around the upgrade time
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-07 22:31:36 +02:00
Łukasz Magiera bea31fdcb0 Merge pull request #3603 from filecoin-project/asr/specs-for-0.6.0
Update to specs actors v0.9.6
2020-09-07 21:54:36 +02:00
Aayush Rajasekaran 529002c2b7 Update to markets master 2020-09-07 15:48:42 -04:00
Aayush Rajasekaran 4367d74102 Update statediff and test-vectors 2020-09-07 15:48:42 -04:00
hannahhoward 04e34b8ca7 docs(apidocs): run docsgen 2020-09-07 15:48:42 -04:00
hannahhoward 5ad8e23eae feat(markets): use new api 2020-09-07 15:48:42 -04:00
hannahhoward 2db4b57013 feat(markets): upgrade markets 0.6.0 2020-09-07 15:48:42 -04:00
Aayush Rajasekaran d678fe4bfa Fix tests 2020-09-07 15:48:42 -04:00
Aayush Rajasekaran be7fb9d3df Use custom markets 2020-09-07 15:48:42 -04:00
Aayush Rajasekaran 39755a294a Update to specs v0.9.6 2020-09-07 15:48:41 -04:00
anorth a8dcea1422 Remove use of exitcode.SysErrInvalidParameters 2020-09-07 15:48:41 -04:00
Łukasz Magiera 2080458f0d Merge pull request #3518 from filecoin-project/feat/pubsub-red
integrate pubsub Random Early Drop
2020-09-07 21:42:14 +02:00
Jakub Sztandera 3398426293 Merge pull request #3592 from filecoin-project/feat/improved-publish-logic
Improve publish/republish logic
2020-09-07 21:32:52 +02:00
vyzo 2233751668 use the baseFeeLowerBound for computing repub message chains 2020-09-07 21:53:30 +03:00
Łukasz Magiera b86831356b Merge pull request #3622 from filecoin-project/revert-3615-fix/stormgr-undef-unsealed
Revert "storage manager: bail out with an error if unsealed cid is undefined"
2020-09-07 20:50:04 +02:00
Łukasz Magiera 47c59afea0 Revert "storage manager: bail out with an error if unsealed cid is undefined" 2020-09-07 20:12:29 +02:00
vyzo 41222792ed add docstring for verifyMsgBeforeAdd 2020-09-07 20:26:51 +03:00
vyzo 5659faf7f0 don't immediately publish messages that cannot be included in the next 20 blocks 2020-09-07 20:20:49 +03:00
vyzo 2e75d9c80a be explicit about republish interval, check against timecache duration 2020-09-07 20:20:49 +03:00
vyzo 0fcf8838cc improve republish logic to only republish messages that can be included in the next 20 blocks 2020-09-07 20:20:49 +03:00
Łukasz Magiera 758aae8556 Merge pull request #3586 from filecoin-project/feat/expected-height-metric
metrics: add expected height metric
2020-09-07 19:09:06 +02:00
Łukasz Magiera ffbbd968c2 Merge pull request #3602 from filecoin-project/feat/delayed-pubsub-join
only subscribe to pubsub topics once we are synced
2020-09-07 19:08:21 +02:00
vyzo 0d0dd250ee use faster decay for bootstrappers 2020-09-07 19:54:38 +03:00
vyzo e3aaedbc33 fix tests 2020-09-07 19:46:58 +03:00
vyzo 81e674ad36 subscribe early in bootstrappers and get rid of ugly test flag 2020-09-07 19:46:35 +03:00
Łukasz Magiera f6f5405a2c Fix lint 2020-09-07 18:21:45 +02:00
Łukasz Magiera 551ff6a6fb Merge pull request #3608 from filecoin-project/fix/second-argument-error-message
fix: second argument error message
2020-09-07 18:06:22 +02:00
Łukasz Magiera d3e5092b43 Merge pull request #3611 from filecoin-project/fix/tscache-nil-best
chain events: if cache best() is nil, return chain head
2020-09-07 18:05:34 +02:00
Łukasz Magiera 3fe8cdece3 Merge pull request #3615 from filecoin-project/fix/stormgr-undef-unsealed
storage manager: bail out with an error if unsealed cid is undefined
2020-09-07 18:02:44 +02:00
Łukasz Magiera 69f203a718 Merge pull request #3606 from filecoin-project/rm-chain-validation
decommission chain-validation.
2020-09-07 18:00:08 +02:00
Dirk McCormick a97f978cad fix: storage manager - dont fail on successful read piece 2020-09-07 16:14:19 +02:00
Dirk McCormick 07a4553e6e fix: storage manager - bail out with an error if unsealed cid is undefined 2020-09-07 16:04:12 +02:00
vyzo e33798ff90 rename variable for better semantics 2020-09-07 15:58:05 +03:00
vyzo d9faff19a5 fix tests 2020-09-07 15:55:53 +03:00
vyzo 4f0ab4f226 remove notifee after subscribing 2020-09-07 15:55:53 +03:00
vyzo 05740e0f64 silence linter for unnecessary conversion 2020-09-07 15:55:53 +03:00
vyzo 666dc65b8e only subscribed to pubsub topics once we are synced 2020-09-07 15:55:53 +03:00
Dirk McCormick 76a1b3286b fix: if cache best is nil, return chain head 2020-09-07 14:43:06 +02:00
Alan Shaw 9d9d2a2a98 fix: second argument error message
Second argument should be a pointer, not runtime.
2020-09-07 12:29:40 +01:00
vyzo 219c8b927d go mod tidy 2020-09-07 13:46:23 +03:00
vyzo c616958557 specify topic delivery weights, with priority for blocks 2020-09-07 13:40:48 +03:00
vyzo 453ab95e54 enable pubsub RED 2020-09-07 13:40:48 +03:00
vyzo 7fdab46729 update go-libp2p-pubsub@master 2020-09-07 13:40:42 +03:00
Raúl Kripalani 798061506e decommission chain validation. 2020-09-07 11:34:36 +01:00
Aayush Rajasekaran 0ad0d4ea11 Merge pull request #3579 from filecoin-project/fix/mpool-basefee-check
add defensive check for minimum GasFeeCap for inclusion within the next 20 blocks
2020-09-07 03:03:35 -04:00
Travis Person f7b52d16f5 metrics: add expected height metric 2020-09-07 02:57:12 +00:00
vyzo e24a29b146 fix tests that touch the mpool; mock block must have a ParentBaseFee 2020-09-06 11:55:43 +03:00
vyzo ffb2640736 use faster lookup for base fee 2020-09-06 11:55:43 +03:00
vyzo f9492691a6 don't check baseFee lower bound for local messages 2020-09-06 11:55:43 +03:00
vyzo 1c0e6d76f0 add defensive check for minimum GasFeeCap for inclusion within the next 20 blocks 2020-09-06 11:55:43 +03:00
Łukasz Magiera 6bdd433570 Merge pull request #3538 from filecoin-project/steb/safe-exports
Robustify state manager against holes in actor method numbers
2020-09-05 21:58:03 +02:00
Łukasz Magiera c767e5ebed Merge pull request #3547 from filecoin-project/feat/paych-status-addr
paych: get available funds by address or by from/to
2020-09-05 21:55:08 +02:00
Łukasz Magiera 4718efab9b docsgen 2020-09-05 21:51:30 +02:00
Łukasz Magiera 145493388a Merge pull request #3553 from filecoin-project/fix/panic-in-expired-slashed
Fix panic in OnDealExpiredSlashed
2020-09-05 21:49:54 +02:00
Łukasz Magiera 16bd0d134e Merge pull request #3556 from filecoin-project/fix/pubsub-reduce-gossipfactor
adjust gossipsub gossip factor
2020-09-05 21:49:32 +02:00
Łukasz Magiera f58cbc2594 Merge pull request #3557 from filecoin-project/fix/mpool-repub-negative
republish messages even if the chains have negative performance
2020-09-05 21:48:39 +02:00
Łukasz Magiera 1e190e462a Merge pull request #3562 from filecoin-project/fix/mpool-log-spam
reduce mpool add failure log spam
2020-09-05 21:47:29 +02:00
Łukasz Magiera 70da2b7b4d Merge pull request #3568 from filecoin-project/feat/lotus-shed-math
lotus-shed: add math command
2020-09-05 21:47:06 +02:00
Łukasz Magiera 2297c58ab6 Merge pull request #3578 from filecoin-project/misc/debug-info-premium
Add additional info about gas premium
2020-09-05 21:45:57 +02:00
Łukasz Magiera 5e97e29f95 Merge pull request #3580 from filecoin-project/fix/mpool-selection-bug
fix selection bug; priority messages were not included if other chains were negative
2020-09-05 21:44:03 +02:00
vyzo 5037282b98 add test for priority selection with negative chains 2020-09-05 22:15:18 +03:00
vyzo 0b3685e529 fix selection bug; priority messages were not included if other's chains were negative 2020-09-05 21:30:02 +03:00
Jakub Sztandera 2adb80729b Add additional info about gas premium
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-05 15:17:55 +02:00
Łukasz Magiera c074c8d0ca Merge pull request #3570 from filecoin-project/feat/lotus-pcr-current-tipset
lotus-pcr: use current tipset during refund
2020-09-05 05:29:59 +02:00
Łukasz Magiera 2b62573b65 Merge pull request #3571 from shepf/master
Batch replacement,update lotus-storage-miner to lotus-miner.
2020-09-05 05:29:28 +02:00
shepf 16fd12024e Batch replacement,update lotus-storage-miner to lotus-miner. 2020-09-05 10:40:53 +08:00
Travis Person bf3466f3cb lotus-pcr: use current tipset during refund
Using the tipset which is being processed might lead to incorrect gas
estimations or balance checking for the wallet.
2020-09-05 02:38:24 +00:00
Travis Person eebd2efcbf lotus-shed: add math command 2020-09-05 00:50:56 +00:00
Jakub Sztandera c573310c77 Merge pull request #3565 from filecoin-project/feat/lotus-pcr-aggregate-tipsets
lotus-pcr: add tipset aggregation
2020-09-05 00:43:27 +02:00
Travis Person d6691fe9d8 lotus-pcr: add tipset aggregation 2020-09-04 22:28:13 +00:00
vyzo 275f071b12 reduce mpool add failure log spam 2020-09-05 00:28:13 +03:00
vyzo ad8d550d73 remove unused ts argument from Trim, replace it with allowNegative specifier 2020-09-04 22:32:30 +03:00
Steven Allen fceeaf42ca Robustify state manager against holes in actor method numbers
Also, don't simply assume that the field order matches the method numbers in
`builtin.Method*` structs.
2020-09-04 12:26:55 -07:00
Steven Allen 30fdff17b5 Skip nil exports
The actors may skip previously used but no longer defined method numbers.
2020-09-04 12:26:55 -07:00
vyzo 6d53862142 republish messages even if the chains have negative performance 2020-09-04 22:16:10 +03:00
vyzo 1c27a0c1cf adjust gossipsub gossip factor 2020-09-04 22:04:48 +03:00
hannahhoward 5ef753bfa8 fix(markets): check for nil tipset
check for nil tipset when check func is called to avoid panic
2020-09-04 10:04:50 -07:00
Łukasz Magiera 52ce80f2b4 Merge pull request #3551 from filecoin-project/fix/paych-cli-tests
paych: fix broken paych tests
2020-09-04 18:32:26 +02:00
Jakub Sztandera d8a790a13c Merge pull request #3552 from filecoin-project/fix/fee-cap-premium
Fix GasPremium capping logic
2020-09-04 18:29:33 +02:00
Jakub Sztandera 20801263ec Fix paych tests
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-04 18:13:09 +02:00
Jakub Sztandera 4cf52ea025 Add 0.1FIL cap too DefaultMessageSendSpec
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-04 15:52:50 +02:00
Dirk McCormick de132d39ec fix: broken paych tests 2020-09-04 15:48:13 +02:00
Jakub Sztandera 114c0ea85c Fix GasPremium capping logic
Cap it just to FeeCap, there is no reason to cap it proportionally

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-04 15:42:12 +02:00
Dirk McCormick 51ef39592f feat: paych - get available funds by address or by from/to 2020-09-04 13:44:09 +02:00
Łukasz Magiera a081dc7674 Merge pull request #3520 from filecoin-project/feat/paych-cli-add-funds
paych: rename CLI command from "paych get" to "paych add-funds"
2020-09-04 04:21:54 +02:00
Łukasz Magiera 924fd82d7f Merge pull request #3523 from filecoin-project/feat/paych-cli-status
paych: Create `lotus paych status` command
2020-09-04 04:20:45 +02:00
Łukasz Magiera 2177fd59ef Merge pull request #3521 from filecoin-project/conformance/tipset-actor-address
conformance: various changes
2020-09-04 04:18:41 +02:00
Łukasz Magiera d81feb05d1 Merge pull request #3527 from filecoin-project/feat/watch-option-miner-storage-deals-list
Add watch option to storage-deals list
2020-09-04 04:13:01 +02:00
Łukasz Magiera 0a620514b7 Merge pull request #3526 from filecoin-project/fix/chainwatch/no-panic-during-processing
Stop SyncIncomingBlocks from leaking into chainwatch processing; No panics during processing
2020-09-04 03:55:59 +02:00
Łukasz Magiera e52232d85f Merge pull request #3535 from filecoin-project/steb/robust-method-lookup
[cli/state] Robust actor lookup
2020-09-04 03:52:43 +02:00
Łukasz Magiera 4cdd81ec86 Merge pull request #3534 from filecoin-project/feat/netpeers-agent-version
Add agent flag to net peers
2020-09-04 02:50:04 +02:00
Steven Allen 6e711ed739 [cli/state] Robust actor name lookup 2020-09-03 17:22:18 -07:00
Steven Allen 8778787091 [cli/state] Robust actor lookup
This probably isn't critical, but I noticed it, so I fixed it.
2020-09-03 17:19:05 -07:00
Łukasz Magiera ce8bcf7932 Add agent flag to net peers 2020-09-04 02:00:53 +02:00
Mike Greenberg abaef98fd8 fix(chainwatch): Stop SyncIncomingBlocks from leaking into processing
The SQL query was anchoring data from the `blocks` table, which includes
all blocks seen from SyncIncomingBlocks which isn't always available in
the chainstate via the API. In order to prevent these blocks from
leaking into normal processing (which errors anyway), the join was
changed to allow `blocks_synced` to anchor the set as we originally
intended.
2020-09-03 19:15:25 -04:00
Mike Greenberg ddc5e57d4d fix(chainwatch): Error instead of panic during processing 2020-09-03 19:15:19 -04:00
Raúl Kripalani c723554d2e upgrade test-vectors deps. 2020-09-03 23:44:21 +01:00
Whyrusleeping 021f4a881c Merge pull request #3448 from filecoin-project/feat/paych-get-avail-funds
paych: Add PaychAvailableFunds API method
2020-09-03 15:26:25 -07:00
Alan Shaw ada5e6ae68 refactor: remove puppet actor from conformance tests
The puppet actor has been subsumed into the chaos actor and test-vector tests no longer use it.
2020-09-03 23:19:53 +01:00
Raúl Kripalani 8e7a8d8c97 conformance: tipset-class driver: allow actor msgs, dummy-sign secp msgs. 2020-09-03 22:54:19 +01:00
Łukasz Magiera 9151f8b492 Merge pull request #3533 from filecoin-project/feat/fast-export
Make chain export ~1000x times faster
2020-09-03 22:47:20 +02:00
Łukasz Magiera 86cb865fdd Make chain export ~1000x times faster 2020-09-03 21:56:35 +02:00
Aayush Rajasekaran 38cb2601d7 Merge pull request #3531 from filecoin-project/asr/changelog
Lotus version 0.5.10
2020-09-03 15:03:00 -04:00
Aayush Rajasekaran 94173c273a Lotus version 0.9.10 2020-09-03 14:57:58 -04:00
Łukasz Magiera 01449e486c Merge pull request #3528 from filecoin-project/fix/sele-gas-reward
Fix calculation of GasReward in messagepool
2020-09-03 20:41:28 +02:00
Jakub Sztandera 8111b227c4 Appease the linter
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-03 20:19:01 +02:00
Jakub Sztandera 8bb471bccd Add getGasPerf test
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-03 20:19:01 +02:00
Jakub Sztandera 5074b526d0 Fix calculation of GasReward in messagepool
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-03 19:36:03 +02:00
Ingar Shu 1608cd2d53 Add watch option to "lotus-miner storage-deals list" 2020-09-03 10:14:30 -07:00
Łukasz Magiera a123ef6fce Merge pull request #3525 from filecoin-project/asr/changelog
Lotus version v0.5.9
2020-09-03 19:11:43 +02:00
Aayush Rajasekaran 23ec780a13 Lotus version v0.5.9 2020-09-03 12:48:20 -04:00
Aayush Rajasekaran 5569f96885 Merge pull request #3450 from filecoin-project/feat/mpool-nonce-gaps
track expected nonce in mpool, ignore messages with large nonce gaps
2020-09-03 12:27:32 -04:00
Dirk McCormick 930be3d0e5 feat: paych CLI - lotus paych status <from> <to> 2020-09-03 18:11:11 +02:00
Dirk McCormick f84b1d0de9 feat: paych - rename CLI command from "paych get" to "paych add-funds" 2020-09-03 15:45:53 +02:00
Dirk McCormick 8423325a6e refactor: paych - use channel accessor from/to instead of passing them around as params 2020-09-03 15:31:49 +02:00
Łukasz Magiera 97273655dc Merge pull request #3502 from filecoin-project/area/ux-3388-sync-wait-target-height
Added target height to sync wait
2020-09-03 14:49:30 +02:00
Łukasz Magiera 10acc04ba5 Merge pull request #3497 from filecoin-project/feat/bandwidth-tracking
add apis and command to inspect bandwidth usage
2020-09-03 14:37:54 +02:00
vyzo d20b6adfd2 refuse to add duplicates in the mpool 2020-09-03 15:28:44 +03:00
vyzo a4c650316a fix test 2020-09-03 15:28:44 +03:00
vyzo 28f57667f0 cap MaxNonceGap to 4, add delay between batch messages during republish 2020-09-03 15:28:44 +03:00
vyzo f53d2e3a46 cap MaxNonceGap to 16 2020-09-03 15:28:44 +03:00
vyzo 7b76aa2078 warn when adding a nonce-gapped message to the mpool 2020-09-03 15:28:44 +03:00
vyzo d76a3b87c5 ignore messages with large nonce gaps 2020-09-03 15:28:44 +03:00
vyzo da6d384300 fix tests 2020-09-03 15:28:44 +03:00
vyzo 4c489d18a2 track expected nonce in mpool, refuse messages with large gaps 2020-09-03 15:28:44 +03:00
Łukasz Magiera 9785f14df8 Merge pull request #3516 from filecoin-project/feat/cap-fee
Cap fees to reasonable level by default
2020-09-03 14:10:58 +02:00
Jakub Sztandera d35b273dbf Cap fees to reasonable level by default
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-03 13:49:50 +02:00
Jakub Sztandera 13c828f112 Merge pull request #3514 from filecoin-project/ci/disable-codecov-annotations
Disable codecov annotations
2020-09-03 13:47:33 +02:00
Łukasz Magiera ea6ee8e899 Disable codecov annotations 2020-09-03 13:39:16 +02:00
Dirk McCormick 1d3a21f6c8 docs: paych - correct comments on store fields 2020-09-03 08:22:40 +02:00
Dirk McCormick 3daa0b5e63 fix: paych - clarify behaviour of current available funds for non-existent channel 2020-09-03 08:20:08 +02:00
Aayush Rajasekaran 5426ef0b46 Merge pull request #3501 from filecoin-project/asr/changelog
Lotus version 0.5.8
2020-09-02 20:41:22 -04:00
jennijuju 860a6a231d 3388: Added target height to sync wait 2020-09-02 19:48:24 -04:00
whyrusleeping da7fc8dbb3 further appeasement 2020-09-02 16:42:55 -07:00
Aayush Rajasekaran f03f4775fc Lotus version 0.5.8 2020-09-02 19:42:19 -04:00
whyrusleeping 0e39d62c9d Appease the CI overlords 2020-09-02 16:31:41 -07:00
whyrusleeping d196e4a8df docs, mod tidy 2020-09-02 15:45:57 -07:00
whyrusleeping a59dadccc9 add apis and command to inspect bandwidth usage 2020-09-02 15:25:53 -07:00
Łukasz Magiera 05db79ee35 Merge pull request #3496 from filecoin-project/feat/update-markets-0.5.9
Upgrade markets to v0.5.9
2020-09-02 23:47:18 +02:00
Łukasz Magiera d552803f56 Merge pull request #3494 from filecoin-project/feat/faster-blocksync-serving
load fewer messages from disk when serving blocksync requests
2020-09-02 22:43:12 +02:00
hannahhoward d2a10413a1 feat(markets): upgrade to v0.5.9 2020-09-02 13:19:39 -07:00
Lucas MolasandŁukasz Magiera ca8f5861fe Update chain/blocksync/server.go
Co-authored-by: Łukasz Magiera <magik6k@users.noreply.github.com>
2020-09-02 17:07:39 -03:00
Łukasz Magiera 7536744dcf Merge pull request #3495 from filecoin-project/revert-3464-feat/blst-adx
Revert "adx blst"
2020-09-02 21:16:05 +02:00
Łukasz Magiera 8ba0385b3a Revert "adx blst" 2020-09-02 21:05:38 +02:00
whyrusleeping 9a5542100a load fewer messages from disk when serving blocksync requests 2020-09-02 11:43:05 -07:00
Łukasz Magiera b774563ec3 Merge pull request #3492 from filecoin-project/fix/readpiece-panic
ffiwrapper: Fix ReadPiece panic
2020-09-02 18:59:22 +02:00
Łukasz Magiera ca7aa69597 ffiwrapper: More correct error check on openPartialFile 2020-09-02 18:45:07 +02:00
Łukasz Magiera 5aeabe39b5 Merge pull request #3456 from filecoin-project/misc/account-for-premium
Account for GasPremium in GasEstimateFeeCap
2020-09-02 18:20:32 +02:00
Łukasz Magiera 5f79ff340d Merge pull request #3489 from filecoin-project/fix/sched-deadlocks
sealing sched: Fix deadlock between worker.wndLk / workersLk
2020-09-02 18:03:18 +02:00
Łukasz Magiera 5a2b439773 sched: Fix tests 2020-09-02 17:37:19 +02:00
Łukasz Magiera cfbbcd420f Merge pull request #3463 from filecoin-project/feat/chain-state-export
allow exporting a number of recent chain state trees
2020-09-02 17:21:14 +02:00
Jakub Sztandera 59f765f7be Rename to import-snapshot, require more than finality for state export
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-02 17:15:36 +02:00
Łukasz Magiera 528e39fcb3 docsgen, fix snapshot flag name 2020-09-02 17:15:10 +02:00
whyrusleeping 2b16e69e90 allow snapshot importing 2020-09-02 17:15:10 +02:00
whyrusleeping 09ebd1a557 allow exporting a number of recent chain state trees 2020-09-02 17:15:10 +02:00
Łukasz Magiera edc2a28f1d Merge pull request #3485 from filecoin-project/tipset-vector
tipset-class test vector driver (take 2)
2020-09-02 17:08:26 +02:00
Łukasz Magiera 7fe8580da5 sealing sched: Fix deadlock between worker.wndLk / workersLk 2020-09-02 17:06:48 +02:00
Raúl Kripalani 7cc9c83ab8 upgrade test-vectors. 2020-09-02 14:12:27 +01:00
Raúl Kripalani 0962292f92 conformance: add driver for tipset-class vectors. 2020-09-02 14:09:12 +01:00
Łukasz Magiera b7f2487c4f Merge pull request #3457 from filecoin-project/fix/disable-badger-gc
Disable GC on chain badger datastore
2020-09-02 15:02:52 +02:00
Łukasz Magiera db86647e3a Merge pull request #3458 from austinabell/rand/rmheight
Remove height from chain rand
2020-09-02 14:59:29 +02:00
Łukasz Magiera 7415627d95 Merge pull request #3483 from filecoin-project/revert-3449-tipset-vector
Revert "conformance: add driver for tipset-class vectors."
2020-09-02 14:51:11 +02:00
Łukasz Magiera fa6bae988e Revert "conformance: add driver for tipset-class vectors." 2020-09-02 14:49:55 +02:00
Dirk McCormick 2c98bf0cc7 feat: PaychAvailableFunds API method 2020-09-02 14:31:32 +02:00
Łukasz Magiera 351313523c Merge pull request #3470 from filecoin-project/feat/toggle-message-processing
lotus-pcr: add toggle for message processing
2020-09-02 14:26:40 +02:00
Łukasz Magiera 80ecbeddbb Merge pull request #3464 from filecoin-project/feat/blst-adx
adx blst
2020-09-02 14:25:00 +02:00
Łukasz Magiera 8222f803d5 Merge pull request #3476 from filecoin-project/asr/advance-block
Check error in advance-block
2020-09-02 13:46:34 +02:00
Łukasz Magiera d5b33671c2 Merge pull request #3481 from filecoin-project/misc/consensus-label
Add Impact Consensus label
2020-09-02 13:43:23 +02:00
Łukasz Magiera e86749dfe2 Merge pull request #3449 from filecoin-project/tipset-vector
conformance: add driver for tipset-class vectors.
2020-09-02 13:42:42 +02:00
Raúl Kripalani ec5903ca19 fix lint error. 2020-09-02 12:28:55 +01:00
Jakub Sztandera b5dcb5964a Add Impact Consensus label 2020-09-02 13:07:56 +02:00
Aayush Rajasekaran 8417f516e5 Check error in advance-block 2020-09-02 02:41:12 -04:00
Travis Person 9532441ed4 lotus-pcr: add toggle for message processing 2020-09-02 03:50:16 +00:00
Travis Person 630dfb9b55 adx blst 2020-09-02 01:04:56 +00:00
Łukasz Magiera f31dc791e4 Merge pull request #3455 from filecoin-project/deps/update-pubsub
update go-libp2p-pubsub@master
2020-09-01 22:13:25 +02:00
austinabell ba881eb4cf Remove height from chain rand 2020-09-01 15:48:16 -04:00
Raúl Kripalani ad5793e446 update test-vectors commit. 2020-09-01 20:01:41 +01:00
Jakub Sztandera 997d49b63f Disable GC on chain badger datastore
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-01 20:39:58 +02:00
Jakub Sztandera 72fb6afae2 Account for GasPremium in GasEstimateFeeCap
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-09-01 20:35:29 +02:00
vyzo f9df806f15 update go-libp2p-pubsub@master 2020-09-01 20:46:12 +03:00
Raúl Kripalani 01737ef1cc upgrade test-vectors deps. 2020-09-01 17:00:18 +01:00
Raúl Kripalani 3321f36b51 update test-vectors commit. 2020-09-01 16:35:26 +01:00
Raúl Kripalani 64bdd620ac conformance: add driver for tipset-class vectors. 2020-09-01 15:35:19 +01:00
Star.LI 82f5984de1 fix crash - segment fault when partialFile.Allocated() is invoked.
When openPartialFile is invoked, more errors than "existed error" are
returned. If only existing error is checked, the allocated field of
partialFile may be nil.

Signed-off-by: Star.LI <star@trapdoortech.com>
2020-09-01 11:41:26 +02:00
Łukasz Magiera b8bbbf3ea3 Merge pull request #3436 from mitchwagner/patch-2
fix: referenced filename
2020-09-01 11:09:26 +02:00
Łukasz Magiera 247b5205fb Merge pull request #3442 from filecoin-project/fix/chainwatch/logging-sync-blocks
Some more Chainwatch improvements
2020-09-01 10:57:55 +02:00
Mike Greenberg 2b83089da8 fix(chainwatch): Add important documentation 2020-08-31 22:55:11 -04:00
Mike Greenberg 7290431cb0 fix(chainwatch): Restore IncomingBlockSync listening 2020-08-31 22:46:28 -04:00
Mike Greenberg 95a75daf9f fix(chainwatch): Remove useless logging 2020-08-31 22:32:34 -04:00
Mike Greenberg 80ed6b8c25 fix(chainwatch): Process chain waitout waiting for update via ChainNotify 2020-08-31 22:31:25 -04:00
Aayush Rajasekaran 49d64f7f7e Merge pull request #3438 from filecoin-project/asr/changelog
Lotus version 0.5.7
2020-08-31 20:04:19 -04:00
Aayush Rajasekaran f09f38085e Lotus version 0.5.7 2020-08-31 20:03:38 -04:00
Aayush Rajasekaran 04a9822573 Merge pull request #3428 from filecoin-project/fix/estim-gas-price-one-msg
Fix GasEstimateGasPremium when there is only one message on chain
2020-08-31 20:01:02 -04:00
Mitch Wagner 5848877734 fix: referenced filename 2020-08-31 19:29:43 -04:00
Aayush Rajasekaran 93814cc85a Merge pull request #3392 from filecoin-project/fix/mpool-priority-selection
Tweak priority selection to not select negative perfoming chains
2020-08-31 19:22:12 -04:00
Aayush Rajasekaran 4f30311971 Merge pull request #3430 from filecoin-project/misc/bitswap-close-ctx
Don't use context to close bitswap
2020-08-31 19:21:06 -04:00
Aayush Rajasekaran cfe5134375 Use Sign() to check zero-equality 2020-08-31 18:53:14 -04:00
Łukasz Magiera 219d3c9f18 Merge pull request #3425 from filecoin-project/feat/better-worker-selection
Improve worker selection a bit
2020-08-31 23:11:25 +02:00
Łukasz Magiera 9110776a01 Merge pull request #3424 from filecoin-project/fix/move-unsealed
storage: Correcty move unsealed sectors in FinalizeSector
2020-08-31 23:09:36 +02:00
Jakub Sztandera 625c6951bb Don't use context to close bitswap
Use just the Close

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-31 19:24:04 +02:00
Jakub Sztandera 56235aee90 Fix GasEstimateGasPremium when there is only one message on chain
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-31 18:12:06 +02:00
Łukasz Magiera e14c80360d sealing sched: Factor worker queues into utilization calc 2020-08-31 13:41:34 +02:00
Łukasz Magiera 98d51d3d80 storage: Correcty move unsealed sectors in FinalizeSector 2020-08-31 12:45:57 +02:00
Łukasz Magiera 4f45c623a5 Merge pull request #3401 from filecoin-project/asr/unsealed-infos
Rebuild unsealed infos on miner restart
2020-08-31 10:35:33 +02:00
Łukasz Magiera c96613a499 Merge pull request #3405 from filecoin-project/feat/worker-storage-cli
worker: Cli to attach storage paths
2020-08-31 10:09:20 +02:00
Łukasz Magiera e1e01524e7 Merge pull request #3421 from IPFSMain-Official/master
remove the unnecessary err check
2020-08-31 10:08:36 +02:00
刘林欣 0926f95979 remove the unnecessary err check 2020-08-31 15:11:45 +08:00
David Dias a4decaa188 docs: add label for markets 2020-08-31 08:04:37 +01:00
Aayush Rajasekaran 27f7d3a658 Rebuild unsealed infos on miner restart 2020-08-30 18:01:07 -04:00
Łukasz Magiera 0e6ff668eb worker: Cli to attach storage paths 2020-08-30 20:33:02 +02:00
vyzo fba3ed7b4d update documentation about priority addresses 2020-08-29 15:56:31 +03:00
vyzo 648130eec5 don't include negative performing chains in priority message selection 2020-08-29 15:55:19 +03:00
Aayush Rajasekaran 606a58bc6b Lotus version 0.5.6 2020-08-29 00:56:24 -04:00
Aayush Rajasekaran 09a645e455 Merge pull request #3387 from filecoin-project/asr/import-fix
Fix chain import
2020-08-29 00:55:54 -04:00
Łukasz Magiera d972a47c84 Bump version to 0.5.6 2020-08-29 06:48:28 +02:00
Łukasz Magiera 494c774303 Merge pull request #3389 from filecoin-project/fix/sched-compact-panic
sched: Fix panic in workerCompactWindows
2020-08-29 06:47:12 +02:00
Łukasz Magiera 28ac2fce61 sched: Fix panic in workerCompactWindows 2020-08-29 06:41:19 +02:00
Aayush Rajasekaran 5095e6f07b Fix chain import 2020-08-28 22:15:43 -04:00
Łukasz Magiera 9a3b2abbab Merge pull request #3383 from filecoin-project/asr/changelog
Lotus version 0.5.5
2020-08-29 03:52:00 +02:00
Aayush Rajasekaran 4e5b11b1d5 Lotus version 0.5.5 2020-08-28 21:49:56 -04:00
Łukasz Magiera 7eb2710e67 Merge pull request #3384 from filecoin-project/feat/markets-update-0.5.8
Update to markets v0.5.8
2020-08-29 03:46:38 +02:00
hannahhoward 0a36db06ed feat(markets): update to markets v0.5.8 2020-08-28 18:03:27 -07:00
Łukasz Magiera e86f90fe8d Merge pull request #3380 from filecoin-project/fix/chainwatch/perf
perf(chainwatch): parallelize miner processing
2020-08-29 02:51:46 +02:00
Łukasz Magiera 953effcc43 Merge pull request #3350 from filecoin-project/fix/some-fsm-issues
Fix some fsm issues
2020-08-29 02:16:59 +02:00
Łukasz Magiera a62e44c4e5 Fix lint 2020-08-29 02:13:38 +02:00
Łukasz Magiera 84a632787c Merge pull request #3313 from filecoin-project/feat/mpool-balance-tracking
Message Pool Rudimentary Spam Protection Measures
2020-08-28 22:35:30 +02:00
Łukasz Magiera 16f0daab90 Merge pull request #3379 from filecoin-project/feat/add-list-deals-watch-option
Add watch option to list-deals
2020-08-28 22:33:48 +02:00
Łukasz Magiera 3149390b3b Merge pull request #3381 from filecoin-project/fix/dynamic-chain-sync-window
dynamic chain sync window
2020-08-28 22:31:21 +02:00
frrist 0185090cbb perf(chainwatch): parallelize miner processing 2020-08-28 13:26:11 -07:00
vyzo 806f7dd15f windowSize should not exceed blocksync.MaxRequestLength 2020-08-28 23:18:06 +03:00
Łukasz Magiera 013ebc617e docsgen 2020-08-28 22:17:35 +02:00
vyzo 63a60cdd75 be more conservative in increasing the window size, check that we actually had more messages 2020-08-28 23:09:48 +03:00
Łukasz Magiera 4bcc71c68f Merge pull request #3197 from filecoin-project/fix/paych-spendable-submit-voucher
paych: fix issue where `voucher spendable` fails for submitted vouchers
2020-08-28 22:05:04 +02:00
Łukasz Magiera 7f1374e058 docsgen 2020-08-28 22:03:09 +02:00
vyzo 3935fd77ac remember syncer windowSize 2020-08-28 22:52:40 +03:00
Łukasz Magiera 9d0c8ae3dd sectorstorage: update sched tests for new logic 2020-08-28 21:38:21 +02:00
vyzo 4e7fd5b6d7 sync: increase window size when successful fetching messages 2020-08-28 22:03:06 +03:00
Ingar Shu a4ded8c2b9 Add watch option to list-deals 2020-08-28 10:40:27 -07:00
Łukasz Magiera 4a75e1e4b4 sectorstorage: Don't require tasks within a window to run in order 2020-08-28 19:38:55 +02:00
Łukasz Magiera 11b11e416b sectorstorage: Compact assigned windows 2020-08-28 18:26:38 +02:00
vyzo 1f660c9e04 sync: half window size and retry when fetching messages fails 2020-08-28 18:45:20 +03:00
Łukasz Magiera 20ffce5c0d Merge remote-tracking branch 'origin/master' into fix/some-fsm-issues 2020-08-28 16:47:25 +02:00
Łukasz Magiera a7ef61279c Merge pull request #3374 from IPFSMain-Official/fix-packing-sector
ignore resend SectorStartPacking event. and fix StartPacking's unsealedInfoMap lock
2020-08-28 16:37:16 +02:00
Łukasz Magiera 5ee85dc263 sectorstorage: Fix tests 2020-08-28 16:33:41 +02:00
刘林欣 93dc33687a ignore resend SectorStartPacking event, and unsealedInfoMap lock 2020-08-28 19:04:23 +08:00
Łukasz Magiera 932ab61c2d Merge pull request #3275 from filecoin-project/fix/chainwatch/sync
fix(chainwatch): use height to determine unsynced blocks and fix deadlock in sector deal table
2020-08-28 12:16:00 +02:00
Łukasz Magiera 1d9b1f4aab Merge pull request #3311 from filecoin-project/daviddias-patch-1
docs: removed non used packages from the list
2020-08-28 12:08:20 +02:00
Łukasz Magiera 7aed16ce4c Merge pull request #3372 from filecoin-project/fix/distinguish-local-msg-errors
distinguish local message validation failures from remote
2020-08-28 12:07:52 +02:00
Łukasz Magiera 9f4506bda5 metrics: gofmt 2020-08-28 11:51:51 +02:00
Łukasz Magiera fa6f9f4ae0 Merge pull request #3367 from filecoin-project/feat/chainwatch/add-power-reward-metrics
feat(chainwatch): Add more complete power and reward metrics
2020-08-28 11:49:22 +02:00
Łukasz Magiera 78ff5e270c Merge pull request #3369 from filecoin-project/asr/advance-block
Use beacon entries in advance-block
2020-08-28 11:46:34 +02:00
Łukasz Magiera 6d1682a27e storagefsm: wire up RecoverDealIDs fully 2020-08-28 11:44:15 +02:00
lanzafame 64768f093d rename local recordFailure func 2020-08-28 17:15:11 +10:00
lanzafame a24db6c584 refactor block validate recordFailure func 2020-08-28 17:11:59 +10:00
lanzafame 050a0ec5e4 further reduce code duplication 2020-08-28 17:01:45 +10:00
lanzafame 0254e4b365 reduce code duplication 2020-08-28 16:53:59 +10:00
lanzafame 3ebe4ebb3d Add views for pubsub metrics 2020-08-28 16:25:50 +10:00
lanzafame 094baf8aa9 distinguish local message validation failures from remote 2020-08-28 16:11:24 +10:00
Mike Greenberg ff5ac51c54 fix(chainwatch): Upsert on chain_economics
This table may get multiple updates depending on how many blocks get
added into a tipset. Each new block affects the tipset state, but the
parent state root will remain the same. This allows the very latest
value to be applied.
2020-08-27 23:21:20 -04:00
Mike Greenberg 9e130af9e7 feat(chainwatch): Add more complete power and reward metrics 2020-08-27 23:00:12 -04:00
Aayush Rajasekaran bed7158212 Use beacon entries in advance-block 2020-08-27 21:38:51 -04:00
Łukasz Magiera 398cbd7f2c deps: Update markets 2020-08-28 01:09:45 +02:00
Łukasz Magiera 5aa90b0478 Merge pull request #3337 from filecoin-project/feat/chainwatch/lotus-tokens
polish(chainwatch): accept lotus api and token
2020-08-28 00:27:27 +02:00
Łukasz Magiera 86c936759b Merge pull request #3357 from filecoin-project/fix/block-validator-power
ignore, don't reject block if we can't determine power
2020-08-28 00:24:53 +02:00
Łukasz Magiera 22bdc43023 Merge pull request #3359 from austinabell/runner/returnval
Add in return value check in test-vector runner
2020-08-28 00:19:32 +02:00
Łukasz Magiera ec2bc0baf6 Merge pull request #3363 from filecoin-project/fix/pubsub-params-tweaking
tweak some pubsub parameters
2020-08-28 00:18:26 +02:00
Łukasz Magiera 5b860261a0 Merge pull request #3366 from austinabell/vm/rmusm
Remove unsigned message pointer from Runtime
2020-08-28 00:14:26 +02:00
Łukasz Magiera 010e32d778 Merge pull request #3360 from filecoin-project/fix/dont-fail-drand-dns
Don't fail if could not resolve drand dnsaddr
2020-08-28 00:13:07 +02:00
Łukasz Magiera 1097d29213 sealing sched: Call trySched less when there are many tasks 2020-08-28 00:03:42 +02:00
Łukasz Magiera a6492b1ed6 storagefsm: Auto-retry failed remove 2020-08-27 23:59:01 +02:00
Łukasz Magiera 59d2034cbb sealing sched: Wait a bit for tasks to come in on restart 2020-08-27 23:58:37 +02:00
austinabell 39ef3a701b Remove unsigned message pointer from Runtime 2020-08-27 17:34:45 -04:00
Łukasz Magiera 7fdffc0340 sealing sched: Give more priority to tasks (re)moving data 2020-08-27 23:29:39 +02:00
Łukasz Magiera f2bd680cc5 gofmt 2020-08-27 23:14:46 +02:00
Łukasz Magiera 59f554b658 sealing sched: Show waiting tasks assigned to workers in sealing jobs cli 2020-08-27 23:14:33 +02:00
frrist 0ad38fe38f lint 2020-08-27 14:09:03 -07:00
frrist 5c4db23da4 polish(chainwatch): accept lotus api and token 2020-08-27 14:05:39 -07:00
vyzo 708a8b6543 flag to allow add to skip limit check
essential for correctness in the revert case
2020-08-28 00:04:21 +03:00
Łukasz Magiera d8e58e67c6 storagefsm: Treat PackingFailed sectors as expired 2020-08-27 22:41:35 +02:00
Łukasz Magiera 6c7874c883 Merge remote-tracking branch 'origin/master' into fix/some-fsm-issues 2020-08-27 21:37:08 +02:00
Łukasz Magiera 15204a9b90 storagefsm: fix tests 2020-08-27 21:34:45 +02:00
Łukasz Magiera 489d5239a5 storagefsm: Attempt to auto-recover from reorged DealIDs 2020-08-27 21:11:11 +02:00
frrist f934ebd429 fix(chainwatch): sync based on height 2020-08-27 11:47:53 -07:00
frrist fccdd70524 polish(chainwatch): relax scheduler refresh 2020-08-27 11:47:53 -07:00
frrist 5e40dda3bc fix(chainwatch): fix deadlock in sector deals 2020-08-27 11:47:53 -07:00
frrist fb8340acb2 polish(chainwatch): clean up logging 2020-08-27 11:47:53 -07:00
vyzo 20fbd66c90 tweak some pubsub parameters
- increase Bootstapp prune backoff to 5min from the default 1min
- reduce opportunistic graft threshold to 3.5 to account for low peer scores
2020-08-27 21:12:38 +03:00
Jakub Sztandera b27ee8241a Add TODO note
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-27 19:05:37 +02:00
Łukasz Magiera 7806a9885a storagefsm: Record publish deals message CID 2020-08-27 17:50:50 +02:00
Jakub Sztandera 6e4889d340 Don't fail if could not resolved drand dnsaddr
Resolves https://github.com/filecoin-project/lotus/issues/3335

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-27 17:50:16 +02:00
austinabell 679a8e0c24 Add in return value check in test-vector runner 2020-08-27 11:42:01 -04:00
vyzo 6c3d8ec1de ignore, don't reject block if we can't determine power 2020-08-27 16:53:53 +03:00
Łukasz Magiera 29078aaae9 storagefsm: Retry sending messages on out-of-gas errors 2020-08-27 14:02:00 +02:00
Łukasz Magiera 8a45148070 docsgen 2020-08-27 13:53:04 +02:00
Łukasz Magiera df635579c4 storagefsm: Handle sectors with expired deals better 2020-08-27 13:51:38 +02:00
Łukasz Magiera 788c7dbf48 storagefsm: Separate satte for submitting commit message 2020-08-27 12:57:28 +02:00
Łukasz Magiera 99ecef89b8 gofmt 2020-08-27 12:41:24 +02:00
Łukasz Magiera 51ca460f18 miner: Fix sorting of some sector states in miner-info 2020-08-27 12:41:12 +02:00
Łukasz Magiera e236173417 miner: Print (pre)commit message cids in sector status 2020-08-27 12:40:19 +02:00
Łukasz Magiera 15191ff80f storagefsm: Allow removing sectors in all states 2020-08-27 12:39:20 +02:00
Łukasz Magiera efd2129187 Merge pull request #3330 from filecoin-project/feat/slightly-better-log-info
print block 'age' when validating blocks during sync
2020-08-27 11:13:49 +02:00
Łukasz Magiera 73da4b9eed Merge pull request #3336 from filecoin-project/feat/even-less-flaky-tests
Wait until blocks show up full nodes 'head' before claiming block has been mined
2020-08-27 11:07:14 +02:00
whyrusleeping 36ff37ba47 Wait until blocks show up full nodes 'head' before claiming block has been mined 2020-08-26 17:51:16 -07:00
whyrusleeping a33784c434 print block 'age' when validating blocks during sync 2020-08-26 14:48:53 -07:00
Whyrusleeping deb013cecb Merge pull request #3081 from filecoin-project/conformance-tests
driver, runner and CI for interoperable test-vector based testing.
2020-08-26 14:06:39 -07:00
Whyrusleeping cb411637cc Merge pull request #3328 from filecoin-project/fix/log-level-miner
use node type agnostic api getter in log commands
2020-08-26 14:02:29 -07:00
Will be89466367 add back junit report in conformance ci (#3327) 2020-08-26 21:55:06 +01:00
whyrusleeping 111c7cf688 use node type agnostic api getter in log commands 2020-08-26 13:51:32 -07:00
Raúl Kripalani 75e0387be2 fix ffiwrapper import. 2020-08-26 21:49:55 +01:00
Łukasz Magiera c4e32fac1f Merge pull request #3324 from filecoin-project/fix/retrieval-closing-panic
Resolve retrieval close event panic
2020-08-26 22:15:21 +02:00
vyzo 038e83b647 log error if we trip over too many pending messages for actor 2020-08-26 22:55:39 +03:00
vyzo 82ef0529d8 named error for too many pending messages 2020-08-26 22:48:03 +03:00
vyzo 6abfbbddd5 fix tests 2020-08-26 22:44:47 +03:00
vyzo ad889a7240 rate limit messages per actor by enforcing maximum pending message limit 2020-08-26 22:40:10 +03:00
Łukasz Magiera e22ae9f826 Merge pull request #3323 from filecoin-project/steb/fix-post
Fix PoSt with bad sectors
2020-08-26 21:22:21 +02:00
vyzo d3e95d6b77 cast min base fee to uint64 2020-08-26 21:37:32 +03:00
vyzo 8db262c941 check gas fee cap for minimum value 2020-08-26 21:23:28 +03:00
vyzo 793eda986b comment out Value inclusion for required funds tracking
we are not sure whether we want it yet.
2020-08-26 21:10:46 +03:00
hannahhoward 1cd49cec39 fix(client): insure cancelled context avoids lock 2020-08-26 10:59:07 -07:00
hannahhoward 10c1399474 fix(retrieval): resolve retrieval close event panic
Refactor ClientRetrieve command to remove the possibility of a send on close channel race condition
2020-08-26 10:48:23 -07:00
Raúl Kripalani 4709e231b8 drop aurora as dep; upgrade test-vectors. 2020-08-26 18:35:41 +01:00
Steven Allen f8a14184c7 Fix lint issue 2020-08-26 10:05:03 -07:00
Steven Allen 0155a31d1f Fix PoSt with bad sectors
"skipped" sectors must be replaced with a substitute "good" sector, or the
entire partition must be skipped. They should not just be omitted.

This patch also fixes the test to verify the _entire_ proof instead of just
verifying that the proof includes the correct sectors.
2020-08-26 09:56:51 -07:00
vyzo 8848c549a0 move msg serialization outside of lock, consistently use curTs 2020-08-26 19:42:56 +03:00
vyzo 4919a005d3 always verify message min gas 2020-08-26 19:37:27 +03:00
Raúl Kripalani dabe14889d actually apply all messages. 2020-08-26 16:48:47 +01:00
Alan Shaw 6d1e711b2a feat: bleeding edge conformance (#3317) 2020-08-26 16:03:44 +01:00
Raúl Kripalani e19087722f Merge branch 'master' into conformance-tests 2020-08-26 15:13:46 +01:00
Raúl Kripalani d3ac243cea Merge remote-tracking branch 'origin/master' into conformance-tests 2020-08-26 15:12:02 +01:00
Łukasz Magiera 348dadf7ae Merge pull request #3305 from filecoin-project/feat/update-pubsub
update go-libp2p-pubsub
2020-08-26 16:09:48 +02:00
Raúl Kripalani cba5ae81ed call out to filecoin-project/statediff upon state mismatches. 2020-08-26 15:09:33 +01:00
Łukasz Magiera 6d328c0a71 Merge pull request #3298 from filecoin-project/fix/flaky-mining-tests
improve flakiness of a few tests
2020-08-26 16:07:52 +02:00
vyzo 7a7066896e better code for getRequiredFunds 2020-08-26 15:37:42 +03:00
vyzo a2c0c10d2a correctly account for message replacement in required funds tracking 2020-08-26 15:27:09 +03:00
vyzo c473d3c682 rename ErrValidationFailure to ErrSoftValidationFailure
to make it clear to readers that this failure is soft; we might be out of sync.
2020-08-26 15:16:04 +03:00
vyzo bedbdcaf13 give some score weight to the messages topic 2020-08-26 15:14:15 +03:00
vyzo 87e6c0973a include message Value only in soft validation failures 2020-08-26 15:13:50 +03:00
vyzo 78876947a4 ErrBroadcastAnyway is now ErrValidationFailure 2020-08-26 15:03:13 +03:00
vyzo b59f58435c fix tests 2020-08-26 14:58:32 +03:00
vyzo 4adb83eaae check aggregate pending message required funds against balance 2020-08-26 14:58:26 +03:00
vyzo 4ac9828b0c track required funds in message set 2020-08-26 14:38:26 +03:00
vyzo 77f6e0d4f8 refactor balance check, apply it in PushWithNonce 2020-08-26 14:23:34 +03:00
vyzo 835dbfe001 check message before adding in PushWithNonce 2020-08-26 14:13:46 +03:00
David Dias f5eb3fd086 docs: removed non used packages from the list 2020-08-26 12:10:11 +01:00
vyzo da9630c561 remove duplicate check
gas limit is checked against block gas limit in ValidForBlockInclusion
2020-08-26 14:02:34 +03:00
Alan Shaw a89faa72ea feat(conformance): skip incorrect tests (#3310)
Fixes https://github.com/filecoin-project/test-vectors/issues/72
2020-08-26 11:45:34 +01:00
vyzo e042ce21f6 gomod: update go-libp2p-pubsub@v0.3.5 2020-08-26 08:36:58 +03:00
Whyrusleeping d4fef1b5f8 Merge pull request #3301 from filecoin-project/feat/release-0.5.4
Lotus release v0.5.4
2020-08-25 17:55:15 -07:00
whyrusleeping d5c4b66ec7 Lotus release v0.5.4 2020-08-25 17:31:40 -07:00
Whyrusleeping 0009f7c8dc Merge pull request #3300 from filecoin-project/fix/set-peer-id
fix parsing of peerID in input to set-peer-id
2020-08-25 17:26:05 -07:00
Whyrusleeping cd2e794d3f Merge pull request #3299 from filecoin-project/steb/update-deps
update deps for bug fixes
2020-08-25 17:18:02 -07:00
whyrusleeping 9bb862d025 fix parsing of peerID in input to set-peer-id 2020-08-25 17:10:06 -07:00
whyrusleeping 91bb559bdf address another spot with the more certain mining fix 2020-08-25 17:06:45 -07:00
Steven Allen 7fb4851eb9 update deps for bug fixes
* updates bitswap to include _many_ perf enhancements and bug fixes.
* updates go-fs-lock because the version here is pretty old.
* updates go-libp2p
* updates bbloom _just_ in case, because the version we were depending on had bugs (looks like we're not actually using it).
2020-08-25 17:06:07 -07:00
Whyrusleeping 6c2fa9086e Merge pull request #3238 from filecoin-project/fix/jsonrpc-ctx
refactor(ctx): for go-jsonrpc/pull/26
2020-08-25 15:33:38 -07:00
frrist 0d61e0d717 refactor(ctx): update to latest go-jsonrpc 2020-08-25 15:20:41 -07:00
whyrusleeping d0585ca7bb improve flakiness of a few tests 2020-08-25 15:07:10 -07:00
Whyrusleeping 14cda27e9f Merge pull request #3294 from filecoin-project/feat/sync-tweaking
Add some tracing and the ability to tweak message fetch window size
2020-08-25 13:25:22 -07:00
Whyrusleeping cf177bfea5 Merge pull request #3296 from filecoin-project/steb/fix-lints-again
Fix more lint warnings.
2020-08-25 13:24:34 -07:00
Steven Allen f84bbd4520 Fix more lint warnings.
This way we can keep CI green.
2020-08-25 12:56:30 -07:00
Whyrusleeping 2bf8fb8c84 Merge pull request #3295 from filecoin-project/fix/use-safe-ellipsis-for-cli-output
Use a safe string ellipsis/truncation function for client CLI output
2020-08-25 12:50:27 -07:00
whyrusleeping a553db4b82 Add some tracing and the ability to tweak message fetch window size 2020-08-25 12:39:17 -07:00
Ingar Shu 121be5c6e8 Add and use a safe ellipsis function for truncating strings 2020-08-25 12:03:08 -07:00
Łukasz Magiera e23e3db5b5 Merge pull request #3278 from filecoin-project/remove-mkminer
lotus-fountain: remove make miner workflow
2020-08-25 18:02:48 +02:00
Łukasz Magiera babaab20ea Merge pull request #3283 from filecoin-project/feat/moar-mpool-tests
More message pool tests and a couple of bug fixes
2020-08-25 17:59:49 +02:00
Łukasz Magiera 9d67c16ab9 Merge pull request #3284 from filecoin-project/misc/stats-gas-limit
Add gas_limit_uniq_total to stats
2020-08-25 17:49:59 +02:00
Jakub Sztandera 9908031b0b Add gas_limit_uniq_total to stats
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2020-08-25 16:59:27 +02:00
vyzo 6b3282150b appease linter 2020-08-25 14:03:49 +03:00
vyzo 58cfac9f67 add test for message republish 2020-08-25 13:57:02 +03:00
Dirk McCormick 340d11be38 fix: check voucher spendable should take into account submitted vouchers 2020-08-25 12:51:29 +02:00
vyzo 62b15ecc12 remove bug line 2020-08-25 13:41:20 +03:00
vyzo 6b9d392d0e add another priority selection test 2020-08-25 13:36:03 +03:00
vyzo 9c68123ede add test for Updates, fix behaviour for closed mpool 2020-08-25 13:29:09 +03:00
vyzo 7049b6478c add test for Clear 2020-08-25 13:24:11 +03:00
vyzo 0e6d34c0c9 add test for loadLocal 2020-08-25 13:16:55 +03:00
vyzo a01fa11a26 exercise debug code, fix deadlock 2020-08-25 13:03:50 +03:00
vyzo 4c71182c6b Merge pull request #3280 from filecoin-project/fix/mpool-init-crash
initialize mpool ts _before_ loading local messages
2020-08-25 09:04:11 +03:00
vyzo 7e81081899 initialize mpool ts _before_ loading local messages 2020-08-25 08:49:15 +03:00
Travis Person fb033a3719 lotus-fountain: remove make miner workflow 2020-08-25 05:10:12 +00:00
Will a03931daab archive more relevant coverage for conformance tests (#3176) 2020-08-21 16:41:35 +01:00
Raúl Kripalani 6ed1c9e905 register the puppet actor conditionally. 2020-08-21 11:51:50 +01:00
Raúl Kripalani e38f4219c5 update test-vectors commit. 2020-08-19 18:19:03 +01:00
Raúl Kripalani 30b6f38704 update test-vectors commit. 2020-08-19 18:14:19 +01:00
Raúl Kripalani 04e4bab313 register chaos actor only if selector says to do so. 2020-08-19 18:10:56 +01:00
Raúl Kripalani dddf7951ef update test-vectors commit. 2020-08-19 17:33:30 +01:00
Raúl Kripalani b13681df32 update test-vectors commit. 2020-08-19 14:40:55 +01:00
Raúl Kripalani a21234cd54 deploy the chaos actor. 2020-08-19 14:31:34 +01:00
Raúl Kripalani 4f4cebadc7 Merge branch 'master' into conformance-tests 2020-08-19 13:33:15 +01:00
Raúl Kripalani f1c452754f separate conformance suite on CI. 2020-08-16 22:50:00 +01:00
Raúl Kripalani b9d67296ef small adjustments to runner. 2020-08-16 22:15:12 +01:00
Raúl Kripalani 483e82e14b point test-vectors to master. 2020-08-16 22:05:43 +01:00
Raúl Kripalani a0c0d9c98a small fixes. 2020-08-16 00:37:16 +01:00
Raúl Kripalani 322b33197c introduce interoperable vector-based conformance testing.
This commit introduces a new package `conformance` containing:

 1. the test driver to exercise Lotus against interoperable
    test vectors, and
 2. the test runner, which integrates go test with the test vector
    corpus hosted at https://github.com/filecoin-project/conformance-vectors.

The corpus is mounted via a git submodule.

Right now, only message-class test vectors are supported. In the
next week, this support will be extended to tipset-class, chain-class,
and block sequence-class vectors.
2020-08-16 00:15:52 +01:00
322 changed files with 8124 additions and 3369 deletions
+67 -1
View File
@@ -113,7 +113,7 @@ jobs:
test: &test
description: |
Run tests with gotestsum.
parameters:
parameters: &test-params
executor:
type: executor
default: golang
@@ -161,6 +161,7 @@ jobs:
name: go test
environment:
LOTUS_TEST_WINDOW_POST: << parameters.winpost-test >>
SKIP_CONFORMANCE: "1"
command: |
mkdir -p /tmp/test-reports/<< parameters.test-suite-name >>
mkdir -p /tmp/test-artifacts
@@ -191,6 +192,63 @@ jobs:
<<: *test
test-window-post:
<<: *test
test-conformance:
description: |
Run tests using a corpus of interoperable test vectors for Filecoin
implementations to test their correctness and compliance with the Filecoin
specifications.
parameters:
<<: *test-params
vectors-branch:
type: string
default: ""
description: |
Branch on github.com/filecoin-project/test-vectors to checkout and
test with. If empty (the default) the commit defined by the git
submodule is used.
executor: << parameters.executor >>
steps:
- install-deps
- prepare
- run:
command: make deps lotus
no_output_timeout: 30m
- download-params
- when:
condition:
not:
equal: [ "", << parameters.vectors-branch >> ]
steps:
- run:
name: checkout vectors branch
command: |
cd extern/test-vectors
git fetch
git checkout origin/<< parameters.vectors-branch >>
- run:
name: go get vectors branch
command: go get github.com/filecoin-project/test-vectors@<< parameters.vectors-branch >>
- go/install-gotestsum:
gobin: $HOME/.local/bin
version: 0.5.2
- run:
name: go test
environment:
SKIP_CONFORMANCE: "0"
command: |
mkdir -p /tmp/test-reports
mkdir -p /tmp/test-artifacts
gotestsum \
--format pkgname-and-test-fails \
--junitfile /tmp/test-reports/junit.xml \
-- \
-v -coverpkg ./chain/vm/,github.com/filecoin-project/specs-actors/... -coverprofile=/tmp/conformance.out ./conformance/
go tool cover -html=/tmp/conformance.out -o /tmp/test-artifacts/conformance-coverage.html
no_output_timeout: 30m
- store_test_results:
path: /tmp/test-reports
- store_artifacts:
path: /tmp/test-artifacts/conformance-coverage.html
build-macos:
description: build darwin lotus binary
@@ -356,6 +414,14 @@ workflows:
tags:
only:
- /^v\d+\.\d+\.\d+$/
- test-conformance:
test-suite-name: conformance
packages: "./conformance"
- test-conformance:
name: test-conformance-bleeding-edge
test-suite-name: conformance-bleeding-edge
packages: "./conformance"
vectors-branch: master
- build-debug
- build-all:
requires:
+2
View File
@@ -1,3 +1,5 @@
comment: off
ignore:
- "cbor_gen.go"
github_checks:
annotations: false
+8 -2
View File
@@ -26,11 +26,14 @@
color: 00A4E2
description: "Area: Chain/VM"
- name: area/chain/sync
color: 00A4E2
color: 00A4E4
description: "Area: Chain/Sync"
- name: area/chain/misc
color: 00A4E2
color: 00A4E6
description: "Area: Chain/Misc"
- name: area/markets
color: 00A4E8
description: "Area: Markets"
- name: area/sealing/fsm
color: 0bb1ed
description: "Area: Sealing/FSM"
@@ -149,6 +152,9 @@
- name: impact/test-flakiness
color: DDE1E4
description: "Impact: Test Flakiness"
- name: impact/consensus
color: b20014
description: "Impact: Consensus"
###
### Topics
+3
View File
@@ -5,3 +5,6 @@
[submodule "extern/serialization-vectors"]
path = extern/serialization-vectors
url = https://github.com/filecoin-project/serialization-vectors
[submodule "extern/test-vectors"]
path = extern/test-vectors
url = https://github.com/filecoin-project/test-vectors.git
+184
View File
@@ -1,5 +1,189 @@
# Lotus changelog
# 0.6.0 / 2020-09-07
This consensus-breaking release of Lotus is designed to test a network upgrade on the space race testnet. The changes that break consensus are:
- Tweaking of some cryptoecon parameters in specs-actors 0.9.7 (https://github.com/filecoin-project/specs-actors/releases/tag/v0.9.7)
- Rebalancing FIL distribution to make testnet FIL scarce, which prevents base fee spikes and sets better expectations for mainnet
This release also introduces many improvements to Lotus! Among them are a new version of go-fil-markets that supports non-blocking retrieval, various spam reduction measures in the messagepool and p2p logic, and UX improvements to payment channels, dealmaking, and state inspection.
## Changes
#### Core Lotus and dependencies
- Implement faucet funds reallocation logic (https://github.com/filecoin-project/lotus/pull/3632)
- Network upgrade: Upgrade to correct fork threshold (https://github.com/filecoin-project/lotus/pull/3628)
- Update to specs 0.9.7 and markets 0.6.0 (https://github.com/filecoin-project/lotus/pull/3627)
- Network upgrade: Perform base fee tamping (https://github.com/filecoin-project/lotus/pull/3623)
- Chain events: if cache best() is nil, return chain head (https://github.com/filecoin-project/lotus/pull/3611)
- Update to specs actors v0.9.6 (https://github.com/filecoin-project/lotus/pull/3603)
#### Messagepool
- Temporarily allow negative chains (https://github.com/filecoin-project/lotus/pull/3625)
- Improve publish/republish logic (https://github.com/filecoin-project/lotus/pull/3592)
- Fix selection bug; priority messages were not included if other chains were negative (https://github.com/filecoin-project/lotus/pull/3580)
- Add defensive check for minimum GasFeeCap for inclusion within the next 20 blocks (https://github.com/filecoin-project/lotus/pull/3579)
- Add additional info about gas premium (https://github.com/filecoin-project/lotus/pull/3578)
- Fix GasPremium capping logic (https://github.com/filecoin-project/lotus/pull/3552)
#### Payment channels
- Get available funds by address or by from/to (https://github.com/filecoin-project/lotus/pull/3547)
- Create `lotus paych status` command (https://github.com/filecoin-project/lotus/pull/3523)
- Rename CLI command from "paych get" to "paych add-funds" (https://github.com/filecoin-project/lotus/pull/3520)
#### Peer-to-peer
- Only subscribe to pubsub topics once we are synced (https://github.com/filecoin-project/lotus/pull/3602)
- Reduce mpool add failure log spam (https://github.com/filecoin-project/lotus/pull/3562)
- Republish messages even if the chains have negative performance(https://github.com/filecoin-project/lotus/pull/3557)
- Adjust gossipsub gossip factor (https://github.com/filecoin-project/lotus/pull/3556)
- Integrate pubsub Random Early Drop (https://github.com/filecoin-project/lotus/pull/3518)
#### Miscellaneous
- Fix panic in OnDealExpiredSlashed (https://github.com/filecoin-project/lotus/pull/3553)
- Robustify state manager against holes in actor method numbers (https://github.com/filecoin-project/lotus/pull/3538)
#### UX
- VM: Fix an error message (https://github.com/filecoin-project/lotus/pull/3608)
- Documentation: Batch replacement,update lotus-storage-miner to lotus-miner (https://github.com/filecoin-project/lotus/pull/3571)
- CLI: Robust actor lookup (https://github.com/filecoin-project/lotus/pull/3535)
- Add agent flag to net peers (https://github.com/filecoin-project/lotus/pull/3534)
- Add watch option to storage-deals list (https://github.com/filecoin-project/lotus/pull/3527)
#### Testing & tooling
- Decommission chain-validation (https://github.com/filecoin-project/lotus/pull/3606)
- Metrics: add expected height metric (https://github.com/filecoin-project/lotus/pull/3586)
- PCR: Use current tipset during refund (https://github.com/filecoin-project/lotus/pull/3570)
- Lotus-shed: Add math command (https://github.com/filecoin-project/lotus/pull/3568)
- PCR: Add tipset aggergation (https://github.com/filecoin-project/lotus/pull/3565)- Fix broken paych tests (https://github.com/filecoin-project/lotus/pull/3551)
- Make chain export ~1000x times faster (https://github.com/filecoin-project/lotus/pull/3533)
- Chainwatch: Stop SyncIncomingBlocks from leaking into chainwatch processing; No panics during processing (https://github.com/filecoin-project/lotus/pull/3526)
- Conformance: various changes (https://github.com/filecoin-project/lotus/pull/3521)
# 0.5.10 / 2020-09-03
This patch includes a crucial fix to the message pool selection logic, strongly disfavouring messages that might cause a miner penalty.
## Changes
- Fix calculation of GasReward in messagepool (https://github.com/filecoin-project/lotus/pull/3528)
# 0.5.9 / 2020-09-03
This patch includes a hotfix to the `GasEstimateFeeCap` method, capping the estimated fee to a reasonable level by default.
## Changes
- Added target height to sync wait (https://github.com/filecoin-project/lotus/pull/3502)
- Disable codecov annotations (https://github.com/filecoin-project/lotus/pull/3514)
- Cap fees to reasonable level by default (https://github.com/filecoin-project/lotus/pull/3516)
- Add APIs and command to inspect bandwidth usage (https://github.com/filecoin-project/lotus/pull/3497)
- Track expected nonce in mpool, ignore messages with large nonce gaps (https://github.com/filecoin-project/lotus/pull/3450)
# 0.5.8 / 2020-09-02
This patch includes some bugfixes to the sector sealing process, and updates go-fil-markets. It also improves the performance of blocksync, adds a method to export chain state trees, and improves chainwatch.
## Changes
- Upgrade markets to v0.5.9 (https://github.com/filecoin-project/lotus/pull/3496)
- Improve blocksync to load fewer messages: (https://github.com/filecoin-project/lotus/pull/3494)
- Fix a panic in the ffi-wrapper's `ReadPiece` (https://github.com/filecoin-project/lotus/pull/3492/files)
- Fix a deadlock in the sealing scheduler (https://github.com/filecoin-project/lotus/pull/3489)
- Add test vectors for tipset tests (https://github.com/filecoin-project/lotus/pull/3485/files)
- Improve the advance-block debug command (https://github.com/filecoin-project/lotus/pull/3476)
- Add toggle for message processing to Lotus PCR (https://github.com/filecoin-project/lotus/pull/3470)
- Allow exporting recent chain state trees (https://github.com/filecoin-project/lotus/pull/3463)
- Remove height from chain rand (https://github.com/filecoin-project/lotus/pull/3458)
- Disable GC on chain badger datastore (https://github.com/filecoin-project/lotus/pull/3457)
- Account for `GasPremium` in `GasEstimateFeeCap` (https://github.com/filecoin-project/lotus/pull/3456)
- Update go-libp2p-pubsub to `master` (https://github.com/filecoin-project/lotus/pull/3455)
- Chainwatch improvements (https://github.com/filecoin-project/lotus/pull/3442)
# 0.5.7 / 2020-08-31
This patch release includes some bugfixes and enhancements to the sector lifecycle and message pool logic.
## Changes
- Rebuild unsealed infos on miner restart (https://github.com/filecoin-project/lotus/pull/3401)
- CLI to attach storage paths to workers (https://github.com/filecoin-project/lotus/pull/3405)
- Do not select negative performing message chains for inclusion (https://github.com/filecoin-project/lotus/pull/3392)
- Remove a redundant error-check (https://github.com/filecoin-project/lotus/pull/3421)
- Correctly move unsealed sectors in `FinalizeSectors` (https://github.com/filecoin-project/lotus/pull/3424)
- Improve worker selection logic (https://github.com/filecoin-project/lotus/pull/3425)
- Don't use context to close bitswap (https://github.com/filecoin-project/lotus/pull/3430)
- Correctly estimate gas premium when there is only one message on chain (https://github.com/filecoin-project/lotus/pull/3428)
# 0.5.6 / 2020-08-29
Hotfix release that fixes a panic in the sealing scheduler (https://github.com/filecoin-project/lotus/pull/3389).
# 0.5.5
This patch release introduces a large number of improvements to the sealing process.
It also updates go-fil-markets to
[version 0.5.8](https://github.com/filecoin-project/go-fil-markets/releases/tag/v0.5.8),
and go-libp2p-pubsub to [v0.3.5](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.3.5).
#### Downstream upgrades
- Upgrades markets to v0.5.8 (https://github.com/filecoin-project/lotus/pull/3384)
- Upgrades go-libp2p-pubsub to v0.3.5 (https://github.com/filecoin-project/lotus/pull/3305)
#### Sector sealing
- The following improvements were introduced in https://github.com/filecoin-project/lotus/pull/3350.
- Allow `lotus-miner sectors remove` to remove a sector in any state.
- Create a separate state in the storage FSM dedicated to submitting the Commit message.
- Recovery for when the Deal IDs of deals in a sector get changed in a reorg.
- Auto-retry sending Precommit and Commit messages if they run out of gas
- Auto-retry sector remove tasks when they fail
- Compact worker windows, and allow their tasks to be executed in any order
- Don't simply skip PoSt for bad sectors (https://github.com/filecoin-project/lotus/pull/3323)
#### Message Pool
- Spam Protection: Track required funds for pending messages (https://github.com/filecoin-project/lotus/pull/3313)
#### Chainwatch
- Add more power and reward metrics (https://github.com/filecoin-project/lotus/pull/3367)
- Fix raciness in sector deal table (https://github.com/filecoin-project/lotus/pull/3275)
- Parallelize miner processing (https://github.com/filecoin-project/lotus/pull/3380)
- Accept Lotus API and token (https://github.com/filecoin-project/lotus/pull/3337)
# 0.5.4
A patch release, containing a few nice bugfixes and improvements:
- Fix parsing of peer ID in `lotus-miner actor set-peer-id` (@whyrusleeping)
- Update dependencies, fixing several bugs (@Stebalien)
- Fix remaining linter warnings (@Stebalien)
- Use safe string truncation (@Ingar)
- Allow tweaking of blocksync message window size (@whyrusleeping)
- Add some additional gas stats to metrics (@Kubuxu)
- Fix an edge case bug in message selection, add many tests (@vyzo)
# 0.5.3
Yet another hotfix release.
A lesson for readers, having people who have been awake for 12+ hours review
your hotfix PR is not a good idea. Find someone who has enough slept recently
enough to give you good code review, otherwise you'll end up quickly bumping
versions again.
- Fixed a bug in the mempool that was introduced in v0.5.2
# 0.5.2 / 2020-08-24
This is a hotfix release.
-3
View File
@@ -40,9 +40,6 @@ All work is tracked via issues. An attempt at keeping an up-to-date view on rema
The lotus Filecoin implementation unfolds into the following packages:
- [This repo](https://github.com/filecoin-project/lotus)
- [storage-fsm](https://github.com/filecoin-project/storage-fsm)
- [sector-storage](https://github.com/filecoin-project/sector-storage)
- [specs-storage](https://github.com/filecoin-project/specs-storage)
- [go-fil-markets](https://github.com/filecoin-project/go-fil-markets) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/markets-shared-components-5daa144a7046a60001c6e253/board)
- [spec-actors](https://github.com/filecoin-project/specs-actors) which has its own [kanban work tracker available here](https://app.zenhub.com/workspaces/actors-5ee6f3aa87591f0016c05685/board)
+15
View File
@@ -5,8 +5,10 @@ import (
"fmt"
"github.com/filecoin-project/go-jsonrpc/auth"
metrics "github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
protocol "github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/lotus/build"
)
@@ -28,6 +30,19 @@ type Common interface {
NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
NetPubsubScores(context.Context) ([]PubsubScore, error)
NetAutoNatStatus(context.Context) (NatInfo, error)
NetAgentVersion(ctx context.Context, p peer.ID) (string, error)
// NetBandwidthStats returns statistics about the nodes total bandwidth
// usage and current rate across all peers and protocols.
NetBandwidthStats(ctx context.Context) (metrics.Stats, error)
// NetBandwidthStatsByPeer returns statistics about the nodes bandwidth
// usage and current rate per peer
NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error)
// NetBandwidthStatsByProtocol returns statistics about the nodes bandwidth
// usage and current rate per protocol
NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error)
// MethodGroup: Common
+57 -12
View File
@@ -4,21 +4,24 @@ import (
"context"
"time"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-multistore"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/chain/types"
marketevents "github.com/filecoin-project/lotus/markets/loggers"
@@ -109,7 +112,10 @@ type FullNode interface {
ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error)
// ChainExport returns a stream of bytes with CAR dump of chain data.
ChainExport(context.Context, types.TipSetKey) (<-chan []byte, error)
// The exported chain data includes the header chain from the given tipset
// back to genesis, the entire genesis state, and the most recent 'nroots'
// state trees.
ChainExport(ctx context.Context, nroots abi.ChainEpoch, tsk types.TipSetKey) (<-chan []byte, error)
// MethodGroup: Beacon
// The Beacon method group contains methods for interacting with the random beacon (DRAND)
@@ -243,6 +249,8 @@ type FullNode interface {
ClientGetDealInfo(context.Context, cid.Cid) (*DealInfo, error)
// ClientListDeals returns information about the deals made by the local client.
ClientListDeals(ctx context.Context) ([]DealInfo, error)
// ClientGetDealUpdates returns the status of updated deals
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error)
// ClientHasLocal indicates whether a certain CID is locally stored.
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
@@ -265,6 +273,9 @@ type FullNode interface {
// ClientListTransfers returns the status of all ongoing transfers of data
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
// ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel
// which are stuck due to insufficient funds
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
// ClientUnimport removes references to the specified file from filestore
//ClientUnimport(path string)
@@ -295,7 +306,7 @@ type FullNode interface {
// StateMinerSectors returns info about the given miner's sectors. If the filter bitfield is nil, all sectors are included.
// If the filterOut boolean is set to true, any sectors in the filter are excluded.
// If false, only those sectors in the filter are included.
StateMinerSectors(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*ChainSectorInfo, error)
// StateMinerActiveSectors returns info about sectors that a given miner is actively proving.
StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error)
// StateMinerProvingDeadline calculates the deadline at some epoch for a proving period
@@ -310,11 +321,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) (bitfield.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) (bitfield.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
@@ -323,7 +334,7 @@ type FullNode interface {
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
// StateSectorGetInfo returns the on-chain info for the specified miner's sector
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
// NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate
// expiration epoch
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
@@ -416,6 +427,8 @@ type FullNode interface {
PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*ChannelInfo, error)
PaychGetWaitReady(context.Context, cid.Cid) (address.Address, error)
PaychAvailableFunds(ch address.Address) (*ChannelAvailableFunds, error)
PaychAvailableFundsByFromTo(from, to address.Address) (*ChannelAvailableFunds, error)
PaychList(context.Context) ([]address.Address, error)
PaychStatus(context.Context, address.Address) (*PaychStatus, error)
PaychSettle(context.Context, address.Address) (cid.Cid, error)
@@ -424,10 +437,10 @@ type FullNode interface {
PaychNewPayment(ctx context.Context, from, to address.Address, vouchers []VoucherSpec) (*PaymentInfo, error)
PaychVoucherCheckValid(context.Context, address.Address, *paych.SignedVoucher) error
PaychVoucherCheckSpendable(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error)
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*paych.SignedVoucher, error)
PaychVoucherCreate(context.Context, address.Address, types.BigInt, uint64) (*VoucherCreateResult, error)
PaychVoucherAdd(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error)
PaychVoucherList(context.Context, address.Address) ([]*paych.SignedVoucher, error)
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher) (cid.Cid, error)
PaychVoucherSubmit(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error)
}
type FileRef struct {
@@ -533,6 +546,28 @@ type ChannelInfo struct {
WaitSentinel cid.Cid
}
type ChannelAvailableFunds struct {
// Channel is the address of the channel
Channel *address.Address
// From is the from address of the channel (channel creator)
From address.Address
// To is the to address of the channel
To address.Address
// ConfirmedAmt is the amount of funds that have been confirmed on-chain
// for the channel
ConfirmedAmt types.BigInt
// PendingAmt is the amount of funds that are pending confirmation on-chain
PendingAmt types.BigInt
// PendingWaitSentinel can be used with PaychGetWaitReady to wait for
// confirmation of pending funds
PendingWaitSentinel *cid.Cid
// QueuedAmt is the amount that is queued up behind a pending request
QueuedAmt types.BigInt
// VoucherRedeemedAmt is the amount that is redeemed by vouchers on-chain
// and in the local datastore
VoucherReedeemedAmt types.BigInt
}
type PaymentInfo struct {
Channel address.Address
WaitSentinel cid.Cid
@@ -548,6 +583,16 @@ type VoucherSpec struct {
Extra *paych.ModVerifyParams
}
// VoucherCreateResult is the response to calling PaychVoucherCreate
type VoucherCreateResult struct {
// Voucher that was created, or nil if there was an error or if there
// were insufficient funds in the channel
Voucher *paych.SignedVoucher
// Shortfall is the additional amount that would be needed in the channel
// in order to be able to create the voucher
Shortfall types.BigInt
}
type MinerPower struct {
MinerPower power.Claim
TotalPower power.Claim
@@ -699,7 +744,7 @@ type CirculatingSupply struct {
type MiningBaseInfo struct {
MinerPower types.BigInt
NetworkPower types.BigInt
Sectors []abi.SectorInfo
Sectors []proof.SectorInfo
WorkerKey address.Address
SectorSize abi.SectorSize
PrevBeaconEntry types.BeaconEntry
@@ -716,7 +761,7 @@ type BlockTemplate struct {
Messages []*types.SignedMessage
Epoch abi.ChainEpoch
Timestamp uint64
WinningPoStProof []abi.PoStProof
WinningPoStProof []proof.PoStProof
}
type DataSize struct {
+14 -12
View File
@@ -11,11 +11,11 @@ import (
"github.com/filecoin-project/go-fil-markets/piecestore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"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"
)
// StorageMiner is a low-level interface to the Filecoin network storage miner node
@@ -73,7 +73,7 @@ type StorageMiner interface {
MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error
MarketListDeals(ctx context.Context) ([]storagemarket.StorageDeal, error)
MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error)
MarketGetDealUpdates(ctx context.Context, d cid.Cid) (<-chan storagemarket.MinerDeal, error)
MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error)
MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error)
MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error
MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error)
@@ -120,16 +120,18 @@ type SectorLog struct {
}
type SectorInfo struct {
SectorID abi.SectorNumber
State SectorState
CommD *cid.Cid
CommR *cid.Cid
Proof []byte
Deals []abi.DealID
Ticket SealTicket
Seed SealSeed
Retries uint64
ToUpgrade bool
SectorID abi.SectorNumber
State SectorState
CommD *cid.Cid
CommR *cid.Cid
Proof []byte
Deals []abi.DealID
Ticket SealTicket
Seed SealSeed
PreCommitMsg *cid.Cid
CommitMsg *cid.Cid
Retries uint64
ToUpgrade bool
LastErr string
+4 -2
View File
@@ -6,10 +6,10 @@ import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
"github.com/filecoin-project/lotus/extern/sector-storage/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"
"github.com/filecoin-project/lotus/build"
@@ -27,11 +27,13 @@ type WorkerAPI interface {
storage.Sealer
MoveStorage(ctx context.Context, sector abi.SectorID) error
MoveStorage(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error
UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error
ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (bool, error)
StorageAddLocal(ctx context.Context, path string) error
Fetch(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error
Closing(context.Context) (<-chan struct{}, error)
+109 -61
View File
@@ -6,26 +6,29 @@ import (
"time"
"github.com/ipfs/go-cid"
metrics "github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
protocol "github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-fil-markets/piecestore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/go-multistore"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"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"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-storage/storage"
"github.com/filecoin-project/lotus/api"
@@ -42,14 +45,18 @@ type CommonStruct struct {
AuthVerify func(ctx context.Context, token string) ([]auth.Permission, error) `perm:"read"`
AuthNew func(ctx context.Context, perms []auth.Permission) ([]byte, error) `perm:"admin"`
NetConnectedness func(context.Context, peer.ID) (network.Connectedness, error) `perm:"read"`
NetPeers func(context.Context) ([]peer.AddrInfo, error) `perm:"read"`
NetConnect func(context.Context, peer.AddrInfo) error `perm:"write"`
NetAddrsListen func(context.Context) (peer.AddrInfo, error) `perm:"read"`
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"`
NetConnectedness func(context.Context, peer.ID) (network.Connectedness, error) `perm:"read"`
NetPeers func(context.Context) ([]peer.AddrInfo, error) `perm:"read"`
NetConnect func(context.Context, peer.AddrInfo) error `perm:"write"`
NetAddrsListen func(context.Context) (peer.AddrInfo, error) `perm:"read"`
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"`
NetBandwidthStats func(ctx context.Context) (metrics.Stats, error) `perm:"read"`
NetBandwidthStatsByPeer func(ctx context.Context) (map[string]metrics.Stats, error) `perm:"read"`
NetBandwidthStatsByProtocol func(ctx context.Context) (map[protocol.ID]metrics.Stats, error) `perm:"read"`
NetAgentVersion func(ctx context.Context, p peer.ID) (string, error) `perm:"read"`
ID func(context.Context) (peer.ID, error) `perm:"read"`
Version func(context.Context) (api.Version, error) `perm:"read"`
@@ -86,7 +93,7 @@ type FullNodeStruct struct {
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"`
ChainExport func(context.Context, abi.ChainEpoch, types.TipSetKey) (<-chan []byte, error) `perm:"read"`
BeaconGetEntry func(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
@@ -130,35 +137,37 @@ 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"`
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"`
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"`
ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"`
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
ClientRetrieveWithEvents func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
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"`
ClientRetrieveTryRestartInsufficientFunds func(ctx context.Context, paymentChannel address.Address) error `perm:"write"`
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *abi.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"`
StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"`
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error) `perm:"read"`
StateMinerPartitions func(context.Context, address.Address, uint64, types.TipSetKey) ([]*miner.Partition, error) `perm:"read"`
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (abi.BitField, error) `perm:"read"`
StateMinerFaults func(context.Context, address.Address, types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
StateAllMinerFaults func(context.Context, abi.ChainEpoch, types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
StateMinerRecoveries func(context.Context, address.Address, types.TipSetKey) (abi.BitField, error) `perm:"read"`
StateMinerRecoveries func(context.Context, address.Address, types.TipSetKey) (bitfield.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"`
@@ -200,21 +209,23 @@ type FullNodeStruct struct {
MarketEnsureAvailable func(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"`
PaychGet func(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
PaychGetWaitReady func(context.Context, cid.Cid) (address.Address, error) `perm:"sign"`
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
PaychStatus func(context.Context, address.Address) (*api.PaychStatus, error) `perm:"read"`
PaychSettle func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
PaychCollect func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
PaychAllocateLane func(context.Context, address.Address) (uint64, error) `perm:"sign"`
PaychNewPayment func(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"`
PaychVoucherCheck func(context.Context, *paych.SignedVoucher) error `perm:"read"`
PaychVoucherCheckValid func(context.Context, address.Address, *paych.SignedVoucher) error `perm:"read"`
PaychVoucherCheckSpendable func(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) `perm:"read"`
PaychVoucherAdd func(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) `perm:"write"`
PaychVoucherCreate func(context.Context, address.Address, big.Int, uint64) (*paych.SignedVoucher, error) `perm:"sign"`
PaychVoucherList func(context.Context, address.Address) ([]*paych.SignedVoucher, error) `perm:"write"`
PaychVoucherSubmit func(context.Context, address.Address, *paych.SignedVoucher) (cid.Cid, error) `perm:"sign"`
PaychGet func(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
PaychGetWaitReady func(context.Context, cid.Cid) (address.Address, error) `perm:"sign"`
PaychAvailableFunds func(address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"`
PaychAvailableFundsByFromTo func(address.Address, address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"`
PaychList func(context.Context) ([]address.Address, error) `perm:"read"`
PaychStatus func(context.Context, address.Address) (*api.PaychStatus, error) `perm:"read"`
PaychSettle func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
PaychCollect func(context.Context, address.Address) (cid.Cid, error) `perm:"sign"`
PaychAllocateLane func(context.Context, address.Address) (uint64, error) `perm:"sign"`
PaychNewPayment func(ctx context.Context, from, to address.Address, vouchers []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"`
PaychVoucherCheck func(context.Context, *paych.SignedVoucher) error `perm:"read"`
PaychVoucherCheckValid func(context.Context, address.Address, *paych.SignedVoucher) error `perm:"read"`
PaychVoucherCheckSpendable func(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (bool, error) `perm:"read"`
PaychVoucherAdd func(context.Context, address.Address, *paych.SignedVoucher, []byte, types.BigInt) (types.BigInt, error) `perm:"write"`
PaychVoucherCreate func(context.Context, address.Address, big.Int, uint64) (*api.VoucherCreateResult, error) `perm:"sign"`
PaychVoucherList func(context.Context, address.Address) ([]*paych.SignedVoucher, error) `perm:"write"`
PaychVoucherSubmit func(context.Context, address.Address, *paych.SignedVoucher, []byte, []byte) (cid.Cid, error) `perm:"sign"`
}
}
@@ -234,7 +245,7 @@ type StorageMinerStruct struct {
MarketImportDealData func(context.Context, cid.Cid, string) error `perm:"write"`
MarketListDeals func(ctx context.Context) ([]storagemarket.StorageDeal, error) `perm:"read"`
MarketListRetrievalDeals func(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) `perm:"read"`
MarketGetDealUpdates func(ctx context.Context, d cid.Cid) (<-chan storagemarket.MinerDeal, error) `perm:"read"`
MarketGetDealUpdates func(ctx context.Context) (<-chan storagemarket.MinerDeal, error) `perm:"read"`
MarketListIncompleteDeals func(ctx context.Context) ([]storagemarket.MinerDeal, error) `perm:"read"`
MarketSetAsk func(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error `perm:"admin"`
MarketGetAsk func(ctx context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
@@ -316,7 +327,8 @@ type WorkerStruct struct {
FinalizeSector func(context.Context, abi.SectorID, []storage.Range) error `perm:"admin"`
ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error `perm:"admin"`
Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
MoveStorage func(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error `perm:"admin"`
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"`
ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (bool, error) `perm:"admin"`
@@ -369,6 +381,22 @@ func (c *CommonStruct) NetAutoNatStatus(ctx context.Context) (api.NatInfo, error
return c.Internal.NetAutoNatStatus(ctx)
}
func (c *CommonStruct) NetBandwidthStats(ctx context.Context) (metrics.Stats, error) {
return c.Internal.NetBandwidthStats(ctx)
}
func (c *CommonStruct) NetBandwidthStatsByPeer(ctx context.Context) (map[string]metrics.Stats, error) {
return c.Internal.NetBandwidthStatsByPeer(ctx)
}
func (c *CommonStruct) NetBandwidthStatsByProtocol(ctx context.Context) (map[protocol.ID]metrics.Stats, error) {
return c.Internal.NetBandwidthStatsByProtocol(ctx)
}
func (c *CommonStruct) NetAgentVersion(ctx context.Context, p peer.ID) (string, error) {
return c.Internal.NetAgentVersion(ctx, p)
}
// ID implements API.ID
func (c *CommonStruct) ID(ctx context.Context) (peer.ID, error) {
return c.Internal.ID(ctx)
@@ -433,6 +461,10 @@ func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, e
return c.Internal.ClientListDeals(ctx)
}
func (c *FullNodeStruct) ClientGetDealUpdates(ctx context.Context) (<-chan api.DealInfo, error) {
return c.Internal.ClientGetDealUpdates(ctx)
}
func (c *FullNodeStruct) ClientRetrieve(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error {
return c.Internal.ClientRetrieve(ctx, order, ref)
}
@@ -464,6 +496,10 @@ func (c *FullNodeStruct) ClientDataTransferUpdates(ctx context.Context) (<-chan
return c.Internal.ClientDataTransferUpdates(ctx)
}
func (c *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error {
return c.Internal.ClientRetrieveTryRestartInsufficientFunds(ctx, paymentChannel)
}
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)
}
@@ -648,8 +684,8 @@ func (c *FullNodeStruct) ChainGetPath(ctx context.Context, from types.TipSetKey,
return c.Internal.ChainGetPath(ctx, from, to)
}
func (c *FullNodeStruct) ChainExport(ctx context.Context, tsk types.TipSetKey) (<-chan []byte, error) {
return c.Internal.ChainExport(ctx, tsk)
func (c *FullNodeStruct) ChainExport(ctx context.Context, nroots abi.ChainEpoch, tsk types.TipSetKey) (<-chan []byte, error) {
return c.Internal.ChainExport(ctx, nroots, tsk)
}
func (c *FullNodeStruct) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
@@ -680,7 +716,7 @@ func (c *FullNodeStruct) StateNetworkName(ctx context.Context) (dtypes.NetworkNa
return c.Internal.StateNetworkName(ctx)
}
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, filter *abi.BitField, filterOut bool, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, filter *bitfield.BitField, filterOut bool, tsk types.TipSetKey) ([]*api.ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, filter, filterOut, tsk)
}
@@ -708,7 +744,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) (bitfield.BitField, error) {
return c.Internal.StateMinerFaults(ctx, actor, tsk)
}
@@ -716,7 +752,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) (bitfield.BitField, error) {
return c.Internal.StateMinerRecoveries(ctx, actor, tsk)
}
@@ -876,6 +912,14 @@ func (c *FullNodeStruct) PaychGetWaitReady(ctx context.Context, sentinel cid.Cid
return c.Internal.PaychGetWaitReady(ctx, sentinel)
}
func (c *FullNodeStruct) PaychAvailableFunds(ch address.Address) (*api.ChannelAvailableFunds, error) {
return c.Internal.PaychAvailableFunds(ch)
}
func (c *FullNodeStruct) PaychAvailableFundsByFromTo(from, to address.Address) (*api.ChannelAvailableFunds, error) {
return c.Internal.PaychAvailableFundsByFromTo(from, to)
}
func (c *FullNodeStruct) PaychList(ctx context.Context) ([]address.Address, error) {
return c.Internal.PaychList(ctx)
}
@@ -896,7 +940,7 @@ func (c *FullNodeStruct) PaychVoucherAdd(ctx context.Context, addr address.Addre
return c.Internal.PaychVoucherAdd(ctx, addr, sv, proof, minDelta)
}
func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*paych.SignedVoucher, error) {
func (c *FullNodeStruct) PaychVoucherCreate(ctx context.Context, pch address.Address, amt types.BigInt, lane uint64) (*api.VoucherCreateResult, error) {
return c.Internal.PaychVoucherCreate(ctx, pch, amt, lane)
}
@@ -920,8 +964,8 @@ func (c *FullNodeStruct) PaychNewPayment(ctx context.Context, from, to address.A
return c.Internal.PaychNewPayment(ctx, from, to, vouchers)
}
func (c *FullNodeStruct) PaychVoucherSubmit(ctx context.Context, ch address.Address, sv *paych.SignedVoucher) (cid.Cid, error) {
return c.Internal.PaychVoucherSubmit(ctx, ch, sv)
func (c *FullNodeStruct) PaychVoucherSubmit(ctx context.Context, ch address.Address, sv *paych.SignedVoucher, secret []byte, proof []byte) (cid.Cid, error) {
return c.Internal.PaychVoucherSubmit(ctx, ch, sv, secret, proof)
}
// StorageMinerStruct
@@ -1064,8 +1108,8 @@ func (c *StorageMinerStruct) MarketListRetrievalDeals(ctx context.Context) ([]re
return c.Internal.MarketListRetrievalDeals(ctx)
}
func (c *StorageMinerStruct) MarketGetDealUpdates(ctx context.Context, d cid.Cid) (<-chan storagemarket.MinerDeal, error) {
return c.Internal.MarketGetDealUpdates(ctx, d)
func (c *StorageMinerStruct) MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error) {
return c.Internal.MarketGetDealUpdates(ctx)
}
func (c *StorageMinerStruct) MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) {
@@ -1214,8 +1258,12 @@ func (w *WorkerStruct) Remove(ctx context.Context, sector abi.SectorID) error {
return w.Internal.Remove(ctx, sector)
}
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID) error {
return w.Internal.MoveStorage(ctx, sector)
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error {
return w.Internal.MoveStorage(ctx, sector, types)
}
func (w *WorkerStruct) StorageAddLocal(ctx context.Context, path string) error {
return w.Internal.StorageAddLocal(ctx, path)
}
func (w *WorkerStruct) UnsealPiece(ctx context.Context, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"fmt"
"io"
abi "github.com/filecoin-project/specs-actors/actors/abi"
abi "github.com/filecoin-project/go-state-types/abi"
paych "github.com/filecoin-project/specs-actors/actors/builtin/paych"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
+9 -8
View File
@@ -1,6 +1,7 @@
package client
import (
"context"
"net/http"
"net/url"
"path"
@@ -14,9 +15,9 @@ import (
)
// NewCommonRPC creates a new http jsonrpc client.
func NewCommonRPC(addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) {
func NewCommonRPC(ctx context.Context, addr string, requestHeader http.Header) (api.Common, jsonrpc.ClientCloser, error) {
var res apistruct.CommonStruct
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
[]interface{}{
&res.Internal,
},
@@ -27,9 +28,9 @@ func NewCommonRPC(addr string, requestHeader http.Header) (api.Common, jsonrpc.C
}
// NewFullNodeRPC creates a new http jsonrpc client.
func NewFullNodeRPC(addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) {
func NewFullNodeRPC(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) {
var res apistruct.FullNodeStruct
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
[]interface{}{
&res.CommonStruct.Internal,
&res.Internal,
@@ -39,9 +40,9 @@ 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, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) {
func NewStorageMinerRPC(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.StorageMiner, jsonrpc.ClientCloser, error) {
var res apistruct.StorageMinerStruct
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
[]interface{}{
&res.CommonStruct.Internal,
&res.Internal,
@@ -53,7 +54,7 @@ func NewStorageMinerRPC(addr string, requestHeader http.Header, opts ...jsonrpc.
return &res, closer, err
}
func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WorkerAPI, jsonrpc.ClientCloser, error) {
u, err := url.Parse(addr)
if err != nil {
return nil, nil, err
@@ -69,7 +70,7 @@ func NewWorkerRPC(addr string, requestHeader http.Header) (api.WorkerAPI, jsonrp
u.Path = path.Join(u.Path, "../streams/v0/push")
var res apistruct.WorkerStruct
closer, err := jsonrpc.NewMergeClient(addr, "Filecoin",
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
[]interface{}{
&res.Internal,
},
+21 -3
View File
@@ -14,8 +14,10 @@ import (
"github.com/ipfs/go-cid"
"github.com/ipfs/go-filestore"
metrics "github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
protocol "github.com/libp2p/go-libp2p-core/protocol"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/multiformats/go-multiaddr"
@@ -26,9 +28,9 @@ import (
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/go-multistore"
"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"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/api/apistruct"
@@ -133,6 +135,22 @@ func init() {
InvalidMessageDeliveries: 3,
},
})
addExample(map[string]metrics.Stats{
"12D3KooWSXmXLJmBR1M7i9RW9GQPNUhZSzXKzxDHWtAgNuJAbyEJ": {
RateIn: 100,
RateOut: 50,
TotalIn: 174000,
TotalOut: 12500,
},
})
addExample(map[protocol.ID]metrics.Stats{
"/fil/hello/1.0.0": {
RateIn: 100,
RateOut: 50,
TotalIn: 174000,
TotalOut: 12500,
},
})
maddr, err := multiaddr.NewMultiaddr("/ip4/52.36.61.156/tcp/1347/p2p/12D3KooWFETiESTf1v4PGUvtnxMAcEFMzLZbJGg4tjWfGEimYior")
if err != nil {
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"testing"
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/specs-actors/actors/abi"
)
type BlockMiner struct {
@@ -41,7 +41,7 @@ func (bm *BlockMiner) MineBlocks() {
nulls := atomic.SwapInt64(&bm.nulls, 0)
if err := bm.miner.MineOne(bm.ctx, miner.MineReq{
InjectNulls: abi.ChainEpoch(nulls),
Done: func(bool, error) {},
Done: func(bool, abi.ChainEpoch, error) {},
}); err != nil {
bm.t.Error(err)
}
+1 -1
View File
@@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl"
+16 -13
View File
@@ -20,6 +20,7 @@ import (
"github.com/ipld/go-car"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
@@ -35,7 +36,7 @@ import (
var MineNext = miner.MineReq{
InjectNulls: 0,
Done: func(bool, error) {},
Done: func(bool, abi.ChainEpoch, error) {},
}
func init() {
@@ -333,7 +334,7 @@ loop:
func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode, deal *cid.Cid) {
subCtx, cancel := context.WithCancel(ctx)
defer cancel()
updates, err := miner.MarketGetDealUpdates(subCtx, *deal)
updates, err := miner.MarketGetDealUpdates(subCtx)
if err != nil {
t.Fatal(err)
}
@@ -342,18 +343,20 @@ func waitDealPublished(t *testing.T, ctx context.Context, miner TestStorageNode,
case <-ctx.Done():
t.Fatal("context timeout")
case di := <-updates:
switch di.State {
case storagemarket.StorageDealProposalRejected:
t.Fatal("deal rejected")
case storagemarket.StorageDealFailing:
t.Fatal("deal failed")
case storagemarket.StorageDealError:
t.Fatal("deal errored", di.Message)
case storagemarket.StorageDealFinalizing, storagemarket.StorageDealSealing, storagemarket.StorageDealActive:
fmt.Println("COMPLETE", di)
return
if deal.Equals(di.ProposalCid) {
switch di.State {
case storagemarket.StorageDealProposalRejected:
t.Fatal("deal rejected")
case storagemarket.StorageDealFailing:
t.Fatal("deal failed")
case storagemarket.StorageDealError:
t.Fatal("deal errored", di.Message)
case storagemarket.StorageDealFinalizing, storagemarket.StorageDealSealing, storagemarket.StorageDealActive:
fmt.Println("COMPLETE", di)
return
}
fmt.Println("Deal state: ", storagemarket.DealStates[di.State])
}
fmt.Println("Deal state: ", storagemarket.DealStates[di.State])
}
}
}
+8 -10
View File
@@ -12,7 +12,7 @@ import (
logging "github.com/ipfs/go-log/v2"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/lotus/build"
@@ -31,22 +31,20 @@ func (ts *testSuite) testMining(t *testing.T) {
newHeads, err := api.ChainNotify(ctx)
require.NoError(t, err)
initHead := (<-newHeads)[0]
if initHead.Val.Height() != 2 {
<-newHeads
}
baseHeight := initHead.Val.Height()
h1, err := api.ChainHead(ctx)
require.NoError(t, err)
require.Equal(t, abi.ChainEpoch(2), h1.Height())
require.Equal(t, int64(h1.Height()), int64(baseHeight))
err = sn[0].MineOne(ctx, MineNext)
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
require.NoError(t, err)
<-newHeads
h2, err := api.ChainHead(ctx)
require.NoError(t, err)
require.Equal(t, abi.ChainEpoch(3), h2.Height())
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
}
func (ts *testSuite) testMiningReal(t *testing.T) {
@@ -70,7 +68,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
require.NoError(t, err)
require.Equal(t, abi.ChainEpoch(2), h1.Height())
err = sn[0].MineOne(ctx, MineNext)
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
require.NoError(t, err)
<-newHeads
@@ -79,7 +77,7 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
require.NoError(t, err)
require.Equal(t, abi.ChainEpoch(3), h2.Height())
err = sn[0].MineOne(ctx, MineNext)
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
require.NoError(t, err)
<-newHeads
@@ -144,7 +142,7 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
complChan := minedTwo
for atomic.LoadInt32(&mine) != 0 {
wait := make(chan int)
mdone := func(mined bool, err error) {
mdone := func(mined bool, _ abi.ChainEpoch, err error) {
n := 0
if mined {
n = 1
+10 -4
View File
@@ -10,8 +10,8 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/ipfs/go-cid"
@@ -96,18 +96,24 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
if err != nil {
t.Fatal(err)
}
if vouch1.Voucher == nil {
t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouch1.Shortfall))
}
vouch2, err := paymentCreator.PaychVoucherCreate(ctx, channel, abi.NewTokenAmount(2000), lane)
if err != nil {
t.Fatal(err)
}
delta1, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch1, nil, abi.NewTokenAmount(1000))
if vouch2.Voucher == nil {
t.Fatal(fmt.Errorf("Not enough funds to create voucher: missing %d", vouch2.Shortfall))
}
delta1, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch1.Voucher, nil, abi.NewTokenAmount(1000))
if err != nil {
t.Fatal(err)
}
if !delta1.Equals(abi.NewTokenAmount(1000)) {
t.Fatal("voucher didn't have the right amount")
}
delta2, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch2, nil, abi.NewTokenAmount(1000))
delta2, err := paymentReceiver.PaychVoucherAdd(ctx, channel, vouch2.Voucher, nil, abi.NewTokenAmount(1000))
if err != nil {
t.Fatal(err)
}
+51 -1
View File
@@ -3,11 +3,13 @@ package test
import (
"context"
"testing"
"time"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/miner"
)
func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.Address, amount abi.TokenAmount) {
@@ -34,3 +36,51 @@ func SendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.
t.Fatal("did not successfully send money")
}
}
func MineUntilBlock(ctx context.Context, t *testing.T, fn TestNode, sn TestStorageNode, cb func(abi.ChainEpoch)) {
for i := 0; i < 1000; i++ {
var success bool
var err error
var epoch abi.ChainEpoch
wait := make(chan struct{})
mineErr := sn.MineOne(ctx, miner.MineReq{
Done: func(win bool, ep abi.ChainEpoch, e error) {
success = win
err = e
epoch = ep
wait <- struct{}{}
},
})
if mineErr != nil {
t.Fatal(mineErr)
}
<-wait
if err != nil {
t.Fatal(err)
}
if success {
// Wait until it shows up on the given full nodes ChainHead
nloops := 50
for i := 0; i < nloops; i++ {
ts, err := fn.ChainHead(ctx)
if err != nil {
t.Fatal(err)
}
if ts.Height() == epoch {
break
}
if i == nloops-1 {
t.Fatal("block never managed to sync to node")
}
time.Sleep(time.Millisecond * 10)
}
if cb != nil {
cb(epoch)
}
return
}
t.Log("did not mine block, trying again", i)
}
t.Fatal("failed to mine 1000 times in a row...")
}
+6 -2
View File
@@ -12,9 +12,9 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/mock"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/specs-actors/actors/abi"
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/api"
@@ -53,7 +53,7 @@ func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSect
defer close(done)
for mine {
build.Clock.Sleep(blocktime)
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, error) {
if err := sn[0].MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
}}); err != nil {
t.Error(err)
@@ -216,6 +216,10 @@ func TestWindowPost(t *testing.T, b APIBuilder, blocktime time.Duration, nSector
sn, err := parts[0].Sectors.First()
require.NoError(t, err)
all, err := parts[0].Sectors.All(2)
require.NoError(t, err)
fmt.Println("the sectors", all)
s = abi.SectorID{
Miner: abi.ActorID(mid),
Number: abi.SectorNumber(sn),
+4 -3
View File
@@ -6,8 +6,8 @@ import (
"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/go-state-types/abi"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/ipfs/go-cid"
@@ -96,7 +96,8 @@ type MessageSendSpec struct {
}
var DefaultMessageSendSpec = MessageSendSpec{
MaxFee: big.Zero(),
// MaxFee of 0.1FIL
MaxFee: abi.NewTokenAmount(int64(build.FilecoinPrecision) / 10),
}
func (ms *MessageSendSpec) Get() MessageSendSpec {
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/crypto"
)
type SignFunc = func(context.Context, []byte) (*crypto.Signature, error)
+5 -2
View File
@@ -3,13 +3,16 @@
package build
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
)
const UpgradeBreezeHeight = 0
const BreezeGasTampingDuration = 0
func init() {
power.ConsensusMinerMinPower = big.NewInt(2048)
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/node/modules/dtypes"
+1 -1
View File
@@ -5,7 +5,7 @@ package build
import (
"math/big"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
)
+4 -1
View File
@@ -10,7 +10,7 @@ package build
import (
"math/big"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
)
@@ -69,4 +69,7 @@ var (
PackingEfficiencyNum int64 = 4
PackingEfficiencyDenom int64 = 5
UpgradeBreezeHeight abi.ChainEpoch = 0
BreezeGasTampingDuration abi.ChainEpoch = 0
)
+5 -2
View File
@@ -5,13 +5,16 @@
package build
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
)
const UpgradeBreezeHeight = 41280
const BreezeGasTampingDuration = 120
func init() {
power.ConsensusMinerMinPower = big.NewInt(10 << 40)
miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{
+2 -2
View File
@@ -25,7 +25,7 @@ func buildType() string {
}
// BuildVersion is the local build version, set by build system
const BuildVersion = "0.5.2"
const BuildVersion = "0.6.0"
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, 12, 0)
var APIVersion Version = newVer(0, 14, 0)
//nolint:varcheck,deadcode
const (
+1 -1
View File
@@ -3,7 +3,7 @@ package aerrors
import (
"fmt"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/filecoin-project/go-state-types/exitcode"
"golang.org/x/xerrors"
)
+1 -1
View File
@@ -3,8 +3,8 @@ package aerrors_test
import (
"testing"
"github.com/filecoin-project/go-state-types/exitcode"
. "github.com/filecoin-project/lotus/chain/actors/aerrors"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/stretchr/testify/assert"
"golang.org/x/xerrors"
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"errors"
"fmt"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/filecoin-project/go-state-types/exitcode"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
)
+5 -1
View File
@@ -3,7 +3,7 @@ package beacon
import (
"context"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
logging "github.com/ipfs/go-log"
"golang.org/x/xerrors"
@@ -37,6 +37,10 @@ func ValidateBlockValues(b RandomBeacon, h *types.BlockHeader, prevEntry types.B
return nil
}
if len(h.BeaconEntries) == 0 {
return xerrors.Errorf("expected to have beacon entries in this block, but didn't find any")
}
last := h.BeaconEntries[len(h.BeaconEntries)-1]
if last.Round != maxRound {
return xerrors.Errorf("expected final beacon entry in block to be at round %d, got %d", maxRound, last.Round)
+1 -1
View File
@@ -19,7 +19,7 @@ import (
logging "github.com/ipfs/go-log"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/beacon"
+1 -1
View File
@@ -6,8 +6,8 @@ import (
"encoding/binary"
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/minio/blake2b-simd"
"golang.org/x/xerrors"
)
+6
View File
@@ -308,6 +308,12 @@ func (client *BlockSync) GetChainMessages(
length uint64,
) ([]*CompactedMessages, error) {
ctx, span := trace.StartSpan(ctx, "GetChainMessages")
if span.IsRecordingEvents() {
span.AddAttributes(
trace.StringAttribute("tipset", fmt.Sprint(head.Cids())),
trace.Int64Attribute("count", int64(length)),
)
}
defer span.End()
req := &Request{
+24 -15
View File
@@ -221,37 +221,36 @@ func collectChainSegment(
func gatherMessages(cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [][]uint64, []*types.SignedMessage, [][]uint64, error) {
blsmsgmap := make(map[cid.Cid]uint64)
secpkmsgmap := make(map[cid.Cid]uint64)
var secpkmsgs []*types.SignedMessage
var blsmsgs []*types.Message
var secpkincl, blsincl [][]uint64
var blscids, secpkcids []cid.Cid
for _, block := range ts.Blocks() {
bmsgs, smsgs, err := cs.MessagesForBlock(block)
bc, sc, err := cs.ReadMsgMetaCids(block.Messages)
if err != nil {
return nil, nil, nil, nil, err
}
// FIXME: DRY. Use `chain.Message` interface.
bmi := make([]uint64, 0, len(bmsgs))
for _, m := range bmsgs {
i, ok := blsmsgmap[m.Cid()]
bmi := make([]uint64, 0, len(bc))
for _, m := range bc {
i, ok := blsmsgmap[m]
if !ok {
i = uint64(len(blsmsgs))
blsmsgs = append(blsmsgs, m)
blsmsgmap[m.Cid()] = i
i = uint64(len(blscids))
blscids = append(blscids, m)
blsmsgmap[m] = i
}
bmi = append(bmi, i)
}
blsincl = append(blsincl, bmi)
smi := make([]uint64, 0, len(smsgs))
for _, m := range smsgs {
i, ok := secpkmsgmap[m.Cid()]
smi := make([]uint64, 0, len(sc))
for _, m := range sc {
i, ok := secpkmsgmap[m]
if !ok {
i = uint64(len(secpkmsgs))
secpkmsgs = append(secpkmsgs, m)
secpkmsgmap[m.Cid()] = i
i = uint64(len(secpkcids))
secpkcids = append(secpkcids, m)
secpkmsgmap[m] = i
}
smi = append(smi, i)
@@ -259,5 +258,15 @@ func gatherMessages(cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [
secpkincl = append(secpkincl, smi)
}
blsmsgs, err := cs.LoadMessagesFromCids(blscids)
if err != nil {
return nil, nil, nil, nil, err
}
secpkmsgs, err := cs.LoadSignedMessagesFromCids(secpkcids)
if err != nil {
return nil, nil, nil, nil, err
}
return blsmsgs, blsincl, secpkmsgs, secpkincl, nil
}
+3 -2
View File
@@ -5,7 +5,7 @@ import (
"sync"
"time"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2"
"golang.org/x/xerrors"
@@ -35,6 +35,7 @@ type eventAPI interface {
ChainNotify(context.Context) (<-chan []*api.HeadChange, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
ChainHead(context.Context) (*types.TipSet, error)
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
@@ -57,7 +58,7 @@ type Events struct {
func NewEvents(ctx context.Context, api eventAPI) *Events {
gcConfidence := 2 * build.ForkLengthThreshold
tsc := newTSCache(gcConfidence, api.ChainGetTipSetByHeight)
tsc := newTSCache(gcConfidence, api)
e := &Events{
api: api,
+5 -2
View File
@@ -5,7 +5,7 @@ import (
"math"
"sync"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
@@ -307,7 +307,10 @@ func (e *hcEvents) onHeadChanged(check CheckFunc, hnd EventHandler, rev RevertHa
defer e.lk.Unlock()
// Check if the event has already occurred
ts := e.tsc.best()
ts, err := e.tsc.best()
if err != nil {
return 0, xerrors.Errorf("error getting best tipset: %w", err)
}
done, more, err := check(ts)
if err != nil {
return 0, xerrors.Errorf("called check error (h: %d): %w", ts.Height(), err)
+12 -3
View File
@@ -4,8 +4,9 @@ import (
"context"
"sync"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/types"
)
@@ -152,8 +153,12 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence
e.lk.Lock() // Tricky locking, check your locks if you modify this function!
bestH := e.tsc.best().Height()
best, err := e.tsc.best()
if err != nil {
return xerrors.Errorf("error getting best tipset: %w", err)
}
bestH := best.Height()
if bestH >= h+abi.ChainEpoch(confidence) {
ts, err := e.tsc.getNonNull(h)
if err != nil {
@@ -172,7 +177,11 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence
}
e.lk.Lock()
bestH = e.tsc.best().Height()
best, err = e.tsc.best()
if err != nil {
return xerrors.Errorf("error getting best tipset: %w", err)
}
bestH = best.Height()
}
defer e.lk.Unlock()
+16 -5
View File
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
@@ -46,6 +46,10 @@ type fakeCS struct {
sub func(rev, app []*types.TipSet)
}
func (fcs *fakeCS) ChainHead(ctx context.Context) (*types.TipSet, error) {
panic("implement me")
}
func (fcs *fakeCS) ChainGetTipSet(ctx context.Context, key types.TipSetKey) (*types.TipSet, error) {
return fcs.tipsets[key], nil
}
@@ -110,7 +114,11 @@ func (fcs *fakeCS) makeTs(t *testing.T, parents []cid.Cid, h abi.ChainEpoch, msg
func (fcs *fakeCS) ChainNotify(context.Context) (<-chan []*api.HeadChange, error) {
out := make(chan []*api.HeadChange, 1)
out <- []*api.HeadChange{{Type: store.HCCurrent, Val: fcs.tsc.best()}}
best, err := fcs.tsc.best()
if err != nil {
return nil, err
}
out <- []*api.HeadChange{{Type: store.HCCurrent, Val: best}}
fcs.sub = func(rev, app []*types.TipSet) {
notif := make([]*api.HeadChange, len(rev)+len(app))
@@ -174,7 +182,8 @@ func (fcs *fakeCS) advance(rev, app int, msgs map[int]cid.Cid, nulls ...int) { /
var revs []*types.TipSet
for i := 0; i < rev; i++ {
ts := fcs.tsc.best()
ts, err := fcs.tsc.best()
require.NoError(fcs.t, err)
if _, ok := nullm[int(ts.Height())]; !ok {
revs = append(revs, ts)
@@ -196,7 +205,9 @@ func (fcs *fakeCS) advance(rev, app int, msgs map[int]cid.Cid, nulls ...int) { /
continue
}
ts := fcs.makeTs(fcs.t, fcs.tsc.best().Key().Cids(), fcs.h, mc)
best, err := fcs.tsc.best()
require.NoError(fcs.t, err)
ts := fcs.makeTs(fcs.t, best.Key().Cids(), fcs.h, mc)
require.NoError(fcs.t, fcs.tsc.add(ts))
if hasMsgs {
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"context"
"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/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
+3 -3
View File
@@ -13,11 +13,11 @@ import (
cbornode "github.com/ipfs/go-ipld-cbor"
"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/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/util/adt"
tutils "github.com/filecoin-project/specs-actors/support/testing"
+15 -8
View File
@@ -3,13 +3,16 @@ package events
import (
"context"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/types"
)
type tsByHFunc func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
type tsCacheAPI interface {
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
ChainHead(context.Context) (*types.TipSet, error)
}
// tipSetCache implements a simple ring-buffer cache to keep track of recent
// tipsets
@@ -18,10 +21,10 @@ type tipSetCache struct {
start int
len int
storage tsByHFunc
storage tsCacheAPI
}
func newTSCache(cap abi.ChainEpoch, storage tsByHFunc) *tipSetCache {
func newTSCache(cap abi.ChainEpoch, storage tsCacheAPI) *tipSetCache {
return &tipSetCache{
cache: make([]*types.TipSet, cap),
start: 0,
@@ -94,7 +97,7 @@ func (tsc *tipSetCache) getNonNull(height abi.ChainEpoch) (*types.TipSet, error)
func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
if tsc.len == 0 {
log.Warnf("tipSetCache.get: cache is empty, requesting from storage (h=%d)", height)
return tsc.storage(context.TODO(), height, types.EmptyTSK)
return tsc.storage.ChainGetTipSetByHeight(context.TODO(), height, types.EmptyTSK)
}
headH := tsc.cache[tsc.start].Height()
@@ -114,14 +117,18 @@ func (tsc *tipSetCache) get(height abi.ChainEpoch) (*types.TipSet, error) {
if height < tail.Height() {
log.Warnf("tipSetCache.get: requested tipset not in cache, requesting from storage (h=%d; tail=%d)", height, tail.Height())
return tsc.storage(context.TODO(), height, tail.Key())
return tsc.storage.ChainGetTipSetByHeight(context.TODO(), height, tail.Key())
}
return tsc.cache[normalModulo(tsc.start-int(headH-height), clen)], nil
}
func (tsc *tipSetCache) best() *types.TipSet {
return tsc.cache[tsc.start]
func (tsc *tipSetCache) best() (*types.TipSet, error) {
best := tsc.cache[tsc.start]
if best == nil {
return tsc.storage.ChainHead(context.TODO())
}
return best, nil
}
func normalModulo(n, m int) int {
+61 -15
View File
@@ -4,8 +4,8 @@ import (
"context"
"testing"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
@@ -13,10 +13,7 @@ import (
)
func TestTsCache(t *testing.T) {
tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) {
t.Fatal("storage call")
return &types.TipSet{}, nil
})
tsc := newTSCache(50, &tsCacheAPIFailOnStorageCall{t: t})
h := abi.ChainEpoch(75)
@@ -43,7 +40,12 @@ func TestTsCache(t *testing.T) {
for i := 0; i < 9000; i++ {
if i%90 > 60 {
if err := tsc.revert(tsc.best()); err != nil {
best, err := tsc.best()
if err != nil {
t.Fatal(err, "; i:", i)
return
}
if err := tsc.revert(best); err != nil {
t.Fatal(err, "; i:", i)
return
}
@@ -55,11 +57,21 @@ func TestTsCache(t *testing.T) {
}
type tsCacheAPIFailOnStorageCall struct {
t *testing.T
}
func (tc *tsCacheAPIFailOnStorageCall) ChainGetTipSetByHeight(ctx context.Context, epoch abi.ChainEpoch, key types.TipSetKey) (*types.TipSet, error) {
tc.t.Fatal("storage call")
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIFailOnStorageCall) ChainHead(ctx context.Context) (*types.TipSet, error) {
tc.t.Fatal("storage call")
return &types.TipSet{}, nil
}
func TestTsCacheNulls(t *testing.T) {
tsc := newTSCache(50, func(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error) {
t.Fatal("storage call")
return &types.TipSet{}, nil
})
tsc := newTSCache(50, &tsCacheAPIFailOnStorageCall{t: t})
h := abi.ChainEpoch(75)
@@ -91,7 +103,9 @@ func TestTsCacheNulls(t *testing.T) {
add()
add()
require.Equal(t, h-1, tsc.best().Height())
best, err := tsc.best()
require.NoError(t, err)
require.Equal(t, h-1, best.Height())
ts, err := tsc.get(h - 1)
require.NoError(t, err)
@@ -109,9 +123,17 @@ func TestTsCacheNulls(t *testing.T) {
require.NoError(t, err)
require.Equal(t, h-8, ts.Height())
require.NoError(t, tsc.revert(tsc.best()))
require.NoError(t, tsc.revert(tsc.best()))
require.Equal(t, h-8, tsc.best().Height())
best, err = tsc.best()
require.NoError(t, err)
require.NoError(t, tsc.revert(best))
best, err = tsc.best()
require.NoError(t, err)
require.NoError(t, tsc.revert(best))
best, err = tsc.best()
require.NoError(t, err)
require.Equal(t, h-8, best.Height())
h += 50
add()
@@ -120,3 +142,27 @@ func TestTsCacheNulls(t *testing.T) {
require.NoError(t, err)
require.Equal(t, h-1, ts.Height())
}
type tsCacheAPIStorageCallCounter struct {
t *testing.T
chainGetTipSetByHeight int
chainHead int
}
func (tc *tsCacheAPIStorageCallCounter) ChainGetTipSetByHeight(ctx context.Context, epoch abi.ChainEpoch, key types.TipSetKey) (*types.TipSet, error) {
tc.chainGetTipSetByHeight++
return &types.TipSet{}, nil
}
func (tc *tsCacheAPIStorageCallCounter) ChainHead(ctx context.Context) (*types.TipSet, error) {
tc.chainHead++
return &types.TipSet{}, nil
}
func TestTsCacheEmpty(t *testing.T) {
// Calling best on an empty cache should just call out to the chain API
callCounter := &tsCacheAPIStorageCallCounter{t: t}
tsc := newTSCache(50, callCounter)
_, err := tsc.best()
require.NoError(t, err)
require.Equal(t, 1, callCounter.chainHead)
}
+12 -10
View File
@@ -8,11 +8,13 @@ import (
"sync/atomic"
"time"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"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/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
saminer "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/crypto"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
@@ -46,7 +48,7 @@ const msgsPerBlock = 20
//nolint:deadcode,varcheck
var log = logging.Logger("gen")
var ValidWpostForTesting = []abi.PoStProof{{
var ValidWpostForTesting = []proof.PoStProof{{
ProofBytes: []byte("valid proof"),
}}
@@ -457,7 +459,7 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch,
wpost []abi.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
wpost []proof.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
var ts uint64
if cg.Timestamper != nil {
@@ -588,7 +590,7 @@ func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*cr
type WinningPoStProver interface {
GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error)
ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error)
ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error)
}
type wppProvider struct{}
@@ -597,7 +599,7 @@ func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandom
return []uint64{0}, nil
}
func (wpp *wppProvider) ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error) {
func (wpp *wppProvider) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) {
return ValidWpostForTesting, nil
}
@@ -664,15 +666,15 @@ type genFakeVerifier struct{}
var _ ffiwrapper.Verifier = (*genFakeVerifier)(nil)
func (m genFakeVerifier) VerifySeal(svi abi.SealVerifyInfo) (bool, error) {
func (m genFakeVerifier) VerifySeal(svi proof.SealVerifyInfo) (bool, error) {
return true, nil
}
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info abi.WinningPoStVerifyInfo) (bool, error) {
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) {
panic("not supported")
}
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info abi.WindowPoStVerifyInfo) (bool, error) {
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) {
panic("not supported")
}
+2 -2
View File
@@ -3,8 +3,8 @@ package gen
import (
"testing"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
+10 -3
View File
@@ -6,6 +6,8 @@ import (
"encoding/json"
"fmt"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
cbor "github.com/ipfs/go-ipld-cbor"
@@ -14,13 +16,13 @@ import (
"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/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/account"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/build"
@@ -404,6 +406,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
var sum abi.PaddedPieceSize
nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion {
return runtime.NetworkVersion1
}
vmopt := vm.VMOpts{
StateBase: stateroot,
Epoch: 0,
@@ -411,6 +417,7 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
CircSupplyCalc: nil,
NtwkVersion: nwv,
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(&vmopt)
+8 -3
View File
@@ -14,15 +14,15 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"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/market"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/lotus/chain/store"
@@ -61,6 +61,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
return big.Zero(), nil
}
nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion {
return runtime.NetworkVersion1
}
vmopt := &vm.VMOpts{
StateBase: sroot,
Epoch: 0,
@@ -68,6 +72,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
Bstore: cs.Blockstore(),
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
CircSupplyCalc: csc,
NtwkVersion: nwv,
BaseFee: types.NewInt(0),
}
+1 -1
View File
@@ -3,7 +3,7 @@ package genesis
import (
"context"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
+1 -1
View File
@@ -3,7 +3,7 @@ package gen
import (
"context"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/util/adt"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
+1 -1
View File
@@ -9,8 +9,8 @@ import (
ds "github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
)
type SlashFilter struct {
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"context"
"sync"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"go.uber.org/fx"
"github.com/filecoin-project/specs-actors/actors/builtin"
+2 -2
View File
@@ -10,9 +10,9 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/crypto"
tutils "github.com/filecoin-project/specs-actors/support/testing"
"github.com/filecoin-project/lotus/api"
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
)
+313 -93
View File
@@ -6,12 +6,12 @@ import (
"errors"
"fmt"
"math"
stdbig "math/big"
"sort"
"sync"
"time"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/hashicorp/go-multierror"
lru "github.com/hashicorp/golang-lru"
"github.com/ipfs/go-cid"
@@ -38,14 +38,21 @@ import (
var log = logging.Logger("messagepool")
const futureDebug = false
var futureDebug = false
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 RepublishInterval = time.Duration(10*build.BlockDelaySecs+build.PropagationDelaySecs) * time.Second
var minimumBaseFee = types.NewInt(uint64(build.MinimumBaseFee))
var baseFeeLowerBoundFactor = types.NewInt(10)
var MaxActorPendingMessages = 1000
var MaxNonceGap = uint64(4)
var (
ErrMessageTooBig = errors.New("message too big")
@@ -54,12 +61,16 @@ var (
ErrNonceTooLow = errors.New("message nonce too low")
ErrGasFeeCapTooLow = errors.New("gas fee cap too low")
ErrNotEnoughFunds = errors.New("not enough funds to execute transaction")
ErrInvalidToAddr = errors.New("message had invalid to address")
ErrBroadcastAnyway = errors.New("broadcasting message despite validation fail")
ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium")
ErrSoftValidationFailure = errors.New("validation failure")
ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium")
ErrTooManyPendingMessages = errors.New("too many pending messages for actor")
ErrNonceGap = errors.New("unfulfilled nonce gap")
ErrTryAgain = errors.New("state inconsistency while pushing message; please try again")
)
@@ -70,6 +81,18 @@ const (
localUpdates = "update"
)
// this is *temporary* mutilation until we have implemented uncapped miner penalties -- it will go
// away in the next fork.
var strictBaseFeeValidation = false
func init() {
// if the republish interval is too short compared to the pubsub timecache, adjust it
minInterval := pubsub.TimeCacheDuration + time.Duration(build.PropagationDelaySecs)
if RepublishInterval < minInterval {
RepublishInterval = minInterval
}
}
type MessagePool struct {
lk sync.Mutex
@@ -118,22 +141,44 @@ type MessagePool struct {
}
type msgSet struct {
msgs map[uint64]*types.SignedMessage
nextNonce uint64
msgs map[uint64]*types.SignedMessage
nextNonce uint64
requiredFunds *stdbig.Int
}
func newMsgSet() *msgSet {
func newMsgSet(nonce uint64) *msgSet {
return &msgSet{
msgs: make(map[uint64]*types.SignedMessage),
msgs: make(map[uint64]*types.SignedMessage),
nextNonce: nonce,
requiredFunds: stdbig.NewInt(0),
}
}
func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool) (bool, error) {
if len(ms.msgs) == 0 || m.Message.Nonce >= ms.nextNonce {
ms.nextNonce = m.Message.Nonce + 1
func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict bool) (bool, error) {
nextNonce := ms.nextNonce
nonceGap := false
switch {
case m.Message.Nonce == nextNonce:
nextNonce++
// advance if we are filling a gap
for _, fillGap := ms.msgs[nextNonce]; fillGap; _, fillGap = ms.msgs[nextNonce] {
nextNonce++
}
case strict && m.Message.Nonce > nextNonce+MaxNonceGap:
return false, xerrors.Errorf("message nonce has too big a gap from expected nonce (Nonce: %d, nextNonce: %d): %w", m.Message.Nonce, nextNonce, ErrNonceGap)
case m.Message.Nonce > nextNonce:
nonceGap = true
}
exms, has := ms.msgs[m.Message.Nonce]
if has {
// refuse RBF if we have a gap
if strict && nonceGap {
return false, xerrors.Errorf("rejecting replace by fee because of nonce gap (Nonce: %d, nextNonce: %d): %w", m.Message.Nonce, nextNonce, ErrNonceGap)
}
if m.Cid() != exms.Cid() {
// check if RBF passes
minPrice := exms.Message.GasPremium
@@ -149,22 +194,87 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool) (bool, error) {
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPremium,
ErrRBFTooLowPremium)
}
} else {
return false, xerrors.Errorf("message from %s with nonce %d already in mpool: %w",
m.Message.From, m.Message.Nonce, ErrSoftValidationFailure)
}
ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.RequiredFunds().Int)
//ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.Value.Int)
}
if !has && strict && len(ms.msgs) > MaxActorPendingMessages {
log.Errorf("too many pending messages from actor %s", m.Message.From)
return false, ErrTooManyPendingMessages
}
if strict && nonceGap {
log.Warnf("adding nonce-gapped message from %s (nonce: %d, nextNonce: %d)",
m.Message.From, m.Message.Nonce, nextNonce)
}
ms.nextNonce = nextNonce
ms.msgs[m.Message.Nonce] = m
ms.requiredFunds.Add(ms.requiredFunds, m.Message.RequiredFunds().Int)
//ms.requiredFunds.Add(ms.requiredFunds, m.Message.Value.Int)
return !has, nil
}
func (ms *msgSet) rm(nonce uint64, applied bool) {
m, has := ms.msgs[nonce]
if !has {
if applied && nonce >= ms.nextNonce {
// we removed a message we did not know about because it was applied
// we need to adjust the nonce and check if we filled a gap
ms.nextNonce = nonce + 1
for _, fillGap := ms.msgs[ms.nextNonce]; fillGap; _, fillGap = ms.msgs[ms.nextNonce] {
ms.nextNonce++
}
}
return
}
ms.requiredFunds.Sub(ms.requiredFunds, m.Message.RequiredFunds().Int)
//ms.requiredFunds.Sub(ms.requiredFunds, m.Message.Value.Int)
delete(ms.msgs, nonce)
// adjust next nonce
if applied {
// we removed a (known) message because it was applied in a tipset
// we can't possibly have filled a gap in this case
if nonce >= ms.nextNonce {
ms.nextNonce = nonce + 1
}
return
}
// we removed a message because it was pruned
// we have to adjust the nonce if it creates a gap or rewinds state
if nonce < ms.nextNonce {
ms.nextNonce = nonce
}
}
func (ms *msgSet) getRequiredFunds(nonce uint64) types.BigInt {
requiredFunds := new(stdbig.Int).Set(ms.requiredFunds)
m, has := ms.msgs[nonce]
if has {
requiredFunds.Sub(requiredFunds, m.Message.RequiredFunds().Int)
//requiredFunds.Sub(requiredFunds, m.Message.Value.Int)
}
return types.BigInt{Int: requiredFunds}
}
func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*MessagePool, error) {
cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
verifcache, _ := lru.New2Q(build.VerifSigCacheSize)
cfg, err := loadConfig(ds)
if err != nil {
if err != nil {
return nil, xerrors.Errorf("error loading mpool config: %w", err)
}
return nil, xerrors.Errorf("error loading mpool config: %w", err)
}
mp := &MessagePool{
@@ -190,12 +300,7 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
// enable initial prunes
mp.pruneCooldown <- struct{}{}
if err := mp.loadLocal(); err != nil {
log.Errorf("loading local messages: %+v", err)
}
go mp.runLoop()
// load the current tipset and subscribe to head changes _before_ loading local messages
mp.curTs = api.SubscribeHeadChanges(func(rev, app []*types.TipSet) error {
err := mp.HeadChange(rev, app)
if err != nil {
@@ -204,6 +309,12 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
return err
})
if err := mp.loadLocal(); err != nil {
log.Errorf("loading local messages: %+v", err)
}
go mp.runLoop()
return mp, nil
}
@@ -256,13 +367,48 @@ func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error {
return nil
}
func (mp *MessagePool) verifyMsgBeforePush(m *types.SignedMessage, epoch abi.ChainEpoch) error {
// verifyMsgBeforeAdd verifies that the message meets the minimum criteria for block inclusio
// and whether the message has enough funds to be included in the next 20 blocks.
// If the message is not valid for block inclusion, it returns an error.
// For local messages, if the message can be included in the next 20 blocks, it returns true to
// signal that it should be immediately published. If the message cannot be included in the next 20
// blocks, it returns false so that the message doesn't immediately get published (and ignored by our
// peers); instead it will be published through the republish loop, once the base fee has fallen
// sufficiently.
// For non local messages, if the message cannot be included in the next 20 blocks it returns
// a (soft) validation error.
func (mp *MessagePool) verifyMsgBeforeAdd(m *types.SignedMessage, curTs *types.TipSet, local bool) (bool, error) {
epoch := curTs.Height()
minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength())
if err := m.VMMessage().ValidForBlockInclusion(minGas.Total()); err != nil {
return xerrors.Errorf("message will not be included in a block: %w", err)
return false, xerrors.Errorf("message will not be included in a block: %w", err)
}
return nil
// this checks if the GasFeeCap is suffisciently high for inclusion in the next 20 blocks
// if the GasFeeCap is too low, we soft reject the message (Ignore in pubsub) and rely
// on republish to push it through later, if the baseFee has fallen.
// this is a defensive check that stops minimum baseFee spam attacks from overloading validation
// queues.
// Note that for local messages, we always add them so that they can be accepted and republished
// automatically.
publish := local
if strictBaseFeeValidation && len(curTs.Blocks()) > 0 {
baseFee := curTs.Blocks()[0].ParentBaseFee
baseFeeLowerBound := types.BigDiv(baseFee, baseFeeLowerBoundFactor)
if m.Message.GasFeeCap.LessThan(baseFeeLowerBound) {
if local {
log.Warnf("local message will not be immediately published because GasFeeCap doesn't meet the lower bound for inclusion in the next 20 blocks (GasFeeCap: %s, baseFeeLowerBound: %s)",
m.Message.GasFeeCap, baseFeeLowerBound)
publish = false
} else {
return false, xerrors.Errorf("GasFeeCap doesn't meet base fee lower bound for inclusion in the next 20 blocks (GasFeeCap: %s, baseFeeLowerBound: %s): %w",
m.Message.GasFeeCap, baseFeeLowerBound, ErrSoftValidationFailure)
}
}
}
return publish, nil
}
func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
@@ -277,26 +423,14 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
<-mp.addSema
}()
mp.curTsLk.Lock()
curTs := mp.curTs
epoch := curTs.Height()
mp.curTsLk.Unlock()
if err := mp.verifyMsgBeforePush(m, epoch); err != nil {
return cid.Undef, err
}
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, err
}
mp.curTsLk.Lock()
if mp.curTs != curTs {
mp.curTsLk.Unlock()
return cid.Undef, ErrTryAgain
}
if err := mp.addTs(m, mp.curTs); err != nil {
publish, err := mp.addTs(m, mp.curTs, true)
if err != nil {
mp.curTsLk.Unlock()
return cid.Undef, err
}
@@ -309,7 +443,11 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
}
mp.lk.Unlock()
return m.Cid(), mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
if publish {
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
}
return m.Cid(), err
}
func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
@@ -318,7 +456,7 @@ func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
return xerrors.Errorf("mpool message too large (%dB): %w", m.Size(), ErrMessageTooBig)
}
// Perform syntaxtic validation, minGas=0 as we check if correctly in select messages
// Perform syntactic validation, minGas=0 as we check the actual mingas before we add it
if err := m.Message.ValidForBlockInclusion(0); err != nil {
return xerrors.Errorf("message not valid for block inclusion: %w", err)
}
@@ -331,8 +469,12 @@ func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
return ErrMessageValueTooHigh
}
if m.Message.GasFeeCap.LessThan(minimumBaseFee) {
return ErrGasFeeCapTooLow
}
if err := mp.VerifyMsgSig(m); err != nil {
log.Warnf("mpooladd signature verification failed: %s", err)
log.Warnf("signature verification failed: %s", err)
return err
}
@@ -353,7 +495,9 @@ func (mp *MessagePool) Add(m *types.SignedMessage) error {
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
return mp.addTs(m, mp.curTs)
_, err = mp.addTs(m, mp.curTs, false)
return err
}
func sigCacheKey(m *types.SignedMessage) (string, error) {
@@ -392,48 +536,107 @@ func (mp *MessagePool) VerifyMsgSig(m *types.SignedMessage) error {
return nil
}
func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet) error {
func (mp *MessagePool) checkBalance(m *types.SignedMessage, curTs *types.TipSet) error {
balance, err := mp.getStateBalance(m.Message.From, curTs)
if err != nil {
return xerrors.Errorf("failed to check sender balance: %s: %w", err, ErrSoftValidationFailure)
}
requiredFunds := m.Message.RequiredFunds()
if balance.LessThan(requiredFunds) {
return xerrors.Errorf("not enough funds (required: %s, balance: %s): %w", types.FIL(requiredFunds), types.FIL(balance), ErrNotEnoughFunds)
}
// add Value for soft failure check
//requiredFunds = types.BigAdd(requiredFunds, m.Message.Value)
mset, ok := mp.pending[m.Message.From]
if ok {
requiredFunds = types.BigAdd(requiredFunds, mset.getRequiredFunds(m.Message.Nonce))
}
if balance.LessThan(requiredFunds) {
// Note: we fail here for ErrSoftValidationFailure to signal a soft failure because we might
// be out of sync.
return xerrors.Errorf("not enough funds including pending messages (required: %s, balance: %s): %w", types.FIL(requiredFunds), types.FIL(balance), ErrSoftValidationFailure)
}
return nil
}
func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local bool) (bool, error) {
snonce, err := mp.getStateNonce(m.Message.From, curTs)
if err != nil {
return xerrors.Errorf("failed to look up actor state nonce: %s: %w", err, ErrBroadcastAnyway)
return false, xerrors.Errorf("failed to look up actor state nonce: %s: %w", err, ErrSoftValidationFailure)
}
if snonce > m.Message.Nonce {
return false, xerrors.Errorf("minimum expected nonce is %d: %w", snonce, ErrNonceTooLow)
}
mp.lk.Lock()
defer mp.lk.Unlock()
publish, err := mp.verifyMsgBeforeAdd(m, curTs, local)
if err != nil {
return false, err
}
if err := mp.checkBalance(m, curTs); err != nil {
return false, err
}
return publish, mp.addLocked(m, true)
}
func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
err := mp.checkMessage(m)
if err != nil {
return err
}
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
curTs := mp.curTs
snonce, err := mp.getStateNonce(m.Message.From, curTs)
if err != nil {
return xerrors.Errorf("failed to look up actor state nonce: %s: %w", err, ErrSoftValidationFailure)
}
if snonce > m.Message.Nonce {
return xerrors.Errorf("minimum expected nonce is %d: %w", snonce, ErrNonceTooLow)
}
balance, err := mp.getStateBalance(m.Message.From, curTs)
if err != nil {
return xerrors.Errorf("failed to check sender balance: %s: %w", err, ErrBroadcastAnyway)
}
if balance.LessThan(m.Message.RequiredFunds()) {
return xerrors.Errorf("not enough funds (required: %s, balance: %s): %w", types.FIL(m.Message.RequiredFunds()), types.FIL(balance), ErrNotEnoughFunds)
}
mp.lk.Lock()
defer mp.lk.Unlock()
return mp.addLocked(m)
_, err = mp.verifyMsgBeforeAdd(m, curTs, true)
if err != nil {
return err
}
if err := mp.checkBalance(m, curTs); err != nil {
return err
}
return mp.addLocked(m, false)
}
func (mp *MessagePool) addSkipChecks(m *types.SignedMessage) error {
mp.lk.Lock()
defer mp.lk.Unlock()
return mp.addLocked(m)
return mp.addLocked(m, false)
}
func (mp *MessagePool) addLocked(m *types.SignedMessage) error {
func (mp *MessagePool) addLocked(m *types.SignedMessage, strict bool) error {
log.Debugf("mpooladd: %s %d", m.Message.From, m.Message.Nonce)
if m.Signature.Type == crypto.SigTypeBLS {
mp.blsSigCache.Add(m.Cid(), m.Signature)
}
if m.Message.GasLimit > build.BlockGasLimit {
return xerrors.Errorf("given message has too high of a gas limit")
}
if _, err := mp.api.PutMessage(m); err != nil {
log.Warnf("mpooladd cs.PutMessage failed: %s", err)
return err
@@ -446,13 +649,18 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage) error {
mset, ok := mp.pending[m.Message.From]
if !ok {
mset = newMsgSet()
nonce, err := mp.getStateNonce(m.Message.From, mp.curTs)
if err != nil {
return xerrors.Errorf("failed to get initial actor nonce: %w", err)
}
mset = newMsgSet(nonce)
mp.pending[m.Message.From] = mset
}
incr, err := mset.add(m, mp)
incr, err := mset.add(m, mp, strict)
if err != nil {
log.Info(err)
log.Debug(err)
return err
}
@@ -561,6 +769,16 @@ func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address,
return nil, err
}
err = mp.checkMessage(msg)
if err != nil {
return nil, err
}
msgb, err := msg.Serialize()
if err != nil {
return nil, err
}
// reacquire the locks and check state for consistency
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
@@ -581,33 +799,37 @@ func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address,
return nil, ErrTryAgain
}
if err := mp.verifyMsgBeforePush(msg, mp.curTs.Height()); err != nil {
return nil, err
}
msgb, err := msg.Serialize()
publish, err := mp.verifyMsgBeforeAdd(msg, curTs, true)
if err != nil {
return nil, err
}
if err := mp.addLocked(msg); err != nil {
if err := mp.checkBalance(msg, curTs); err != nil {
return nil, err
}
if err := mp.addLocked(msg, true); err != nil {
return nil, xerrors.Errorf("add locked failed: %w", err)
}
if err := mp.addLocal(msg, msgb); err != nil {
log.Errorf("addLocal failed: %+v", err)
}
return msg, mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
if publish {
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
}
return msg, err
}
func (mp *MessagePool) Remove(from address.Address, nonce uint64) {
func (mp *MessagePool) Remove(from address.Address, nonce uint64, applied bool) {
mp.lk.Lock()
defer mp.lk.Unlock()
mp.remove(from, nonce)
mp.remove(from, nonce, applied)
}
func (mp *MessagePool) remove(from address.Address, nonce uint64) {
func (mp *MessagePool) remove(from address.Address, nonce uint64, applied bool) {
mset, ok := mp.pending[from]
if !ok {
return
@@ -624,22 +846,10 @@ func (mp *MessagePool) remove(from address.Address, nonce uint64) {
// NB: This deletes any message with the given nonce. This makes sense
// as two messages with the same sender cannot have the same nonce
delete(mset.msgs, nonce)
mset.rm(nonce, applied)
if len(mset.msgs) == 0 {
delete(mp.pending, from)
} else {
var max uint64
for nonce := range mset.msgs {
if max < nonce {
max = nonce
}
}
if max < nonce {
max = nonce // we could have not seen the removed message before
}
mset.nextNonce = max + 1
}
}
@@ -650,6 +860,10 @@ func (mp *MessagePool) Pending() ([]*types.SignedMessage, *types.TipSet) {
mp.lk.Lock()
defer mp.lk.Unlock()
return mp.allPending()
}
func (mp *MessagePool) allPending() ([]*types.SignedMessage, *types.TipSet) {
out := make([]*types.SignedMessage, 0)
for a := range mp.pending {
out = append(out, mp.pendingFor(a)...)
@@ -657,6 +871,7 @@ func (mp *MessagePool) Pending() ([]*types.SignedMessage, *types.TipSet) {
return out, mp.curTs
}
func (mp *MessagePool) PendingFor(a address.Address) ([]*types.SignedMessage, *types.TipSet) {
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
@@ -702,7 +917,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
rm := func(from address.Address, nonce uint64) {
s, ok := rmsgs[from]
if !ok {
mp.Remove(from, nonce)
mp.Remove(from, nonce, true)
return
}
@@ -711,7 +926,7 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
return
}
mp.Remove(from, nonce)
mp.Remove(from, nonce, true)
}
maybeRepub := func(cid cid.Cid) {
@@ -789,7 +1004,9 @@ func (mp *MessagePool) HeadChange(revert []*types.TipSet, apply []*types.TipSet)
}
if len(revert) > 0 && futureDebug {
msgs, ts := mp.Pending()
mp.lk.Lock()
msgs, ts := mp.allPending()
mp.lk.Unlock()
buckets := map[address.Address]*statBucket{}
@@ -900,8 +1117,6 @@ func (mp *MessagePool) runHeadChange(from *types.TipSet, to *types.TipSet, rmsgs
}
for _, ts := range apply {
mp.curTs = ts
for _, b := range ts.Blocks() {
bmsgs, smsgs, err := mp.api.MessagesForBlock(b)
if err != nil {
@@ -974,6 +1189,7 @@ func (mp *MessagePool) Updates(ctx context.Context) (<-chan api.MpoolUpdate, err
go func() {
defer mp.changes.Unsub(sub, localUpdates)
defer close(out)
for {
select {
@@ -982,9 +1198,13 @@ func (mp *MessagePool) Updates(ctx context.Context) (<-chan api.MpoolUpdate, err
case out <- u.(api.MpoolUpdate):
case <-ctx.Done():
return
case <-mp.closer:
return
}
case <-ctx.Done():
return
case <-mp.closer:
return
}
}
}()
@@ -1008,7 +1228,7 @@ func (mp *MessagePool) loadLocal() error {
return xerrors.Errorf("unmarshaling local message: %w", err)
}
if err := mp.Add(&sm); err != nil {
if err := mp.addLoaded(&sm); err != nil {
if xerrors.Is(err, ErrNonceTooLow) {
continue // todo: drop the message from local cache (if above certain confidence threshold)
}
+280 -2
View File
@@ -7,13 +7,14 @@ import (
"testing"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"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"
logging "github.com/ipfs/go-log/v2"
@@ -31,6 +32,10 @@ type testMpoolAPI struct {
balance map[address.Address]types.BigInt
tipsets []*types.TipSet
published int
baseFee types.BigInt
}
func newTestMpoolAPI() *testMpoolAPI {
@@ -38,6 +43,7 @@ func newTestMpoolAPI() *testMpoolAPI {
bmsgs: make(map[cid.Cid][]*types.SignedMessage),
statenonce: make(map[address.Address]uint64),
balance: make(map[address.Address]types.BigInt),
baseFee: types.NewInt(100),
}
genesis := mock.MkBlock(nil, 1, 1)
tma.tipsets = append(tma.tipsets, mock.TipSet(genesis))
@@ -90,10 +96,16 @@ func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) {
}
func (tma *testMpoolAPI) PubSubPublish(string, []byte) error {
tma.published++
return nil
}
func (tma *testMpoolAPI) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
// regression check for load bug
if ts == nil {
panic("GetActorAfter called with nil tipset")
}
balance, ok := tma.balance[addr]
if !ok {
balance = types.NewInt(1000e6)
@@ -173,7 +185,7 @@ func (tma *testMpoolAPI) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
}
func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
return types.NewInt(100), nil
return tma.baseFee, nil
}
func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) {
@@ -281,6 +293,11 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
}
func TestRevertMessages(t *testing.T) {
futureDebug = true
defer func() {
futureDebug = false
}()
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@@ -338,6 +355,12 @@ func TestRevertMessages(t *testing.T) {
}
func TestPruningSimple(t *testing.T) {
oldMaxNonceGap := MaxNonceGap
MaxNonceGap = 1000
defer func() {
MaxNonceGap = oldMaxNonceGap
}()
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@@ -359,6 +382,7 @@ func TestPruningSimple(t *testing.T) {
if err != nil {
t.Fatal(err)
}
tma.setBalance(sender, 1) // in FIL
target := mock.Address(1001)
for i := 0; i < 5; i++ {
@@ -385,3 +409,257 @@ func TestPruningSimple(t *testing.T) {
t.Fatal("expected only 5 messages in pool, got: ", len(msgs))
}
}
func TestLoadLocal(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(tma, ds, "mptest")
if err != nil {
t.Fatal(err)
}
// 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)
}
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
msgs := make(map[cid.Cid]struct{})
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
cid, err := mp.Push(m)
if err != nil {
t.Fatal(err)
}
msgs[cid] = struct{}{}
}
err = mp.Close()
if err != nil {
t.Fatal(err)
}
mp, err = New(tma, ds, "mptest")
if err != nil {
t.Fatal(err)
}
pmsgs, _ := mp.Pending()
if len(msgs) != len(pmsgs) {
t.Fatalf("expected %d messages, but got %d", len(msgs), len(pmsgs))
}
for _, m := range pmsgs {
cid := m.Cid()
_, ok := msgs[cid]
if !ok {
t.Fatal("unknown message")
}
delete(msgs, cid)
}
if len(msgs) > 0 {
t.Fatalf("not all messages were laoded; missing %d messages", len(msgs))
}
}
func TestClearAll(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(tma, ds, "mptest")
if err != nil {
t.Fatal(err)
}
// 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)
}
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m)
if err != nil {
t.Fatal(err)
}
}
for i := 0; i < 10; i++ {
m := makeTestMessage(w2, a2, a1, uint64(i), gasLimit, uint64(i+1))
mustAdd(t, mp, m)
}
mp.Clear(true)
pending, _ := mp.Pending()
if len(pending) > 0 {
t.Fatalf("cleared the mpool, but got %d pending messages", len(pending))
}
}
func TestClearNonLocal(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(tma, ds, "mptest")
if err != nil {
t.Fatal(err)
}
// 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)
}
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m)
if err != nil {
t.Fatal(err)
}
}
for i := 0; i < 10; i++ {
m := makeTestMessage(w2, a2, a1, uint64(i), gasLimit, uint64(i+1))
mustAdd(t, mp, m)
}
mp.Clear(false)
pending, _ := mp.Pending()
if len(pending) != 10 {
t.Fatalf("expected 10 pending messages, but got %d instead", len(pending))
}
for _, m := range pending {
if m.Message.From != a1 {
t.Fatalf("expected message from %s but got one from %s instead", a1, m.Message.From)
}
}
}
func TestUpdates(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(tma, ds, "mptest")
if err != nil {
t.Fatal(err)
}
// 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)
}
ctx, cancel := context.WithCancel(context.TODO())
defer cancel()
ch, err := mp.Updates(ctx)
if err != nil {
t.Fatal(err)
}
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m)
if err != nil {
t.Fatal(err)
}
_, ok := <-ch
if !ok {
t.Fatal("expected update, but got a closed channel instead")
}
}
err = mp.Close()
if err != nil {
t.Fatal(err)
}
_, ok := <-ch
if ok {
t.Fatal("expected closed channel, but got an update instead")
}
}
+1 -1
View File
@@ -98,7 +98,7 @@ keepLoop:
// and remove all messages that are still in pruneMsgs after processing the chains
log.Infof("Pruning %d messages", len(pruneMsgs))
for _, m := range pruneMsgs {
mp.remove(m.Message.From, m.Message.Nonce)
mp.remove(m.Message.From, m.Message.Nonce, false)
}
return nil
+29 -16
View File
@@ -3,6 +3,7 @@ package messagepool
import (
"context"
"sort"
"time"
"golang.org/x/xerrors"
@@ -15,6 +16,8 @@ import (
const repubMsgLimit = 30
var RepublishBatchDelay = 100 * time.Millisecond
func (mp *MessagePool) republishPendingMessages() error {
mp.curTsLk.Lock()
ts := mp.curTs
@@ -24,6 +27,7 @@ func (mp *MessagePool) republishPendingMessages() error {
mp.curTsLk.Unlock()
return xerrors.Errorf("computing basefee: %w", err)
}
baseFeeLowerBound := types.BigDiv(baseFee, baseFeeLowerBoundFactor)
pending := make(map[address.Address]map[uint64]*types.SignedMessage)
mp.lk.Lock()
@@ -52,7 +56,11 @@ func (mp *MessagePool) republishPendingMessages() error {
var chains []*msgChain
for actor, mset := range pending {
next := mp.createMessageChains(actor, mset, baseFee, ts)
// We use the baseFee lower bound for createChange so that we optimistically include
// chains that might become profitable in the next 20 blocks.
// We still check the lowerBound condition for individual messages so that we don't send
// messages that will be rejected by the mpool spam protector, so this is safe to do.
next := mp.createMessageChains(actor, mset, baseFeeLowerBound, ts)
chains = append(chains, next...)
}
@@ -64,15 +72,10 @@ func (mp *MessagePool) republishPendingMessages() error {
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
loop:
for i := 0; i < len(chains); {
chain := chains[i]
@@ -86,12 +89,6 @@ func (mp *MessagePool) republishPendingMessages() error {
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++
@@ -100,15 +97,25 @@ func (mp *MessagePool) republishPendingMessages() error {
// does it fit in a block?
if chain.gasLimit <= gasLimit {
gasLimit -= chain.gasLimit
msgs = append(msgs, chain.msgs...)
// check the baseFee lower bound -- only republish messages that can be included in the chain
// within the next 20 blocks.
for _, m := range chain.msgs {
if !allowNegativeChains(ts.Height()) && m.Message.GasFeeCap.LessThan(baseFeeLowerBound) {
chain.Invalidate()
continue loop
}
gasLimit -= m.Message.GasLimit
msgs = append(msgs, m)
}
// we processed the whole chain, advance
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)
chain.Trim(gasLimit, mp, baseFee, true)
for j := i; j < len(chains)-1; j++ {
if chains[j].Before(chains[j+1]) {
break
@@ -131,6 +138,12 @@ func (mp *MessagePool) republishPendingMessages() error {
}
count++
if count < len(msgs) {
// this delay is here to encourage the pubsub subsystem to process the messages serially
// and avoid creating nonce gaps because of concurrent validation.
time.Sleep(RepublishBatchDelay)
}
}
// track most recently republished messages
+72
View File
@@ -0,0 +1,72 @@
package messagepool
import (
"testing"
"time"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/ipfs/go-datastore"
)
func TestRepubMessages(t *testing.T) {
oldRepublishBatchDelay := RepublishBatchDelay
RepublishBatchDelay = time.Microsecond
defer func() {
RepublishBatchDelay = oldRepublishBatchDelay
}()
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(tma, ds, "mptest")
if err != nil {
t.Fatal(err)
}
// 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)
}
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m)
if err != nil {
t.Fatal(err)
}
}
if tma.published != 10 {
t.Fatalf("expected to have published 10 messages, but got %d instead", tma.published)
}
mp.repubTrigger <- struct{}{}
time.Sleep(100 * time.Millisecond)
if tma.published != 20 {
t.Fatalf("expected to have published 20 messages, but got %d instead", tma.published)
}
}
+54 -27
View File
@@ -9,15 +9,22 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
tbig "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
abig "github.com/filecoin-project/specs-actors/actors/abi/big"
)
var bigBlockGasLimit = big.NewInt(build.BlockGasLimit)
// this is *temporary* mutilation until we have implemented uncapped miner penalties -- it will go
// away in the next fork.
func allowNegativeChains(epoch abi.ChainEpoch) bool {
return epoch < build.UpgradeBreezeHeight+5
}
const MaxBlocks = 15
type msgChain struct {
@@ -100,9 +107,9 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64
return chains[i].Before(chains[j])
})
if len(chains) != 0 && chains[0].gasPerf < 0 {
if !allowNegativeChains(curTs.Height()) && 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
return result, nil
}
// 3. Parition chains into blocks (without trimming)
@@ -153,7 +160,7 @@ func (mp *MessagePool) selectMessagesOptimal(curTs, ts *types.TipSet, tq float64
last := len(chains)
for i, chain := range chains {
// did we run out of performing chains?
if chain.gasPerf < 0 {
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
break
}
@@ -217,7 +224,7 @@ tailLoop:
for gasLimit >= minGas && last < len(chains) {
// trim if necessary
if chains[last].gasLimit > gasLimit {
chains[last].Trim(gasLimit, mp, baseFee, ts, false)
chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
}
// push down if it hasn't been invalidated
@@ -243,7 +250,7 @@ tailLoop:
}
// if gasPerf < 0 we have no more profitable chains
if chain.gasPerf < 0 {
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
break tailLoop
}
@@ -284,7 +291,7 @@ tailLoop:
}
// dependencies fit, just trim it
chain.Trim(gasLimit-depGasLimit, mp, baseFee, ts, false)
chain.Trim(gasLimit-depGasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
last += i
continue tailLoop
}
@@ -349,9 +356,9 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S
return chains[i].Before(chains[j])
})
if len(chains) != 0 && chains[0].gasPerf < 0 {
if !allowNegativeChains(curTs.Height()) && 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
return result, nil
}
// 3. Merge the head chains to produce the list of messages selected for inclusion, subject to
@@ -360,7 +367,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S
last := len(chains)
for i, chain := range chains {
// did we run out of performing chains?
if chain.gasPerf < 0 {
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
break
}
@@ -389,7 +396,7 @@ func (mp *MessagePool) selectMessagesGreedy(curTs, ts *types.TipSet) ([]*types.S
tailLoop:
for gasLimit >= minGas && last < len(chains) {
// trim
chains[last].Trim(gasLimit, mp, baseFee, ts, false)
chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(curTs.Height()))
// push down if it hasn't been invalidated
if chains[last].valid {
@@ -409,7 +416,7 @@ tailLoop:
}
// if gasPerf < 0 we have no more profitable chains
if chain.gasPerf < 0 {
if !allowNegativeChains(curTs.Height()) && chain.gasPerf < 0 {
break tailLoop
}
@@ -462,15 +469,27 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui
}
}
if len(chains) == 0 {
return nil, gasLimit
}
// 2. Sort the chains
sort.Slice(chains, func(i, j int) bool {
return chains[i].Before(chains[j])
})
// 3. Merge chains until the block limit; we are willing to include negative performing chains
// as these are messages from our own miners
if !allowNegativeChains(ts.Height()) && len(chains) != 0 && chains[0].gasPerf < 0 {
log.Warnw("all priority messages in mpool have negative gas performance", "bestGasPerf", chains[0].gasPerf)
return nil, gasLimit
}
// 3. Merge chains until the block limit, as long as they have non-negative gas performance
last := len(chains)
for i, chain := range chains {
if !allowNegativeChains(ts.Height()) && chain.gasPerf < 0 {
break
}
if chain.gasLimit <= gasLimit {
gasLimit -= chain.gasLimit
result = append(result, chain.msgs...)
@@ -484,8 +503,8 @@ func (mp *MessagePool) selectPriorityMessages(pending map[address.Address]map[ui
tailLoop:
for gasLimit >= minGas && last < len(chains) {
// trim, without discarding negative performing messages
chains[last].Trim(gasLimit, mp, baseFee, ts, true)
// trim, discarding negative performing messages
chains[last].Trim(gasLimit, mp, baseFee, allowNegativeChains(ts.Height()))
// push down if it hasn't been invalidated
if chains[last].valid {
@@ -503,6 +522,12 @@ tailLoop:
if !chain.valid {
continue
}
// if gasPerf < 0 we have no more profitable chains
if !allowNegativeChains(ts.Height()) && chain.gasPerf < 0 {
break tailLoop
}
// does it fit in the bock?
if chain.gasLimit <= gasLimit {
gasLimit -= chain.gasLimit
@@ -515,9 +540,9 @@ tailLoop:
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
}
return result, gasLimit
@@ -567,16 +592,18 @@ func (mp *MessagePool) getPendingMessages(curTs, ts *types.TipSet) (map[address.
return result, nil
}
func (mp *MessagePool) getGasReward(msg *types.SignedMessage, baseFee types.BigInt, ts *types.TipSet) *big.Int {
func (*MessagePool) getGasReward(msg *types.SignedMessage, baseFee types.BigInt) *big.Int {
maxPremium := types.BigSub(msg.Message.GasFeeCap, baseFee)
if types.BigCmp(maxPremium, msg.Message.GasPremium) < 0 {
if types.BigCmp(maxPremium, msg.Message.GasPremium) > 0 {
maxPremium = msg.Message.GasPremium
}
gasReward := abig.Mul(maxPremium, types.NewInt(uint64(msg.Message.GasLimit)))
gasReward := tbig.Mul(maxPremium, types.NewInt(uint64(msg.Message.GasLimit)))
return gasReward.Int
}
func (mp *MessagePool) getGasPerf(gasReward *big.Int, gasLimit int64) float64 {
func (*MessagePool) getGasPerf(gasReward *big.Int, gasLimit int64) float64 {
// gasPerf = gasReward * build.BlockGasLimit / gasLimit
a := new(big.Rat).SetInt(new(big.Int).Mul(gasReward, bigBlockGasLimit))
b := big.NewRat(1, gasLimit)
@@ -654,7 +681,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
balance = new(big.Int).Sub(balance, value)
}
gasReward := mp.getGasReward(m, baseFee, ts)
gasReward := mp.getGasReward(m, baseFee)
rewards = append(rewards, gasReward)
}
@@ -755,10 +782,10 @@ func (mc *msgChain) Before(other *msgChain) bool {
(mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0)
}
func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, ts *types.TipSet, priority bool) {
func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, allowNegative bool) {
i := len(mc.msgs) - 1
for i >= 0 && (mc.gasLimit > gasLimit || (!priority && mc.gasPerf < 0)) {
gasReward := mp.getGasReward(mc.msgs[i], baseFee, ts)
for i >= 0 && (mc.gasLimit > gasLimit || (!allowNegative && mc.gasPerf < 0)) {
gasReward := mp.getGasReward(mc.msgs[i], baseFee)
mc.gasReward = new(big.Int).Sub(mc.gasReward, gasReward)
mc.gasLimit -= mc.msgs[i].Message.GasLimit
if mc.gasLimit > 0 {
+211 -4
View File
@@ -2,19 +2,20 @@ package messagepool
import (
"context"
"fmt"
"math"
"math/big"
"math/rand"
"testing"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock"
"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"
@@ -23,6 +24,11 @@ import (
logging "github.com/ipfs/go-log"
)
func init() {
// bump this for the selection tests
MaxActorPendingMessages = 1000000
}
func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, gasLimit int64, gasPrice uint64) *types.SignedMessage {
msg := &types.Message{
From: from,
@@ -364,6 +370,12 @@ func TestMessageChainSkipping(t *testing.T) {
}
func TestBasicMessageSelection(t *testing.T) {
oldMaxNonceGap := MaxNonceGap
MaxNonceGap = 1000
defer func() {
MaxNonceGap = oldMaxNonceGap
}()
mp, tma := makeTestMpool()
// the actors
@@ -649,6 +661,169 @@ func TestPriorityMessageSelection(t *testing.T) {
}
}
func TestPriorityMessageSelection2(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 := tma.nextBlock()
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 := int(2 * 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)
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)
}
expectedMsgs := int(build.BlockGasLimit / gasLimit)
if len(msgs) != expectedMsgs {
t.Fatalf("expected %d messages but got %d", expectedMsgs, len(msgs))
}
// all messages must be from a1
nextNonce := uint64(0)
for _, m := range msgs {
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++
}
}
func TestPriorityMessageSelection3(t *testing.T) {
t.Skip("reenable after removing allow negative")
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 := tma.nextBlock()
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}
tma.baseFee = types.NewInt(1000)
nMessages := 10
for i := 0; i < nMessages; i++ {
bias := (nMessages - i) / 3
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(1000+i%3+bias))
mustAdd(t, mp, m)
// messages from a2 have negative performance
m = makeTestMessage(w2, a2, a1, uint64(i), gasLimit, 100)
mustAdd(t, mp, m)
}
// test greedy selection
msgs, err := mp.SelectMessages(ts, 1.0)
if err != nil {
t.Fatal(err)
}
expectedMsgs := 10
if len(msgs) != expectedMsgs {
t.Fatalf("expected %d messages but got %d", expectedMsgs, len(msgs))
}
// all messages must be from a1
nextNonce := uint64(0)
for _, m := range msgs {
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++
}
// test optimal selection
msgs, err = mp.SelectMessages(ts, 0.1)
if err != nil {
t.Fatal(err)
}
expectedMsgs = 10
if len(msgs) != expectedMsgs {
t.Fatalf("expected %d messages but got %d", expectedMsgs, len(msgs))
}
// all messages must be from a1
nextNonce = uint64(0)
for _, m := range msgs {
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++
}
}
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
@@ -983,17 +1158,17 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
greedyReward := big.NewInt(0)
for _, m := range greedyMsgs {
greedyReward.Add(greedyReward, mp.getGasReward(m, baseFee, ts))
greedyReward.Add(greedyReward, mp.getGasReward(m, baseFee))
}
optReward := big.NewInt(0)
for _, m := range optMsgs {
optReward.Add(optReward, mp.getGasReward(m, baseFee, ts))
optReward.Add(optReward, mp.getGasReward(m, baseFee))
}
bestTqReward := big.NewInt(0)
for _, m := range bestMsgs {
bestTqReward.Add(bestTqReward, mp.getGasReward(m, baseFee, ts))
bestTqReward.Add(bestTqReward, mp.getGasReward(m, baseFee))
}
totalBestTQReward += float64(bestTqReward.Uint64())
@@ -1074,3 +1249,35 @@ func TestCompetitiveMessageSelectionZipf(t *testing.T) {
t.Logf("Average reward boost across all seeds: %f", rewardBoost)
t.Logf("Average reward of best ticket across all seeds: %f", tqReward)
}
func TestGasReward(t *testing.T) {
tests := []struct {
Premium uint64
FeeCap uint64
BaseFee uint64
GasReward int64
}{
{Premium: 100, FeeCap: 200, BaseFee: 100, GasReward: 100},
{Premium: 100, FeeCap: 200, BaseFee: 210, GasReward: -10},
{Premium: 200, FeeCap: 250, BaseFee: 210, GasReward: 40},
{Premium: 200, FeeCap: 250, BaseFee: 2000, GasReward: -1750},
}
mp := new(MessagePool)
for _, test := range tests {
test := test
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
msg := &types.SignedMessage{
Message: types.Message{
GasLimit: 10,
GasFeeCap: types.NewInt(test.FeeCap),
GasPremium: types.NewInt(test.Premium),
},
}
rew := mp.getGasReward(msg, types.NewInt(test.BaseFee))
if rew.Cmp(big.NewInt(test.GasReward*10)) != 0 {
t.Errorf("bad reward: expected %d, got %s", test.GasReward*10, rew)
}
})
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"encoding/json"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
+6 -4
View File
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/ipfs/go-cid"
"go.opencensus.io/trace"
"golang.org/x/xerrors"
@@ -29,6 +29,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: types.NewInt(0),
}
@@ -95,7 +96,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
state := ts.ParentState()
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
r := store.NewChainRand(sm.cs, ts.Cids())
return sm.CallRaw(ctx, msg, state, r, ts.Height())
}
@@ -113,7 +114,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
return nil, xerrors.Errorf("computing tipset state: %w", err)
}
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
r := store.NewChainRand(sm.cs, ts.Cids())
if span.IsRecordingEvents() {
span.AddAttributes(
@@ -130,6 +131,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
+302 -2
View File
@@ -3,11 +3,23 @@ package stmgr
import (
"context"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/util/adt"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
)
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, types.StateTree) error{}
var ForksAtHeight = map[abi.ChainEpoch]func(context.Context, *StateManager, types.StateTree) error{
build.UpgradeBreezeHeight: UpgradeFaucetBurnRecovery,
}
func (sm *StateManager) handleStateForks(ctx context.Context, st types.StateTree, height abi.ChainEpoch) (err error) {
f, ok := ForksAtHeight[height]
@@ -20,3 +32,291 @@ func (sm *StateManager) handleStateForks(ctx context.Context, st types.StateTree
return nil
}
type forEachTree interface {
ForEach(func(address.Address, *types.Actor) error) error
}
func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error {
fromAct, err := tree.GetActor(from)
if err != nil {
return xerrors.Errorf("failed to get 'from' actor for transfer: %w", err)
}
fromAct.Balance = types.BigSub(fromAct.Balance, amt)
if fromAct.Balance.Sign() < 0 {
return xerrors.Errorf("(sanity) deducted more funds from target account than it had (%s, %s)", from, types.FIL(amt))
}
if err := tree.SetActor(from, fromAct); err != nil {
return xerrors.Errorf("failed to persist from actor: %w", err)
}
toAct, err := tree.GetActor(to)
if err != nil {
return xerrors.Errorf("failed to get 'to' actor for transfer: %w", err)
}
toAct.Balance = types.BigAdd(toAct.Balance, amt)
if err := tree.SetActor(to, toAct); err != nil {
return xerrors.Errorf("failed to persist to actor: %w", err)
}
return nil
}
func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, tree types.StateTree) error {
// Some initial parameters
FundsForMiners := types.FromFil(1_000_000)
LookbackEpoch := abi.ChainEpoch(32000)
AccountCap := types.FromFil(0)
BaseMinerBalance := types.FromFil(20)
DesiredReimbursementBalance := types.FromFil(5_000_000)
isSystemAccount := func(addr address.Address) (bool, error) {
id, err := address.IDFromAddress(addr)
if err != nil {
return false, xerrors.Errorf("id address: %w", err)
}
if id < 1000 {
return true, nil
}
return false, nil
}
minerFundsAlloc := func(pow, tpow abi.StoragePower) abi.TokenAmount {
return types.BigDiv(types.BigMul(pow, FundsForMiners), tpow)
}
// Grab lookback state for account checks
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, LookbackEpoch, nil, false)
if err != nil {
return xerrors.Errorf("failed to get tipset at lookback height: %w", err)
}
var lbtree *state.StateTree
if err = sm.WithStateTree(lbts.ParentState(), func(state *state.StateTree) error {
lbtree = state
return nil
}); err != nil {
return xerrors.Errorf("loading state tree failed: %w", err)
}
ReserveAddress, err := address.NewFromString("t090")
if err != nil {
return xerrors.Errorf("failed to parse reserve address: %w", err)
}
fetree, ok := tree.(forEachTree)
if !ok {
return xerrors.Errorf("fork transition state tree doesnt support ForEach (%T)", tree)
}
type transfer struct {
From address.Address
To address.Address
Amt abi.TokenAmount
}
var transfers []transfer
// Take all excess funds away, put them into the reserve account
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
switch act.Code {
case builtin.AccountActorCodeID, builtin.MultisigActorCodeID, builtin.PaymentChannelActorCodeID:
sysAcc, err := isSystemAccount(addr)
if err != nil {
return xerrors.Errorf("checking system account: %w", err)
}
if !sysAcc {
transfers = append(transfers, transfer{
From: addr,
To: ReserveAddress,
Amt: act.Balance,
})
}
case builtin.StorageMinerActorCodeID:
var st miner.State
if err := sm.WithActorState(ctx, &st)(act); err != nil {
return xerrors.Errorf("failed to load miner state: %w", err)
}
var available abi.TokenAmount
{
defer func() {
if err := recover(); err != nil {
log.Warnf("Get available balance failed (%s, %s, %s): %s", addr, act.Head, act.Balance, err)
}
available = abi.NewTokenAmount(0)
}()
// this panics if the miner doesnt have enough funds to cover their locked pledge
available = st.GetAvailableBalance(act.Balance)
}
transfers = append(transfers, transfer{
From: addr,
To: ReserveAddress,
Amt: available,
})
}
return nil
})
if err != nil {
return xerrors.Errorf("foreach over state tree failed: %w", err)
}
// Execute transfers from previous step
for _, t := range transfers {
if err := doTransfer(tree, t.From, t.To, t.Amt); err != nil {
return xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
}
}
// pull up power table to give miners back some funds proportional to their power
var ps power.State
powAct, err := tree.GetActor(builtin.StoragePowerActorAddr)
if err != nil {
return xerrors.Errorf("failed to load power actor: %w", err)
}
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
if err := cst.Get(ctx, powAct.Head, &ps); err != nil {
return xerrors.Errorf("failed to get power actor state: %w", err)
}
totalPower := ps.TotalBytesCommitted
var transfersBack []transfer
// Now, we return some funds to places where they are needed
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
lbact, err := lbtree.GetActor(addr)
if err != nil {
if !xerrors.Is(err, types.ErrActorNotFound) {
return xerrors.Errorf("failed to get actor in lookback state")
}
}
prevBalance := abi.NewTokenAmount(0)
if lbact != nil {
prevBalance = lbact.Balance
}
switch act.Code {
case builtin.AccountActorCodeID, builtin.MultisigActorCodeID, builtin.PaymentChannelActorCodeID:
nbalance := big.Min(prevBalance, AccountCap)
if nbalance.Sign() != 0 {
transfersBack = append(transfersBack, transfer{
From: ReserveAddress,
To: addr,
Amt: nbalance,
})
}
case builtin.StorageMinerActorCodeID:
var st miner.State
if err := sm.WithActorState(ctx, &st)(act); err != nil {
return xerrors.Errorf("failed to load miner state: %w", err)
}
var minfo miner.MinerInfo
if err := cst.Get(ctx, st.Info, &minfo); err != nil {
return xerrors.Errorf("failed to get miner info: %w", err)
}
sectorsArr, err := adt.AsArray(sm.ChainStore().Store(ctx), st.Sectors)
if err != nil {
return xerrors.Errorf("failed to load sectors array: %w", err)
}
slen := sectorsArr.Length()
power := types.BigMul(types.NewInt(slen), types.NewInt(uint64(minfo.SectorSize)))
mfunds := minerFundsAlloc(power, totalPower)
transfersBack = append(transfersBack, transfer{
From: ReserveAddress,
To: minfo.Worker,
Amt: mfunds,
})
// Now make sure to give each miner who had power at the lookback some FIL
lbact, err := lbtree.GetActor(addr)
if err == nil {
var lbst miner.State
if err := sm.WithActorState(ctx, &lbst)(lbact); err != nil {
return xerrors.Errorf("failed to load miner state: %w", err)
}
lbsectors, err := adt.AsArray(sm.ChainStore().Store(ctx), lbst.Sectors)
if err != nil {
return xerrors.Errorf("failed to load lb sectors array: %w", err)
}
if lbsectors.Length() > 0 {
transfersBack = append(transfersBack, transfer{
From: ReserveAddress,
To: minfo.Worker,
Amt: BaseMinerBalance,
})
}
} else {
log.Warnf("failed to get miner in lookback state: %s", err)
}
}
return nil
})
if err != nil {
return xerrors.Errorf("foreach over state tree failed: %w", err)
}
for _, t := range transfersBack {
if err := doTransfer(tree, t.From, t.To, t.Amt); err != nil {
return xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
}
}
// transfer all burnt funds back to the reserve account
burntAct, err := tree.GetActor(builtin.BurntFundsActorAddr)
if err != nil {
return xerrors.Errorf("failed to load burnt funds actor: %w", err)
}
if err := doTransfer(tree, builtin.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
return xerrors.Errorf("failed to unburn funds: %w", err)
}
// Top up the reimbursement service
reimbAddr, err := address.NewFromString("t0111")
if err != nil {
return xerrors.Errorf("failed to parse reimbursement service address")
}
reimb, err := tree.GetActor(reimbAddr)
if err != nil {
return xerrors.Errorf("failed to load reimbursement account actor: %w", err)
}
difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance)
if err := doTransfer(tree, ReserveAddress, reimbAddr, difference); err != nil {
return xerrors.Errorf("failed to top up reimbursement account: %w", err)
}
// Now, a final sanity check to make sure the balances all check out
total := abi.NewTokenAmount(0)
err = fetree.ForEach(func(addr address.Address, act *types.Actor) error {
total = types.BigAdd(total, act.Balance)
return nil
})
if err != nil {
return xerrors.Errorf("checking final state balance failed: %w", err)
}
exp := types.FromFil(build.FilBase)
if !exp.Equals(total) {
return xerrors.Errorf("resultant state tree account balance was not correct: %s", total)
}
return nil
}
+2 -2
View File
@@ -7,8 +7,8 @@ import (
"testing"
"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/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
init_ "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
+18 -3
View File
@@ -5,6 +5,8 @@ import (
"fmt"
"sync"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
@@ -18,8 +20,8 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/market"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
@@ -154,6 +156,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: baseFee,
}
@@ -338,7 +341,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet
cids[i] = v.Cid()
}
r := store.NewChainRand(sm.cs, cids, blks[0].Height)
r := store.NewChainRand(sm.cs, cids)
blkmsgs, err := sm.cs.BlockMsgsForTipset(ts)
if err != nil {
@@ -1120,3 +1123,15 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
return csi.FilCirculating, nil
}
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) runtime.NetworkVersion {
if build.UpgradeBreezeHeight == 0 {
return runtime.NetworkVersion1
}
if height <= build.UpgradeBreezeHeight {
return runtime.NetworkVersion0
}
return runtime.NetworkVersion1
}
+77 -27
View File
@@ -3,8 +3,14 @@ package stmgr
import (
"bytes"
"context"
"fmt"
"os"
"reflect"
"runtime"
"strings"
saruntime "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
@@ -13,8 +19,9 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"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/account"
"github.com/filecoin-project/specs-actors/actors/builtin/cron"
@@ -26,7 +33,6 @@ import (
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
@@ -157,13 +163,13 @@ func MinerSectorInfo(ctx context.Context, sm *StateManager, maddr address.Addres
return nil, err
}
if !ok {
return nil, xerrors.New("sector not found")
return nil, nil
}
return sectorInfo, nil
}
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address, filter *bitfield.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
var mas miner.State
_, err := sm.LoadActorState(ctx, maddr, &mas, ts)
if err != nil {
@@ -173,8 +179,8 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
return LoadSectorsFromSet(ctx, sm.ChainStore().Blockstore(), mas.Sectors, filter, filterOut)
}
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
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof.SectorInfo, error) {
var partsProving []bitfield.BitField
var mas *miner.State
var info *miner.MinerInfo
@@ -261,7 +267,7 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return nil, xerrors.Errorf("failed to load sectors amt: %w", err)
}
out := make([]abi.SectorInfo, len(ids))
out := make([]proof.SectorInfo, len(ids))
for i, n := range ids {
sid := sectors[n]
@@ -272,7 +278,7 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return nil, xerrors.Errorf("failed to find sector %d", sid)
}
out[i] = abi.SectorInfo{
out[i] = proof.SectorInfo{
SealProof: spt,
SectorNumber: sinfo.SectorNumber,
SealedCID: sinfo.SealedCID,
@@ -387,7 +393,7 @@ func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([
return miners, nil
}
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid, filter *abi.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
func LoadSectorsFromSet(ctx context.Context, bs blockstore.Blockstore, ssc cid.Cid, filter *bitfield.BitField, filterOut bool) ([]*api.ChainSectorInfo, error) {
a, err := adt.AsArray(store.ActorStore(ctx, bs), ssc)
if err != nil {
return nil, err
@@ -432,7 +438,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
return cid.Undef, nil, err
}
r := store.NewChainRand(sm.cs, ts.Cids(), height)
r := store.NewChainRand(sm.cs, ts.Cids())
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: height,
@@ -440,6 +446,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: ts.Blocks()[0].ParentBaseFee,
}
vmi, err := vm.NewVM(vmopt)
@@ -586,14 +593,14 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBe
}, nil
}
type methodMeta struct {
type MethodMeta struct {
Name string
Params reflect.Type
Ret reflect.Type
}
var MethodsMap = map[cid.Cid][]methodMeta{}
var MethodsMap = map[cid.Cid]map[abi.MethodNum]MethodMeta{}
func init() {
cidToMethods := map[cid.Cid][2]interface{}{
@@ -611,25 +618,65 @@ func init() {
}
for c, m := range cidToMethods {
rt := reflect.TypeOf(m[0])
nf := rt.NumField()
exports := m[1].(saruntime.Invokee).Exports()
methods := make(map[abi.MethodNum]MethodMeta, len(exports))
MethodsMap[c] = append(MethodsMap[c], methodMeta{
// Explicitly add send, it's special.
methods[builtin.MethodSend] = MethodMeta{
Name: "Send",
Params: reflect.TypeOf(new(adt.EmptyValue)),
Ret: reflect.TypeOf(new(adt.EmptyValue)),
})
exports := m[1].(abi.Invokee).Exports()
for i := 0; i < nf; i++ {
export := reflect.TypeOf(exports[i+1])
MethodsMap[c] = append(MethodsMap[c], methodMeta{
Name: rt.Field(i).Name,
Params: export.In(1),
Ret: export.Out(0),
})
}
// Learn method names from the builtin.Methods* structs.
rv := reflect.ValueOf(m[0])
rt := rv.Type()
nf := rt.NumField()
methodToName := make([]string, len(exports))
for i := 0; i < nf; i++ {
name := rt.Field(i).Name
number := rv.Field(i).Interface().(abi.MethodNum)
methodToName[number] = name
}
// Iterate over exported methods. Some of these _may_ be nil and
// must be skipped.
for number, export := range exports {
if export == nil {
continue
}
ev := reflect.ValueOf(export)
et := ev.Type()
// Make sure the method name is correct.
// This is just a nice sanity check.
fnName := runtime.FuncForPC(ev.Pointer()).Name()
fnName = strings.TrimSuffix(fnName[strings.LastIndexByte(fnName, '.')+1:], "-fm")
mName := methodToName[number]
if mName != fnName {
panic(fmt.Sprintf(
"actor method name is %s but exported method name is %s",
fnName, mName,
))
}
switch abi.MethodNum(number) {
case builtin.MethodSend:
panic("method 0 is reserved for Send")
case builtin.MethodConstructor:
if fnName != "Constructor" {
panic("method 1 is reserved for Constructor")
}
}
methods[abi.MethodNum(number)] = MethodMeta{
Name: fnName,
Params: et.In(1),
Ret: et.Out(0),
}
}
MethodsMap[c] = methods
}
}
@@ -639,7 +686,10 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
return nil, xerrors.Errorf("getting actor: %w", err)
}
m := MethodsMap[act.Code][method]
m, found := MethodsMap[act.Code][method]
if !found {
return nil, fmt.Errorf("unknown method %d for actor %s", method, act.Code)
}
return reflect.New(m.Ret.Elem()).Interface().(cbg.CBORUnmarshaler), nil
}
+6 -2
View File
@@ -3,10 +3,10 @@ package store
import (
"context"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
)
@@ -40,6 +40,10 @@ func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int
}
func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) {
if ts.Height() > build.UpgradeBreezeHeight && ts.Height() < build.UpgradeBreezeHeight+build.BreezeGasTampingDuration {
return abi.NewTokenAmount(100), nil
}
zero := abi.NewTokenAmount(0)
// totalLimit is sum of GasLimits of unique messages in a tipset
+1 -1
View File
@@ -5,8 +5,8 @@ import (
"os"
"strconv"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/abi"
lru "github.com/hashicorp/golang-lru"
"golang.org/x/xerrors"
)
+1 -1
View File
@@ -5,11 +5,11 @@ import (
"context"
"testing"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/filecoin-project/specs-actors/actors/abi"
datastore "github.com/ipfs/go-datastore"
syncds "github.com/ipfs/go-datastore/sync"
"github.com/stretchr/testify/assert"
+55 -17
View File
@@ -5,16 +5,17 @@ import (
"context"
"encoding/binary"
"encoding/json"
"errors"
"io"
"os"
"strconv"
"sync"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/minio/blake2b-simd"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/api"
@@ -49,6 +50,9 @@ var chainHeadKey = dstore.NewKey("head")
var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation")
var DefaultTipSetCacheSize = 8192
var DefaultMsgMetaCacheSize = 2048
var ErrNotifieeDone = errors.New("notifee is done and should be removed")
func init() {
if s := os.Getenv("LOTUS_CHAIN_TIPSET_CACHE"); s != "" {
@@ -58,6 +62,14 @@ func init() {
}
DefaultTipSetCacheSize = tscs
}
if s := os.Getenv("LOTUS_CHAIN_MSGMETA_CACHE"); s != "" {
mmcs, err := strconv.Atoi(s)
if err != nil {
log.Errorf("failed to parse 'LOTUS_CHAIN_MSGMETA_CACHE' env var: %s", err)
}
DefaultMsgMetaCacheSize = mmcs
}
}
// ReorgNotifee represents a callback that gets called upon reorgs.
@@ -97,7 +109,7 @@ type ChainStore struct {
}
func NewChainStore(bs bstore.Blockstore, ds dstore.Batching, vmcalls vm.SyscallBuilder) *ChainStore {
c, _ := lru.NewARC(2048)
c, _ := lru.NewARC(DefaultMsgMetaCacheSize)
tsc, _ := lru.NewARC(DefaultTipSetCacheSize)
cs := &ChainStore{
bs: bs,
@@ -349,11 +361,33 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo
apply[i], apply[opp] = apply[opp], apply[i]
}
for _, hcf := range notifees {
if err := hcf(revert, apply); err != nil {
log.Error("head change func errored (BAD): ", err)
var toremove map[int]struct{}
for i, hcf := range notifees {
err := hcf(revert, apply)
if err != nil {
if err == ErrNotifieeDone {
if toremove == nil {
toremove = make(map[int]struct{})
}
toremove[i] = struct{}{}
} else {
log.Error("head change func errored (BAD): ", err)
}
}
}
if len(toremove) > 0 {
newNotifees := make([]ReorgNotifee, 0, len(notifees)-len(toremove))
for i, hcf := range notifees {
_, remove := toremove[i]
if remove {
continue
}
newNotifees = append(newNotifees, hcf)
}
notifees = newNotifees
}
case <-ctx.Done():
return
}
@@ -834,7 +868,7 @@ type mmCids struct {
secpk []cid.Cid
}
func (cs *ChainStore) readMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) {
func (cs *ChainStore) ReadMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) {
o, ok := cs.mmCache.Get(mmc)
if ok {
mmcids := o.(*mmCids)
@@ -890,7 +924,7 @@ func (cs *ChainStore) GetPath(ctx context.Context, from types.TipSetKey, to type
}
func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
blscids, secpkcids, err := cs.readMsgMetaCids(b.Messages)
blscids, secpkcids, err := cs.ReadMsgMetaCids(b.Messages)
if err != nil {
return nil, nil, err
}
@@ -1114,7 +1148,7 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
return cs.LoadTipSet(lbts.Parents())
}
func recurseLinks(bs bstore.Blockstore, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) {
func recurseLinks(bs bstore.Blockstore, walked *cid.Set, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) {
if root.Prefix().Codec != cid.DagCBOR {
return in, nil
}
@@ -1131,9 +1165,14 @@ func recurseLinks(bs bstore.Blockstore, root cid.Cid, in []cid.Cid) ([]cid.Cid,
return
}
// traversed this already...
if !walked.Visit(c) {
return
}
in = append(in, c)
var err error
in, err = recurseLinks(bs, c, in)
in, err = recurseLinks(bs, walked, c, in)
if err != nil {
rerr = err
}
@@ -1145,12 +1184,13 @@ func recurseLinks(bs bstore.Blockstore, root cid.Cid, in []cid.Cid) ([]cid.Cid,
return in, rerr
}
func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, w io.Writer) error {
func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRoots abi.ChainEpoch, w io.Writer) error {
if ts == nil {
ts = cs.GetHeaviestTipSet()
}
seen := cid.NewSet()
walked := cid.NewSet()
h := &car.CarHeader{
Roots: ts.Cids(),
@@ -1182,7 +1222,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, w io.Writer)
return xerrors.Errorf("unmarshaling block header (cid=%s): %w", blk, err)
}
cids, err := recurseLinks(cs.bs, b.Messages, []cid.Cid{b.Messages})
cids, err := recurseLinks(cs.bs, walked, b.Messages, []cid.Cid{b.Messages})
if err != nil {
return xerrors.Errorf("recursing messages failed: %w", err)
}
@@ -1198,8 +1238,8 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, w io.Writer)
out := cids
if b.Height == 0 {
cids, err := recurseLinks(cs.bs, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot})
if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots {
cids, err := recurseLinks(cs.bs, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot})
if err != nil {
return xerrors.Errorf("recursing genesis state failed: %w", err)
}
@@ -1282,14 +1322,12 @@ func (cs *ChainStore) GetLatestBeaconEntry(ts *types.TipSet) (*types.BeaconEntry
type chainRand struct {
cs *ChainStore
blks []cid.Cid
bh abi.ChainEpoch
}
func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight abi.ChainEpoch) vm.Rand {
func NewChainRand(cs *ChainStore, blks []cid.Cid) vm.Rand {
return &chainRand{
cs: cs,
blks: blks,
bh: bheight,
}
}
+4 -4
View File
@@ -7,12 +7,12 @@ import (
datastore "github.com/ipfs/go-datastore"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/store"
@@ -96,7 +96,7 @@ func TestChainExportImport(t *testing.T) {
}
buf := new(bytes.Buffer)
if err := cg.ChainStore().Export(context.TODO(), last, buf); err != nil {
if err := cg.ChainStore().Export(context.TODO(), last, 0, buf); err != nil {
t.Fatal(err)
}
+2 -2
View File
@@ -4,10 +4,10 @@ import (
"context"
"math/big"
big2 "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
big2 "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"
cbor "github.com/ipfs/go-ipld-cbor"
@@ -41,7 +41,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
var st power.State
if err := cst.Get(ctx, act.Head, &st); err != nil {
return types.NewInt(0), xerrors.Errorf("get power actor head: %w", err)
return types.NewInt(0), xerrors.Errorf("get power actor head (%s, height=%d): %w", act.Head, ts.Height(), err)
}
tpow = st.TotalQualityAdjPower // TODO: REVIEW: Is this correct?
}
+42 -22
View File
@@ -3,6 +3,7 @@ package sub
import (
"bytes"
"context"
"errors"
"fmt"
"sync"
"time"
@@ -40,6 +41,9 @@ import (
var log = logging.Logger("sub")
var ErrSoftFailure = errors.New("soft validation failure")
var ErrInsufficientPower = errors.New("incoming block's miner does not have minimum power")
func HandleIncomingBlocks(ctx context.Context, bsub *pubsub.Subscription, s *chain.Syncer, bserv bserv.BlockService, cmgr connmgr.ConnManager) {
for {
msg, err := bsub.Next(ctx)
@@ -258,16 +262,15 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
stats.Record(ctx, metrics.BlockReceived.M(1))
recordFailure := func(what string) {
ctx, _ = tag.New(ctx, tag.Insert(metrics.FailureType, what))
stats.Record(ctx, metrics.BlockValidationFailure.M(1))
recordFailureFlagPeer := func(what string) {
recordFailure(ctx, metrics.BlockValidationFailure, what)
bv.flagPeer(pid)
}
blk, what, err := bv.decodeAndCheckBlock(msg)
if err != nil {
log.Error("got invalid block over pubsub: ", err)
recordFailure(what)
recordFailureFlagPeer(what)
return pubsub.ValidationReject
}
@@ -275,7 +278,7 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
err = bv.validateMsgMeta(ctx, blk)
if err != nil {
log.Warnf("error validating message metadata: %s", err)
recordFailure("invalid_block_meta")
recordFailureFlagPeer("invalid_block_meta")
return pubsub.ValidationReject
}
@@ -288,11 +291,12 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
// if we are synced and the miner is unknown, then the block is rejcected.
key, err := bv.checkPowerAndGetWorkerKey(ctx, blk.Header)
if err != nil {
if bv.isChainNearSynced() {
if err != ErrSoftFailure && bv.isChainNearSynced() {
log.Warnf("received block from unknown miner or miner that doesn't meet min power over pubsub; rejecting message")
recordFailure("unknown_miner")
recordFailureFlagPeer("unknown_miner")
return pubsub.ValidationReject
}
log.Warnf("cannot validate block message; unknown miner or miner that doesn't meet min power in unsynced chain")
return pubsub.ValidationIgnore
}
@@ -300,13 +304,13 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
err = sigs.CheckBlockSignature(ctx, blk.Header, key)
if err != nil {
log.Errorf("block signature verification failed: %s", err)
recordFailure("signature_verification_failed")
recordFailureFlagPeer("signature_verification_failed")
return pubsub.ValidationReject
}
if blk.Header.ElectionProof.WinCount < 1 {
log.Errorf("block is not claiming to be winning")
recordFailure("not_winning")
recordFailureFlagPeer("not_winning")
return pubsub.ValidationReject
}
@@ -473,19 +477,19 @@ func (bv *BlockValidator) checkPowerAndGetWorkerKey(ctx context.Context, bh *typ
baseTs := bv.chain.GetHeaviestTipSet()
lbts, err := stmgr.GetLookbackTipSetForRound(ctx, bv.stmgr, baseTs, bh.Height)
if err != nil {
log.Warnf("failed to load lookback tipset for incoming block")
return address.Undef, err
log.Warnf("failed to load lookback tipset for incoming block: %s", err)
return address.Undef, ErrSoftFailure
}
hmp, err := stmgr.MinerHasMinPower(ctx, bv.stmgr, bh.Miner, lbts)
if err != nil {
log.Warnf("failed to determine if incoming block's miner has minimum power")
return address.Undef, err
log.Warnf("failed to determine if incoming block's miner has minimum power: %s", err)
return address.Undef, ErrSoftFailure
}
if !hmp {
log.Warnf("incoming block's miner does not have minimum power")
return address.Undef, xerrors.New("incoming block's miner does not have minimum power")
return address.Undef, ErrInsufficientPower
}
return key, nil
@@ -541,14 +545,18 @@ func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubs
log.Debugf("failed to add message from network to message pool (From: %s, To: %s, Nonce: %d, Value: %s): %s", m.Message.From, m.Message.To, m.Message.Nonce, types.FIL(m.Message.Value), err)
ctx, _ = tag.New(
ctx,
tag.Insert(metrics.FailureType, "add"),
tag.Upsert(metrics.Local, "false"),
)
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
recordFailure(ctx, metrics.MessageValidationFailure, "add")
switch {
case xerrors.Is(err, messagepool.ErrBroadcastAnyway):
case xerrors.Is(err, messagepool.ErrSoftValidationFailure):
fallthrough
case xerrors.Is(err, messagepool.ErrRBFTooLowPremium):
fallthrough
case xerrors.Is(err, messagepool.ErrTooManyPendingMessages):
fallthrough
case xerrors.Is(err, messagepool.ErrNonceGap):
fallthrough
case xerrors.Is(err, messagepool.ErrNonceTooLow):
return pubsub.ValidationIgnore
default:
@@ -560,37 +568,41 @@ func (mv *MessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubs
}
func (mv *MessageValidator) validateLocalMessage(ctx context.Context, msg *pubsub.Message) pubsub.ValidationResult {
ctx, _ = tag.New(
ctx,
tag.Upsert(metrics.Local, "true"),
)
// 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))
recordFailure(ctx, metrics.MessageValidationFailure, "decode")
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))
recordFailure(ctx, metrics.MessageValidationFailure, "oversize")
return pubsub.ValidationIgnore
}
if m.Message.To == address.Undef {
log.Warn("local message has invalid destination address")
stats.Record(ctx, metrics.MessageValidationFailure.M(1))
recordFailure(ctx, metrics.MessageValidationFailure, "undef-addr")
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))
recordFailure(ctx, metrics.MessageValidationFailure, "value-too-high")
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))
recordFailure(ctx, metrics.MessageValidationFailure, "verify-sig")
return pubsub.ValidationIgnore
}
@@ -613,3 +625,11 @@ func HandleIncomingMessages(ctx context.Context, mpool *messagepool.MessagePool,
// Do nothing... everything happens in validate
}
}
func recordFailure(ctx context.Context, metric *stats.Int64Measure, failureType string) {
ctx, _ = tag.New(
ctx,
tag.Upsert(metrics.FailureType, failureType),
)
stats.Record(ctx, metric.M(1))
}
+72 -5
View File
@@ -7,9 +7,12 @@ import (
"fmt"
"os"
"sort"
"strconv"
"strings"
"time"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/Gurpartap/async"
"github.com/hashicorp/go-multierror"
"github.com/ipfs/go-cid"
@@ -24,11 +27,11 @@ import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"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"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/specs-actors/actors/util/adt"
blst "github.com/supranational/blst/bindings/go"
@@ -52,6 +55,19 @@ import (
//the theoretical max height based on systime are quickly rejected
const MaxHeightDrift = 5
var defaultMessageFetchWindowSize = 200
func init() {
if s := os.Getenv("LOTUS_BSYNC_MSG_WINDOW"); s != "" {
val, err := strconv.Atoi(s)
if err != nil {
log.Errorf("failed to parse LOTUS_BSYNC_MSG_WINDOW: %s", err)
return
}
defaultMessageFetchWindowSize = val
}
}
var log = logging.Logger("chain")
var LocalIncoming = "incoming"
@@ -109,6 +125,10 @@ type Syncer struct {
receiptTracker *blockReceiptTracker
verifier ffiwrapper.Verifier
windowSize int
tickerCtxCancel context.CancelFunc
}
// NewSyncer creates a new Syncer object.
@@ -134,6 +154,7 @@ func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connm
receiptTracker: newBlockReceiptTracker(),
connmgr: connmgr,
verifier: verifier,
windowSize: defaultMessageFetchWindowSize,
incoming: pubsub.New(50),
}
@@ -149,11 +170,35 @@ func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connm
}
func (syncer *Syncer) Start() {
tickerCtx, tickerCtxCancel := context.WithCancel(context.Background())
syncer.syncmgr.Start()
syncer.tickerCtxCancel = tickerCtxCancel
go syncer.runMetricsTricker(tickerCtx)
}
func (syncer *Syncer) runMetricsTricker(tickerCtx context.Context) {
genesisTime := time.Unix(int64(syncer.Genesis.MinTimestamp()), 0)
ticker := build.Clock.Ticker(time.Duration(build.BlockDelaySecs) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
sinceGenesis := build.Clock.Now().Sub(genesisTime)
expectedHeight := int64(sinceGenesis.Seconds()) / int64(build.BlockDelaySecs)
stats.Record(tickerCtx, metrics.ChainNodeHeightExpected.M(expectedHeight))
case <-tickerCtx.Done():
return
}
}
}
func (syncer *Syncer) Stop() {
syncer.syncmgr.Stop()
syncer.tickerCtxCancel()
}
// InformNewHead informs the syncer about a new potential tipset
@@ -641,7 +686,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
validationStart := build.Clock.Now()
defer func() {
stats.Record(ctx, metrics.BlockValidationDurationMilliseconds.M(metrics.SinceInMilliseconds(validationStart)))
log.Infow("block validation", "took", time.Since(validationStart), "height", b.Header.Height)
log.Infow("block validation", "took", time.Since(validationStart), "height", b.Header.Height, "age", time.Since(time.Unix(int64(b.Header.Timestamp), 0)))
}()
ctx, span := trace.StartSpan(ctx, "validateBlock")
@@ -936,7 +981,7 @@ func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.Block
return xerrors.Errorf("getting winning post sector set: %w", err)
}
ok, err := ffiwrapper.ProofVerifier.VerifyWinningPoSt(ctx, abi.WinningPoStVerifyInfo{
ok, err := ffiwrapper.ProofVerifier.VerifyWinningPoSt(ctx, proof.WinningPoStVerifyInfo{
Randomness: rand,
Proofs: h.WinPoStProof,
ChallengedSectors: sectors,
@@ -1399,7 +1444,8 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
span.AddAttributes(trace.Int64Attribute("num_headers", int64(len(headers))))
windowSize := 200
windowSize := syncer.windowSize
mainLoop:
for i := len(headers) - 1; i >= 0; {
fts, err := syncer.store.TryFillTipSet(headers[i])
if err != nil {
@@ -1427,6 +1473,12 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
nreq := batchSize - len(bstout)
bstips, err := syncer.Bsync.GetChainMessages(ctx, next, uint64(nreq))
if err != nil {
// TODO check errors for temporary nature
if windowSize > 1 {
windowSize /= 2
log.Infof("error fetching messages: %s; reducing window size to %d and trying again", err, windowSize)
continue mainLoop
}
return xerrors.Errorf("message processing failed: %w", err)
}
@@ -1461,9 +1513,24 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
return xerrors.Errorf("message processing failed: %w", err)
}
}
if i >= windowSize {
newWindowSize := windowSize + 10
if newWindowSize > int(blocksync.MaxRequestLength) {
newWindowSize = int(blocksync.MaxRequestLength)
}
if newWindowSize > windowSize {
windowSize = newWindowSize
log.Infof("successfully fetched %d messages; increasing window size to %d", len(bstout), windowSize)
}
}
i -= batchSize
}
// remember our window size
syncer.windowSize = windowSize
return nil
}
+9 -4
View File
@@ -7,6 +7,8 @@ import (
"testing"
"time"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore"
@@ -16,8 +18,8 @@ import (
"github.com/stretchr/testify/require"
"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/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
@@ -32,6 +34,7 @@ import (
"github.com/filecoin-project/lotus/node"
"github.com/filecoin-project/lotus/node/impl"
"github.com/filecoin-project/lotus/node/modules"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/repo"
)
@@ -231,6 +234,7 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
node.Repo(sourceRepo),
node.MockHost(tu.mn),
node.Test(),
node.Override(new(dtypes.Bootstrapper), dtypes.Bootstrapper(true)),
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)),
)
@@ -263,6 +267,7 @@ func (tu *syncTestUtil) addClientNode() int {
node.Repo(repo.NewMemory(nil)),
node.MockHost(tu.mn),
node.Test(),
node.Override(new(dtypes.Bootstrapper), dtypes.Bootstrapper(true)),
node.Override(new(modules.Genesis), modules.LoadGenesis(tu.genesis)),
)
@@ -442,8 +447,8 @@ func (wpp badWpp) GenerateCandidates(context.Context, abi.PoStRandomness, uint64
return []uint64{1}, nil
}
func (wpp badWpp) ComputeProof(context.Context, []abi.SectorInfo, abi.PoStRandomness) ([]abi.PoStProof, error) {
return []abi.PoStProof{
func (wpp badWpp) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) {
return []proof.PoStProof{
{
PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1,
ProofBytes: []byte("evil"),
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"sync"
"time"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"fmt"
"math/big"
big2 "github.com/filecoin-project/specs-actors/actors/abi/big"
big2 "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
)
+5 -3
View File
@@ -4,10 +4,12 @@ import (
"bytes"
"math/big"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/minio/blake2b-simd"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
@@ -53,7 +55,7 @@ type BlockHeader struct {
BeaconEntries []BeaconEntry // 3
WinPoStProof []abi.PoStProof // 4
WinPoStProof []proof.PoStProof // 4
Parents []cid.Cid // 5
+5 -3
View File
@@ -7,12 +7,14 @@ import (
"reflect"
"testing"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
cid "github.com/ipfs/go-cid"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
)
func testBlockHeader(t testing.TB) *BlockHeader {
@@ -80,7 +82,7 @@ func TestInteropBH(t *testing.T) {
t.Fatal(err)
}
posts := []abi.PoStProof{
posts := []proof.PoStProof{
{PoStProof: abi.RegisteredPoStProof_StackedDrgWinning2KiBV1, ProofBytes: []byte{0x07}},
}
+8 -7
View File
@@ -6,9 +6,10 @@ import (
"fmt"
"io"
abi "github.com/filecoin-project/specs-actors/actors/abi"
crypto "github.com/filecoin-project/specs-actors/actors/crypto"
exitcode "github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
abi "github.com/filecoin-project/go-state-types/abi"
crypto "github.com/filecoin-project/go-state-types/crypto"
exitcode "github.com/filecoin-project/go-state-types/exitcode"
proof "github.com/filecoin-project/specs-actors/actors/runtime/proof"
cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
@@ -58,7 +59,7 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
}
}
// t.WinPoStProof ([]abi.PoStProof) (slice)
// t.WinPoStProof ([]proof.PoStProof) (slice)
if len(t.WinPoStProof) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.WinPoStProof was too long")
}
@@ -243,7 +244,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
t.BeaconEntries[i] = v
}
// t.WinPoStProof ([]abi.PoStProof) (slice)
// t.WinPoStProof ([]proof.PoStProof) (slice)
maj, extra, err = cbg.CborReadHeaderBuf(br, scratch)
if err != nil {
@@ -259,12 +260,12 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
}
if extra > 0 {
t.WinPoStProof = make([]abi.PoStProof, extra)
t.WinPoStProof = make([]proof.PoStProof, extra)
}
for i := 0; i < int(extra); i++ {
var v abi.PoStProof
var v proof.PoStProof
if err := v.UnmarshalCBOR(br); err != nil {
return err
}
+2 -2
View File
@@ -4,9 +4,9 @@ import (
"bytes"
"fmt"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
xerrors "golang.org/x/xerrors"
+1 -1
View File
@@ -3,7 +3,7 @@ package types
import (
"bytes"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/filecoin-project/go-state-types/exitcode"
)
type MessageReceipt struct {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/specs-actors/actors/builtin"
)
+4 -2
View File
@@ -5,10 +5,11 @@ import (
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
)
@@ -80,6 +81,7 @@ func MkBlock(parents *types.TipSet, weightInc uint64, ticketNonce uint64) *types
Height: height,
ParentStateRoot: pstateRoot,
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")},
ParentBaseFee: types.NewInt(uint64(build.MinimumBaseFee)),
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"bytes"
"testing"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/crypto"
)
func TestSignatureSerializeRoundTrip(t *testing.T) {
+2 -2
View File
@@ -3,8 +3,8 @@ package types
import (
"bytes"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
)
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"io"
"sort"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2"
"github.com/minio/blake2b-simd"
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"encoding/json"
"strings"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
)
-215
View File
@@ -1,215 +0,0 @@
package validation
import (
"context"
"golang.org/x/xerrors"
"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/crypto"
"github.com/filecoin-project/specs-actors/actors/puppet"
"github.com/ipfs/go-cid"
vtypes "github.com/filecoin-project/chain-validation/chain/types"
vstate "github.com/filecoin-project/chain-validation/state"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
)
// Applier applies messages to state trees and storage.
type Applier struct {
stateWrapper *StateWrapper
syscalls vm.SyscallBuilder
}
var _ vstate.Applier = &Applier{}
func NewApplier(sw *StateWrapper, syscalls vm.SyscallBuilder) *Applier {
return &Applier{sw, syscalls}
}
func (a *Applier) ApplyMessage(epoch abi.ChainEpoch, message *vtypes.Message) (vtypes.ApplyMessageResult, error) {
lm := toLotusMsg(message)
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
return vtypes.ApplyMessageResult{
Msg: *message,
Receipt: receipt,
Penalty: penalty,
Reward: reward,
Root: a.stateWrapper.Root().String(),
}, err
}
func (a *Applier) ApplySignedMessage(epoch abi.ChainEpoch, msg *vtypes.SignedMessage) (vtypes.ApplyMessageResult, error) {
var lm types.ChainMsg
switch msg.Signature.Type {
case crypto.SigTypeSecp256k1:
lm = toLotusSignedMsg(msg)
case crypto.SigTypeBLS:
lm = toLotusMsg(&msg.Message)
default:
return vtypes.ApplyMessageResult{}, xerrors.New("Unknown signature type")
}
// TODO: Validate the sig first
receipt, penalty, reward, err := a.applyMessage(epoch, lm)
return vtypes.ApplyMessageResult{
Msg: msg.Message,
Receipt: receipt,
Penalty: penalty,
Reward: reward,
Root: a.stateWrapper.Root().String(),
}, err
}
func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.BlockMessagesInfo, rnd vstate.RandomnessSource) (vtypes.ApplyTipSetResult, error) {
cs := store.NewChainStore(a.stateWrapper.bs, a.stateWrapper.ds, a.syscalls)
sm := stmgr.NewStateManager(cs)
var bms []store.BlockMessages
for _, b := range blocks {
bm := store.BlockMessages{
Miner: b.Miner,
WinCount: 1,
}
for _, m := range b.BLSMessages {
bm.BlsMessages = append(bm.BlsMessages, toLotusMsg(m))
}
for _, m := range b.SECPMessages {
bm.SecpkMessages = append(bm.SecpkMessages, toLotusSignedMsg(m))
}
bms = append(bms, bm)
}
var receipts []vtypes.MessageReceipt
// TODO: base fee
sroot, _, err := sm.ApplyBlocks(context.TODO(), epoch-1, a.stateWrapper.Root(), bms, epoch, &randWrapper{rnd}, func(c cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
if msg.From == builtin.SystemActorAddr {
return nil // ignore reward and cron calls
}
rval := ret.Return
if rval == nil {
rval = []byte{} // chain validation tests expect empty arrays to not be nil...
}
receipts = append(receipts, vtypes.MessageReceipt{
ExitCode: ret.ExitCode,
ReturnValue: rval,
GasUsed: vtypes.GasUnits(ret.GasUsed),
})
return nil
}, abi.NewTokenAmount(100))
if err != nil {
return vtypes.ApplyTipSetResult{}, err
}
a.stateWrapper.stateRoot = sroot
return vtypes.ApplyTipSetResult{
Receipts: receipts,
Root: a.stateWrapper.Root().String(),
}, nil
}
type randWrapper struct {
rand vstate.RandomnessSource
}
// 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) 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")
}
func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes.MessageReceipt, abi.TokenAmount, abi.TokenAmount, error) {
ctx := context.TODO()
base := a.stateWrapper.Root()
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: epoch,
Rand: &vmRand{},
Bstore: a.stateWrapper.bs,
Syscalls: a.syscalls,
CircSupplyCalc: nil,
BaseFee: abi.NewTokenAmount(100),
}
lotusVM, err := vm.NewVM(vmopt)
// need to modify the VM invoker to add the puppet actor
chainValInvoker := vm.NewInvoker()
chainValInvoker.Register(puppet.PuppetActorCodeID, puppet.Actor{}, puppet.State{})
lotusVM.SetInvoker(chainValInvoker)
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
ret, err := lotusVM.ApplyMessage(ctx, lm)
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
rval := ret.Return
if rval == nil {
rval = []byte{}
}
a.stateWrapper.stateRoot, err = lotusVM.Flush(ctx)
if err != nil {
return vtypes.MessageReceipt{}, big.Zero(), big.Zero(), err
}
mr := vtypes.MessageReceipt{
ExitCode: ret.ExitCode,
ReturnValue: rval,
GasUsed: vtypes.GasUnits(ret.GasUsed),
}
return mr, ret.Penalty, abi.NewTokenAmount(ret.GasUsed), nil
}
func toLotusMsg(msg *vtypes.Message) *types.Message {
return &types.Message{
To: msg.To,
From: msg.From,
Nonce: msg.CallSeqNum,
Method: msg.Method,
Value: msg.Value,
GasLimit: msg.GasLimit,
GasFeeCap: msg.GasFeeCap,
GasPremium: msg.GasPremium,
Params: msg.Params,
}
}
func toLotusSignedMsg(msg *vtypes.SignedMessage) *types.SignedMessage {
return &types.SignedMessage{
Message: *toLotusMsg(&msg.Message),
Signature: msg.Signature,
}
}
-37
View File
@@ -1,37 +0,0 @@
package validation
//
// Config
//
type Config struct {
trackGas bool
checkExitCode bool
checkReturnValue bool
checkState bool
}
func NewConfig(gas, exit, ret, state bool) *Config {
return &Config{
trackGas: gas,
checkExitCode: exit,
checkReturnValue: ret,
checkState: state,
}
}
func (v Config) ValidateGas() bool {
return v.trackGas
}
func (v Config) ValidateExitCode() bool {
return v.checkExitCode
}
func (v Config) ValidateReturnValue() bool {
return v.checkReturnValue
}
func (v Config) ValidateStateRoot() bool {
return v.checkState
}
-40
View File
@@ -1,40 +0,0 @@
package validation
import (
"context"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/specs-actors/actors/runtime"
cbor "github.com/ipfs/go-ipld-cbor"
vstate "github.com/filecoin-project/chain-validation/state"
)
type Factories struct {
*Applier
}
var _ vstate.Factories = &Factories{}
func NewFactories() *Factories {
return &Factories{}
}
func (f *Factories) NewStateAndApplier(syscalls runtime.Syscalls) (vstate.VMWrapper, vstate.Applier) {
st := NewState()
return st, NewApplier(st, func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
return syscalls
})
}
func (f *Factories) NewKeyManager() vstate.KeyManager {
return newKeyManager()
}
func (f *Factories) NewValidationConfig() vstate.ValidationConfig {
trackGas := true
checkExit := true
checkRet := true
checkState := true
return NewConfig(trackGas, checkExit, checkRet, checkState)
}
-104
View File
@@ -1,104 +0,0 @@
package validation
import (
"fmt"
"math/rand"
"github.com/minio/blake2b-simd"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-crypto"
acrypto "github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
)
type KeyManager struct {
// Private keys by address
keys map[address.Address]*wallet.Key
// Seed for deterministic secp key generation.
secpSeed int64
// Seed for deterministic bls key generation.
blsSeed int64 // nolint: structcheck
}
func newKeyManager() *KeyManager {
return &KeyManager{
keys: make(map[address.Address]*wallet.Key),
secpSeed: 0,
}
}
func (k *KeyManager) NewSECP256k1AccountAddress() address.Address {
secpKey := k.newSecp256k1Key()
k.keys[secpKey.Address] = secpKey
return secpKey.Address
}
func (k *KeyManager) NewBLSAccountAddress() address.Address {
blsKey := k.newBLSKey()
k.keys[blsKey.Address] = blsKey
return blsKey.Address
}
func (k *KeyManager) Sign(addr address.Address, data []byte) (acrypto.Signature, error) {
ki, ok := k.keys[addr]
if !ok {
return acrypto.Signature{}, fmt.Errorf("unknown address %v", addr)
}
var sigType acrypto.SigType
if ki.Type == wallet.KTSecp256k1 {
sigType = acrypto.SigTypeBLS
hashed := blake2b.Sum256(data)
sig, err := crypto.Sign(ki.PrivateKey, hashed[:])
if err != nil {
return acrypto.Signature{}, err
}
return acrypto.Signature{
Type: sigType,
Data: sig,
}, nil
} else if ki.Type == wallet.KTBLS {
panic("lotus validator cannot sign BLS messages")
} else {
panic("unknown signature type")
}
}
func (k *KeyManager) newSecp256k1Key() *wallet.Key {
randSrc := rand.New(rand.NewSource(k.secpSeed)) // nolint
prv, err := crypto.GenerateKeyFromSeed(randSrc)
if err != nil {
panic(err)
}
k.secpSeed++
key, err := wallet.NewKey(types.KeyInfo{
Type: wallet.KTSecp256k1,
PrivateKey: prv,
})
if err != nil {
panic(err)
}
return key
}
func (k *KeyManager) newBLSKey() *wallet.Key {
// FIXME: bls needs deterministic key generation
//sk := ffi.PrivateKeyGenerate(s.blsSeed)
// s.blsSeed++
sk := [32]byte{}
sk[0] = uint8(k.blsSeed) // hack to keep gas values determinist
k.blsSeed++
key, err := wallet.NewKey(types.KeyInfo{
Type: wallet.KTBLS,
PrivateKey: sk[:],
})
if err != nil {
panic(err)
}
return key
}
-217
View File
@@ -1,217 +0,0 @@
package validation
import (
"context"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
vstate "github.com/filecoin-project/chain-validation/state"
"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/runtime"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore"
)
var _ vstate.VMWrapper = &StateWrapper{}
type StateWrapper struct {
// The blockstore underlying the state tree and storage.
bs blockstore.Blockstore
ds datastore.Batching
// HAMT-CBOR store on top of the blockstore.
cst cbor.IpldStore
// CID of the root of the state tree.
stateRoot cid.Cid
}
func NewState() *StateWrapper {
bs := blockstore.NewTemporary()
cst := cbor.NewCborStore(bs)
// Put EmptyObjectCid value in the store. When an actor is initially created its Head is set to this value.
_, err := cst.Put(context.TODO(), map[string]string{})
if err != nil {
panic(err)
}
treeImpl, err := state.NewStateTree(cst)
if err != nil {
panic(err) // Never returns error, the error return should be removed.
}
root, err := treeImpl.Flush(context.TODO())
if err != nil {
panic(err)
}
return &StateWrapper{
bs: bs,
ds: datastore.NewMapDatastore(),
cst: cst,
stateRoot: root,
}
}
func (s *StateWrapper) NewVM() {
return
}
func (s *StateWrapper) Root() cid.Cid {
return s.stateRoot
}
// StoreGet the value at key from vm store
func (s *StateWrapper) StoreGet(key cid.Cid, out runtime.CBORUnmarshaler) error {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return err
}
return tree.Store.Get(context.Background(), key, out)
}
// StorePut `value` into vm store
func (s *StateWrapper) StorePut(value runtime.CBORMarshaler) (cid.Cid, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return cid.Undef, err
}
return tree.Store.Put(context.Background(), value)
}
func (s *StateWrapper) Actor(addr address.Address) (vstate.Actor, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, err
}
fcActor, err := tree.GetActor(addr)
if err != nil {
return nil, err
}
return &actorWrapper{*fcActor}, nil
}
func (s *StateWrapper) SetActorState(addr address.Address, balance abi.TokenAmount, actorState runtime.CBORMarshaler) (vstate.Actor, error) {
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, err
}
// actor should exist
act, err := tree.GetActor(addr)
if err != nil {
return nil, err
}
// add the state to the store and get a new head cid
actHead, err := tree.Store.Put(context.Background(), actorState)
if err != nil {
return nil, err
}
// update the actor object with new head and balance parameter
actr := &actorWrapper{types.Actor{
Code: act.Code,
Nonce: act.Nonce,
// updates
Head: actHead,
Balance: balance,
}}
if err := tree.SetActor(addr, &actr.Actor); err != nil {
return nil, err
}
return actr, s.flush(tree)
}
func (s *StateWrapper) CreateActor(code cid.Cid, addr address.Address, balance abi.TokenAmount, actorState runtime.CBORMarshaler) (vstate.Actor, address.Address, error) {
idAddr := addr
tree, err := state.LoadStateTree(s.cst, s.stateRoot)
if err != nil {
return nil, address.Undef, err
}
if addr.Protocol() != address.ID {
actHead, err := tree.Store.Put(context.Background(), actorState)
if err != nil {
return nil, address.Undef, err
}
actr := &actorWrapper{types.Actor{
Code: code,
Head: actHead,
Balance: balance,
}}
idAddr, err = tree.RegisterNewAddress(addr)
if err != nil {
return nil, address.Undef, xerrors.Errorf("register new address for actor: %w", err)
}
if err := tree.SetActor(addr, &actr.Actor); err != nil {
return nil, address.Undef, xerrors.Errorf("setting new actor for actor: %w", err)
}
}
// store newState
head, err := tree.Store.Put(context.Background(), actorState)
if err != nil {
return nil, address.Undef, err
}
// create and store actor object
a := types.Actor{
Code: code,
Head: head,
Balance: balance,
}
if err := tree.SetActor(idAddr, &a); err != nil {
return nil, address.Undef, err
}
return &actorWrapper{a}, idAddr, s.flush(tree)
}
// Flushes a state tree to storage and sets this state's root to that tree's root CID.
func (s *StateWrapper) flush(tree *state.StateTree) (err error) {
s.stateRoot, err = tree.Flush(context.TODO())
return
}
//
// Actor Wrapper
//
type actorWrapper struct {
types.Actor
}
func (a *actorWrapper) Code() cid.Cid {
return a.Actor.Code
}
func (a *actorWrapper) Head() cid.Cid {
return a.Actor.Head
}
func (a *actorWrapper) CallSeqNum() uint64 {
return a.Actor.Nonce
}
func (a *actorWrapper) Balance() big.Int {
return a.Actor.Balance
}
//
// Storage
//
type contextStore struct {
cbor.IpldStore
ctx context.Context
}
func (s *contextStore) Context() context.Context {
return s.ctx
}
+5 -4
View File
@@ -6,19 +6,20 @@ import (
"math/rand"
"os"
"github.com/filecoin-project/specs-actors/actors/builtin/power"
"github.com/filecoin-project/go-address"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/vectors"
"github.com/filecoin-project/lotus/chain/wallet"
"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/power"
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
"github.com/filecoin-project/specs-actors/actors/crypto"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
+1 -1
View File
@@ -1,8 +1,8 @@
package vectors
import (
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/specs-actors/actors/crypto"
)
type HeaderVector struct {
+2 -2
View File
@@ -1,8 +1,8 @@
package vm
import (
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/abi/big"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
)
const (
+9 -7
View File
@@ -3,10 +3,12 @@ package vm
import (
"fmt"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/filecoin-project/go-address"
addr "github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/runtime"
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/ipfs/go-cid"
@@ -77,8 +79,8 @@ type Pricelist interface {
OnVerifySignature(sigType crypto.SigType, planTextSize int) (GasCharge, error)
OnHashing(dataSize int) GasCharge
OnComputeUnsealedSectorCid(proofType abi.RegisteredSealProof, pieces []abi.PieceInfo) GasCharge
OnVerifySeal(info abi.SealVerifyInfo) GasCharge
OnVerifyPost(info abi.WindowPoStVerifyInfo) GasCharge
OnVerifySeal(info proof.SealVerifyInfo) GasCharge
OnVerifyPost(info proof.WindowPoStVerifyInfo) GasCharge
OnVerifyConsensusFault() GasCharge
}
@@ -183,7 +185,7 @@ func (ps pricedSyscalls) ComputeUnsealedSectorCID(reg abi.RegisteredSealProof, p
}
// Verifies a sector seal proof.
func (ps pricedSyscalls) VerifySeal(vi abi.SealVerifyInfo) error {
func (ps pricedSyscalls) VerifySeal(vi proof.SealVerifyInfo) error {
ps.chargeGas(ps.pl.OnVerifySeal(vi))
defer ps.chargeGas(gasOnActorExec)
@@ -191,7 +193,7 @@ func (ps pricedSyscalls) VerifySeal(vi abi.SealVerifyInfo) error {
}
// Verifies a proof of spacetime.
func (ps pricedSyscalls) VerifyPoSt(vi abi.WindowPoStVerifyInfo) error {
func (ps pricedSyscalls) VerifyPoSt(vi proof.WindowPoStVerifyInfo) error {
ps.chargeGas(ps.pl.OnVerifyPost(vi))
defer ps.chargeGas(gasOnActorExec)
@@ -215,7 +217,7 @@ func (ps pricedSyscalls) VerifyConsensusFault(h1 []byte, h2 []byte, extra []byte
return ps.under.VerifyConsensusFault(h1, h2, extra)
}
func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]abi.SealVerifyInfo) (map[address.Address][]bool, error) {
func (ps pricedSyscalls) BatchVerifySeals(inp map[address.Address][]proof.SealVerifyInfo) (map[address.Address][]bool, error) {
count := int64(0)
for _, svis := range inp {
count += int64(len(svis))

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