From f4fa4c8cce4d4dc1ec973919bb828a3435d90274 Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Tue, 27 Jul 2021 17:09:44 -0700 Subject: [PATCH 01/79] fix(marketevents): use ReceivedCidsLen improve data transfer logger by not reading in entire cid lists --- markets/loggers/loggers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markets/loggers/loggers.go b/markets/loggers/loggers.go index e5f669f2f5c..2acf987cb13 100644 --- a/markets/loggers/loggers.go +++ b/markets/loggers/loggers.go @@ -40,7 +40,7 @@ func DataTransferLogger(event datatransfer.Event, state datatransfer.ChannelStat "sent", state.Sent(), "received", state.Received(), "queued", state.Queued(), - "received count", len(state.ReceivedCids()), + "received count", state.ReceivedCidsLen(), "total size", state.TotalSize(), "remote peer", state.OtherPeer(), "event message", event.Message, From 8a54273f8b03a62348b54723e5aa479cac605156 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Tue, 27 Jul 2021 22:37:24 -0400 Subject: [PATCH 02/79] add v1.11.1-rc1 changelog and bump the version --- CHANGELOG.md | 179 +++++++++++++++++++++++++++++++++++++++++++++++ build/version.go | 2 +- 2 files changed, 180 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c90c80fefb9..c00105f5c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,184 @@ # Lotus changelog +# 1.11.1-rc1 / 2021-07-27 + +This is the first release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. A more organized and detailed release note will be shared in the next few days with future RCs, highlights are: +- [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) +- [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) + +- github.com/filecoin-project/lotus: + - Merge branch 'releases' into release/v1.11.1 + - Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890)) + - lotus-shed: initial export cmd for markets related metadata ([filecoin-project/lotus#6840](https://github.com/filecoin-project/lotus/pull/6840)) + - add a very verbose -vv flag to lotus and lotus-miner. ([filecoin-project/lotus#6888](https://github.com/filecoin-project/lotus/pull/6888)) + - Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880)) + - Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854)) + - Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879)) + - Add allocated sectorid vis ([filecoin-project/lotus#4638](https://github.com/filecoin-project/lotus/pull/4638)) + - rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886)) + - update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885)) + - Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674)) + - Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683)) + - fix racy TestSimultanenousTransferLimit. ([filecoin-project/lotus#6862](https://github.com/filecoin-project/lotus/pull/6862)) + - Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867)) + - ValidateBlock: Assert that block header height's are greater than parents ([filecoin-project/lotus#6872](https://github.com/filecoin-project/lotus/pull/6872)) + - feat: Don't panic when api impl is nil ([filecoin-project/lotus#6857](https://github.com/filecoin-project/lotus/pull/6857)) + - splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811)) + - Fix links in issue templates + - Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856)) + - Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833)) + - Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848)) + - fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724)) + - Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798)) + - Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837)) + - add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544)) + - fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841)) + - add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640)) + - PriceListByVersion ([filecoin-project/lotus#6766](https://github.com/filecoin-project/lotus/pull/6766)) + - easy way to make install app ([filecoin-project/lotus#5183](https://github.com/filecoin-project/lotus/pull/5183)) + - api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) + - cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760)) + - fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) + - Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775)) + - Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817)) + - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818)) + - add SealProof in SectorBuilder ([filecoin-project/lotus#6815](https://github.com/filecoin-project/lotus/pull/6815)) + - release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828)) + - sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763)) + - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802)) + - ClientFindData: always fetch peer id from chain ([filecoin-project/lotus#6807](https://github.com/filecoin-project/lotus/pull/6807)) + - test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804)) + - ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800)) + - fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787)) + - Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777)) + - Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773)) + - update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764)) + - Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762)) + - Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642)) + - test: handle null blocks in TestForkRefuseCall ([filecoin-project/lotus#6758](https://github.com/filecoin-project/lotus/pull/6758)) + - Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757)) + - Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756)) + - Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747)) + - Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754)) + - ([filecoin-project/lotus#6746](https://github.com/filecoin-project/lotus/pull/6746)) + - Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743)) + - Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629)) + - Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356)) + - Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474)) + - ([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739)) + - Add more deal details to lotus-miner info ([filecoin-project/lotus#6708](https://github.com/filecoin-project/lotus/pull/6708)) + - Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710)) + - Fix Lotus shed + - Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066)) + - add election backtest ([filecoin-project/lotus#5950](https://github.com/filecoin-project/lotus/pull/5950)) + - Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620)) + - Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709)) + - Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697)) + - Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689)) + - Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696)) + - Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694)) + - add dollar sign ([filecoin-project/lotus#6690](https://github.com/filecoin-project/lotus/pull/6690)) + - get-actor cli spelling fix ([filecoin-project/lotus#6681](https://github.com/filecoin-project/lotus/pull/6681)) + - fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688)) + - polish(statetree): accept a context in statetree diff for timeouts ([filecoin-project/lotus#6639](https://github.com/filecoin-project/lotus/pull/6639)) + - Add helptext to lotus chain export ([filecoin-project/lotus#6672](https://github.com/filecoin-project/lotus/pull/6672)) + - Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679)) + - Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680)) + - add an incremental nonce itest. ([filecoin-project/lotus#6663](https://github.com/filecoin-project/lotus/pull/6663)) + - storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653)) + - Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664)) + - Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658)) + - fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635)) + - commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650)) + - commit batch: Initialize the FailedSectors map ([filecoin-project/lotus#6647](https://github.com/filecoin-project/lotus/pull/6647)) + - Fast-path retry submitting commit aggregate if commit is still valid ([filecoin-project/lotus#6638](https://github.com/filecoin-project/lotus/pull/6638)) + - remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634)) + - Reuse timers in sealing batch logic ([filecoin-project/lotus#6636](https://github.com/filecoin-project/lotus/pull/6636)) + - shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631)) + - fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625)) + - Update version.go to 1.11.1 ([filecoin-project/lotus#6621](https://github.com/filecoin-project/lotus/pull/6621)) +- github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.0): + - release: v1.7.0 + - Fire a transfer queued event when a transfer is queued in Graphsync (#221) ([filecoin-project/go-data-transfer#221](https://github.com/filecoin-project/go-data-transfer/pull/221)) + - feat: pass ChannelID to ValidatePush & ValidatePull (#220) ([filecoin-project/go-data-transfer#220](https://github.com/filecoin-project/go-data-transfer/pull/220)) + - release: v1.6.1 ([filecoin-project/go-data-transfer#218](https://github.com/filecoin-project/go-data-transfer/pull/218)) + - Remove CID lists (#217) ([filecoin-project/go-data-transfer#217](https://github.com/filecoin-project/go-data-transfer/pull/217)) + - Merge v1.6.0 ([filecoin-project/go-data-transfer#214](https://github.com/filecoin-project/go-data-transfer/pull/214)) + - Remove restart ack timeout (#211) ([filecoin-project/go-data-transfer#211](https://github.com/filecoin-project/go-data-transfer/pull/211)) + - feat: use different extension names to fit multiple hooks data in same graphsync message (#204) ([filecoin-project/go-data-transfer#204](https://github.com/filecoin-project/go-data-transfer/pull/204)) + - fix: map race in GS transport (#208) ([filecoin-project/go-data-transfer#208](https://github.com/filecoin-project/go-data-transfer/pull/208)) + - refactor: simplify graphsync transport (#203) ([filecoin-project/go-data-transfer#203](https://github.com/filecoin-project/go-data-transfer/pull/203)) + - release: v1.5.0 (#200) ([filecoin-project/go-data-transfer#200](https://github.com/filecoin-project/go-data-transfer/pull/200)) +- github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.0): + - release: v1.6.0 + - support padding out smaller files (#536) ([filecoin-project/go-fil-markets#536](https://github.com/filecoin-project/go-fil-markets/pull/536)) + - On overloaded CI 10 seconds just isn't enough (#587) ([filecoin-project/go-fil-markets#587](https://github.com/filecoin-project/go-fil-markets/pull/587)) + - Do not hex-encode CIDs in logs (#561) ([filecoin-project/go-fil-markets#561](https://github.com/filecoin-project/go-fil-markets/pull/561)) + - remove wrong peer check in push deal validation (#585) ([filecoin-project/go-fil-markets#585](https://github.com/filecoin-project/go-fil-markets/pull/585)) + - fix: circleci docs-gen task (#574) ([filecoin-project/go-fil-markets#574](https://github.com/filecoin-project/go-fil-markets/pull/574)) + - Storage market request queued event and validation interface changes (#555) ([filecoin-project/go-fil-markets#555](https://github.com/filecoin-project/go-fil-markets/pull/555)) + - build(deps): bump ws from 6.2.1 to 6.2.2 (#554) ([filecoin-project/go-fil-markets#554](https://github.com/filecoin-project/go-fil-markets/pull/554)) + - release: v1.5.0 ([filecoin-project/go-fil-markets#553](https://github.com/filecoin-project/go-fil-markets/pull/553)) +- github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1): + - New method to pad harder (#6) ([filecoin-project/go-padreader#6](https://github.com/filecoin-project/go-padreader/pull/6)) + - Create SECURITY.md (#5) ([filecoin-project/go-padreader#5](https://github.com/filecoin-project/go-padreader/pull/5)) +- github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210722133031-ad9bfe54c124): + - Add version 6.5 (#30) ([filecoin-project/go-state-types#30](https://github.com/filecoin-project/go-state-types/pull/30)) + - rename file +- github.com/filecoin-project/specs-actors/v5 (v5.0.1 -> v5.0.3): + - Adjust code for subtle change in go-multihash 0.0.15 (#1463) ([filecoin-project/specs-actors#1463](https://github.com/filecoin-project/specs-actors/pull/1463)) + - Bump go state types (#1464) ([filecoin-project/specs-actors#1464](https://github.com/filecoin-project/specs-actors/pull/1464)) + - Create CODEOWNERS (#1465) ([filecoin-project/specs-actors#1465](https://github.com/filecoin-project/specs-actors/pull/1465)) + - Test deterministic offset (#1462) ([filecoin-project/specs-actors#1462](https://github.com/filecoin-project/specs-actors/pull/1462)) + +Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| vyzo | 295 | +8700/-5936 | 397 | +| Anton Evangelatov | 94 | +4680/-2965 | 277 | +| Łukasz Magiera | 37 | +3851/-1611 | 146 | +| Mike Greenberg | 1 | +2310/-578 | 8 | +| dirkmc | 7 | +1154/-726 | 29 | +| Jennifer Wang | 9 | +485/-341 | 26 | +| Peter Rabbitson | 18 | +469/-273 | 64 | +| Cory Schwartz | 5 | +576/-135 | 14 | +| hunjixin | 7 | +404/-82 | 19 | +| ZenGround0 | 17 | +284/-135 | 44 | +| Dirk McCormick | 17 | +348/-47 | 17 | +| Raúl Kripalani | 18 | +254/-97 | 62 | +| tchardin | 1 | +261/-33 | 4 | +| Jakub Sztandera | 4 | +254/-16 | 4 | +| Aarsh Shah | 2 | +196/-40 | 28 | +| whyrusleeping | 3 | +150/-9 | 8 | +| Whyrusleeping | 2 | +87/-66 | 10 | +| Aayush Rajasekaran | 10 | +81/-53 | 13 | +| zgfzgf | 2 | +104/-4 | 2 | +| aarshkshah1992 | 4 | +73/-7 | 6 | +| llifezou | 4 | +59/-20 | 4 | +| Steven Allen | 7 | +47/-17 | 9 | +| johnli-helloworld | 3 | +46/-15 | 5 | +| frrist | 1 | +28/-23 | 2 | +| Jennifer | 4 | +31/-2 | 4 | +| wangchao | 1 | +1/-27 | 1 | +| Jiaying Wang | 2 | +7/-21 | 2 | +| hannahhoward | 3 | +21/-2 | 3 | +| chadwick2143 | 1 | +15/-1 | 1 | +| Jerry | 2 | +9/-4 | 2 | +| Steve Loeppky | 2 | +12/-0 | 2 | +| David Dias | 1 | +9/-0 | 1 | +| dependabot[bot] | 1 | +3/-3 | 1 | +| zhoutian527 | 1 | +2/-2 | 1 | +| xloem | 1 | +4/-0 | 1 | +| Travis Person | 2 | +2/-2 | 3 | +| Liviu Damian | 2 | +2/-2 | 2 | +| Jim Pick | 2 | +2/-2 | 2 | +| Frank | 1 | +3/-0 | 1 | +| turuslan | 1 | +1/-1 | 1 | +| Kirk Baird | 1 | +0/-0 | 1 | + + + # 1.11.0 / 2021-07-22 This is a **highly recommended** release of Lotus that have many bug fixes, improvements and new features. diff --git a/build/version.go b/build/version.go index c6a1be3e2dc..64d1049b5b4 100644 --- a/build/version.go +++ b/build/version.go @@ -34,7 +34,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.11.1-dev" +const BuildVersion = "1.11.1-rc1" func UserVersion() string { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { From 2e98f8b5d2094e76ad83a9fb6db90b5c98cd61b7 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Tue, 27 Jul 2021 22:52:39 -0400 Subject: [PATCH 03/79] make gen --- build/openrpc/full.json.gz | Bin 25240 -> 25240 bytes build/openrpc/miner.json.gz | Bin 9479 -> 9479 bytes build/openrpc/worker.json.gz | Bin 2710 -> 2710 bytes documentation/en/cli-lotus-miner.md | 2 +- documentation/en/cli-lotus-worker.md | 2 +- documentation/en/cli-lotus.md | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index c940d921b0af50de4f243bc595a80f87b709ce86..ddcf0611767ea9b47c66180b6063a2252ebf40ab 100644 GIT binary patch delta 25057 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 BZjb-~ delta 25103 zcma%?Q*dT&^yOpQw#|-hCmnWd+kRvB8{1aLwvCQ$+vfB)^PigAsdKaI)VX--seP*U zUhB8ghCtJXK;xnSa@d;>{!c#agQW{*U7rp@-VoE`i_a@!NJFOQC?eqr$Pqo{{8|rh z0@$q7y@HyEpRdQc=-v{;q)xr;Q2L$70@v(rvyjN5;X=@>XMaEJc9i>P8Mk?Vem@2F zfbYOK5Gs&TUHhKN=LTCazw}GVdoWc#fx>~|@k0w$k7AAhOnRFYVWdC<^?{N%H2}~c z0ri_G=!kGoRHe5aJrv)P53&b8Jja75FrlIEQ?_IU!TT1-?7uamf9daza{*6p0$9`L zELsmwK5bj-ItVwkVC1iGB(KKu;IEEB4k(}|0(~Hnqz-|Jx0t97>Z`P-0m?{N5y7aU z5HFx^V$f{>zts?M0p!WLd`2{Jfb-i&q>&D3XZiJRR

6o%-h-Z!lb-L#nw&h? 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 41e51a13ec002908072c639cd2136778bea75f3e..5a65b3a33921ffe18ee4fe002bdec37d7b59b576 100644 GIT binary patch delta 22 dcmZqoYWJGZ&Sc8Iv9nBt<4W=INty>4831D42wwmI delta 22 dcmZqoYWJGZ&g4|Sv9nBt!^8GVj^;r|1^{F>2q6Ff diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 075b54c3277e2bc961f796975999dbcd64e8d26b..09e5b1a87e567fbadc0a81ca94a0e97e5021fc73 100644 GIT binary patch delta 22 ecmbOxI!$y!6I0^$jV)YU9Q&+p-iWMXU;qGOdI(Se delta 22 dcmbOxI!$y!6BE1K#uhFv4&_7bA0w+67ywd72N3`O diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 29593fbd4da..863ca8dc93a 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -7,7 +7,7 @@ USAGE: lotus-miner [global options] command [command options] [arguments...] VERSION: - 1.11.1-dev + 1.11.1-rc1 COMMANDS: init Initialize a lotus miner repo diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index dbfc8da295a..0319649fba3 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -7,7 +7,7 @@ USAGE: lotus-worker [global options] command [command options] [arguments...] VERSION: - 1.11.1-dev + 1.11.1-rc1 COMMANDS: run Start lotus worker diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index 5faf5c58b68..c7504246f89 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -7,7 +7,7 @@ USAGE: lotus [global options] command [command options] [arguments...] VERSION: - 1.11.1-dev + 1.11.1-rc1 COMMANDS: daemon Start a lotus daemon process From 5073c7e6cf7eea3403eb74b826aec2ad71a66fec Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Wed, 28 Jul 2021 14:46:13 -0700 Subject: [PATCH 04/79] feat(deps): update to branches with improved logging update sub repos with improved logging around data transfer processing --- go.mod | 8 ++++---- go.sum | 14 ++++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 5f968f6e0ec..89db6a3ae4a 100644 --- a/go.mod +++ b/go.mod @@ -33,16 +33,16 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.7.0 + github.com/filecoin-project/go-data-transfer v1.7.1 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.6.0 + github.com/filecoin-project/go-fil-markets v1.6.1 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 - github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe + github.com/filecoin-project/go-statemachine v1.0.0 github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.14 @@ -78,7 +78,7 @@ require ( github.com/ipfs/go-ds-pebble v0.0.2-0.20200921225637-ce220f8ac459 github.com/ipfs/go-filestore v1.0.0 github.com/ipfs/go-fs-lock v0.0.6 - github.com/ipfs/go-graphsync v0.6.5 + github.com/ipfs/go-graphsync v0.6.6 github.com/ipfs/go-ipfs-blockstore v1.0.3 github.com/ipfs/go-ipfs-chunker v0.0.5 github.com/ipfs/go-ipfs-ds-help v1.0.0 diff --git a/go.sum b/go.sum index b22f3dc1562..e39d883d990 100644 --- a/go.sum +++ b/go.sum @@ -274,8 +274,9 @@ github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7/ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= -github.com/filecoin-project/go-data-transfer v1.7.0 h1:mFRn+UuTdPROmhplLSekzd4rAs9ug8ubtSY4nw9wYkU= github.com/filecoin-project/go-data-transfer v1.7.0/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= +github.com/filecoin-project/go-data-transfer v1.7.1 h1:Co4bTenvCc3WnOhQWyXRt59FLZvxwH8UeF0ZCOc1ik0= +github.com/filecoin-project/go-data-transfer v1.7.1/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= @@ -285,8 +286,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+ github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.6.0 h1:+1usyX7rXz6Ey6hbHd/Fhx616ZvGCI94rW7wneMcptU= -github.com/filecoin-project/go-fil-markets v1.6.0/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= +github.com/filecoin-project/go-fil-markets v1.6.1 h1:8xdFyWrELfOzwcGa229bLu/olD+1l4sEWFIsZR7oz5U= +github.com/filecoin-project/go-fil-markets v1.6.1/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -311,8 +312,9 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 h1:veGrNABg/9I7prngrowkhwbvW5d5JN55MNKmbsr5FqA= github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= -github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe h1:dF8u+LEWeIcTcfUcCf3WFVlc81Fr2JKg8zPzIbBDKDw= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= +github.com/filecoin-project/go-statemachine v1.0.0 h1:b8FpFewPSklyAIUqH0oHt4nvKf03bU7asop1bJpjAtQ= +github.com/filecoin-project/go-statemachine v1.0.0/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/c3OROw/kXVNSTZk= github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= @@ -631,8 +633,8 @@ github.com/ipfs/go-graphsync v0.1.0/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CE github.com/ipfs/go-graphsync v0.4.2/go.mod h1:/VmbZTUdUMTbNkgzAiCEucIIAU3BkLE2cZrDCVUhyi0= github.com/ipfs/go-graphsync v0.4.3/go.mod h1:mPOwDYv128gf8gxPFgXnz4fNrSYPsWyqisJ7ych+XDY= github.com/ipfs/go-graphsync v0.6.4/go.mod h1:5WyaeigpNdpiYQuW2vwpuecOoEfB4h747ZGEOKmAGTg= -github.com/ipfs/go-graphsync v0.6.5 h1:YAJl6Yit23PQcaawzb1rPK9PSnbbq2jjMRPpRpJ0Y5U= -github.com/ipfs/go-graphsync v0.6.5/go.mod h1:GdHT8JeuIZ0R4lSjFR16Oe4zPi5dXwKi9zR9ADVlcdk= +github.com/ipfs/go-graphsync v0.6.6 h1:In7jjzvSXlrAUz4OjN41lxYf/dzkf1bVeVxLpwKMRo8= +github.com/ipfs/go-graphsync v0.6.6/go.mod h1:GdHT8JeuIZ0R4lSjFR16Oe4zPi5dXwKi9zR9ADVlcdk= github.com/ipfs/go-hamt-ipld v0.1.1/go.mod h1:1EZCr2v0jlCnhpa+aZ0JZYp8Tt2w16+JJOAVz17YcDk= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= From 9b7a7713a78ec32316665abf8c99562f7ea55c01 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 12:10:17 +0300 Subject: [PATCH 05/79] add RuntimeSubsystems API method; use it in `lotus-miner info` --- api/api_storage.go | 2 + api/api_subsystems.go | 63 +++ api/docgen/docgen.go | 11 +- api/proxy_gen.go | 13 + cmd/lotus-miner/info.go | 480 ++++++++++++----------- documentation/en/api-v0-methods-miner.md | 14 + node/builder_miner.go | 2 + node/impl/storminer.go | 6 + node/modules/storageminer.go | 17 + v1.11.1 | 170 ++++++++ 10 files changed, 539 insertions(+), 239 deletions(-) create mode 100644 api/api_subsystems.go create mode 100644 v1.11.1 diff --git a/api/api_storage.go b/api/api_storage.go index 154abcea713..d5203265088 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -166,6 +166,8 @@ type StorageMiner interface { MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write MarketPublishPendingDeals(ctx context.Context) error //perm:admin + RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read + DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin DealsList(ctx context.Context) ([]MarketDeal, error) //perm:admin DealsConsiderOnlineStorageDeals(context.Context) (bool, error) //perm:admin diff --git a/api/api_subsystems.go b/api/api_subsystems.go new file mode 100644 index 00000000000..1894bbdd8a6 --- /dev/null +++ b/api/api_subsystems.go @@ -0,0 +1,63 @@ +package api + +import ( + "bytes" + "encoding/json" +) + +type MinerSubsystems []MinerSubsystem + +func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { + for _, v := range ms { + if v == entry { + return true + } + + } + return false +} + +type MinerSubsystem int + +const ( + MarketsSubsystem MinerSubsystem = iota + MiningSubsystem + SealingSubsystem + SectorStorageSubsystem +) + +func (ms MinerSubsystem) String() string { + return MinerSubsystemToString[ms] +} + +var MinerSubsystemToString = map[MinerSubsystem]string{ + MarketsSubsystem: "Markets", + MiningSubsystem: "Mining", + SealingSubsystem: "Sealing", + SectorStorageSubsystem: "SectorStorage", +} + +var MinerSubsystemToID = map[string]MinerSubsystem{ + "Markets": MarketsSubsystem, + "Mining": MiningSubsystem, + "Sealing": SealingSubsystem, + "SectorStorage": SectorStorageSubsystem, +} + +func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { + buffer := bytes.NewBufferString(`"`) + buffer.WriteString(MinerSubsystemToString[ms]) + buffer.WriteString(`"`) + return buffer.Bytes(), nil +} + +func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { + var j string + err := json.Unmarshal(b, &j) + if err != nil { + return err + } + // TODO: handle zero value + *ms = MinerSubsystemToID[j] + return nil +} diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 39980023f0a..1e712a0aeab 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -46,11 +46,12 @@ import ( ) var ExampleValues = map[reflect.Type]interface{}{ - reflect.TypeOf(auth.Permission("")): auth.Permission("write"), - reflect.TypeOf(""): "string value", - reflect.TypeOf(uint64(42)): uint64(42), - reflect.TypeOf(byte(7)): byte(7), - reflect.TypeOf([]byte{}): []byte("byte array"), + reflect.TypeOf(api.MinerSubsystem(0)): api.MinerSubsystem(1), + reflect.TypeOf(auth.Permission("")): auth.Permission("write"), + reflect.TypeOf(""): "string value", + reflect.TypeOf(uint64(42)): uint64(42), + reflect.TypeOf(byte(7)): byte(7), + reflect.TypeOf([]byte{}): []byte("byte array"), } func addExample(v interface{}) { diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 7d96425ffab..a4feb7be157 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -699,6 +699,8 @@ type StorageMinerStruct struct { ReturnUnsealPiece func(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error `perm:"admin"` + RuntimeSubsystems func(p0 context.Context) (MinerSubsystems, error) `perm:"read"` + SealingAbort func(p0 context.Context, p1 storiface.CallID) error `perm:"admin"` SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"` @@ -4095,6 +4097,17 @@ func (s *StorageMinerStub) ReturnUnsealPiece(p0 context.Context, p1 storiface.Ca return ErrNotSupported } +func (s *StorageMinerStruct) RuntimeSubsystems(p0 context.Context) (MinerSubsystems, error) { + if s.Internal.RuntimeSubsystems == nil { + return *new(MinerSubsystems), ErrNotSupported + } + return s.Internal.RuntimeSubsystems(p0) +} + +func (s *StorageMinerStub) RuntimeSubsystems(p0 context.Context) (MinerSubsystems, error) { + return *new(MinerSubsystems), ErrNotSupported +} + func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error { if s.Internal.SealingAbort == nil { return ErrNotSupported diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 3941ce5632f..4c409788fbb 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -55,7 +55,7 @@ func infoCmdAct(cctx *cli.Context) error { } defer closer() - api, acloser, err := lcli.GetFullNodeAPI(cctx) + fullapi, acloser, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err } @@ -63,9 +63,16 @@ func infoCmdAct(cctx *cli.Context) error { ctx := lcli.ReqContext(cctx) + subsystems, err := nodeApi.RuntimeSubsystems(ctx) + if err != nil { + return err + } + + fmt.Println("Enabled subsystems:", subsystems) + fmt.Print("Chain: ") - head, err := api.ChainHead(ctx) + head, err := fullapi.ChainHead(ctx) if err != nil { return err } @@ -95,284 +102,289 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() - maddr, err := getActorAddress(ctx, cctx) - if err != nil { - return err - } - - mact, err := api.StateGetActor(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } - - tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(api), blockstore.NewMemory()) - mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) - if err != nil { - return err - } + if subsystems.Has(api.SectorStorageSubsystem) { + maddr, err := getActorAddress(ctx, cctx) + if err != nil { + return err + } - // Sector size - mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + mact, err := fullapi.StateGetActor(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) - fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) + tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullapi), blockstore.NewMemory()) + mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) + if err != nil { + return err + } - pow, err := api.StateMinerPower(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + // Sector size + mi, err := fullapi.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - fmt.Printf("Power: %s / %s (%0.4f%%)\n", - color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), - types.DeciStr(pow.TotalPower.QualityAdjPower), - types.BigDivFloat( - types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), - pow.TotalPower.QualityAdjPower, - ), - ) - - fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", - color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), - types.SizeStr(pow.TotalPower.RawBytePower), - types.BigDivFloat( - types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), - pow.TotalPower.RawBytePower, - ), - ) - secCounts, err := api.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) + fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) - proving := secCounts.Active + secCounts.Faulty - nfaults := secCounts.Faulty - fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Live), types.NewInt(uint64(mi.SectorSize))))) - if nfaults == 0 { - fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize))))) - } else { - var faultyPercentage float64 - if secCounts.Live != 0 { - faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) + pow, err := fullapi.StateMinerPower(ctx, maddr, types.EmptyTSK) + if err != nil { + return err } - fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", - types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), - types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))), - faultyPercentage) - } - if !pow.HasMinPower { - fmt.Print("Below minimum power threshold, no blocks will be won") - } else { - - winRatio := new(corebig.Rat).SetFrac( - types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, - pow.TotalPower.QualityAdjPower.Int, + fmt.Printf("Power: %s / %s (%0.4f%%)\n", + color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), + types.DeciStr(pow.TotalPower.QualityAdjPower), + types.BigDivFloat( + types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), + pow.TotalPower.QualityAdjPower, + ), ) - if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { + fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", + color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), + types.SizeStr(pow.TotalPower.RawBytePower), + types.BigDivFloat( + types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), + pow.TotalPower.RawBytePower, + ), + ) + secCounts, err := fullapi.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - // if the corresponding poisson distribution isn't infinitely small then - // throw it into the mix as well, accounting for multi-wins - winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) - winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) - if winRationWithPoisson != nil { - winRatio = winRationWithPoisson - winRatioFloat = winRationWithPoissonFloat + proving := secCounts.Active + secCounts.Faulty + nfaults := secCounts.Faulty + fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Live), types.NewInt(uint64(mi.SectorSize))))) + if nfaults == 0 { + fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize))))) + } else { + var faultyPercentage float64 + if secCounts.Live != 0 { + faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) } + fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", + types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), + types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))), + faultyPercentage) + } - weekly, _ := new(corebig.Rat).Mul( - winRatio, - new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), - ).Float64() - - avgDuration, _ := new(corebig.Rat).Mul( - new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), - new(corebig.Rat).Inv(winRatio), - ).Float64() - - fmt.Print("Projected average block win rate: ") - color.Blue( - "%.02f/week (every %s)", - weekly, - (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), - ) + if !pow.HasMinPower { + fmt.Print("Below minimum power threshold, no blocks will be won") + } else { - // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples - // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t - // t == how many dice-rolls (epochs) before win - // p == winRate == ( minerPower / netPower ) - // c == target probability of win ( 99.9% in this case ) - fmt.Print("Projected block win with ") - color.Green( - "99.9%% probability every %s", - (time.Second * time.Duration( - builtin.EpochDurationSeconds*math.Log(1-0.999)/ - math.Log(1-winRatioFloat), - )).Truncate(time.Second).String(), + winRatio := new(corebig.Rat).SetFrac( + types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, + pow.TotalPower.QualityAdjPower.Int, ) - fmt.Println("(projections DO NOT account for future network and miner growth)") + + if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { + + // if the corresponding poisson distribution isn't infinitely small then + // throw it into the mix as well, accounting for multi-wins + winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) + winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) + if winRationWithPoisson != nil { + winRatio = winRationWithPoisson + winRatioFloat = winRationWithPoissonFloat + } + + weekly, _ := new(corebig.Rat).Mul( + winRatio, + new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), + ).Float64() + + avgDuration, _ := new(corebig.Rat).Mul( + new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), + new(corebig.Rat).Inv(winRatio), + ).Float64() + + fmt.Print("Projected average block win rate: ") + color.Blue( + "%.02f/week (every %s)", + weekly, + (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), + ) + + // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples + // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t + // t == how many dice-rolls (epochs) before win + // p == winRate == ( minerPower / netPower ) + // c == target probability of win ( 99.9% in this case ) + fmt.Print("Projected block win with ") + color.Green( + "99.9%% probability every %s", + (time.Second * time.Duration( + builtin.EpochDurationSeconds*math.Log(1-0.999)/ + math.Log(1-winRatioFloat), + )).Truncate(time.Second).String(), + ) + fmt.Println("(projections DO NOT account for future network and miner growth)") + } } - } - fmt.Println() + fmt.Println() - deals, err := nodeApi.MarketListIncompleteDeals(ctx) - if err != nil { - return err - } + spendable := big.Zero() - type dealStat struct { - count, verifCount int - bytes, verifBytes uint64 - } - dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { - ds.count++ - ds.bytes += uint64(deal.Proposal.PieceSize) - if deal.Proposal.VerifiedDeal { - ds.verifCount++ - ds.verifBytes += uint64(deal.Proposal.PieceSize) + // NOTE: there's no need to unlock anything here. Funds only + // vest on deadline boundaries, and they're unlocked by cron. + lockedFunds, err := mas.LockedFunds() + if err != nil { + return xerrors.Errorf("getting locked funds: %w", err) } - } + availBalance, err := mas.AvailableBalance(mact.Balance) + if err != nil { + return xerrors.Errorf("getting available balance: %w", err) + } + spendable = big.Add(spendable, availBalance) - showDealStates := map[storagemarket.StorageDealStatus]struct{}{ - storagemarket.StorageDealActive: {}, - storagemarket.StorageDealTransferring: {}, - storagemarket.StorageDealStaged: {}, - storagemarket.StorageDealAwaitingPreCommit: {}, - storagemarket.StorageDealSealing: {}, - storagemarket.StorageDealPublish: {}, - storagemarket.StorageDealCheckForAcceptance: {}, - storagemarket.StorageDealPublishing: {}, - } + fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) + fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) + fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) + fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) + colorTokenAmount(" Available: %s\n", availBalance) - var total dealStat - perState := map[storagemarket.StorageDealStatus]*dealStat{} - for _, deal := range deals { - if _, ok := showDealStates[deal.State]; !ok { - continue - } - if perState[deal.State] == nil { - perState[deal.State] = new(dealStat) + mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting market balance: %w", err) } + spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) - dsAdd(&total, deal) - dsAdd(perState[deal.State], deal) - } + fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) + fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) + colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) - type wstr struct { - str string - status storagemarket.StorageDealStatus - } - sorted := make([]wstr, 0, len(perState)) - for status, stat := range perState { - st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") - sorted = append(sorted, wstr{ - str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), - status: status, - }, - ) - } - sort.Slice(sorted, func(i, j int) bool { - if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { - return sorted[i].status == storagemarket.StorageDealActive + wb, err := fullapi.WalletBalance(ctx, mi.Worker) + if err != nil { + return xerrors.Errorf("getting worker balance: %w", err) } - return sorted[i].status > sorted[j].status - }) + spendable = big.Add(spendable, wb) + color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) + if len(mi.ControlAddresses) > 0 { + cbsum := big.Zero() + for _, ca := range mi.ControlAddresses { + b, err := fullapi.WalletBalance(ctx, ca) + if err != nil { + return xerrors.Errorf("getting control address balance: %w", err) + } + cbsum = big.Add(cbsum, b) + } + spendable = big.Add(spendable, cbsum) - fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) + fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) + } + colorTokenAmount("Total Spendable: %s\n", spendable) - tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) - for _, e := range sorted { - _, _ = tw.Write([]byte(e.str)) - } + fmt.Println() - _ = tw.Flush() - fmt.Println() + if !cctx.Bool("hide-sectors-info") { + fmt.Println("Sectors:") + err = sectorsInfo(ctx, nodeApi) + if err != nil { + return err + } + } - retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) - if err != nil { - return xerrors.Errorf("getting retrieval deal list: %w", err) + // TODO: grab actr state / info + // * Sealed sectors (count / bytes) + // * Power } - var retrComplete dealStat - for _, retrieval := range retrievals { - if retrieval.Status == retrievalmarket.DealStatusCompleted { - retrComplete.count++ - retrComplete.bytes += retrieval.TotalSent + if subsystems.Has(api.MarketsSubsystem) { + deals, err := nodeApi.MarketListIncompleteDeals(ctx) + if err != nil { + return err } - } - - fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) - fmt.Println() + type dealStat struct { + count, verifCount int + bytes, verifBytes uint64 + } + dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { + ds.count++ + ds.bytes += uint64(deal.Proposal.PieceSize) + if deal.Proposal.VerifiedDeal { + ds.verifCount++ + ds.verifBytes += uint64(deal.Proposal.PieceSize) + } + } - spendable := big.Zero() + showDealStates := map[storagemarket.StorageDealStatus]struct{}{ + storagemarket.StorageDealActive: {}, + storagemarket.StorageDealTransferring: {}, + storagemarket.StorageDealStaged: {}, + storagemarket.StorageDealAwaitingPreCommit: {}, + storagemarket.StorageDealSealing: {}, + storagemarket.StorageDealPublish: {}, + storagemarket.StorageDealCheckForAcceptance: {}, + storagemarket.StorageDealPublishing: {}, + } - // NOTE: there's no need to unlock anything here. Funds only - // vest on deadline boundaries, and they're unlocked by cron. - lockedFunds, err := mas.LockedFunds() - if err != nil { - return xerrors.Errorf("getting locked funds: %w", err) - } - availBalance, err := mas.AvailableBalance(mact.Balance) - if err != nil { - return xerrors.Errorf("getting available balance: %w", err) - } - spendable = big.Add(spendable, availBalance) + var total dealStat + perState := map[storagemarket.StorageDealStatus]*dealStat{} + for _, deal := range deals { + if _, ok := showDealStates[deal.State]; !ok { + continue + } + if perState[deal.State] == nil { + perState[deal.State] = new(dealStat) + } - fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) - fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) - fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) - fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) - colorTokenAmount(" Available: %s\n", availBalance) + dsAdd(&total, deal) + dsAdd(perState[deal.State], deal) + } - mb, err := api.StateMarketBalance(ctx, maddr, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("getting market balance: %w", err) - } - spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) + type wstr struct { + str string + status storagemarket.StorageDealStatus + } + sorted := make([]wstr, 0, len(perState)) + for status, stat := range perState { + st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") + sorted = append(sorted, wstr{ + str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), + status: status, + }, + ) + } + sort.Slice(sorted, func(i, j int) bool { + if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { + return sorted[i].status == storagemarket.StorageDealActive + } + return sorted[i].status > sorted[j].status + }) - fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) - fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) - colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) + fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) - wb, err := api.WalletBalance(ctx, mi.Worker) - if err != nil { - return xerrors.Errorf("getting worker balance: %w", err) - } - spendable = big.Add(spendable, wb) - color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) - if len(mi.ControlAddresses) > 0 { - cbsum := big.Zero() - for _, ca := range mi.ControlAddresses { - b, err := api.WalletBalance(ctx, ca) - if err != nil { - return xerrors.Errorf("getting control address balance: %w", err) - } - cbsum = big.Add(cbsum, b) + tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + for _, e := range sorted { + _, _ = tw.Write([]byte(e.str)) } - spendable = big.Add(spendable, cbsum) - - fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) - } - colorTokenAmount("Total Spendable: %s\n", spendable) - fmt.Println() + _ = tw.Flush() + fmt.Println() - if !cctx.Bool("hide-sectors-info") { - fmt.Println("Sectors:") - err = sectorsInfo(ctx, nodeApi) + retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) if err != nil { - return err + return xerrors.Errorf("getting retrieval deal list: %w", err) } + + var retrComplete dealStat + for _, retrieval := range retrievals { + if retrieval.Status == retrievalmarket.DealStatusCompleted { + retrComplete.count++ + retrComplete.bytes += retrieval.TotalSent + } + } + + fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) + + fmt.Println() } - // TODO: grab actr state / info - // * Sealed sectors (count / bytes) - // * Power return nil } diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index e8598ff0ceb..dcd3abd4df6 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -94,6 +94,8 @@ * [ReturnSealPreCommit1](#ReturnSealPreCommit1) * [ReturnSealPreCommit2](#ReturnSealPreCommit2) * [ReturnUnsealPiece](#ReturnUnsealPiece) +* [Runtime](#Runtime) + * [RuntimeSubsystems](#RuntimeSubsystems) * [Sealing](#Sealing) * [SealingAbort](#SealingAbort) * [SealingSchedDiag](#SealingSchedDiag) @@ -1522,6 +1524,18 @@ Inputs: Response: `{}` +## Runtime + + +### RuntimeSubsystems + + +Perms: read + +Inputs: `null` + +Response: `null` + ## Sealing diff --git a/node/builder_miner.go b/node/builder_miner.go index 0c0f9d15af9..d62cbcad9bb 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,6 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), + Override(new([]api.MinerSubsystem), modules.AddMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), @@ -215,6 +216,7 @@ func StorageMiner(out *api.StorageMiner, subsystemsCfg config.MinerSubsystemConf func(s *Settings) error { resAPI := &impl.StorageMinerAPI{} + s.invokes[ExtractApiKey] = fx.Populate(resAPI) *out = resAPI return nil diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 9db6a3775ce..86c84fee7ea 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -48,6 +48,8 @@ import ( type StorageMinerAPI struct { fx.In + Subsystems api.MinerSubsystems + api.Common api.Net @@ -703,4 +705,8 @@ func (sm *StorageMinerAPI) ComputeProof(ctx context.Context, ssi []builtin.Secto return sm.Epp.ComputeProof(ctx, ssi, rand) } +func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubsystems, err error) { + return sm.Subsystems, nil +} + var _ api.StorageMiner = &StorageMinerAPI{} diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 3a3914e0c85..06ef78ca0af 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -1007,3 +1007,20 @@ func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error { return multierr.Combine(typeErr, setConfigErr) } + +func AddMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { + if cfg.EnableMining { + res = append(res, api.MiningSubsystem) + } + if cfg.EnableSealing { + res = append(res, api.SealingSubsystem) + } + if cfg.EnableSectorStorage { + res = append(res, api.SectorStorageSubsystem) + } + if cfg.EnableMarkets { + res = append(res, api.MarketsSubsystem) + } + + return +} diff --git a/v1.11.1 b/v1.11.1 new file mode 100644 index 00000000000..225a346deba --- /dev/null +++ b/v1.11.1 @@ -0,0 +1,170 @@ +- github.com/filecoin-project/lotus: + - Merge branch 'releases' into release/v1.11.1 + - Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890)) + - lotus-shed: initial export cmd for markets related metadata ([filecoin-project/lotus#6840](https://github.com/filecoin-project/lotus/pull/6840)) + - add a very verbose -vv flag to lotus and lotus-miner. ([filecoin-project/lotus#6888](https://github.com/filecoin-project/lotus/pull/6888)) + - Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880)) + - Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854)) + - Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879)) + - Add allocated sectorid vis ([filecoin-project/lotus#4638](https://github.com/filecoin-project/lotus/pull/4638)) + - rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886)) + - update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885)) + - Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674)) + - Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683)) + - fix racy TestSimultanenousTransferLimit. ([filecoin-project/lotus#6862](https://github.com/filecoin-project/lotus/pull/6862)) + - Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867)) + - ValidateBlock: Assert that block header height's are greater than parents ([filecoin-project/lotus#6872](https://github.com/filecoin-project/lotus/pull/6872)) + - feat: Don't panic when api impl is nil ([filecoin-project/lotus#6857](https://github.com/filecoin-project/lotus/pull/6857)) + - splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811)) + - Fix links in issue templates + - Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856)) + - Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833)) + - Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848)) + - fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724)) + - Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798)) + - Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837)) + - add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544)) + - fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841)) + - add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640)) + - PriceListByVersion ([filecoin-project/lotus#6766](https://github.com/filecoin-project/lotus/pull/6766)) + - easy way to make install app ([filecoin-project/lotus#5183](https://github.com/filecoin-project/lotus/pull/5183)) + - api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) + - cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760)) + - fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) + - Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775)) + - Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817)) + - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818)) + - add SealProof in SectorBuilder ([filecoin-project/lotus#6815](https://github.com/filecoin-project/lotus/pull/6815)) + - release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828)) + - sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763)) + - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802)) + - ClientFindData: always fetch peer id from chain ([filecoin-project/lotus#6807](https://github.com/filecoin-project/lotus/pull/6807)) + - test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804)) + - ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800)) + - fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787)) + - Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777)) + - Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773)) + - update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764)) + - Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762)) + - Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642)) + - test: handle null blocks in TestForkRefuseCall ([filecoin-project/lotus#6758](https://github.com/filecoin-project/lotus/pull/6758)) + - Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757)) + - Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756)) + - Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747)) + - Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754)) + - ([filecoin-project/lotus#6746](https://github.com/filecoin-project/lotus/pull/6746)) + - Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743)) + - Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629)) + - Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356)) + - Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474)) + - ([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739)) + - Add more deal details to lotus-miner info ([filecoin-project/lotus#6708](https://github.com/filecoin-project/lotus/pull/6708)) + - Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710)) + - Fix Lotus shed + - Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066)) + - add election backtest ([filecoin-project/lotus#5950](https://github.com/filecoin-project/lotus/pull/5950)) + - Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620)) + - Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709)) + - Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697)) + - Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689)) + - Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696)) + - Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694)) + - add dollar sign ([filecoin-project/lotus#6690](https://github.com/filecoin-project/lotus/pull/6690)) + - get-actor cli spelling fix ([filecoin-project/lotus#6681](https://github.com/filecoin-project/lotus/pull/6681)) + - fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688)) + - polish(statetree): accept a context in statetree diff for timeouts ([filecoin-project/lotus#6639](https://github.com/filecoin-project/lotus/pull/6639)) + - Add helptext to lotus chain export ([filecoin-project/lotus#6672](https://github.com/filecoin-project/lotus/pull/6672)) + - Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679)) + - Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680)) + - add an incremental nonce itest. ([filecoin-project/lotus#6663](https://github.com/filecoin-project/lotus/pull/6663)) + - storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653)) + - Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664)) + - Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658)) + - fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635)) + - commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650)) + - commit batch: Initialize the FailedSectors map ([filecoin-project/lotus#6647](https://github.com/filecoin-project/lotus/pull/6647)) + - Fast-path retry submitting commit aggregate if commit is still valid ([filecoin-project/lotus#6638](https://github.com/filecoin-project/lotus/pull/6638)) + - remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634)) + - Reuse timers in sealing batch logic ([filecoin-project/lotus#6636](https://github.com/filecoin-project/lotus/pull/6636)) + - shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631)) + - fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625)) + - Update version.go to 1.11.1 ([filecoin-project/lotus#6621](https://github.com/filecoin-project/lotus/pull/6621)) +- github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.0): + - release: v1.7.0 + - Fire a transfer queued event when a transfer is queued in Graphsync (#221) ([filecoin-project/go-data-transfer#221](https://github.com/filecoin-project/go-data-transfer/pull/221)) + - feat: pass ChannelID to ValidatePush & ValidatePull (#220) ([filecoin-project/go-data-transfer#220](https://github.com/filecoin-project/go-data-transfer/pull/220)) + - release: v1.6.1 ([filecoin-project/go-data-transfer#218](https://github.com/filecoin-project/go-data-transfer/pull/218)) + - Remove CID lists (#217) ([filecoin-project/go-data-transfer#217](https://github.com/filecoin-project/go-data-transfer/pull/217)) + - Merge v1.6.0 ([filecoin-project/go-data-transfer#214](https://github.com/filecoin-project/go-data-transfer/pull/214)) + - Remove restart ack timeout (#211) ([filecoin-project/go-data-transfer#211](https://github.com/filecoin-project/go-data-transfer/pull/211)) + - feat: use different extension names to fit multiple hooks data in same graphsync message (#204) ([filecoin-project/go-data-transfer#204](https://github.com/filecoin-project/go-data-transfer/pull/204)) + - fix: map race in GS transport (#208) ([filecoin-project/go-data-transfer#208](https://github.com/filecoin-project/go-data-transfer/pull/208)) + - refactor: simplify graphsync transport (#203) ([filecoin-project/go-data-transfer#203](https://github.com/filecoin-project/go-data-transfer/pull/203)) + - release: v1.5.0 (#200) ([filecoin-project/go-data-transfer#200](https://github.com/filecoin-project/go-data-transfer/pull/200)) +- github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.0): + - release: v1.6.0 + - support padding out smaller files (#536) ([filecoin-project/go-fil-markets#536](https://github.com/filecoin-project/go-fil-markets/pull/536)) + - On overloaded CI 10 seconds just isn't enough (#587) ([filecoin-project/go-fil-markets#587](https://github.com/filecoin-project/go-fil-markets/pull/587)) + - Do not hex-encode CIDs in logs (#561) ([filecoin-project/go-fil-markets#561](https://github.com/filecoin-project/go-fil-markets/pull/561)) + - remove wrong peer check in push deal validation (#585) ([filecoin-project/go-fil-markets#585](https://github.com/filecoin-project/go-fil-markets/pull/585)) + - fix: circleci docs-gen task (#574) ([filecoin-project/go-fil-markets#574](https://github.com/filecoin-project/go-fil-markets/pull/574)) + - Storage market request queued event and validation interface changes (#555) ([filecoin-project/go-fil-markets#555](https://github.com/filecoin-project/go-fil-markets/pull/555)) + - build(deps): bump ws from 6.2.1 to 6.2.2 (#554) ([filecoin-project/go-fil-markets#554](https://github.com/filecoin-project/go-fil-markets/pull/554)) + - release: v1.5.0 ([filecoin-project/go-fil-markets#553](https://github.com/filecoin-project/go-fil-markets/pull/553)) +- github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1): + - New method to pad harder (#6) ([filecoin-project/go-padreader#6](https://github.com/filecoin-project/go-padreader/pull/6)) + - Create SECURITY.md (#5) ([filecoin-project/go-padreader#5](https://github.com/filecoin-project/go-padreader/pull/5)) +- github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210722133031-ad9bfe54c124): + - Add version 6.5 (#30) ([filecoin-project/go-state-types#30](https://github.com/filecoin-project/go-state-types/pull/30)) + - rename file +- github.com/filecoin-project/specs-actors/v5 (v5.0.1 -> v5.0.3): + - Adjust code for subtle change in go-multihash 0.0.15 (#1463) ([filecoin-project/specs-actors#1463](https://github.com/filecoin-project/specs-actors/pull/1463)) + - Bump go state types (#1464) ([filecoin-project/specs-actors#1464](https://github.com/filecoin-project/specs-actors/pull/1464)) + - Create CODEOWNERS (#1465) ([filecoin-project/specs-actors#1465](https://github.com/filecoin-project/specs-actors/pull/1465)) + - Test deterministic offset (#1462) ([filecoin-project/specs-actors#1462](https://github.com/filecoin-project/specs-actors/pull/1462)) + +Contributors + +| Contributor | Commits | Lines ± | Files Changed | +|-------------|---------|---------|---------------| +| vyzo | 295 | +8700/-5936 | 397 | +| Anton Evangelatov | 94 | +4680/-2965 | 277 | +| Łukasz Magiera | 37 | +3851/-1611 | 146 | +| Mike Greenberg | 1 | +2310/-578 | 8 | +| dirkmc | 7 | +1154/-726 | 29 | +| Jennifer Wang | 9 | +485/-341 | 26 | +| Peter Rabbitson | 18 | +469/-273 | 64 | +| Cory Schwartz | 5 | +576/-135 | 14 | +| hunjixin | 7 | +404/-82 | 19 | +| ZenGround0 | 17 | +284/-135 | 44 | +| Dirk McCormick | 17 | +348/-47 | 17 | +| Raúl Kripalani | 18 | +254/-97 | 62 | +| tchardin | 1 | +261/-33 | 4 | +| Jakub Sztandera | 4 | +254/-16 | 4 | +| Aarsh Shah | 2 | +196/-40 | 28 | +| whyrusleeping | 3 | +150/-9 | 8 | +| Whyrusleeping | 2 | +87/-66 | 10 | +| Aayush Rajasekaran | 10 | +81/-53 | 13 | +| zgfzgf | 2 | +104/-4 | 2 | +| aarshkshah1992 | 4 | +73/-7 | 6 | +| llifezou | 4 | +59/-20 | 4 | +| Steven Allen | 7 | +47/-17 | 9 | +| johnli-helloworld | 3 | +46/-15 | 5 | +| frrist | 1 | +28/-23 | 2 | +| Jennifer | 4 | +31/-2 | 4 | +| wangchao | 1 | +1/-27 | 1 | +| Jiaying Wang | 2 | +7/-21 | 2 | +| hannahhoward | 3 | +21/-2 | 3 | +| chadwick2143 | 1 | +15/-1 | 1 | +| Jerry | 2 | +9/-4 | 2 | +| Steve Loeppky | 2 | +12/-0 | 2 | +| David Dias | 1 | +9/-0 | 1 | +| dependabot[bot] | 1 | +3/-3 | 1 | +| zhoutian527 | 1 | +2/-2 | 1 | +| xloem | 1 | +4/-0 | 1 | +| Travis Person | 2 | +2/-2 | 3 | +| Liviu Damian | 2 | +2/-2 | 2 | +| Jim Pick | 2 | +2/-2 | 2 | +| Frank | 1 | +3/-0 | 1 | +| turuslan | 1 | +1/-1 | 1 | +| Kirk Baird | 1 | +0/-0 | 1 | From 0dd83c675557f36d4295dc1b30cb53e70769e6cc Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 16:23:04 +0300 Subject: [PATCH 06/79] fixup --- node/builder_miner.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/node/builder_miner.go b/node/builder_miner.go index d62cbcad9bb..830e6d075b2 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,7 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), - Override(new([]api.MinerSubsystem), modules.AddMinerSubsystems(cfg.Subsystems)), + Override(new(api.MinerSubsystems), modules.AddMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), @@ -216,7 +216,6 @@ func StorageMiner(out *api.StorageMiner, subsystemsCfg config.MinerSubsystemConf func(s *Settings) error { resAPI := &impl.StorageMinerAPI{} - s.invokes[ExtractApiKey] = fx.Populate(resAPI) *out = resAPI return nil From cea26348c44a56ecd46f6443c503cdb3ddab3cf7 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 17:30:59 +0300 Subject: [PATCH 07/79] extract outputs for mining node and markets node in separate functions --- cmd/lotus-miner/info.go | 471 +++++++++++++++++++++------------------- 1 file changed, 245 insertions(+), 226 deletions(-) diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 4c409788fbb..2a36279595b 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -21,6 +21,7 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api/v0api" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/api" @@ -103,288 +104,306 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() if subsystems.Has(api.SectorStorageSubsystem) { - maddr, err := getActorAddress(ctx, cctx) + err := handleMiningInfo(cctx, ctx, fullapi, nodeApi) if err != nil { return err } + } - mact, err := fullapi.StateGetActor(ctx, maddr, types.EmptyTSK) + if subsystems.Has(api.MarketsSubsystem) { + err := handleMarketsInfo(ctx, nodeApi) if err != nil { return err } + } - tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullapi), blockstore.NewMemory()) - mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) - if err != nil { - return err - } + return nil +} - // Sector size - mi, err := fullapi.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } +func handleMiningInfo(cctx *cli.Context, ctx context.Context, fullapi v0api.FullNode, nodeApi api.StorageMiner) error { + maddr, err := getActorAddress(ctx, cctx) + if err != nil { + return err + } - ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) - fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) + mact, err := fullapi.StateGetActor(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - pow, err := fullapi.StateMinerPower(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullapi), blockstore.NewMemory()) + mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) + if err != nil { + return err + } - fmt.Printf("Power: %s / %s (%0.4f%%)\n", - color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), - types.DeciStr(pow.TotalPower.QualityAdjPower), - types.BigDivFloat( - types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), - pow.TotalPower.QualityAdjPower, - ), - ) + // Sector size + mi, err := fullapi.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", - color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), - types.SizeStr(pow.TotalPower.RawBytePower), - types.BigDivFloat( - types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), - pow.TotalPower.RawBytePower, - ), - ) - secCounts, err := fullapi.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) + fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) - proving := secCounts.Active + secCounts.Faulty - nfaults := secCounts.Faulty - fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Live), types.NewInt(uint64(mi.SectorSize))))) - if nfaults == 0 { - fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize))))) - } else { - var faultyPercentage float64 - if secCounts.Live != 0 { - faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) - } - fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", - types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), - types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))), - faultyPercentage) + pow, err := fullapi.StateMinerPower(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + fmt.Printf("Power: %s / %s (%0.4f%%)\n", + color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), + types.DeciStr(pow.TotalPower.QualityAdjPower), + types.BigDivFloat( + types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), + pow.TotalPower.QualityAdjPower, + ), + ) + + fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", + color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), + types.SizeStr(pow.TotalPower.RawBytePower), + types.BigDivFloat( + types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), + pow.TotalPower.RawBytePower, + ), + ) + secCounts, err := fullapi.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + proving := secCounts.Active + secCounts.Faulty + nfaults := secCounts.Faulty + fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Live), types.NewInt(uint64(mi.SectorSize))))) + if nfaults == 0 { + fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize))))) + } else { + var faultyPercentage float64 + if secCounts.Live != 0 { + faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) } + fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", + types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), + types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))), + faultyPercentage) + } - if !pow.HasMinPower { - fmt.Print("Below minimum power threshold, no blocks will be won") - } else { + if !pow.HasMinPower { + fmt.Print("Below minimum power threshold, no blocks will be won") + } else { - winRatio := new(corebig.Rat).SetFrac( - types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, - pow.TotalPower.QualityAdjPower.Int, - ) + winRatio := new(corebig.Rat).SetFrac( + types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, + pow.TotalPower.QualityAdjPower.Int, + ) - if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { - - // if the corresponding poisson distribution isn't infinitely small then - // throw it into the mix as well, accounting for multi-wins - winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) - winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) - if winRationWithPoisson != nil { - winRatio = winRationWithPoisson - winRatioFloat = winRationWithPoissonFloat - } - - weekly, _ := new(corebig.Rat).Mul( - winRatio, - new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), - ).Float64() - - avgDuration, _ := new(corebig.Rat).Mul( - new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), - new(corebig.Rat).Inv(winRatio), - ).Float64() - - fmt.Print("Projected average block win rate: ") - color.Blue( - "%.02f/week (every %s)", - weekly, - (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), - ) - - // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples - // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t - // t == how many dice-rolls (epochs) before win - // p == winRate == ( minerPower / netPower ) - // c == target probability of win ( 99.9% in this case ) - fmt.Print("Projected block win with ") - color.Green( - "99.9%% probability every %s", - (time.Second * time.Duration( - builtin.EpochDurationSeconds*math.Log(1-0.999)/ - math.Log(1-winRatioFloat), - )).Truncate(time.Second).String(), - ) - fmt.Println("(projections DO NOT account for future network and miner growth)") - } - } + if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { - fmt.Println() + // if the corresponding poisson distribution isn't infinitely small then + // throw it into the mix as well, accounting for multi-wins + winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) + winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) + if winRationWithPoisson != nil { + winRatio = winRationWithPoisson + winRatioFloat = winRationWithPoissonFloat + } - spendable := big.Zero() + weekly, _ := new(corebig.Rat).Mul( + winRatio, + new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), + ).Float64() + + avgDuration, _ := new(corebig.Rat).Mul( + new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), + new(corebig.Rat).Inv(winRatio), + ).Float64() + + fmt.Print("Projected average block win rate: ") + color.Blue( + "%.02f/week (every %s)", + weekly, + (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), + ) - // NOTE: there's no need to unlock anything here. Funds only - // vest on deadline boundaries, and they're unlocked by cron. - lockedFunds, err := mas.LockedFunds() - if err != nil { - return xerrors.Errorf("getting locked funds: %w", err) - } - availBalance, err := mas.AvailableBalance(mact.Balance) - if err != nil { - return xerrors.Errorf("getting available balance: %w", err) + // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples + // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t + // t == how many dice-rolls (epochs) before win + // p == winRate == ( minerPower / netPower ) + // c == target probability of win ( 99.9% in this case ) + fmt.Print("Projected block win with ") + color.Green( + "99.9%% probability every %s", + (time.Second * time.Duration( + builtin.EpochDurationSeconds*math.Log(1-0.999)/ + math.Log(1-winRatioFloat), + )).Truncate(time.Second).String(), + ) + fmt.Println("(projections DO NOT account for future network and miner growth)") } - spendable = big.Add(spendable, availBalance) + } - fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) - fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) - fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) - fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) - colorTokenAmount(" Available: %s\n", availBalance) + fmt.Println() - mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("getting market balance: %w", err) - } - spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) + spendable := big.Zero() - fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) - fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) - colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) + // NOTE: there's no need to unlock anything here. Funds only + // vest on deadline boundaries, and they're unlocked by cron. + lockedFunds, err := mas.LockedFunds() + if err != nil { + return xerrors.Errorf("getting locked funds: %w", err) + } + availBalance, err := mas.AvailableBalance(mact.Balance) + if err != nil { + return xerrors.Errorf("getting available balance: %w", err) + } + spendable = big.Add(spendable, availBalance) - wb, err := fullapi.WalletBalance(ctx, mi.Worker) - if err != nil { - return xerrors.Errorf("getting worker balance: %w", err) - } - spendable = big.Add(spendable, wb) - color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) - if len(mi.ControlAddresses) > 0 { - cbsum := big.Zero() - for _, ca := range mi.ControlAddresses { - b, err := fullapi.WalletBalance(ctx, ca) - if err != nil { - return xerrors.Errorf("getting control address balance: %w", err) - } - cbsum = big.Add(cbsum, b) - } - spendable = big.Add(spendable, cbsum) + fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) + fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) + fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) + fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) + colorTokenAmount(" Available: %s\n", availBalance) - fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) - } - colorTokenAmount("Total Spendable: %s\n", spendable) + mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting market balance: %w", err) + } + spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) - fmt.Println() + fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) + fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) + colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) - if !cctx.Bool("hide-sectors-info") { - fmt.Println("Sectors:") - err = sectorsInfo(ctx, nodeApi) + wb, err := fullapi.WalletBalance(ctx, mi.Worker) + if err != nil { + return xerrors.Errorf("getting worker balance: %w", err) + } + spendable = big.Add(spendable, wb) + color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) + if len(mi.ControlAddresses) > 0 { + cbsum := big.Zero() + for _, ca := range mi.ControlAddresses { + b, err := fullapi.WalletBalance(ctx, ca) if err != nil { - return err + return xerrors.Errorf("getting control address balance: %w", err) } + cbsum = big.Add(cbsum, b) } + spendable = big.Add(spendable, cbsum) - // TODO: grab actr state / info - // * Sealed sectors (count / bytes) - // * Power + fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) } + colorTokenAmount("Total Spendable: %s\n", spendable) - if subsystems.Has(api.MarketsSubsystem) { - deals, err := nodeApi.MarketListIncompleteDeals(ctx) + fmt.Println() + + if !cctx.Bool("hide-sectors-info") { + fmt.Println("Sectors:") + err = sectorsInfo(ctx, nodeApi) if err != nil { return err } + } - type dealStat struct { - count, verifCount int - bytes, verifBytes uint64 - } - dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { - ds.count++ - ds.bytes += uint64(deal.Proposal.PieceSize) - if deal.Proposal.VerifiedDeal { - ds.verifCount++ - ds.verifBytes += uint64(deal.Proposal.PieceSize) - } - } + // TODO: grab actr state / info + // * Sealed sectors (count / bytes) + // * Power - showDealStates := map[storagemarket.StorageDealStatus]struct{}{ - storagemarket.StorageDealActive: {}, - storagemarket.StorageDealTransferring: {}, - storagemarket.StorageDealStaged: {}, - storagemarket.StorageDealAwaitingPreCommit: {}, - storagemarket.StorageDealSealing: {}, - storagemarket.StorageDealPublish: {}, - storagemarket.StorageDealCheckForAcceptance: {}, - storagemarket.StorageDealPublishing: {}, - } + return nil +} - var total dealStat - perState := map[storagemarket.StorageDealStatus]*dealStat{} - for _, deal := range deals { - if _, ok := showDealStates[deal.State]; !ok { - continue - } - if perState[deal.State] == nil { - perState[deal.State] = new(dealStat) - } +func handleMarketsInfo(ctx context.Context, nodeApi api.StorageMiner) error { + deals, err := nodeApi.MarketListIncompleteDeals(ctx) + if err != nil { + return err + } - dsAdd(&total, deal) - dsAdd(perState[deal.State], deal) + type dealStat struct { + count, verifCount int + bytes, verifBytes uint64 + } + dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { + ds.count++ + ds.bytes += uint64(deal.Proposal.PieceSize) + if deal.Proposal.VerifiedDeal { + ds.verifCount++ + ds.verifBytes += uint64(deal.Proposal.PieceSize) } + } - type wstr struct { - str string - status storagemarket.StorageDealStatus + showDealStates := map[storagemarket.StorageDealStatus]struct{}{ + storagemarket.StorageDealActive: {}, + storagemarket.StorageDealTransferring: {}, + storagemarket.StorageDealStaged: {}, + storagemarket.StorageDealAwaitingPreCommit: {}, + storagemarket.StorageDealSealing: {}, + storagemarket.StorageDealPublish: {}, + storagemarket.StorageDealCheckForAcceptance: {}, + storagemarket.StorageDealPublishing: {}, + } + + var total dealStat + perState := map[storagemarket.StorageDealStatus]*dealStat{} + for _, deal := range deals { + if _, ok := showDealStates[deal.State]; !ok { + continue } - sorted := make([]wstr, 0, len(perState)) - for status, stat := range perState { - st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") - sorted = append(sorted, wstr{ - str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), - status: status, - }, - ) + if perState[deal.State] == nil { + perState[deal.State] = new(dealStat) } - sort.Slice(sorted, func(i, j int) bool { - if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { - return sorted[i].status == storagemarket.StorageDealActive - } - return sorted[i].status > sorted[j].status - }) - fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) + dsAdd(&total, deal) + dsAdd(perState[deal.State], deal) + } - tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) - for _, e := range sorted { - _, _ = tw.Write([]byte(e.str)) + type wstr struct { + str string + status storagemarket.StorageDealStatus + } + sorted := make([]wstr, 0, len(perState)) + for status, stat := range perState { + st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") + sorted = append(sorted, wstr{ + str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), + status: status, + }, + ) + } + sort.Slice(sorted, func(i, j int) bool { + if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { + return sorted[i].status == storagemarket.StorageDealActive } + return sorted[i].status > sorted[j].status + }) - _ = tw.Flush() - fmt.Println() + fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) - retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) - if err != nil { - return xerrors.Errorf("getting retrieval deal list: %w", err) - } + tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + for _, e := range sorted { + _, _ = tw.Write([]byte(e.str)) + } - var retrComplete dealStat - for _, retrieval := range retrievals { - if retrieval.Status == retrievalmarket.DealStatusCompleted { - retrComplete.count++ - retrComplete.bytes += retrieval.TotalSent - } - } + _ = tw.Flush() + fmt.Println() - fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) + retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) + if err != nil { + return xerrors.Errorf("getting retrieval deal list: %w", err) + } - fmt.Println() + var retrComplete dealStat + for _, retrieval := range retrievals { + if retrieval.Status == retrievalmarket.DealStatusCompleted { + retrComplete.count++ + retrComplete.bytes += retrieval.TotalSent + } } + fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) + + fmt.Println() + return nil } From 0c036b1157cf8142d0fc440a38935bddafc2d585 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 17:47:01 +0300 Subject: [PATCH 08/79] make linter happy --- cmd/lotus-miner/info.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 2a36279595b..92f25667cc1 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -104,7 +104,7 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() if subsystems.Has(api.SectorStorageSubsystem) { - err := handleMiningInfo(cctx, ctx, fullapi, nodeApi) + err := handleMiningInfo(ctx, cctx, fullapi, nodeApi) if err != nil { return err } @@ -120,7 +120,7 @@ func infoCmdAct(cctx *cli.Context) error { return nil } -func handleMiningInfo(cctx *cli.Context, ctx context.Context, fullapi v0api.FullNode, nodeApi api.StorageMiner) error { +func handleMiningInfo(ctx context.Context, cctx *cli.Context, fullapi v0api.FullNode, nodeApi api.StorageMiner) error { maddr, err := getActorAddress(ctx, cctx) if err != nil { return err From c119ab6ed970483521ed8793451ed2933cfba6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 28 Jul 2021 19:51:45 +0100 Subject: [PATCH 09/79] fix docs and nits. --- api/api_storage.go | 2 + api/api_subsystems.go | 63 ------------------- api/docgen/docgen.go | 10 ++- api/miner_subsystems.go | 79 ++++++++++++++++++++++++ cmd/lotus-miner/info.go | 4 +- documentation/en/api-v0-methods-miner.md | 12 +++- node/builder_miner.go | 2 +- node/impl/storminer.go | 10 +-- node/modules/storageminer.go | 11 ++-- 9 files changed, 113 insertions(+), 80 deletions(-) delete mode 100644 api/api_subsystems.go create mode 100644 api/miner_subsystems.go diff --git a/api/api_storage.go b/api/api_storage.go index d5203265088..c391149290b 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -166,6 +166,8 @@ type StorageMiner interface { MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write MarketPublishPendingDeals(ctx context.Context) error //perm:admin + // RuntimeSubsystems returns the subsystems that are enabled + // in this instance. RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin diff --git a/api/api_subsystems.go b/api/api_subsystems.go deleted file mode 100644 index 1894bbdd8a6..00000000000 --- a/api/api_subsystems.go +++ /dev/null @@ -1,63 +0,0 @@ -package api - -import ( - "bytes" - "encoding/json" -) - -type MinerSubsystems []MinerSubsystem - -func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { - for _, v := range ms { - if v == entry { - return true - } - - } - return false -} - -type MinerSubsystem int - -const ( - MarketsSubsystem MinerSubsystem = iota - MiningSubsystem - SealingSubsystem - SectorStorageSubsystem -) - -func (ms MinerSubsystem) String() string { - return MinerSubsystemToString[ms] -} - -var MinerSubsystemToString = map[MinerSubsystem]string{ - MarketsSubsystem: "Markets", - MiningSubsystem: "Mining", - SealingSubsystem: "Sealing", - SectorStorageSubsystem: "SectorStorage", -} - -var MinerSubsystemToID = map[string]MinerSubsystem{ - "Markets": MarketsSubsystem, - "Mining": MiningSubsystem, - "Sealing": SealingSubsystem, - "SectorStorage": SectorStorageSubsystem, -} - -func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { - buffer := bytes.NewBufferString(`"`) - buffer.WriteString(MinerSubsystemToString[ms]) - buffer.WriteString(`"`) - return buffer.Bytes(), nil -} - -func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { - var j string - err := json.Unmarshal(b, &j) - if err != nil { - return err - } - // TODO: handle zero value - *ms = MinerSubsystemToID[j] - return nil -} diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 1e712a0aeab..f9addc940dd 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -16,10 +16,10 @@ import ( "github.com/google/uuid" "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" - metrics "github.com/libp2p/go-libp2p-core/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/libp2p/go-libp2p-core/protocol" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/multiformats/go-multiaddr" @@ -265,6 +265,12 @@ func init() { addExample(api.CheckStatusCode(0)) addExample(map[string]interface{}{"abc": 123}) + addExample(api.MinerSubsystems{ + api.SubsystemMining, + api.SubsystemSealing, + api.SubsystemSectorStorage, + api.SubsystemMarkets, + }) } func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) { diff --git a/api/miner_subsystems.go b/api/miner_subsystems.go new file mode 100644 index 00000000000..a77de7e3c95 --- /dev/null +++ b/api/miner_subsystems.go @@ -0,0 +1,79 @@ +package api + +import ( + "encoding/json" +) + +// MinerSubsystem represents a miner subsystem. Int and string values are not +// guaranteed to be stable over time is not +// guaranteed to be stable over time. +type MinerSubsystem int + +const ( + // SubsystemUnknown is a placeholder for the zero value. It should never + // be used. + SubsystemUnknown MinerSubsystem = iota + // SubsystemMarkets signifies the storage and retrieval + // deal-making subsystem. + SubsystemMarkets + // SubsystemMining signifies the mining subsystem. + SubsystemMining + // SubsystemSealing signifies the sealing subsystem. + SubsystemSealing + // SubsystemSectorStorage signifies the sector storage subsystem. + SubsystemSectorStorage +) + +var MinerSubsystemToString = map[MinerSubsystem]string{ + SubsystemUnknown: "Unknown", + SubsystemMarkets: "Markets", + SubsystemMining: "Mining", + SubsystemSealing: "Sealing", + SubsystemSectorStorage: "SectorStorage", +} + +var MinerSubsystemToID = map[string]MinerSubsystem{ + "Unknown": SubsystemUnknown, + "Markets": SubsystemMarkets, + "Mining": SubsystemMining, + "Sealing": SubsystemSealing, + "SectorStorage": SubsystemSectorStorage, +} + +func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { + return json.Marshal(MinerSubsystemToString[ms]) +} + +func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { + var j string + err := json.Unmarshal(b, &j) + if err != nil { + return err + } + s, ok := MinerSubsystemToID[j] + if !ok { + *ms = SubsystemUnknown + } else { + *ms = s + } + return nil +} + +type MinerSubsystems []MinerSubsystem + +func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { + for _, v := range ms { + if v == entry { + return true + } + } + return false +} + +func (ms MinerSubsystem) String() string { + s, ok := MinerSubsystemToString[ms] + if !ok { + return MinerSubsystemToString[SubsystemUnknown] + } + return s +} diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 92f25667cc1..878361dacb6 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -103,14 +103,14 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() - if subsystems.Has(api.SectorStorageSubsystem) { + if subsystems.Has(api.SubsystemSectorStorage) { err := handleMiningInfo(ctx, cctx, fullapi, nodeApi) if err != nil { return err } } - if subsystems.Has(api.MarketsSubsystem) { + if subsystems.Has(api.SubsystemMarkets) { err := handleMarketsInfo(ctx, nodeApi) if err != nil { return err diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index dcd3abd4df6..3b6d5ac5181 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -1528,13 +1528,23 @@ Response: `{}` ### RuntimeSubsystems +RuntimeSubsystems returns the subsystems that are enabled +in this instance. Perms: read Inputs: `null` -Response: `null` +Response: +```json +[ + "Mining", + "Sealing", + "SectorStorage", + "Markets" +] +``` ## Sealing diff --git a/node/builder_miner.go b/node/builder_miner.go index 830e6d075b2..acb9d3d43cd 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,7 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), - Override(new(api.MinerSubsystems), modules.AddMinerSubsystems(cfg.Subsystems)), + Override(new(api.MinerSubsystems), modules.PopulateEnabledMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 86c84fee7ea..0fbd1211143 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -23,8 +23,8 @@ import ( "github.com/filecoin-project/go-address" datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-fil-markets/piecestore" - retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" - storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-fil-markets/retrievalmarket" + "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" @@ -48,11 +48,11 @@ import ( type StorageMinerAPI struct { fx.In - Subsystems api.MinerSubsystems - api.Common api.Net + EnabledSubsystems api.MinerSubsystems + Full api.FullNode LocalStore *stores.Local RemoteStore *stores.Remote @@ -706,7 +706,7 @@ func (sm *StorageMinerAPI) ComputeProof(ctx context.Context, ssi []builtin.Secto } func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubsystems, err error) { - return sm.Subsystems, nil + return sm.EnabledSubsystems, nil } var _ api.StorageMiner = &StorageMinerAPI{} diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 06ef78ca0af..26792ca197b 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -1008,19 +1008,18 @@ func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error { return multierr.Combine(typeErr, setConfigErr) } -func AddMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { +func PopulateEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { if cfg.EnableMining { - res = append(res, api.MiningSubsystem) + res = append(res, api.SubsystemMining) } if cfg.EnableSealing { - res = append(res, api.SealingSubsystem) + res = append(res, api.SubsystemSealing) } if cfg.EnableSectorStorage { - res = append(res, api.SectorStorageSubsystem) + res = append(res, api.SubsystemSectorStorage) } if cfg.EnableMarkets { - res = append(res, api.MarketsSubsystem) + res = append(res, api.SubsystemMarkets) } - return } From d8c90b91be22983e23fced4a8facac74c0872c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 28 Jul 2021 23:46:21 +0100 Subject: [PATCH 10/79] address nits. --- node/builder_miner.go | 2 +- node/modules/storageminer.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/builder_miner.go b/node/builder_miner.go index acb9d3d43cd..3be055de79b 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,7 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), - Override(new(api.MinerSubsystems), modules.PopulateEnabledMinerSubsystems(cfg.Subsystems)), + Override(new(api.MinerSubsystems), modules.ExtractEnabledMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 26792ca197b..5497eab5813 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -1008,7 +1008,7 @@ func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error { return multierr.Combine(typeErr, setConfigErr) } -func PopulateEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { +func ExtractEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { if cfg.EnableMining { res = append(res, api.SubsystemMining) } @@ -1021,5 +1021,5 @@ func PopulateEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.Mi if cfg.EnableMarkets { res = append(res, api.SubsystemMarkets) } - return + return res } From d039764a343102dcd856eb26c2842eb212e0120f Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 11:49:42 +0300 Subject: [PATCH 11/79] code cosmetics: rename variables for better readability and some comments --- blockstore/badger/blockstore.go | 69 +++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 8e1a3a1ff8b..49951db6ed1 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -258,16 +258,16 @@ func (b *Blockstore) movingGC() error { b.moveCond.Broadcast() b.moveMx.Unlock() - var path string + var newPath string defer func() { b.lockMove() - db2 := b.dbNext + dbNext := b.dbNext b.dbNext = nil var state bsMoveState - if db2 != nil { + if dbNext != nil { state = moveStateCleanup } else { state = moveStateNone @@ -275,12 +275,13 @@ func (b *Blockstore) movingGC() error { b.unlockMove(state) - if db2 != nil { - err := db2.Close() + if dbNext != nil { + // the move failed and we have a left-over db; delete it. + err := dbNext.Close() if err != nil { log.Warnf("error closing badger db: %s", err) } - b.deleteDB(path) + b.deleteDB(newPath) b.lockMove() b.unlockMove(moveStateNone) @@ -296,63 +297,71 @@ func (b *Blockstore) movingGC() error { } if basePath == linkPath { - path = basePath + newPath = basePath } else { + // we do this dance to create a name adjacent to the current one, while avoiding clown + // shoes with multiple moves (i.e. we can't just take the basename of the linkPath, as it + // could have been created in a previous move and have the timestamp suffix, which would then + // perpetuate itself. name := filepath.Base(basePath) dir := filepath.Dir(linkPath) - path = filepath.Join(dir, name) + newPath = filepath.Join(dir, name) } - path = fmt.Sprintf("%s.%d", path, time.Now().UnixNano()) + newPath = fmt.Sprintf("%s.%d", newPath, time.Now().UnixNano()) - log.Infof("moving blockstore from %s to %s", b.opts.Dir, path) + log.Infof("moving blockstore from %s to %s", b.opts.Dir, newPath) opts := b.opts - opts.Dir = path - opts.ValueDir = path + opts.Dir = newPath + opts.ValueDir = newPath - db2, err := badger.Open(opts.Options) + dbNew, err := badger.Open(opts.Options) if err != nil { - return fmt.Errorf("failed to open badger blockstore in %s: %w", path, err) + return fmt.Errorf("failed to open badger blockstore in %s: %w", newPath, err) } b.lockMove() - b.dbNext = db2 + b.dbNext = dbNew b.unlockMove(moveStateMoving) log.Info("copying blockstore") err = b.doCopy(b.db, b.dbNext) if err != nil { - return fmt.Errorf("error moving badger blockstore to %s: %w", path, err) + return fmt.Errorf("error moving badger blockstore to %s: %w", newPath, err) } b.lockMove() - db1 := b.db + dbOld := b.db b.db = b.dbNext b.dbNext = nil b.unlockMove(moveStateCleanup) - err = db1.Close() + err = dbOld.Close() if err != nil { log.Warnf("error closing old badger db: %s", err) } - dbpath := b.opts.Dir - oldpath := fmt.Sprintf("%s.old.%d", dbpath, time.Now().Unix()) + // this is the canonical db path; this is where our db lives. + dbPath := b.opts.Dir - if err = os.Rename(dbpath, oldpath); err != nil { + // we first move the existing db out of the way, and only delete it after we have symlinked the + // new db to the canonical path + backupPath := fmt.Sprintf("%s.old.%d", dbPath, time.Now().Unix()) + if err = os.Rename(dbPath, backupPath); err != nil { // this is not catastrophic in the sense that we have not lost any data. // but it is pretty bad, as the db path points to the old db, while we are now using to the new // db; we can't continue and leave a ticking bomb for the next restart. // so a panic is appropriate and user can fix. - panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbpath, oldpath, err)) //nolint + panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbPath, backupPath, err)) //nolint } - if err = os.Symlink(path, dbpath); err != nil { + if err = os.Symlink(newPath, dbPath); err != nil { // same here; the db path is pointing to the void. panic and let the user fix. - panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", path, dbpath, err)) //nolint + panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", newPath, dbPath, err)) //nolint } - b.deleteDB(oldpath) + // the delete follows symlinks + b.deleteDB(backupPath) log.Info("moving blockstore done") return nil @@ -390,19 +399,19 @@ func (b *Blockstore) doCopy(from, to *badger.DB) error { func (b *Blockstore) deleteDB(path string) { // follow symbolic links, otherwise the data wil be left behind - lpath, err := filepath.EvalSymlinks(path) + linkPath, err := filepath.EvalSymlinks(path) if err != nil { log.Warnf("error resolving symlinks in %s", path) return } - log.Infof("removing data directory %s", lpath) - if err := os.RemoveAll(lpath); err != nil { - log.Warnf("error deleting db at %s: %s", lpath, err) + log.Infof("removing data directory %s", linkPath) + if err := os.RemoveAll(linkPath); err != nil { + log.Warnf("error deleting db at %s: %s", linkPath, err) return } - if path != lpath { + if path != linkPath { log.Infof("removing link %s", path) if err := os.Remove(path); err != nil { log.Warnf("error removing symbolic link %s", err) From 7a3193a75bf132818e2b617cd8740d6f1b352438 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 11:56:23 +0300 Subject: [PATCH 12/79] make relative links when the canonical and new db paths are in the same directory --- blockstore/badger/blockstore.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 49951db6ed1..3d186228327 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -355,7 +355,7 @@ func (b *Blockstore) movingGC() error { panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbPath, backupPath, err)) //nolint } - if err = os.Symlink(newPath, dbPath); err != nil { + if err = b.symlink(newPath, dbPath); err != nil { // same here; the db path is pointing to the void. panic and let the user fix. panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", newPath, dbPath, err)) //nolint } @@ -367,6 +367,18 @@ func (b *Blockstore) movingGC() error { return nil } +// symlink creates a symlink from path to linkPath; the link is relative if the two are +// in the same directory +func (b *Blockstore) symlink(path, linkTo string) error { + pathDir := filepath.Dir(path) + linkDir := filepath.Dir(linkTo) + if pathDir == linkDir { + path = filepath.Base(path) + } + + return os.Symlink(path, linkTo) +} + // doCopy copies a badger blockstore to another, with an optional filter; if the filter // is not nil, then only cids that satisfy the filter will be copied. func (b *Blockstore) doCopy(from, to *badger.DB) error { From a24b2436b0d9ded5d3ca91929d3944fe98073fcc Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 11:56:35 +0300 Subject: [PATCH 13/79] extend test to check the validity of relative links --- blockstore/badger/blockstore_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/blockstore/badger/blockstore_test.go b/blockstore/badger/blockstore_test.go index ddfa6f28d35..d8ef5241b49 100644 --- a/blockstore/badger/blockstore_test.go +++ b/blockstore/badger/blockstore_test.go @@ -245,6 +245,21 @@ func testMove(t *testing.T, optsF func(string) Options) { checkBlocks() checkPath() + + // reopen the db to make sure our relative link works: + err = db.Close() + if err != nil { + t.Fatal(err) + } + + db, err = Open(optsF(dbPath)) + if err != nil { + t.Fatal(err) + } + + // db.Close() is already deferred + + checkBlocks() } func TestMoveNoPrefix(t *testing.T) { From 0caabf1328d3db16aeda222dc080b701d17c92f1 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 16:15:39 +0300 Subject: [PATCH 14/79] improve detection of relative links --- blockstore/badger/blockstore.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 3d186228327..094b8eb6c5c 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -370,9 +370,17 @@ func (b *Blockstore) movingGC() error { // symlink creates a symlink from path to linkPath; the link is relative if the two are // in the same directory func (b *Blockstore) symlink(path, linkTo string) error { - pathDir := filepath.Dir(path) - linkDir := filepath.Dir(linkTo) - if pathDir == linkDir { + resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) + if err != nil { + return fmt.Errorf("error resolving links in %s: %w", path, err) + } + + resolvedLinkDir, err := filepath.EvalSymlinks(filepath.Dir(linkTo)) + if err != nil { + return fmt.Errorf("error resolving links in %s: %W", linkTo, err) + } + + if resolvedPathDir == resolvedLinkDir { path = filepath.Base(path) } From ec78d3d7b1b7c00e381e74ac41d20fab1bbc3a6f Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 16:20:25 +0300 Subject: [PATCH 15/79] fix format specifier --- blockstore/badger/blockstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 094b8eb6c5c..dad37a6b1ff 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -377,7 +377,7 @@ func (b *Blockstore) symlink(path, linkTo string) error { resolvedLinkDir, err := filepath.EvalSymlinks(filepath.Dir(linkTo)) if err != nil { - return fmt.Errorf("error resolving links in %s: %W", linkTo, err) + return fmt.Errorf("error resolving links in %s: %w", linkTo, err) } if resolvedPathDir == resolvedLinkDir { From 4417be81ad647a85cafcf592390e1c59635196d0 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 17:11:04 +0300 Subject: [PATCH 16/79] fix typo Co-authored-by: Jakub Sztandera --- blockstore/badger/blockstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index dad37a6b1ff..05e9048c90f 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -367,7 +367,7 @@ func (b *Blockstore) movingGC() error { return nil } -// symlink creates a symlink from path to linkPath; the link is relative if the two are +// symlink creates a symlink from path to linkTo; the link is relative if the two are // in the same directory func (b *Blockstore) symlink(path, linkTo string) error { resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) From fd33b96e08d241140e402945bafa0405ae74a772 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 29 Jul 2021 08:35:53 +0300 Subject: [PATCH 17/79] make symlink helper freestanding --- blockstore/badger/blockstore.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 05e9048c90f..a0b51d8df61 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -355,7 +355,7 @@ func (b *Blockstore) movingGC() error { panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbPath, backupPath, err)) //nolint } - if err = b.symlink(newPath, dbPath); err != nil { + if err = symlink(newPath, dbPath); err != nil { // same here; the db path is pointing to the void. panic and let the user fix. panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", newPath, dbPath, err)) //nolint } @@ -369,7 +369,7 @@ func (b *Blockstore) movingGC() error { // symlink creates a symlink from path to linkTo; the link is relative if the two are // in the same directory -func (b *Blockstore) symlink(path, linkTo string) error { +func symlink(path, linkTo string) error { resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) if err != nil { return fmt.Errorf("error resolving links in %s: %w", path, err) From 786d3e79eb9264b528e2f2588c6787aa30b834f4 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Thu, 29 Jul 2021 04:51:28 -0400 Subject: [PATCH 18/79] make gen --- build/openrpc/full.json.gz | Bin 25240 -> 25241 bytes build/openrpc/miner.json.gz | Bin 9479 -> 9596 bytes build/openrpc/worker.json.gz | Bin 2710 -> 2710 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index ddcf0611767ea9b47c66180b6063a2252ebf40ab..6100677034b49cd1397ebfb057a848753b073d4e 100644 GIT binary patch delta 20851 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 KEvu8%>jVI~YL15h delta 20863 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 a*%kMGwJTJzpZ_la0RR6#+m49T>jVIiN@(f; diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 5a65b3a33921ffe18ee4fe002bdec37d7b59b576..963ce6f50c0fa7b5bf03d02e4b213c273755e78f 100644 GIT binary patch delta 9102 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 Z$*9v7o=)$k{|f*B|NkYIA0}CP000Z*f5!j- delta 1731 zcmV;!20Zze6_ypS`vL>BkF}Hj0zZGwNwF&Z3d$ZEDpE*ehGr8-8sz#bM(%d(s**z_R2b2+)eusE23~@q+*ff9rH7ma+ zY-AkvGd*uD{x8Zm0|GSw*a;)u1pu(1$Ll4m42Jgi;ZTCAHnw4QY0ZIIGyPS^&N_DP zTkPze701p?Hspp8Q?m|Nl$GL@=0hJSIX z=3Qyvj~>uZG?=^xn6acG@bAX;(yzrC~G+X^O#jw1@}Uh(m#{x-2k-O)UvYMeP}d zr5UeVf!{^kmE<*YmA0GQI4A4|Vziipxca7MsrYW>6>^yL6Ss*Q@?LcJPoSf5rDVzm zQzW};YiI2eTNB&{DQ}ZG1!gygnSJOKo7pwEKqP!+5{UWUp9Sh4`7CCk>us&n@)Fjo zwVlGAyRcfTpT^Wn!g@)#&r8D7R=1Pa1yz4)_lk{6ugcH4=TVi{p5+#nqBH}gkx~-( zI$S?7kaB)BF0>h9EBXkz8ol^nU3k1EdWh;DFLZHE9cc)1Q(|lj;ATf^anG?9qXxP= z5m9#m=;p0s50A=~+WDK7HNVk$!DDTG)e`n}9%oGBK?xl)Q|QtGrs$BSH91L`{vUtV zFsYF{Ug5N~U$5x3=4qDx3vOzMNrsco;5)H_bf2U%KACh$_e2f4@&P>mFaG?uA56IC z|26Q2Fd24xL)r}{CqV$c&SNiH18lNALsyw}ZZ@CkVKAZGB*>~4r1gUIEo0_R$sx`J z&*j5+Rm|Km-*=-+V;K2+pw@=Do$Y_a+)kat-8I|X1!$XB;Nr=&xqXXs-I5dL z+M!R7lF_PYzQaPQMRb?T!=5jBc&D~zPX;od#zGC=Cu_#REBRAtar=5o89uKCnblP zZ$Pd0lFWp#3?>dZcbDw;OB#6Xj=u~mOLqMw9ePAONTkLvvkD>+ME9CA>u8`aTp=|k z`iDv+K`F{cx6C6Gq{ssxf`)(age2IUIT9(3w0kEbqCj6LA|H@ecPDT+xX19vyq&Y& z#P_LpdRB61GTuJ=(Q(34ai)for7mA&3Cc#x>?hmKtBokfR=Fi@Y(*62gsQzDG5!9L zO}>!u-D&lQlH-Yg5czNs`94F9PEnR>GZ0rhL>YDyy~3hYvs3N8R;z!rtZiSTb7EG1 z{b%#B)wIK29W}QJ^`0|UYxld*?smz!o!Ok2 zzRqDzSG)xFi2p4=@pm$$ewi*?7|&Z?vNT@NywQR=ElIH<%xa*c+o09z0*YQ-@al!| z3Mq0kvbuhigxk!nw3dI)OsoGAZh7^I(t~o9$u~8ATA85Q@6^#*r{q{pw0(D-Z&sx! z*L}6u>_ayHoG7?t4m_{;bXDPYjbmg}r*Tdl!zV5&{ z-*@V@x@VjC#M9n>scO&m&*Trl#NKoD%oJ{N$+mS)9VB%35}1F|qDXLuM^T*tWuquc zFolTY2#^vSMCYwF(52D?Fyz7m2Ms2Op#MbQV6+fH=iC7s9XySxJw}u{REwzl@B&v+ zTi-qMiTwc1ycZR&MhJ5dL7#Q4F_Gg&R&h3S*rxtaME#Vqeo7fZ&2GtQme`gJVP;HK zyhNM3hjN$~S6Ooc@!}dr$S&b(EAQ7U8>*yyOHs7j?sh(`9Y=RmA$uj;&i^D-{X3wb z3{`SYSE!Vw$*(!tYja=e{)^Qw>1yC|`$3|BDe59M1_6i&KrDJnCy@vk3!m-1Qe)p; ZGV1sgPp5a&{{;X5|Np)^+1Ocn000qYVg>*J From 0daee83735ab53db2087b0f78230a9ab059e9e9d Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 29 Jul 2021 15:28:08 +0530 Subject: [PATCH 19/79] more logging in data transfer and markets --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 89db6a3ae4a..4b26657437e 100644 --- a/go.mod +++ b/go.mod @@ -33,10 +33,10 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.7.1 + github.com/filecoin-project/go-data-transfer v1.7.2 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.6.1 + github.com/filecoin-project/go-fil-markets v1.6.2 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 diff --git a/go.sum b/go.sum index e39d883d990..8c8a4396b36 100644 --- a/go.sum +++ b/go.sum @@ -275,8 +275,8 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMX github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= github.com/filecoin-project/go-data-transfer v1.7.0/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= -github.com/filecoin-project/go-data-transfer v1.7.1 h1:Co4bTenvCc3WnOhQWyXRt59FLZvxwH8UeF0ZCOc1ik0= -github.com/filecoin-project/go-data-transfer v1.7.1/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= +github.com/filecoin-project/go-data-transfer v1.7.2 h1:iL3q5pxSloA7V2QucFofoVN3lquULz+Ml0KrNqMT5ZU= +github.com/filecoin-project/go-data-transfer v1.7.2/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= @@ -286,8 +286,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+ github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.6.1 h1:8xdFyWrELfOzwcGa229bLu/olD+1l4sEWFIsZR7oz5U= -github.com/filecoin-project/go-fil-markets v1.6.1/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= +github.com/filecoin-project/go-fil-markets v1.6.2 h1:ib1sGUOF+hf50YwP7+p9yoK+9g84YcXzvuenxd6MYoE= +github.com/filecoin-project/go-fil-markets v1.6.2/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= From 029ba39fd961dc216e913d27d1fb6da35594ef1a Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Thu, 29 Jul 2021 20:04:50 +0530 Subject: [PATCH 20/79] update deps for logging --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4b26657437e..522a0d568b7 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 - github.com/filecoin-project/go-statemachine v1.0.0 + github.com/filecoin-project/go-statemachine v1.0.1 github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.14 diff --git a/go.sum b/go.sum index 8c8a4396b36..90c52baab2b 100644 --- a/go.sum +++ b/go.sum @@ -313,8 +313,8 @@ github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48/ github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 h1:veGrNABg/9I7prngrowkhwbvW5d5JN55MNKmbsr5FqA= github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= -github.com/filecoin-project/go-statemachine v1.0.0 h1:b8FpFewPSklyAIUqH0oHt4nvKf03bU7asop1bJpjAtQ= -github.com/filecoin-project/go-statemachine v1.0.0/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= +github.com/filecoin-project/go-statemachine v1.0.1 h1:LQ60+JDVjMdLxXmVFM2jjontzOYnfVE7u02CXV3WKSw= +github.com/filecoin-project/go-statemachine v1.0.1/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/c3OROw/kXVNSTZk= github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= From 8442bac5b2fb25f39c9415eeb5a2ade66b36bfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 10:55:37 +0100 Subject: [PATCH 21/79] support MARKETS_API_INFO env var; support markets-repo, markets-api-url flags. --- cli/auth.go | 3 +- cli/util/api.go | 142 +++++++++++++++++++++++++------------------- node/repo/fsrepo.go | 5 +- 3 files changed, 88 insertions(+), 62 deletions(-) diff --git a/cli/auth.go b/cli/auth.go index 20b9bb39428..ccf5dcc8bf8 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,8 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - fmt.Printf("%s=%s:%s\n", cliutil.EnvForRepo(t), string(token), ainfo.Addr) + currentEnv, _ := cliutil.EnvsForRepo(t) + fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil }, } diff --git a/cli/util/api.go b/cli/util/api.go index 730b75d9d2c..fca667b5ac9 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -27,112 +27,134 @@ const ( metadataTraceContext = "traceContext" ) -// The flag passed on the command line with the listen address of the API -// server (only used by the tests) -func flagForAPI(t repo.RepoType) string { +// The flags passed on the command line with the listen address of the API +// server (only used by the tests), in the order of precedence they should be +// applied for the requested kind of node. +func flagsForAPI(t repo.RepoType) []string { switch t { case repo.FullNode: - return "api-url" + return []string{"api-url"} case repo.StorageMiner: - return "miner-api-url" + return []string{"miner-api-url"} case repo.Worker: - return "worker-api-url" + return []string{"worker-api-url"} + case repo.Markets: + // support split markets-miner and monolith deployments. + return []string{"markets-api-url", "miner-api-url"} default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } } -func flagForRepo(t repo.RepoType) string { +func flagsForRepo(t repo.RepoType) []string { switch t { case repo.FullNode: - return "repo" + return []string{"repo"} case repo.StorageMiner: - return "miner-repo" + return []string{"miner-repo"} case repo.Worker: - return "worker-repo" + return []string{"worker-repo"} + case repo.Markets: + // support split markets-miner and monolith deployments. + return []string{"markets-repo", "miner-repo"} default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } } -func EnvForRepo(t repo.RepoType) string { +// EnvsForRepo returns the environment variables to use in order of precedence +// to determine the API endpoint of the specified node type. +// +// It returns the current variables and deprecated ones separately, so that +// the user can log a warning when deprecated ones are found to be in use. +func EnvsForRepo(t repo.RepoType) (current []string, deprecated []string) { switch t { case repo.FullNode: - return "FULLNODE_API_INFO" + return []string{"FULLNODE_API_INFO"}, nil case repo.StorageMiner: - return "MINER_API_INFO" + // TODO remove deprecated deprecation period + return []string{"MINER_API_INFO"}, []string{"STORAGE_API_INFO"} case repo.Worker: - return "WORKER_API_INFO" - default: - panic(fmt.Sprintf("Unknown repo type: %v", t)) - } -} - -// TODO remove after deprecation period -func envForRepoDeprecation(t repo.RepoType) string { - switch t { - case repo.FullNode: - return "FULLNODE_API_INFO" - case repo.StorageMiner: - return "STORAGE_API_INFO" - case repo.Worker: - return "WORKER_API_INFO" + return []string{"WORKER_API_INFO"}, nil + case repo.Markets: + // support split markets-miner and monolith deployments. + return []string{"MARKETS_API_INFO, MINER_API_INFO"}, nil default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } } +// GetAPIInfo returns the API endpoint to use for the specified kind of repo. +// +// The order of precedence is as follows: +// +// 1. *-api-url command line flags. +// 2. *_API_INFO environment variables +// 3. deprecated *_API_INFO environment variables +// 4. *-repo command line flags. func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { // Check if there was a flag passed with the listen address of the API // server (only used by the tests) - apiFlag := flagForAPI(t) - if ctx.IsSet(apiFlag) { - strma := ctx.String(apiFlag) + apiFlags := flagsForAPI(t) + for _, f := range apiFlags { + if !ctx.IsSet(f) { + continue + } + strma := ctx.String(f) strma = strings.TrimSpace(strma) return APIInfo{Addr: strma}, nil } - envKey := EnvForRepo(t) - env, ok := os.LookupEnv(envKey) - if !ok { - // TODO remove after deprecation period - envKey = envForRepoDeprecation(t) - env, ok = os.LookupEnv(envKey) + currentEnv, deprecatedEnv := EnvsForRepo(t) + for _, env := range currentEnv { + env, ok := os.LookupEnv(env) if ok { - log.Warnf("Use deprecation env(%s) value, please use env(%s) instead.", envKey, EnvForRepo(t)) + return ParseApiInfo(env), nil } } - if ok { - return ParseApiInfo(env), nil + + for _, env := range deprecatedEnv { + env, ok := os.LookupEnv(env) + if ok { + log.Warnf("Use deprecation env(%s) value, please use env(%s) instead.", env, currentEnv) + return ParseApiInfo(env), nil + } } - repoFlag := flagForRepo(t) + repoFlags := flagsForRepo(t) + for _, f := range repoFlags { + if !ctx.IsSet(f) { + continue + } - p, err := homedir.Expand(ctx.String(repoFlag)) - if err != nil { - return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", repoFlag, err) - } + p, err := homedir.Expand(ctx.String(f)) + if err != nil { + return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err) + } - r, err := repo.NewFS(p) - if err != nil { - return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) - } + r, err := repo.NewFS(p) + if err != nil { + return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) + } - ma, err := r.APIEndpoint() - if err != nil { - return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) - } + ma, err := r.APIEndpoint() + if err != nil { + return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) + } - token, err := r.APIToken() - if err != nil { - log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err) + token, err := r.APIToken() + if err != nil { + log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err) + } + + return APIInfo{ + Addr: ma.String(), + Token: token, + }, nil } - return APIInfo{ - Addr: ma.String(), - Token: token, - }, nil + return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %s", t) } func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 9323410ddd0..d3e6f4f2fc9 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -49,13 +49,16 @@ const ( StorageMiner Worker Wallet + Markets ) func defConfForType(t RepoType) interface{} { switch t { case FullNode: return config.DefaultFullNode() - case StorageMiner: + case StorageMiner, Markets: + // markets is a specialised miner service + // this taxonomy needs to be cleaned up return config.DefaultStorageMiner() case Worker: return &struct{}{} From 92056423c3b540f6ff7ac0ee4d1e4cd1693b143d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 12:37:29 +0100 Subject: [PATCH 22/79] target markets API for markets commands. --- cli/auth.go | 3 ++- cli/cmd.go | 3 ++- cli/util/api.go | 20 +++++++++++++-- cmd/lotus-miner/dagstore.go | 30 ++++++++++++++++++++++ cmd/lotus-miner/main.go | 24 ++++++++++++------ cmd/lotus-miner/market.go | 40 +++++++++++++++++------------- cmd/lotus-miner/retrieval-deals.go | 18 +++++++------- 7 files changed, 101 insertions(+), 37 deletions(-) create mode 100644 cmd/lotus-miner/dagstore.go diff --git a/cli/auth.go b/cli/auth.go index ccf5dcc8bf8..88cbdbb66e1 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -113,7 +113,7 @@ var AuthApiInfoToken = &cli.Command{ ti, ok := cctx.App.Metadata["repoType"] if !ok { - log.Errorf("unknown repo type, are you sure you want to use GetAPI?") + log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?") ti = repo.FullNode } t, ok := ti.(repo.RepoType) @@ -128,6 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented + // WARN: this is unable to tell currentEnv, _ := cliutil.EnvsForRepo(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil diff --git a/cli/cmd.go b/cli/cmd.go index 630aae1bc75..7e4a7636c36 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -44,7 +44,7 @@ func GetFullNodeServices(ctx *cli.Context) (ServicesAPI, error) { var GetAPIInfo = cliutil.GetAPIInfo var GetRawAPI = cliutil.GetRawAPI -var GetAPI = cliutil.GetAPI +var GetAPI = cliutil.GetCommonAPI var DaemonContext = cliutil.DaemonContext var ReqContext = cliutil.ReqContext @@ -54,6 +54,7 @@ var GetFullNodeAPIV1 = cliutil.GetFullNodeAPIV1 var GetGatewayAPI = cliutil.GetGatewayAPI var GetStorageMinerAPI = cliutil.GetStorageMinerAPI +var GetMarketsAPI = cliutil.GetMarketsAPI var GetWorkerAPI = cliutil.GetWorkerAPI var CommonCommands = []*cli.Command{ diff --git a/cli/util/api.go b/cli/util/api.go index fca667b5ac9..76289ec7cd2 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -175,10 +175,10 @@ func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http. return addr, ainfo.AuthHeader(), nil } -func GetAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { +func GetCommonAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { ti, ok := ctx.App.Metadata["repoType"] if !ok { - log.Errorf("unknown repo type, are you sure you want to use GetAPI?") + log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?") ti = repo.FullNode } t, ok := ti.(repo.RepoType) @@ -296,6 +296,22 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { return client.NewWorkerRPCV0(ctx.Context, addr, headers) } +func GetMarketsAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) { + addr, headers, err := GetRawAPI(ctx, repo.Markets, "v0") + if err != nil { + return nil, nil, err + } + + if IsVeryVerbose { + _, _ = fmt.Fprintln(ctx.App.Writer, "using markets API v0 endpoint:", addr) + } + + // the markets node is a specialised miner's node, supporting only the + // markets API, which is a subset of the miner API. All non-markets + // operations will error out with "unsupported". + return client.NewStorageMinerRPCV0(ctx.Context, addr, headers) +} + func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") if err != nil { diff --git a/cmd/lotus-miner/dagstore.go b/cmd/lotus-miner/dagstore.go new file mode 100644 index 00000000000..a50d99d99bd --- /dev/null +++ b/cmd/lotus-miner/dagstore.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/urfave/cli/v2" +) + +var dagstoreCmd = &cli.Command{ + Name: "dagstore", + Usage: "Manage the DAG store", + Subcommands: []*cli.Command{ + dagstoreListShardsCmd, + dagstoreGarbageCollectCmd, + }, +} + +var dagstoreListShardsCmd = &cli.Command{ + Name: "list-shards", + Usage: "List shards known to the DAG store", + Action: func(cctx *cli.Context) error { + return nil + }, +} + +var dagstoreGarbageCollectCmd = &cli.Command{ + Name: "gc", + Usage: "Garbage collect the DAG store", + Action: func(cctx *cli.Context) error { + return nil + }, +} diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index c697de0c9c0..fb8ac35b92c 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -76,10 +76,10 @@ func main() { } app := &cli.App{ - Name: "lotus-miner", - Usage: "Filecoin decentralized storage network miner", - Version: build.UserVersion(), - EnableBashCompletion: true, + Name: "lotus-miner", + Usage: "Filecoin decentralized storage network miner", + Version: build.UserVersion(), + Commands: append(local, lcli.CommonCommands...), Flags: []cli.Flag{ &cli.StringFlag{ Name: "actor", @@ -106,14 +106,24 @@ func main() { Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME Usage: fmt.Sprintf("Specify miner repo path. flag(%s) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON", FlagMinerRepoDeprecation), }, + &cli.BoolFlag{ + Name: "call-on-markets", + Usage: "(experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous", + }, cliutil.FlagVeryVerbose, }, - - Commands: append(local, lcli.CommonCommands...), + EnableBashCompletion: true, + Before: func(c *cli.Context) error { + // this command is explicitly called on markets, inform + // common commands by overriding the repoType. + if c.Bool("call-on-markets") { + c.App.Metadata["repoType"] = repo.Markets + } + return nil + }, } app.Setup() app.Metadata["repoType"] = repo.StorageMiner - lcli.RunApp(app) } diff --git a/cmd/lotus-miner/market.go b/cmd/lotus-miner/market.go index b216d24fcd4..a9d1f2f4658 100644 --- a/cmd/lotus-miner/market.go +++ b/cmd/lotus-miner/market.go @@ -73,7 +73,7 @@ var storageDealSelectionShowCmd = &cli.Command{ Name: "list", Usage: "List storage deal proposal selection criteria", Action: func(cctx *cli.Context) error { - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -100,7 +100,7 @@ var storageDealSelectionResetCmd = &cli.Command{ Name: "reset", Usage: "Reset storage deal proposal selection criteria to default values", Action: func(cctx *cli.Context) error { - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -148,7 +148,7 @@ var storageDealSelectionRejectCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -215,7 +215,13 @@ var setAskCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) - api, closer, err := lcli.GetStorageMinerAPI(cctx) + minerApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + marketsApi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -252,12 +258,12 @@ var setAskCmd = &cli.Command{ return xerrors.Errorf("cannot parse max-piece-size to quantity of bytes: %w", err) } - maddr, err := api.ActorAddress(ctx) + maddr, err := minerApi.ActorAddress(ctx) if err != nil { return err } - ssize, err := api.ActorSectorSize(ctx, maddr) + ssize, err := minerApi.ActorSectorSize(ctx, maddr) if err != nil { return err } @@ -272,7 +278,7 @@ var setAskCmd = &cli.Command{ return xerrors.Errorf("max piece size (w/bit-padding) %s cannot exceed miner sector size %s", types.SizeStr(types.NewInt(uint64(max))), types.SizeStr(types.NewInt(uint64(smax)))) } - return api.MarketSetAsk(ctx, types.BigInt(pri), types.BigInt(vpri), abi.ChainEpoch(qty), abi.PaddedPieceSize(min), abi.PaddedPieceSize(max)) + return marketsApi.MarketSetAsk(ctx, types.BigInt(pri), types.BigInt(vpri), abi.ChainEpoch(qty), abi.PaddedPieceSize(min), abi.PaddedPieceSize(max)) }, } @@ -289,7 +295,7 @@ var getAskCmd = &cli.Command{ } defer closer() - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -352,7 +358,7 @@ var dealsImportDataCmd = &cli.Command{ Usage: "Manually import data for a deal", ArgsUsage: " ", Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -390,7 +396,7 @@ var dealsListCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -494,7 +500,7 @@ var getBlocklistCmd = &cli.Command{ &CidBaseFlag, }, Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -524,7 +530,7 @@ var setBlocklistCmd = &cli.Command{ ArgsUsage: "[ (optional, will read from stdin if omitted)]", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -570,7 +576,7 @@ var resetBlocklistCmd = &cli.Command{ Usage: "Remove all entries from the miner's piece CID blocklist", Flags: []cli.Flag{}, Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -634,7 +640,7 @@ var marketRestartTransfer = &cli.Command{ if !cctx.Args().Present() { return cli.ShowCommandHelp(cctx, cctx.Command.Name) } - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + nodeApi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -699,7 +705,7 @@ var marketCancelTransfer = &cli.Command{ if !cctx.Args().Present() { return cli.ShowCommandHelp(cctx, cctx.Command.Name) } - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + nodeApi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -775,7 +781,7 @@ var transfersListCmd = &cli.Command{ color.NoColor = !cctx.Bool("color") } - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -842,7 +848,7 @@ var dealsPendingPublish = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } diff --git a/cmd/lotus-miner/retrieval-deals.go b/cmd/lotus-miner/retrieval-deals.go index 0411f7f130a..1ce1f6593df 100644 --- a/cmd/lotus-miner/retrieval-deals.go +++ b/cmd/lotus-miner/retrieval-deals.go @@ -39,7 +39,7 @@ var retrievalDealSelectionShowCmd = &cli.Command{ Name: "list", Usage: "List retrieval deal proposal selection criteria", Action: func(cctx *cli.Context) error { - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -66,7 +66,7 @@ var retrievalDealSelectionResetCmd = &cli.Command{ Name: "reset", Usage: "Reset retrieval deal proposal selection criteria to default values", Action: func(cctx *cli.Context) error { - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -98,7 +98,7 @@ var retrievalDealSelectionRejectCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - smapi, closer, err := lcli.GetStorageMinerAPI(cctx) + smapi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -126,7 +126,7 @@ var retrievalDealsListCmd = &cli.Command{ Name: "list", Usage: "List all active retrieval deals for this miner", Action: func(cctx *cli.Context) error { - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -186,7 +186,7 @@ var retrievalSetAskCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -240,7 +240,7 @@ var retrievalGetAskCmd = &cli.Command{ Action: func(cctx *cli.Context) error { ctx := lcli.DaemonContext(cctx) - api, closer, err := lcli.GetStorageMinerAPI(cctx) + api, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -252,13 +252,13 @@ var retrievalGetAskCmd = &cli.Command{ } w := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0) - fmt.Fprintf(w, "Price per Byte\tUnseal Price\tPayment Interval\tPayment Interval Increase\n") + _, _ = fmt.Fprintf(w, "Price per Byte\tUnseal Price\tPayment Interval\tPayment Interval Increase\n") if ask == nil { - fmt.Fprintf(w, "\n") + _, _ = fmt.Fprintf(w, "\n") return w.Flush() } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", + _, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", types.FIL(ask.PricePerByte), types.FIL(ask.UnsealPrice), units.BytesSize(float64(ask.PaymentInterval)), From d37ae957e02259e33b4774695ebeb25616cfff6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 12:51:26 +0100 Subject: [PATCH 23/79] refactor miner info command. --- cli/auth.go | 1 - cmd/lotus-miner/dagstore.go | 30 ------------------------------ cmd/lotus-miner/info.go | 35 ++++++++++++++++++++++------------- 3 files changed, 22 insertions(+), 44 deletions(-) delete mode 100644 cmd/lotus-miner/dagstore.go diff --git a/cli/auth.go b/cli/auth.go index 88cbdbb66e1..33b0d25c880 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,6 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - // WARN: this is unable to tell currentEnv, _ := cliutil.EnvsForRepo(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil diff --git a/cmd/lotus-miner/dagstore.go b/cmd/lotus-miner/dagstore.go deleted file mode 100644 index a50d99d99bd..00000000000 --- a/cmd/lotus-miner/dagstore.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "github.com/urfave/cli/v2" -) - -var dagstoreCmd = &cli.Command{ - Name: "dagstore", - Usage: "Manage the DAG store", - Subcommands: []*cli.Command{ - dagstoreListShardsCmd, - dagstoreGarbageCollectCmd, - }, -} - -var dagstoreListShardsCmd = &cli.Command{ - Name: "list-shards", - Usage: "List shards known to the DAG store", - Action: func(cctx *cli.Context) error { - return nil - }, -} - -var dagstoreGarbageCollectCmd = &cli.Command{ - Name: "gc", - Usage: "Garbage collect the DAG store", - Action: func(cctx *cli.Context) error { - return nil - }, -} diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 878361dacb6..67f8180b725 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -50,7 +50,13 @@ var infoCmd = &cli.Command{ } func infoCmdAct(cctx *cli.Context) error { - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + minerApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + marketsApi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -64,12 +70,19 @@ func infoCmdAct(cctx *cli.Context) error { ctx := lcli.ReqContext(cctx) - subsystems, err := nodeApi.RuntimeSubsystems(ctx) + subsystems, err := minerApi.RuntimeSubsystems(ctx) + if err != nil { + return err + } + + fmt.Println("Enabled subsystems (from miner API):", subsystems) + + subsystems, err = marketsApi.RuntimeSubsystems(ctx) if err != nil { return err } - fmt.Println("Enabled subsystems:", subsystems) + fmt.Println("Enabled subsystems (from markets API):", subsystems) fmt.Print("Chain: ") @@ -103,18 +116,14 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() - if subsystems.Has(api.SubsystemSectorStorage) { - err := handleMiningInfo(ctx, cctx, fullapi, nodeApi) - if err != nil { - return err - } + err = handleMiningInfo(ctx, cctx, fullapi, minerApi) + if err != nil { + return err } - if subsystems.Has(api.SubsystemMarkets) { - err := handleMarketsInfo(ctx, nodeApi) - if err != nil { - return err - } + err = handleMarketsInfo(ctx, marketsApi) + if err != nil { + return err } return nil From 107777fdacb8f914d0dc627b9d5b70a86ddde181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 12:54:23 +0100 Subject: [PATCH 24/79] polish. --- cli/util/api.go | 6 +++--- cmd/lotus-miner/main.go | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index 76289ec7cd2..4ddaac88a22 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -27,9 +27,9 @@ const ( metadataTraceContext = "traceContext" ) -// The flags passed on the command line with the listen address of the API -// server (only used by the tests), in the order of precedence they should be -// applied for the requested kind of node. +// flagsForAPI returns flags passed on the command line with the listen address +// of the API server (only used by the tests), in the order of precedence they +// should be applied for the requested kind of node. func flagsForAPI(t repo.RepoType) []string { switch t { case repo.FullNode: diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index fb8ac35b92c..ea6fca0a18f 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -76,10 +76,10 @@ func main() { } app := &cli.App{ - Name: "lotus-miner", - Usage: "Filecoin decentralized storage network miner", - Version: build.UserVersion(), - Commands: append(local, lcli.CommonCommands...), + Name: "lotus-miner", + Usage: "Filecoin decentralized storage network miner", + Version: build.UserVersion(), + EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ Name: "actor", @@ -112,7 +112,7 @@ func main() { }, cliutil.FlagVeryVerbose, }, - EnableBashCompletion: true, + Commands: append(local, lcli.CommonCommands...), Before: func(c *cli.Context) error { // this command is explicitly called on markets, inform // common commands by overriding the repoType. From 1b5a2dd79a20e484fdb222a43b68c5480801592a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 13:21:55 +0100 Subject: [PATCH 25/79] fix tests. --- cli/util/api.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index 4ddaac88a22..4413fd3bb86 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -117,7 +117,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { for _, env := range deprecatedEnv { env, ok := os.LookupEnv(env) if ok { - log.Warnf("Use deprecation env(%s) value, please use env(%s) instead.", env, currentEnv) + log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, currentEnv) return ParseApiInfo(env), nil } } @@ -125,6 +125,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { if !ctx.IsSet(f) { + fmt.Println("not set", f) continue } @@ -154,7 +155,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } - return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %s", t) + return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t) } func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { @@ -297,6 +298,11 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { } func GetMarketsAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) { + // to support lotus-miner cli tests. + if tn, ok := ctx.App.Metadata["testnode-storage"]; ok { + return tn.(api.StorageMiner), func() {}, nil + } + addr, headers, err := GetRawAPI(ctx, repo.Markets, "v0") if err != nil { return nil, nil, err From 299b106f38beb76d94669f42dc4b90b97781059b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 13:38:08 +0100 Subject: [PATCH 26/79] fix docs, add flag. --- cli/util/api.go | 1 - cmd/lotus-miner/main.go | 6 ++++++ documentation/en/cli-lotus-miner.md | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cli/util/api.go b/cli/util/api.go index 4413fd3bb86..c6e3ae9be2f 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -125,7 +125,6 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { if !ctx.IsSet(f) { - fmt.Println("not set", f) continue } diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index ea6fca0a18f..d1c203b573d 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -23,6 +23,7 @@ import ( var log = logging.Logger("main") const FlagMinerRepo = "miner-repo" +const FlagMarketsRepo = "markets-repo" // TODO remove after deprecation period const FlagMinerRepoDeprecation = "storagerepo" @@ -106,6 +107,11 @@ func main() { Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME Usage: fmt.Sprintf("Specify miner repo path. flag(%s) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON", FlagMinerRepoDeprecation), }, + &cli.StringFlag{ + Name: FlagMarketsRepo, + EnvVars: []string{"LOTUS_MARKETS_PATH"}, + Usage: fmt.Sprintf("Markets repo path"), + }, &cli.BoolFlag{ Name: "call-on-markets", Usage: "(experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous", diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 863ca8dc93a..775f4e9a77f 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -43,6 +43,7 @@ GLOBAL OPTIONS: --actor value, -a value specify other actor to check state for (read only) --color use color in display output (default: depends on output being a TTY) --miner-repo value, --storagerepo value Specify miner repo path. flag(storagerepo) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON (default: "~/.lotusminer") [$LOTUS_MINER_PATH, $LOTUS_STORAGE_PATH] + --call-on-markets (experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous (default: false) --vv enables very verbose mode, useful for debugging the CLI (default: false) --help, -h show help (default: false) --version, -v print the version (default: false) From b3c951c924071936c3ad2013f551753781c77413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 13:49:47 +0100 Subject: [PATCH 27/79] add RepoType#String; adjust repo parsing logic. --- cli/util/api.go | 4 +++- node/repo/fsrepo.go | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cli/util/api.go b/cli/util/api.go index c6e3ae9be2f..bf34f4421d7 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -124,7 +124,9 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { - if !ctx.IsSet(f) { + // cannot use ctx.IsSet because it ignores default values + f := ctx.String(f) + if f == "" { continue } diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index d3e6f4f2fc9..5c1c91bc559 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -52,6 +52,21 @@ const ( Markets ) +func (t RepoType) String() string { + s := [...]string{ + "__invalid__", + "FullNode", + "StorageMiner", + "Worker", + "Wallet", + "Markets", + } + if t < 0 || int(t) > len(s) { + return "__invalid__" + } + return s[t] +} + func defConfForType(t RepoType) interface{} { switch t { case FullNode: From 4b6fa79ea205a2847f583d8ca0c9d005f1c7aa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 14:36:04 +0100 Subject: [PATCH 28/79] bugfix. --- cli/util/api.go | 8 ++++---- cmd/lotus-miner/info.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index bf34f4421d7..766969dfabf 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -78,7 +78,7 @@ func EnvsForRepo(t repo.RepoType) (current []string, deprecated []string) { return []string{"WORKER_API_INFO"}, nil case repo.Markets: // support split markets-miner and monolith deployments. - return []string{"MARKETS_API_INFO, MINER_API_INFO"}, nil + return []string{"MARKETS_API_INFO", "MINER_API_INFO"}, nil default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } @@ -125,12 +125,12 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { // cannot use ctx.IsSet because it ignores default values - f := ctx.String(f) - if f == "" { + path := ctx.String(f) + if path == "" { continue } - p, err := homedir.Expand(ctx.String(f)) + p, err := homedir.Expand(path) if err != nil { return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err) } diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 67f8180b725..f37952057ff 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -386,6 +386,7 @@ func handleMarketsInfo(ctx context.Context, nodeApi api.StorageMiner) error { return sorted[i].status > sorted[j].status }) + fmt.Println() fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) From 00c3432e5a646640398f1ba316b56e7578ac877b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 16:10:04 +0100 Subject: [PATCH 29/79] use fallback api infos last; init service with markets-path. --- cli/auth.go | 2 +- cli/util/api.go | 37 ++++++++++++++++++----------- cmd/lotus-miner/init_restore.go | 11 +++++---- cmd/lotus-miner/init_service.go | 7 +++++- cmd/lotus-miner/main.go | 6 +++-- documentation/en/cli-lotus-miner.md | 1 + 6 files changed, 41 insertions(+), 23 deletions(-) diff --git a/cli/auth.go b/cli/auth.go index 33b0d25c880..342d5e3aa36 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - currentEnv, _ := cliutil.EnvsForRepo(t) + currentEnv, _ := cliutil.EnvsForAPIInfos(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil }, diff --git a/cli/util/api.go b/cli/util/api.go index 766969dfabf..37df41a87ab 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -62,23 +62,23 @@ func flagsForRepo(t repo.RepoType) []string { } } -// EnvsForRepo returns the environment variables to use in order of precedence +// EnvsForAPIInfos returns the environment variables to use in order of precedence // to determine the API endpoint of the specified node type. // // It returns the current variables and deprecated ones separately, so that // the user can log a warning when deprecated ones are found to be in use. -func EnvsForRepo(t repo.RepoType) (current []string, deprecated []string) { +func EnvsForAPIInfos(t repo.RepoType) (primary string, fallbacks []string, deprecated []string) { switch t { case repo.FullNode: - return []string{"FULLNODE_API_INFO"}, nil + return "FULLNODE_API_INFO", nil, nil case repo.StorageMiner: // TODO remove deprecated deprecation period - return []string{"MINER_API_INFO"}, []string{"STORAGE_API_INFO"} + return "MINER_API_INFO", nil, []string{"STORAGE_API_INFO"} case repo.Worker: - return []string{"WORKER_API_INFO"}, nil + return "WORKER_API_INFO", nil, nil case repo.Markets: // support split markets-miner and monolith deployments. - return []string{"MARKETS_API_INFO", "MINER_API_INFO"}, nil + return "MARKETS_API_INFO", []string{"MINER_API_INFO"}, nil default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } @@ -106,18 +106,20 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { return APIInfo{Addr: strma}, nil } - currentEnv, deprecatedEnv := EnvsForRepo(t) - for _, env := range currentEnv { - env, ok := os.LookupEnv(env) - if ok { - return ParseApiInfo(env), nil - } + // + // Note: it is not correct/intuitive to prefer environment variables over + // CLI flags (repo flags below). + // + primaryEnv, fallbacksEnvs, deprecatedEnvs := EnvsForAPIInfos(t) + env, ok := os.LookupEnv(primaryEnv) + if ok { + return ParseApiInfo(env), nil } - for _, env := range deprecatedEnv { + for _, env := range deprecatedEnvs { env, ok := os.LookupEnv(env) if ok { - log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, currentEnv) + log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, primaryEnv) return ParseApiInfo(env), nil } } @@ -156,6 +158,13 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } + for _, env := range fallbacksEnvs { + env, ok := os.LookupEnv(env) + if ok { + return ParseApiInfo(env), nil + } + } + return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t) } diff --git a/cmd/lotus-miner/init_restore.go b/cmd/lotus-miner/init_restore.go index 3b4e2b26d2e..393b44dd2d3 100644 --- a/cmd/lotus-miner/init_restore.go +++ b/cmd/lotus-miner/init_restore.go @@ -17,7 +17,7 @@ import ( "gopkg.in/cheggaaa/pb.v1" "github.com/filecoin-project/go-address" - paramfetch "github.com/filecoin-project/go-paramfetch" + "github.com/filecoin-project/go-paramfetch" "github.com/filecoin-project/go-state-types/big" lapi "github.com/filecoin-project/lotus/api" @@ -72,7 +72,9 @@ var restoreCmd = &cli.Command{ } } - if err := restore(ctx, cctx, storageCfg, nil, func(api lapi.FullNode, maddr address.Address, peerid peer.ID, mi miner.MinerInfo) error { + repoPath := cctx.String(FlagMinerRepo) + + if err := restore(ctx, cctx, repoPath, storageCfg, nil, func(api lapi.FullNode, maddr address.Address, peerid peer.ID, mi miner.MinerInfo) error { log.Info("Checking proof parameters") if err := paramfetch.GetParams(ctx, build.ParametersJSON(), build.SrsJSON(), uint64(mi.SectorSize)); err != nil { @@ -94,7 +96,7 @@ var restoreCmd = &cli.Command{ }, } -func restore(ctx context.Context, cctx *cli.Context, strConfig *stores.StorageConfig, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi miner.MinerInfo) error) error { +func restore(ctx context.Context, cctx *cli.Context, targetPath string, strConfig *stores.StorageConfig, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi miner.MinerInfo) error) error { if cctx.Args().Len() != 1 { return xerrors.Errorf("expected 1 argument") } @@ -142,8 +144,7 @@ func restore(ctx context.Context, cctx *cli.Context, strConfig *stores.StorageCo log.Info("Checking if repo exists") - repoPath := cctx.String(FlagMinerRepo) - r, err := repo.NewFS(repoPath) + r, err := repo.NewFS(targetPath) if err != nil { return err } diff --git a/cmd/lotus-miner/init_service.go b/cmd/lotus-miner/init_service.go index ad803a83040..6e874023e44 100644 --- a/cmd/lotus-miner/init_service.go +++ b/cmd/lotus-miner/init_service.go @@ -71,7 +71,12 @@ var serviceCmd = &cli.Command{ return xerrors.Errorf("--api-sector-index is required without the sector storage module enabled") } - if err := restore(ctx, cctx, &stores.StorageConfig{}, func(cfg *config.StorageMiner) error { + repoPath := cctx.String(FlagMarketsRepo) + if repoPath == "" { + return xerrors.Errorf("please provide Lotus markets repo path via flag %s", FlagMarketsRepo) + } + + if err := restore(ctx, cctx, repoPath, &stores.StorageConfig{}, func(cfg *config.StorageMiner) error { cfg.Subsystems.EnableMarkets = es.Contains(MarketsService) cfg.Subsystems.EnableMining = false cfg.Subsystems.EnableSealing = false diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index d1c203b573d..2916fce1fc0 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -22,8 +22,10 @@ import ( var log = logging.Logger("main") -const FlagMinerRepo = "miner-repo" -const FlagMarketsRepo = "markets-repo" +const ( + FlagMinerRepo = "miner-repo" + FlagMarketsRepo = "markets-repo" +) // TODO remove after deprecation period const FlagMinerRepoDeprecation = "storagerepo" diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 775f4e9a77f..bd87774bcab 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -43,6 +43,7 @@ GLOBAL OPTIONS: --actor value, -a value specify other actor to check state for (read only) --color use color in display output (default: depends on output being a TTY) --miner-repo value, --storagerepo value Specify miner repo path. flag(storagerepo) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON (default: "~/.lotusminer") [$LOTUS_MINER_PATH, $LOTUS_STORAGE_PATH] + --markets-repo value Markets repo path [$LOTUS_MARKETS_PATH] --call-on-markets (experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous (default: false) --vv enables very verbose mode, useful for debugging the CLI (default: false) --help, -h show help (default: false) From bb040abb2c929630e980bbcc418330832285ca64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 16:18:43 +0100 Subject: [PATCH 30/79] fix compilation error. --- cli/auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/auth.go b/cli/auth.go index 342d5e3aa36..286eb978bbf 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - currentEnv, _ := cliutil.EnvsForAPIInfos(t) + currentEnv, _, _ := cliutil.EnvsForAPIInfos(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil }, From 783fa6b7c05a5221dd1b0b4688638032ccf13a58 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 17:56:45 +0300 Subject: [PATCH 31/79] add explicit error msg if repo dir does not exist --- cli/util/api.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cli/util/api.go b/cli/util/api.go index 37df41a87ab..207283fd102 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -2,6 +2,7 @@ package cliutil import ( "context" + "errors" "fmt" "net/http" "net/url" @@ -142,6 +143,15 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) } + exists, err := r.Exists() + if err != nil { + return APIInfo{}, xerrors.Errorf("repo.Exists returned an error: %w", err) + } + + if !exists { + return APIInfo{}, errors.New("repo directory does not exist. Make sure your configuration is correct") + } + ma, err := r.APIEndpoint() if err != nil { return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) From 52b76c9d5cc60253002219e86c7ca43b8df1afd2 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Sun, 1 Aug 2021 03:32:03 -0400 Subject: [PATCH 32/79] Prepare for v1.11.1-rc2: - bump the version - update the changelog --- CHANGELOG.md | 10 ++++++---- build/version.go | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c00105f5c00..1699114fe75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # Lotus changelog -# 1.11.1-rc1 / 2021-07-27 +# 1.11.1-rc2 / 2021-08-01 -This is the first release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. A more organized and detailed release note will be shared in the next few days with future RCs, highlights are: -- [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) -- [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) +> Note: for discussion about this release, please comment [here](https://github.com/filecoin-project/lotus/discussions/6904) + +This is the second release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. A more organized and detailed release note will be shared in the next few days with future RCs, highlights are: +- **Experimental** [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) +- **Under Testing** [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) - github.com/filecoin-project/lotus: - Merge branch 'releases' into release/v1.11.1 diff --git a/build/version.go b/build/version.go index 64d1049b5b4..4d1468cad6d 100644 --- a/build/version.go +++ b/build/version.go @@ -34,7 +34,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "1.11.1-rc1" +const BuildVersion = "1.11.1-rc2" func UserVersion() string { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { From 020cc5e64f14026b16ace8335286f4dcaa54de85 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Sun, 1 Aug 2021 03:46:36 -0400 Subject: [PATCH 33/79] docsgen --- build/openrpc/full.json.gz | Bin 25241 -> 25241 bytes build/openrpc/miner.json.gz | Bin 9596 -> 9596 bytes build/openrpc/worker.json.gz | Bin 2710 -> 2710 bytes documentation/en/cli-lotus-miner.md | 2 +- documentation/en/cli-lotus-worker.md | 2 +- documentation/en/cli-lotus.md | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 6100677034b49cd1397ebfb057a848753b073d4e..35adbd50b6fa41e2d3a10a4790f6543e342fb6db 100644 GIT binary patch delta 25145 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

~x$G>1 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 KeOWq1fcbw-4!{in literal 25241 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 delta 21 dcmez4^~Y;MC!@i}u2(7?jK`j*%|61&0049c37h}` diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 8a39acec0e409a8e57bf321cf6587ecd3ca8073b..9fa491548c83ad0c8ae481a77e828d4089534cba 100644 GIT binary patch delta 22 ecmbOxI!$y!GgJA8jjfzq9PeL*e~qkSU;qGW!wDJy delta 22 ecmbOxI!$y!Gt>5u8(TTKI8>+0t3_5ZFaQ8xuLn5* diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index bd87774bcab..cde45f3d369 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -7,7 +7,7 @@ USAGE: lotus-miner [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc1 + 1.11.1-rc2 COMMANDS: init Initialize a lotus miner repo diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index 0319649fba3..ccd8625d01d 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -7,7 +7,7 @@ USAGE: lotus-worker [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc1 + 1.11.1-rc2 COMMANDS: run Start lotus worker diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index c7504246f89..e9d42f15178 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -7,7 +7,7 @@ USAGE: lotus [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc1 + 1.11.1-rc2 COMMANDS: daemon Start a lotus daemon process From e90e71456ba5f529c46e650cdb3a1adb68ae975c Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 12:10:17 +0300 Subject: [PATCH 34/79] add RuntimeSubsystems API method; use it in `lotus-miner info` --- api/api_storage.go | 2 - api/api_subsystems.go | 63 +++ api/docgen/docgen.go | 10 +- api/miner_subsystems.go | 79 ---- build/openrpc/miner.json.gz | Bin 9596 -> 9540 bytes cmd/lotus-miner/info.go | 501 +++++++++++------------ documentation/en/api-v0-methods-miner.md | 12 +- node/builder_miner.go | 3 +- node/impl/storminer.go | 10 +- node/modules/storageminer.go | 13 +- 10 files changed, 316 insertions(+), 377 deletions(-) create mode 100644 api/api_subsystems.go delete mode 100644 api/miner_subsystems.go diff --git a/api/api_storage.go b/api/api_storage.go index c391149290b..d5203265088 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -166,8 +166,6 @@ type StorageMiner interface { MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write MarketPublishPendingDeals(ctx context.Context) error //perm:admin - // RuntimeSubsystems returns the subsystems that are enabled - // in this instance. RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin diff --git a/api/api_subsystems.go b/api/api_subsystems.go new file mode 100644 index 00000000000..1894bbdd8a6 --- /dev/null +++ b/api/api_subsystems.go @@ -0,0 +1,63 @@ +package api + +import ( + "bytes" + "encoding/json" +) + +type MinerSubsystems []MinerSubsystem + +func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { + for _, v := range ms { + if v == entry { + return true + } + + } + return false +} + +type MinerSubsystem int + +const ( + MarketsSubsystem MinerSubsystem = iota + MiningSubsystem + SealingSubsystem + SectorStorageSubsystem +) + +func (ms MinerSubsystem) String() string { + return MinerSubsystemToString[ms] +} + +var MinerSubsystemToString = map[MinerSubsystem]string{ + MarketsSubsystem: "Markets", + MiningSubsystem: "Mining", + SealingSubsystem: "Sealing", + SectorStorageSubsystem: "SectorStorage", +} + +var MinerSubsystemToID = map[string]MinerSubsystem{ + "Markets": MarketsSubsystem, + "Mining": MiningSubsystem, + "Sealing": SealingSubsystem, + "SectorStorage": SectorStorageSubsystem, +} + +func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { + buffer := bytes.NewBufferString(`"`) + buffer.WriteString(MinerSubsystemToString[ms]) + buffer.WriteString(`"`) + return buffer.Bytes(), nil +} + +func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { + var j string + err := json.Unmarshal(b, &j) + if err != nil { + return err + } + // TODO: handle zero value + *ms = MinerSubsystemToID[j] + return nil +} diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index f9addc940dd..1e712a0aeab 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -16,10 +16,10 @@ import ( "github.com/google/uuid" "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" - "github.com/libp2p/go-libp2p-core/metrics" + metrics "github.com/libp2p/go-libp2p-core/metrics" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + protocol "github.com/libp2p/go-libp2p-core/protocol" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/multiformats/go-multiaddr" @@ -265,12 +265,6 @@ func init() { addExample(api.CheckStatusCode(0)) addExample(map[string]interface{}{"abc": 123}) - addExample(api.MinerSubsystems{ - api.SubsystemMining, - api.SubsystemSealing, - api.SubsystemSectorStorage, - api.SubsystemMarkets, - }) } func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) { diff --git a/api/miner_subsystems.go b/api/miner_subsystems.go deleted file mode 100644 index a77de7e3c95..00000000000 --- a/api/miner_subsystems.go +++ /dev/null @@ -1,79 +0,0 @@ -package api - -import ( - "encoding/json" -) - -// MinerSubsystem represents a miner subsystem. Int and string values are not -// guaranteed to be stable over time is not -// guaranteed to be stable over time. -type MinerSubsystem int - -const ( - // SubsystemUnknown is a placeholder for the zero value. It should never - // be used. - SubsystemUnknown MinerSubsystem = iota - // SubsystemMarkets signifies the storage and retrieval - // deal-making subsystem. - SubsystemMarkets - // SubsystemMining signifies the mining subsystem. - SubsystemMining - // SubsystemSealing signifies the sealing subsystem. - SubsystemSealing - // SubsystemSectorStorage signifies the sector storage subsystem. - SubsystemSectorStorage -) - -var MinerSubsystemToString = map[MinerSubsystem]string{ - SubsystemUnknown: "Unknown", - SubsystemMarkets: "Markets", - SubsystemMining: "Mining", - SubsystemSealing: "Sealing", - SubsystemSectorStorage: "SectorStorage", -} - -var MinerSubsystemToID = map[string]MinerSubsystem{ - "Unknown": SubsystemUnknown, - "Markets": SubsystemMarkets, - "Mining": SubsystemMining, - "Sealing": SubsystemSealing, - "SectorStorage": SubsystemSectorStorage, -} - -func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { - return json.Marshal(MinerSubsystemToString[ms]) -} - -func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { - var j string - err := json.Unmarshal(b, &j) - if err != nil { - return err - } - s, ok := MinerSubsystemToID[j] - if !ok { - *ms = SubsystemUnknown - } else { - *ms = s - } - return nil -} - -type MinerSubsystems []MinerSubsystem - -func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { - for _, v := range ms { - if v == entry { - return true - } - } - return false -} - -func (ms MinerSubsystem) String() string { - s, ok := MinerSubsystemToString[ms] - if !ok { - return MinerSubsystemToString[SubsystemUnknown] - } - return s -} diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 1fd8121c9d3ace29f106a38d5085914181d9aaa9..ccdc26dc7b1a005ece120ba631b701e954d20ac6 100644 GIT binary patch literal 9540 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 m94AUm1VWmA$}_g-s?^4P 0 { + winRatio := new(corebig.Rat).SetFrac( + types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, + pow.TotalPower.QualityAdjPower.Int, + ) - // if the corresponding poisson distribution isn't infinitely small then - // throw it into the mix as well, accounting for multi-wins - winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) - winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) - if winRationWithPoisson != nil { - winRatio = winRationWithPoisson - winRatioFloat = winRationWithPoissonFloat + if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { + + // if the corresponding poisson distribution isn't infinitely small then + // throw it into the mix as well, accounting for multi-wins + winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) + winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) + if winRationWithPoisson != nil { + winRatio = winRationWithPoisson + winRatioFloat = winRationWithPoissonFloat + } + + weekly, _ := new(corebig.Rat).Mul( + winRatio, + new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), + ).Float64() + + avgDuration, _ := new(corebig.Rat).Mul( + new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), + new(corebig.Rat).Inv(winRatio), + ).Float64() + + fmt.Print("Projected average block win rate: ") + color.Blue( + "%.02f/week (every %s)", + weekly, + (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), + ) + + // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples + // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t + // t == how many dice-rolls (epochs) before win + // p == winRate == ( minerPower / netPower ) + // c == target probability of win ( 99.9% in this case ) + fmt.Print("Projected block win with ") + color.Green( + "99.9%% probability every %s", + (time.Second * time.Duration( + builtin.EpochDurationSeconds*math.Log(1-0.999)/ + math.Log(1-winRatioFloat), + )).Truncate(time.Second).String(), + ) + fmt.Println("(projections DO NOT account for future network and miner growth)") } + } - weekly, _ := new(corebig.Rat).Mul( - winRatio, - new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), - ).Float64() - - avgDuration, _ := new(corebig.Rat).Mul( - new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), - new(corebig.Rat).Inv(winRatio), - ).Float64() - - fmt.Print("Projected average block win rate: ") - color.Blue( - "%.02f/week (every %s)", - weekly, - (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), - ) + fmt.Println() - // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples - // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t - // t == how many dice-rolls (epochs) before win - // p == winRate == ( minerPower / netPower ) - // c == target probability of win ( 99.9% in this case ) - fmt.Print("Projected block win with ") - color.Green( - "99.9%% probability every %s", - (time.Second * time.Duration( - builtin.EpochDurationSeconds*math.Log(1-0.999)/ - math.Log(1-winRatioFloat), - )).Truncate(time.Second).String(), - ) - fmt.Println("(projections DO NOT account for future network and miner growth)") + spendable := big.Zero() + + // NOTE: there's no need to unlock anything here. Funds only + // vest on deadline boundaries, and they're unlocked by cron. + lockedFunds, err := mas.LockedFunds() + if err != nil { + return xerrors.Errorf("getting locked funds: %w", err) } - } + availBalance, err := mas.AvailableBalance(mact.Balance) + if err != nil { + return xerrors.Errorf("getting available balance: %w", err) + } + spendable = big.Add(spendable, availBalance) - fmt.Println() + fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) + fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) + fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) + fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) + colorTokenAmount(" Available: %s\n", availBalance) - spendable := big.Zero() + mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting market balance: %w", err) + } + spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) - // NOTE: there's no need to unlock anything here. Funds only - // vest on deadline boundaries, and they're unlocked by cron. - lockedFunds, err := mas.LockedFunds() - if err != nil { - return xerrors.Errorf("getting locked funds: %w", err) - } - availBalance, err := mas.AvailableBalance(mact.Balance) - if err != nil { - return xerrors.Errorf("getting available balance: %w", err) - } - spendable = big.Add(spendable, availBalance) + fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) + fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) + colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) - fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) - fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) - fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) - fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) - colorTokenAmount(" Available: %s\n", availBalance) + wb, err := fullapi.WalletBalance(ctx, mi.Worker) + if err != nil { + return xerrors.Errorf("getting worker balance: %w", err) + } + spendable = big.Add(spendable, wb) + color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) + if len(mi.ControlAddresses) > 0 { + cbsum := big.Zero() + for _, ca := range mi.ControlAddresses { + b, err := fullapi.WalletBalance(ctx, ca) + if err != nil { + return xerrors.Errorf("getting control address balance: %w", err) + } + cbsum = big.Add(cbsum, b) + } + spendable = big.Add(spendable, cbsum) - mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("getting market balance: %w", err) - } - spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) + fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) + } + colorTokenAmount("Total Spendable: %s\n", spendable) - fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) - fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) - colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) + fmt.Println() - wb, err := fullapi.WalletBalance(ctx, mi.Worker) - if err != nil { - return xerrors.Errorf("getting worker balance: %w", err) - } - spendable = big.Add(spendable, wb) - color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) - if len(mi.ControlAddresses) > 0 { - cbsum := big.Zero() - for _, ca := range mi.ControlAddresses { - b, err := fullapi.WalletBalance(ctx, ca) + if !cctx.Bool("hide-sectors-info") { + fmt.Println("Sectors:") + err = sectorsInfo(ctx, nodeApi) if err != nil { - return xerrors.Errorf("getting control address balance: %w", err) + return err } - cbsum = big.Add(cbsum, b) } - spendable = big.Add(spendable, cbsum) - fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) + // TODO: grab actr state / info + // * Sealed sectors (count / bytes) + // * Power } - colorTokenAmount("Total Spendable: %s\n", spendable) - fmt.Println() - - if !cctx.Bool("hide-sectors-info") { - fmt.Println("Sectors:") - err = sectorsInfo(ctx, nodeApi) + if subsystems.Has(api.MarketsSubsystem) { + deals, err := nodeApi.MarketListIncompleteDeals(ctx) if err != nil { return err } - } - // TODO: grab actr state / info - // * Sealed sectors (count / bytes) - // * Power + type dealStat struct { + count, verifCount int + bytes, verifBytes uint64 + } + dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { + ds.count++ + ds.bytes += uint64(deal.Proposal.PieceSize) + if deal.Proposal.VerifiedDeal { + ds.verifCount++ + ds.verifBytes += uint64(deal.Proposal.PieceSize) + } + } - return nil -} + showDealStates := map[storagemarket.StorageDealStatus]struct{}{ + storagemarket.StorageDealActive: {}, + storagemarket.StorageDealTransferring: {}, + storagemarket.StorageDealStaged: {}, + storagemarket.StorageDealAwaitingPreCommit: {}, + storagemarket.StorageDealSealing: {}, + storagemarket.StorageDealPublish: {}, + storagemarket.StorageDealCheckForAcceptance: {}, + storagemarket.StorageDealPublishing: {}, + } -func handleMarketsInfo(ctx context.Context, nodeApi api.StorageMiner) error { - deals, err := nodeApi.MarketListIncompleteDeals(ctx) - if err != nil { - return err - } + var total dealStat + perState := map[storagemarket.StorageDealStatus]*dealStat{} + for _, deal := range deals { + if _, ok := showDealStates[deal.State]; !ok { + continue + } + if perState[deal.State] == nil { + perState[deal.State] = new(dealStat) + } - type dealStat struct { - count, verifCount int - bytes, verifBytes uint64 - } - dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { - ds.count++ - ds.bytes += uint64(deal.Proposal.PieceSize) - if deal.Proposal.VerifiedDeal { - ds.verifCount++ - ds.verifBytes += uint64(deal.Proposal.PieceSize) + dsAdd(&total, deal) + dsAdd(perState[deal.State], deal) } - } - showDealStates := map[storagemarket.StorageDealStatus]struct{}{ - storagemarket.StorageDealActive: {}, - storagemarket.StorageDealTransferring: {}, - storagemarket.StorageDealStaged: {}, - storagemarket.StorageDealAwaitingPreCommit: {}, - storagemarket.StorageDealSealing: {}, - storagemarket.StorageDealPublish: {}, - storagemarket.StorageDealCheckForAcceptance: {}, - storagemarket.StorageDealPublishing: {}, - } - - var total dealStat - perState := map[storagemarket.StorageDealStatus]*dealStat{} - for _, deal := range deals { - if _, ok := showDealStates[deal.State]; !ok { - continue + type wstr struct { + str string + status storagemarket.StorageDealStatus } - if perState[deal.State] == nil { - perState[deal.State] = new(dealStat) + sorted := make([]wstr, 0, len(perState)) + for status, stat := range perState { + st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") + sorted = append(sorted, wstr{ + str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), + status: status, + }, + ) } + sort.Slice(sorted, func(i, j int) bool { + if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { + return sorted[i].status == storagemarket.StorageDealActive + } + return sorted[i].status > sorted[j].status + }) - dsAdd(&total, deal) - dsAdd(perState[deal.State], deal) - } + fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) - type wstr struct { - str string - status storagemarket.StorageDealStatus - } - sorted := make([]wstr, 0, len(perState)) - for status, stat := range perState { - st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") - sorted = append(sorted, wstr{ - str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), - status: status, - }, - ) - } - sort.Slice(sorted, func(i, j int) bool { - if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { - return sorted[i].status == storagemarket.StorageDealActive + tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + for _, e := range sorted { + _, _ = tw.Write([]byte(e.str)) } - return sorted[i].status > sorted[j].status - }) - - fmt.Println() - fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) - - tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) - for _, e := range sorted { - _, _ = tw.Write([]byte(e.str)) - } - _ = tw.Flush() - fmt.Println() + _ = tw.Flush() + fmt.Println() - retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) - if err != nil { - return xerrors.Errorf("getting retrieval deal list: %w", err) - } + retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) + if err != nil { + return xerrors.Errorf("getting retrieval deal list: %w", err) + } - var retrComplete dealStat - for _, retrieval := range retrievals { - if retrieval.Status == retrievalmarket.DealStatusCompleted { - retrComplete.count++ - retrComplete.bytes += retrieval.TotalSent + var retrComplete dealStat + for _, retrieval := range retrievals { + if retrieval.Status == retrievalmarket.DealStatusCompleted { + retrComplete.count++ + retrComplete.bytes += retrieval.TotalSent + } } - } - fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) + fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) - fmt.Println() + fmt.Println() + } return nil } diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 3b6d5ac5181..dcd3abd4df6 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -1528,23 +1528,13 @@ Response: `{}` ### RuntimeSubsystems -RuntimeSubsystems returns the subsystems that are enabled -in this instance. Perms: read Inputs: `null` -Response: -```json -[ - "Mining", - "Sealing", - "SectorStorage", - "Markets" -] -``` +Response: `null` ## Sealing diff --git a/node/builder_miner.go b/node/builder_miner.go index 3be055de79b..d62cbcad9bb 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,7 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), - Override(new(api.MinerSubsystems), modules.ExtractEnabledMinerSubsystems(cfg.Subsystems)), + Override(new([]api.MinerSubsystem), modules.AddMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), @@ -216,6 +216,7 @@ func StorageMiner(out *api.StorageMiner, subsystemsCfg config.MinerSubsystemConf func(s *Settings) error { resAPI := &impl.StorageMinerAPI{} + s.invokes[ExtractApiKey] = fx.Populate(resAPI) *out = resAPI return nil diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 0fbd1211143..86c84fee7ea 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -23,8 +23,8 @@ import ( "github.com/filecoin-project/go-address" datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-fil-markets/piecestore" - "github.com/filecoin-project/go-fil-markets/retrievalmarket" - "github.com/filecoin-project/go-fil-markets/storagemarket" + retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket" + storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" @@ -48,11 +48,11 @@ import ( type StorageMinerAPI struct { fx.In + Subsystems api.MinerSubsystems + api.Common api.Net - EnabledSubsystems api.MinerSubsystems - Full api.FullNode LocalStore *stores.Local RemoteStore *stores.Remote @@ -706,7 +706,7 @@ func (sm *StorageMinerAPI) ComputeProof(ctx context.Context, ssi []builtin.Secto } func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubsystems, err error) { - return sm.EnabledSubsystems, nil + return sm.Subsystems, nil } var _ api.StorageMiner = &StorageMinerAPI{} diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 5497eab5813..06ef78ca0af 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -1008,18 +1008,19 @@ func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error { return multierr.Combine(typeErr, setConfigErr) } -func ExtractEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { +func AddMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { if cfg.EnableMining { - res = append(res, api.SubsystemMining) + res = append(res, api.MiningSubsystem) } if cfg.EnableSealing { - res = append(res, api.SubsystemSealing) + res = append(res, api.SealingSubsystem) } if cfg.EnableSectorStorage { - res = append(res, api.SubsystemSectorStorage) + res = append(res, api.SectorStorageSubsystem) } if cfg.EnableMarkets { - res = append(res, api.SubsystemMarkets) + res = append(res, api.MarketsSubsystem) } - return res + + return } From 45166e760bb3795ed77474eb7a404f454dcbcb89 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 16:23:04 +0300 Subject: [PATCH 35/79] fixup --- node/builder_miner.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/node/builder_miner.go b/node/builder_miner.go index d62cbcad9bb..830e6d075b2 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,7 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), - Override(new([]api.MinerSubsystem), modules.AddMinerSubsystems(cfg.Subsystems)), + Override(new(api.MinerSubsystems), modules.AddMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), @@ -216,7 +216,6 @@ func StorageMiner(out *api.StorageMiner, subsystemsCfg config.MinerSubsystemConf func(s *Settings) error { resAPI := &impl.StorageMinerAPI{} - s.invokes[ExtractApiKey] = fx.Populate(resAPI) *out = resAPI return nil From d92c6a209786f71eb9ef4d71d078e5a9bd8a3ce9 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 17:30:59 +0300 Subject: [PATCH 36/79] extract outputs for mining node and markets node in separate functions --- cmd/lotus-miner/info.go | 471 +++++++++++++++++++++------------------- 1 file changed, 245 insertions(+), 226 deletions(-) diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 4c409788fbb..2a36279595b 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -21,6 +21,7 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/api/v0api" sealing "github.com/filecoin-project/lotus/extern/storage-sealing" "github.com/filecoin-project/lotus/api" @@ -103,288 +104,306 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() if subsystems.Has(api.SectorStorageSubsystem) { - maddr, err := getActorAddress(ctx, cctx) + err := handleMiningInfo(cctx, ctx, fullapi, nodeApi) if err != nil { return err } + } - mact, err := fullapi.StateGetActor(ctx, maddr, types.EmptyTSK) + if subsystems.Has(api.MarketsSubsystem) { + err := handleMarketsInfo(ctx, nodeApi) if err != nil { return err } + } - tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullapi), blockstore.NewMemory()) - mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) - if err != nil { - return err - } + return nil +} - // Sector size - mi, err := fullapi.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } +func handleMiningInfo(cctx *cli.Context, ctx context.Context, fullapi v0api.FullNode, nodeApi api.StorageMiner) error { + maddr, err := getActorAddress(ctx, cctx) + if err != nil { + return err + } - ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) - fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) + mact, err := fullapi.StateGetActor(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - pow, err := fullapi.StateMinerPower(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullapi), blockstore.NewMemory()) + mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact) + if err != nil { + return err + } - fmt.Printf("Power: %s / %s (%0.4f%%)\n", - color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), - types.DeciStr(pow.TotalPower.QualityAdjPower), - types.BigDivFloat( - types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), - pow.TotalPower.QualityAdjPower, - ), - ) + // Sector size + mi, err := fullapi.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } - fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", - color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), - types.SizeStr(pow.TotalPower.RawBytePower), - types.BigDivFloat( - types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), - pow.TotalPower.RawBytePower, - ), - ) - secCounts, err := fullapi.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) - if err != nil { - return err - } + ssize := types.SizeStr(types.NewInt(uint64(mi.SectorSize))) + fmt.Printf("Miner: %s (%s sectors)\n", color.BlueString("%s", maddr), ssize) - proving := secCounts.Active + secCounts.Faulty - nfaults := secCounts.Faulty - fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Live), types.NewInt(uint64(mi.SectorSize))))) - if nfaults == 0 { - fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize))))) - } else { - var faultyPercentage float64 - if secCounts.Live != 0 { - faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) - } - fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", - types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), - types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))), - faultyPercentage) + pow, err := fullapi.StateMinerPower(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + fmt.Printf("Power: %s / %s (%0.4f%%)\n", + color.GreenString(types.DeciStr(pow.MinerPower.QualityAdjPower)), + types.DeciStr(pow.TotalPower.QualityAdjPower), + types.BigDivFloat( + types.BigMul(pow.MinerPower.QualityAdjPower, big.NewInt(100)), + pow.TotalPower.QualityAdjPower, + ), + ) + + fmt.Printf("\tRaw: %s / %s (%0.4f%%)\n", + color.BlueString(types.SizeStr(pow.MinerPower.RawBytePower)), + types.SizeStr(pow.TotalPower.RawBytePower), + types.BigDivFloat( + types.BigMul(pow.MinerPower.RawBytePower, big.NewInt(100)), + pow.TotalPower.RawBytePower, + ), + ) + secCounts, err := fullapi.StateMinerSectorCount(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + proving := secCounts.Active + secCounts.Faulty + nfaults := secCounts.Faulty + fmt.Printf("\tCommitted: %s\n", types.SizeStr(types.BigMul(types.NewInt(secCounts.Live), types.NewInt(uint64(mi.SectorSize))))) + if nfaults == 0 { + fmt.Printf("\tProving: %s\n", types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize))))) + } else { + var faultyPercentage float64 + if secCounts.Live != 0 { + faultyPercentage = float64(100*nfaults) / float64(secCounts.Live) } + fmt.Printf("\tProving: %s (%s Faulty, %.2f%%)\n", + types.SizeStr(types.BigMul(types.NewInt(proving), types.NewInt(uint64(mi.SectorSize)))), + types.SizeStr(types.BigMul(types.NewInt(nfaults), types.NewInt(uint64(mi.SectorSize)))), + faultyPercentage) + } - if !pow.HasMinPower { - fmt.Print("Below minimum power threshold, no blocks will be won") - } else { + if !pow.HasMinPower { + fmt.Print("Below minimum power threshold, no blocks will be won") + } else { - winRatio := new(corebig.Rat).SetFrac( - types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, - pow.TotalPower.QualityAdjPower.Int, - ) + winRatio := new(corebig.Rat).SetFrac( + types.BigMul(pow.MinerPower.QualityAdjPower, types.NewInt(build.BlocksPerEpoch)).Int, + pow.TotalPower.QualityAdjPower.Int, + ) - if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { - - // if the corresponding poisson distribution isn't infinitely small then - // throw it into the mix as well, accounting for multi-wins - winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) - winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) - if winRationWithPoisson != nil { - winRatio = winRationWithPoisson - winRatioFloat = winRationWithPoissonFloat - } - - weekly, _ := new(corebig.Rat).Mul( - winRatio, - new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), - ).Float64() - - avgDuration, _ := new(corebig.Rat).Mul( - new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), - new(corebig.Rat).Inv(winRatio), - ).Float64() - - fmt.Print("Projected average block win rate: ") - color.Blue( - "%.02f/week (every %s)", - weekly, - (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), - ) - - // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples - // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t - // t == how many dice-rolls (epochs) before win - // p == winRate == ( minerPower / netPower ) - // c == target probability of win ( 99.9% in this case ) - fmt.Print("Projected block win with ") - color.Green( - "99.9%% probability every %s", - (time.Second * time.Duration( - builtin.EpochDurationSeconds*math.Log(1-0.999)/ - math.Log(1-winRatioFloat), - )).Truncate(time.Second).String(), - ) - fmt.Println("(projections DO NOT account for future network and miner growth)") - } - } + if winRatioFloat, _ := winRatio.Float64(); winRatioFloat > 0 { - fmt.Println() + // if the corresponding poisson distribution isn't infinitely small then + // throw it into the mix as well, accounting for multi-wins + winRationWithPoissonFloat := -math.Expm1(-winRatioFloat) + winRationWithPoisson := new(corebig.Rat).SetFloat64(winRationWithPoissonFloat) + if winRationWithPoisson != nil { + winRatio = winRationWithPoisson + winRatioFloat = winRationWithPoissonFloat + } - spendable := big.Zero() + weekly, _ := new(corebig.Rat).Mul( + winRatio, + new(corebig.Rat).SetInt64(7*builtin.EpochsInDay), + ).Float64() + + avgDuration, _ := new(corebig.Rat).Mul( + new(corebig.Rat).SetInt64(builtin.EpochDurationSeconds), + new(corebig.Rat).Inv(winRatio), + ).Float64() + + fmt.Print("Projected average block win rate: ") + color.Blue( + "%.02f/week (every %s)", + weekly, + (time.Second * time.Duration(avgDuration)).Truncate(time.Second).String(), + ) - // NOTE: there's no need to unlock anything here. Funds only - // vest on deadline boundaries, and they're unlocked by cron. - lockedFunds, err := mas.LockedFunds() - if err != nil { - return xerrors.Errorf("getting locked funds: %w", err) - } - availBalance, err := mas.AvailableBalance(mact.Balance) - if err != nil { - return xerrors.Errorf("getting available balance: %w", err) + // Geometric distribution of P(Y < k) calculated as described in https://en.wikipedia.org/wiki/Geometric_distribution#Probability_Outcomes_Examples + // https://www.wolframalpha.com/input/?i=t+%3E+0%3B+p+%3E+0%3B+p+%3C+1%3B+c+%3E+0%3B+c+%3C1%3B+1-%281-p%29%5E%28t%29%3Dc%3B+solve+t + // t == how many dice-rolls (epochs) before win + // p == winRate == ( minerPower / netPower ) + // c == target probability of win ( 99.9% in this case ) + fmt.Print("Projected block win with ") + color.Green( + "99.9%% probability every %s", + (time.Second * time.Duration( + builtin.EpochDurationSeconds*math.Log(1-0.999)/ + math.Log(1-winRatioFloat), + )).Truncate(time.Second).String(), + ) + fmt.Println("(projections DO NOT account for future network and miner growth)") } - spendable = big.Add(spendable, availBalance) + } - fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) - fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) - fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) - fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) - colorTokenAmount(" Available: %s\n", availBalance) + fmt.Println() - mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("getting market balance: %w", err) - } - spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) + spendable := big.Zero() - fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) - fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) - colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) + // NOTE: there's no need to unlock anything here. Funds only + // vest on deadline boundaries, and they're unlocked by cron. + lockedFunds, err := mas.LockedFunds() + if err != nil { + return xerrors.Errorf("getting locked funds: %w", err) + } + availBalance, err := mas.AvailableBalance(mact.Balance) + if err != nil { + return xerrors.Errorf("getting available balance: %w", err) + } + spendable = big.Add(spendable, availBalance) - wb, err := fullapi.WalletBalance(ctx, mi.Worker) - if err != nil { - return xerrors.Errorf("getting worker balance: %w", err) - } - spendable = big.Add(spendable, wb) - color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) - if len(mi.ControlAddresses) > 0 { - cbsum := big.Zero() - for _, ca := range mi.ControlAddresses { - b, err := fullapi.WalletBalance(ctx, ca) - if err != nil { - return xerrors.Errorf("getting control address balance: %w", err) - } - cbsum = big.Add(cbsum, b) - } - spendable = big.Add(spendable, cbsum) + fmt.Printf("Miner Balance: %s\n", color.YellowString("%s", types.FIL(mact.Balance).Short())) + fmt.Printf(" PreCommit: %s\n", types.FIL(lockedFunds.PreCommitDeposits).Short()) + fmt.Printf(" Pledge: %s\n", types.FIL(lockedFunds.InitialPledgeRequirement).Short()) + fmt.Printf(" Vesting: %s\n", types.FIL(lockedFunds.VestingFunds).Short()) + colorTokenAmount(" Available: %s\n", availBalance) - fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) - } - colorTokenAmount("Total Spendable: %s\n", spendable) + mb, err := fullapi.StateMarketBalance(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("getting market balance: %w", err) + } + spendable = big.Add(spendable, big.Sub(mb.Escrow, mb.Locked)) - fmt.Println() + fmt.Printf("Market Balance: %s\n", types.FIL(mb.Escrow).Short()) + fmt.Printf(" Locked: %s\n", types.FIL(mb.Locked).Short()) + colorTokenAmount(" Available: %s\n", big.Sub(mb.Escrow, mb.Locked)) - if !cctx.Bool("hide-sectors-info") { - fmt.Println("Sectors:") - err = sectorsInfo(ctx, nodeApi) + wb, err := fullapi.WalletBalance(ctx, mi.Worker) + if err != nil { + return xerrors.Errorf("getting worker balance: %w", err) + } + spendable = big.Add(spendable, wb) + color.Cyan("Worker Balance: %s", types.FIL(wb).Short()) + if len(mi.ControlAddresses) > 0 { + cbsum := big.Zero() + for _, ca := range mi.ControlAddresses { + b, err := fullapi.WalletBalance(ctx, ca) if err != nil { - return err + return xerrors.Errorf("getting control address balance: %w", err) } + cbsum = big.Add(cbsum, b) } + spendable = big.Add(spendable, cbsum) - // TODO: grab actr state / info - // * Sealed sectors (count / bytes) - // * Power + fmt.Printf(" Control: %s\n", types.FIL(cbsum).Short()) } + colorTokenAmount("Total Spendable: %s\n", spendable) - if subsystems.Has(api.MarketsSubsystem) { - deals, err := nodeApi.MarketListIncompleteDeals(ctx) + fmt.Println() + + if !cctx.Bool("hide-sectors-info") { + fmt.Println("Sectors:") + err = sectorsInfo(ctx, nodeApi) if err != nil { return err } + } - type dealStat struct { - count, verifCount int - bytes, verifBytes uint64 - } - dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { - ds.count++ - ds.bytes += uint64(deal.Proposal.PieceSize) - if deal.Proposal.VerifiedDeal { - ds.verifCount++ - ds.verifBytes += uint64(deal.Proposal.PieceSize) - } - } + // TODO: grab actr state / info + // * Sealed sectors (count / bytes) + // * Power - showDealStates := map[storagemarket.StorageDealStatus]struct{}{ - storagemarket.StorageDealActive: {}, - storagemarket.StorageDealTransferring: {}, - storagemarket.StorageDealStaged: {}, - storagemarket.StorageDealAwaitingPreCommit: {}, - storagemarket.StorageDealSealing: {}, - storagemarket.StorageDealPublish: {}, - storagemarket.StorageDealCheckForAcceptance: {}, - storagemarket.StorageDealPublishing: {}, - } + return nil +} - var total dealStat - perState := map[storagemarket.StorageDealStatus]*dealStat{} - for _, deal := range deals { - if _, ok := showDealStates[deal.State]; !ok { - continue - } - if perState[deal.State] == nil { - perState[deal.State] = new(dealStat) - } +func handleMarketsInfo(ctx context.Context, nodeApi api.StorageMiner) error { + deals, err := nodeApi.MarketListIncompleteDeals(ctx) + if err != nil { + return err + } - dsAdd(&total, deal) - dsAdd(perState[deal.State], deal) + type dealStat struct { + count, verifCount int + bytes, verifBytes uint64 + } + dsAdd := func(ds *dealStat, deal storagemarket.MinerDeal) { + ds.count++ + ds.bytes += uint64(deal.Proposal.PieceSize) + if deal.Proposal.VerifiedDeal { + ds.verifCount++ + ds.verifBytes += uint64(deal.Proposal.PieceSize) } + } - type wstr struct { - str string - status storagemarket.StorageDealStatus + showDealStates := map[storagemarket.StorageDealStatus]struct{}{ + storagemarket.StorageDealActive: {}, + storagemarket.StorageDealTransferring: {}, + storagemarket.StorageDealStaged: {}, + storagemarket.StorageDealAwaitingPreCommit: {}, + storagemarket.StorageDealSealing: {}, + storagemarket.StorageDealPublish: {}, + storagemarket.StorageDealCheckForAcceptance: {}, + storagemarket.StorageDealPublishing: {}, + } + + var total dealStat + perState := map[storagemarket.StorageDealStatus]*dealStat{} + for _, deal := range deals { + if _, ok := showDealStates[deal.State]; !ok { + continue } - sorted := make([]wstr, 0, len(perState)) - for status, stat := range perState { - st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") - sorted = append(sorted, wstr{ - str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), - status: status, - }, - ) + if perState[deal.State] == nil { + perState[deal.State] = new(dealStat) } - sort.Slice(sorted, func(i, j int) bool { - if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { - return sorted[i].status == storagemarket.StorageDealActive - } - return sorted[i].status > sorted[j].status - }) - fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) + dsAdd(&total, deal) + dsAdd(perState[deal.State], deal) + } - tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) - for _, e := range sorted { - _, _ = tw.Write([]byte(e.str)) + type wstr struct { + str string + status storagemarket.StorageDealStatus + } + sorted := make([]wstr, 0, len(perState)) + for status, stat := range perState { + st := strings.TrimPrefix(storagemarket.DealStates[status], "StorageDeal") + sorted = append(sorted, wstr{ + str: fmt.Sprintf(" %s:\t%d\t\t%s\t(Verified: %d\t%s)\n", st, stat.count, types.SizeStr(types.NewInt(stat.bytes)), stat.verifCount, types.SizeStr(types.NewInt(stat.verifBytes))), + status: status, + }, + ) + } + sort.Slice(sorted, func(i, j int) bool { + if sorted[i].status == storagemarket.StorageDealActive || sorted[j].status == storagemarket.StorageDealActive { + return sorted[i].status == storagemarket.StorageDealActive } + return sorted[i].status > sorted[j].status + }) - _ = tw.Flush() - fmt.Println() + fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) - retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) - if err != nil { - return xerrors.Errorf("getting retrieval deal list: %w", err) - } + tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + for _, e := range sorted { + _, _ = tw.Write([]byte(e.str)) + } - var retrComplete dealStat - for _, retrieval := range retrievals { - if retrieval.Status == retrievalmarket.DealStatusCompleted { - retrComplete.count++ - retrComplete.bytes += retrieval.TotalSent - } - } + _ = tw.Flush() + fmt.Println() - fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) + retrievals, err := nodeApi.MarketListRetrievalDeals(ctx) + if err != nil { + return xerrors.Errorf("getting retrieval deal list: %w", err) + } - fmt.Println() + var retrComplete dealStat + for _, retrieval := range retrievals { + if retrieval.Status == retrievalmarket.DealStatusCompleted { + retrComplete.count++ + retrComplete.bytes += retrieval.TotalSent + } } + fmt.Printf("Retrieval Deals (complete): %d, %s\n", retrComplete.count, types.SizeStr(types.NewInt(retrComplete.bytes))) + + fmt.Println() + return nil } From 60b612247d26a5419081a595fffbbad7af087c21 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 28 Jul 2021 17:47:01 +0300 Subject: [PATCH 37/79] make linter happy --- cmd/lotus-miner/info.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 2a36279595b..92f25667cc1 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -104,7 +104,7 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() if subsystems.Has(api.SectorStorageSubsystem) { - err := handleMiningInfo(cctx, ctx, fullapi, nodeApi) + err := handleMiningInfo(ctx, cctx, fullapi, nodeApi) if err != nil { return err } @@ -120,7 +120,7 @@ func infoCmdAct(cctx *cli.Context) error { return nil } -func handleMiningInfo(cctx *cli.Context, ctx context.Context, fullapi v0api.FullNode, nodeApi api.StorageMiner) error { +func handleMiningInfo(ctx context.Context, cctx *cli.Context, fullapi v0api.FullNode, nodeApi api.StorageMiner) error { maddr, err := getActorAddress(ctx, cctx) if err != nil { return err From 85a4f8325fb26ebbd0f381e841ab384a6e6784f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Wed, 28 Jul 2021 19:51:45 +0100 Subject: [PATCH 38/79] fix docs and nits. --- api/api_storage.go | 2 + api/api_subsystems.go | 63 ------------------ api/docgen/docgen.go | 10 ++- api/miner_subsystems.go | 79 +++++++++++++++++++++++ build/openrpc/miner.json.gz | Bin 9540 -> 9596 bytes cmd/lotus-miner/info.go | 4 +- documentation/en/api-v0-methods-miner.md | 12 +++- node/builder_miner.go | 2 +- node/impl/storminer.go | 10 +-- node/modules/storageminer.go | 11 ++-- 10 files changed, 113 insertions(+), 80 deletions(-) delete mode 100644 api/api_subsystems.go create mode 100644 api/miner_subsystems.go diff --git a/api/api_storage.go b/api/api_storage.go index d5203265088..c391149290b 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -166,6 +166,8 @@ type StorageMiner interface { MarketPendingDeals(ctx context.Context) (PendingDealInfo, error) //perm:write MarketPublishPendingDeals(ctx context.Context) error //perm:admin + // RuntimeSubsystems returns the subsystems that are enabled + // in this instance. RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error //perm:admin diff --git a/api/api_subsystems.go b/api/api_subsystems.go deleted file mode 100644 index 1894bbdd8a6..00000000000 --- a/api/api_subsystems.go +++ /dev/null @@ -1,63 +0,0 @@ -package api - -import ( - "bytes" - "encoding/json" -) - -type MinerSubsystems []MinerSubsystem - -func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { - for _, v := range ms { - if v == entry { - return true - } - - } - return false -} - -type MinerSubsystem int - -const ( - MarketsSubsystem MinerSubsystem = iota - MiningSubsystem - SealingSubsystem - SectorStorageSubsystem -) - -func (ms MinerSubsystem) String() string { - return MinerSubsystemToString[ms] -} - -var MinerSubsystemToString = map[MinerSubsystem]string{ - MarketsSubsystem: "Markets", - MiningSubsystem: "Mining", - SealingSubsystem: "Sealing", - SectorStorageSubsystem: "SectorStorage", -} - -var MinerSubsystemToID = map[string]MinerSubsystem{ - "Markets": MarketsSubsystem, - "Mining": MiningSubsystem, - "Sealing": SealingSubsystem, - "SectorStorage": SectorStorageSubsystem, -} - -func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { - buffer := bytes.NewBufferString(`"`) - buffer.WriteString(MinerSubsystemToString[ms]) - buffer.WriteString(`"`) - return buffer.Bytes(), nil -} - -func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { - var j string - err := json.Unmarshal(b, &j) - if err != nil { - return err - } - // TODO: handle zero value - *ms = MinerSubsystemToID[j] - return nil -} diff --git a/api/docgen/docgen.go b/api/docgen/docgen.go index 1e712a0aeab..f9addc940dd 100644 --- a/api/docgen/docgen.go +++ b/api/docgen/docgen.go @@ -16,10 +16,10 @@ import ( "github.com/google/uuid" "github.com/ipfs/go-cid" "github.com/ipfs/go-filestore" - metrics "github.com/libp2p/go-libp2p-core/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/libp2p/go-libp2p-core/protocol" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/multiformats/go-multiaddr" @@ -265,6 +265,12 @@ func init() { addExample(api.CheckStatusCode(0)) addExample(map[string]interface{}{"abc": 123}) + addExample(api.MinerSubsystems{ + api.SubsystemMining, + api.SubsystemSealing, + api.SubsystemSectorStorage, + api.SubsystemMarkets, + }) } func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) { diff --git a/api/miner_subsystems.go b/api/miner_subsystems.go new file mode 100644 index 00000000000..a77de7e3c95 --- /dev/null +++ b/api/miner_subsystems.go @@ -0,0 +1,79 @@ +package api + +import ( + "encoding/json" +) + +// MinerSubsystem represents a miner subsystem. Int and string values are not +// guaranteed to be stable over time is not +// guaranteed to be stable over time. +type MinerSubsystem int + +const ( + // SubsystemUnknown is a placeholder for the zero value. It should never + // be used. + SubsystemUnknown MinerSubsystem = iota + // SubsystemMarkets signifies the storage and retrieval + // deal-making subsystem. + SubsystemMarkets + // SubsystemMining signifies the mining subsystem. + SubsystemMining + // SubsystemSealing signifies the sealing subsystem. + SubsystemSealing + // SubsystemSectorStorage signifies the sector storage subsystem. + SubsystemSectorStorage +) + +var MinerSubsystemToString = map[MinerSubsystem]string{ + SubsystemUnknown: "Unknown", + SubsystemMarkets: "Markets", + SubsystemMining: "Mining", + SubsystemSealing: "Sealing", + SubsystemSectorStorage: "SectorStorage", +} + +var MinerSubsystemToID = map[string]MinerSubsystem{ + "Unknown": SubsystemUnknown, + "Markets": SubsystemMarkets, + "Mining": SubsystemMining, + "Sealing": SubsystemSealing, + "SectorStorage": SubsystemSectorStorage, +} + +func (ms MinerSubsystem) MarshalJSON() ([]byte, error) { + return json.Marshal(MinerSubsystemToString[ms]) +} + +func (ms *MinerSubsystem) UnmarshalJSON(b []byte) error { + var j string + err := json.Unmarshal(b, &j) + if err != nil { + return err + } + s, ok := MinerSubsystemToID[j] + if !ok { + *ms = SubsystemUnknown + } else { + *ms = s + } + return nil +} + +type MinerSubsystems []MinerSubsystem + +func (ms MinerSubsystems) Has(entry MinerSubsystem) bool { + for _, v := range ms { + if v == entry { + return true + } + } + return false +} + +func (ms MinerSubsystem) String() string { + s, ok := MinerSubsystemToString[ms] + if !ok { + return MinerSubsystemToString[SubsystemUnknown] + } + return s +} diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index ccdc26dc7b1a005ece120ba631b701e954d20ac6..1fd8121c9d3ace29f106a38d5085914181d9aaa9 100644 GIT binary patch literal 9596 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 Date: Wed, 28 Jul 2021 23:46:21 +0100 Subject: [PATCH 39/79] address nits. --- node/builder_miner.go | 2 +- node/modules/storageminer.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/builder_miner.go b/node/builder_miner.go index acb9d3d43cd..3be055de79b 100644 --- a/node/builder_miner.go +++ b/node/builder_miner.go @@ -72,7 +72,7 @@ func ConfigStorageMiner(c interface{}) Option { return Options( ConfigCommon(&cfg.Common, enableLibp2pNode), - Override(new(api.MinerSubsystems), modules.PopulateEnabledMinerSubsystems(cfg.Subsystems)), + Override(new(api.MinerSubsystems), modules.ExtractEnabledMinerSubsystems(cfg.Subsystems)), Override(new(stores.LocalStorage), From(new(repo.LockedRepo))), Override(new(*stores.Local), modules.LocalStorage), Override(new(*stores.Remote), modules.RemoteStorage), diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 26792ca197b..5497eab5813 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -1008,7 +1008,7 @@ func mutateCfg(r repo.LockedRepo, mutator func(*config.StorageMiner)) error { return multierr.Combine(typeErr, setConfigErr) } -func PopulateEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { +func ExtractEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.MinerSubsystems) { if cfg.EnableMining { res = append(res, api.SubsystemMining) } @@ -1021,5 +1021,5 @@ func PopulateEnabledMinerSubsystems(cfg config.MinerSubsystemConfig) (res api.Mi if cfg.EnableMarkets { res = append(res, api.SubsystemMarkets) } - return + return res } From 2ecf8914a11ef0e976f1a6a64842b2b3c2d0331c Mon Sep 17 00:00:00 2001 From: hannahhoward Date: Wed, 28 Jul 2021 14:46:13 -0700 Subject: [PATCH 40/79] feat(deps): update to branches with improved logging update sub repos with improved logging around data transfer processing --- go.mod | 31 ++++++----- go.sum | 160 ++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 129 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index 522a0d568b7..6c20ebbe9fb 100644 --- a/go.mod +++ b/go.mod @@ -33,16 +33,16 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.7.2 + github.com/filecoin-project/go-data-transfer v1.7.1 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.6.2 + github.com/filecoin-project/go-fil-markets v1.6.1 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 - github.com/filecoin-project/go-statemachine v1.0.1 + github.com/filecoin-project/go-statemachine v1.0.0 github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.14 @@ -56,7 +56,7 @@ require ( github.com/gdamore/tcell/v2 v2.2.0 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect - github.com/golang/mock v1.5.0 + github.com/golang/mock v1.6.0 github.com/google/uuid v1.1.2 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.2 @@ -100,22 +100,21 @@ require ( github.com/ipld/go-car v0.1.1-0.20201119040415-11b6074b6d4d github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018 github.com/kelseyhightower/envconfig v1.4.0 - github.com/lib/pq v1.7.0 github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-eventbus v0.2.1 github.com/libp2p/go-libp2p v0.14.2 github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.8.5 - github.com/libp2p/go-libp2p-discovery v0.5.0 + github.com/libp2p/go-libp2p-core v0.8.6 + github.com/libp2p/go-libp2p-discovery v0.5.1 github.com/libp2p/go-libp2p-kad-dht v0.11.0 github.com/libp2p/go-libp2p-mplex v0.4.1 github.com/libp2p/go-libp2p-noise v0.2.0 - github.com/libp2p/go-libp2p-peerstore v0.2.7 - github.com/libp2p/go-libp2p-pubsub v0.5.0 - github.com/libp2p/go-libp2p-quic-transport v0.10.0 + github.com/libp2p/go-libp2p-peerstore v0.2.8 + github.com/libp2p/go-libp2p-pubsub v0.5.3 + github.com/libp2p/go-libp2p-quic-transport v0.11.2 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 - github.com/libp2p/go-libp2p-swarm v0.5.0 + github.com/libp2p/go-libp2p-swarm v0.5.3 github.com/libp2p/go-libp2p-tls v0.1.3 github.com/libp2p/go-libp2p-yamux v0.5.4 github.com/libp2p/go-maddr-filter v0.1.0 @@ -124,14 +123,14 @@ require ( github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 github.com/mitchellh/go-homedir v1.1.0 github.com/multiformats/go-base32 v0.0.3 - github.com/multiformats/go-multiaddr v0.3.1 + github.com/multiformats/go-multiaddr v0.3.3 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.0.3 github.com/multiformats/go-multihash v0.0.15 github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 github.com/opentracing/opentracing-go v1.2.0 github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a - github.com/prometheus/client_golang v1.6.0 + github.com/prometheus/client_golang v1.10.0 github.com/raulk/clock v1.1.0 github.com/raulk/go-watchdog v1.0.1 github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25 @@ -150,9 +149,9 @@ require ( go.uber.org/fx v1.9.0 go.uber.org/multierr v1.6.0 go.uber.org/zap v1.16.0 - golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 + golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 + golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/tools v0.1.5 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 @@ -167,4 +166,4 @@ replace github.com/filecoin-project/lotus => ./ replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi -replace github.com/filecoin-project/test-vectors => ./extern/test-vectors +replace github.com/filecoin-project/test-vectors => ./extern/test-vectors \ No newline at end of file diff --git a/go.sum b/go.sum index 90c52baab2b..ca71b27d2d8 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,9 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -199,8 +200,9 @@ github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1: github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger v1.6.1 h1:w9pSFNSdq/JPM1N12Fz/F/bzo993Is1W+Q7HjPzi7yg= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= +github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger/v2 v2.0.3/go.mod h1:3KY8+bsP8wI0OEnQJAKpd4wIJW/Mm32yw2j/9FUVnIM= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= @@ -275,8 +277,8 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMX github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= github.com/filecoin-project/go-data-transfer v1.7.0/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= -github.com/filecoin-project/go-data-transfer v1.7.2 h1:iL3q5pxSloA7V2QucFofoVN3lquULz+Ml0KrNqMT5ZU= -github.com/filecoin-project/go-data-transfer v1.7.2/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= +github.com/filecoin-project/go-data-transfer v1.7.1 h1:Co4bTenvCc3WnOhQWyXRt59FLZvxwH8UeF0ZCOc1ik0= +github.com/filecoin-project/go-data-transfer v1.7.1/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= @@ -286,8 +288,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+ github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.6.2 h1:ib1sGUOF+hf50YwP7+p9yoK+9g84YcXzvuenxd6MYoE= -github.com/filecoin-project/go-fil-markets v1.6.2/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= +github.com/filecoin-project/go-fil-markets v1.6.1 h1:8xdFyWrELfOzwcGa229bLu/olD+1l4sEWFIsZR7oz5U= +github.com/filecoin-project/go-fil-markets v1.6.1/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -313,8 +315,8 @@ github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48/ github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 h1:veGrNABg/9I7prngrowkhwbvW5d5JN55MNKmbsr5FqA= github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= -github.com/filecoin-project/go-statemachine v1.0.1 h1:LQ60+JDVjMdLxXmVFM2jjontzOYnfVE7u02CXV3WKSw= -github.com/filecoin-project/go-statemachine v1.0.1/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= +github.com/filecoin-project/go-statemachine v1.0.0 h1:b8FpFewPSklyAIUqH0oHt4nvKf03bU7asop1bJpjAtQ= +github.com/filecoin-project/go-statemachine v1.0.0/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/c3OROw/kXVNSTZk= github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= @@ -399,6 +401,8 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968 h1:s+PDl6lozQ+dEUtUtQnO7+A2iPG3sK1pI4liU+jxn90= github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= @@ -431,8 +435,8 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -445,8 +449,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf h1:gFVkHXmVAhEbxZVDln5V9GKrLaluNoFHDbrZwAWZgws= @@ -459,8 +465,10 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -611,8 +619,9 @@ github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjv github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= -github.com/ipfs/go-ds-badger v0.2.3 h1:J27YvAcpuA5IvZUbeBxOcQgqnYHUPxoygc6QxxkodZ4= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-badger v0.2.7 h1:ju5REfIm+v+wgVnQ19xGLYPHYHbYLR6qJfmMbCDSK1I= +github.com/ipfs/go-ds-badger v0.2.7/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= github.com/ipfs/go-ds-badger2 v0.1.0/go.mod h1:pbR1p817OZbdId9EvLOhKBgUVTM3BMCSTan78lDDVaw= github.com/ipfs/go-ds-badger2 v0.1.1-0.20200708190120-187fc06f714e h1:Xi1nil8K2lBOorBS6Ys7+hmUCzH8fr3U9ipdL/IrcEI= github.com/ipfs/go-ds-badger2 v0.1.1-0.20200708190120-187fc06f714e/go.mod h1:lJnws7amT9Ehqzta0gwMrRsURU04caT0iRPr1W8AsOU= @@ -700,8 +709,9 @@ github.com/ipfs/go-log v1.0.0/go.mod h1:JO7RzlMK6rA+CIxFMLOuB6Wf5b81GDiKElL7UPSI github.com/ipfs/go-log v1.0.1/go.mod h1:HuWlQttfN6FWNHRhlY5yMk/lW7evQC0HHGOxEwMRR8I= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= -github.com/ipfs/go-log v1.0.4 h1:6nLQdX4W8P9yZZFH7mO+X/PzjN8Laozm/lMJ6esdgzY= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= +github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= @@ -802,12 +812,14 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4ufZiIGv2nXn4gMxnfKV306n3mWXgNu/d2TqdTU= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= @@ -821,6 +833,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -837,11 +851,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY= -github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= -github.com/libp2p/go-addr-util v0.0.2 h1:7cWK5cdA5x72jX0g8iLrQWm5TRJZ6CzGdPEhWj7plWU= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= +github.com/libp2p/go-addr-util v0.1.0 h1:acKsntI33w2bTU7tC9a0SaPimJGfSI0bFKC18ChxeVI= +github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= @@ -942,9 +955,9 @@ github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.3/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.5 h1:aEgbIcPGsKy6zYcC+5AJivYFedhYa4sW7mIpWpUaLKw= github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.6 h1:3S8g006qG6Tjpj1JdRK2S+TWc2DJQKX/RG9fdLeiLSU= +github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= @@ -956,8 +969,9 @@ github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFT github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= github.com/libp2p/go-libp2p-discovery v0.4.0/go.mod h1:bZ0aJSrFc/eX2llP0ryhb1kpgkPyTo23SJ5b7UQCMh4= -github.com/libp2p/go-libp2p-discovery v0.5.0 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+WgN9mN0iWviQ= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= +github.com/libp2p/go-libp2p-discovery v0.5.1 h1:CJylx+h2+4+s68GvrM4pGNyfNhOYviWBPtVv5PA7sfo= +github.com/libp2p/go-libp2p-discovery v0.5.1/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= @@ -1011,20 +1025,22 @@ github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.2.7 h1:83JoLxyR9OYTnNfB5vvFqvMUv/xDNa6NoPHnENhBsGw= github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.2.8 h1:nJghUlUkFVvyk7ccsM67oFA6kqUkwyCM1G4WPVMCWYA= +github.com/libp2p/go-libp2p-peerstore v0.2.8/go.mod h1:gGiPlXdz7mIHd2vfAsHzBNAMqSDkt2UBFwgcITgw1lA= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= github.com/libp2p/go-libp2p-pubsub v0.3.2-0.20200527132641-c0712c6e92cf/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= -github.com/libp2p/go-libp2p-pubsub v0.5.0 h1:OzcIuCWyJpOrWH0PTOfvxTzqFur4tiXpY5jXC8OxjyE= -github.com/libp2p/go-libp2p-pubsub v0.5.0/go.mod h1:MKnrsQkFgPcrQs1KVmOXy6Uz2RDQ1xO7dQo/P0Ba+ig= +github.com/libp2p/go-libp2p-pubsub v0.5.3 h1:XCn5xvgA/AKpbbaeqbomfKtQCbT9QsU39tYsVj0IndQ= +github.com/libp2p/go-libp2p-pubsub v0.5.3/go.mod h1:gVOzwebXVdSMDQBTfH8ACO5EJ4SQrvsHqCmYsCZpD0E= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= github.com/libp2p/go-libp2p-quic-transport v0.5.0/go.mod h1:IEcuC5MLxvZ5KuHKjRu+dr3LjCT1Be3rcD/4d8JrX8M= -github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= +github.com/libp2p/go-libp2p-quic-transport v0.11.2 h1:p1YQDZRHH4Cv2LPtHubqlQ9ggz4CKng/REZuXZbZMhM= +github.com/libp2p/go-libp2p-quic-transport v0.11.2/go.mod h1:wlanzKtIh6pHrq+0U3p3DY9PJfGqxMgPaGKaK5LifwQ= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= @@ -1052,9 +1068,9 @@ github.com/libp2p/go-libp2p-swarm v0.2.7/go.mod h1:ZSJ0Q+oq/B1JgfPHJAT2HTall+xYR github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= -github.com/libp2p/go-libp2p-swarm v0.4.3/go.mod h1:mmxP1pGBSc1Arw4F5DIjcpjFAmsRzA1KADuMtMuCT4g= -github.com/libp2p/go-libp2p-swarm v0.5.0 h1:HIK0z3Eqoo8ugmN8YqWAhD2RORgR+3iNXYG4U2PFd1E= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= +github.com/libp2p/go-libp2p-swarm v0.5.3 h1:hsYaD/y6+kZff1o1Mc56NcuwSg80lIphTS/zDk3mO4M= +github.com/libp2p/go-libp2p-swarm v0.5.3/go.mod h1:NBn7eNW2lu568L7Ns9wdFrOhgRlkRnIDg0FLKbuu3i8= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -1063,8 +1079,9 @@ github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eq github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= -github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.4.2 h1:IOiA5mMigi+eEjf4J+B7fepDhsjtsoWA9QbsCqbNp5U= +github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= @@ -1075,8 +1092,9 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2 github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 h1:4JsnbfJzgZeRS9AWN7B9dPqn/LY/HoQTlO9gtdJTIYM= github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.6 h1:SHt3g0FslnqIkEWF25YOB8UCOCTpGAVvHRWQYJ+veiI= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.6/go.mod h1:JE0WQuQdy+uLZ5zOaI3Nw9dWGYJIA7mywEtP2lMvnyk= github.com/libp2p/go-libp2p-yamux v0.5.1 h1:sX4WQPHMhRxJE5UZTfjEuBvlQWXB5Bo3A2JK9ZJ9EM0= github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= @@ -1105,6 +1123,7 @@ github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= @@ -1119,8 +1138,9 @@ github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQy github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= -github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM= github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= +github.com/libp2p/go-reuseport-transport v0.0.5 h1:lJzi+vSYbyJj2faPKLxNGWEIBcaV/uJmyvsUxXy2mLw= +github.com/libp2p/go-reuseport-transport v0.0.5/go.mod h1:TC62hhPc8qs5c/RoXDZG6YmjK+/YWUPC0yYmeUecbjc= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= @@ -1136,8 +1156,9 @@ github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19 github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= -github.com/libp2p/go-tcp-transport v0.2.1 h1:ExZiVQV+h+qL16fzCWtd1HSzPsqWottJ8KXwWaVi8Ns= github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M= +github.com/libp2p/go-tcp-transport v0.2.7 h1:Z8Kc/Kb8tD84WiaH55xAlaEnkqzrp88jSEySCKV4+gg= +github.com/libp2p/go-tcp-transport v0.2.7/go.mod h1:lue9p1b3VmZj1MhhEGB/etmvF/nBQ0X9CW2DutBT3MM= github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-ws-transport v0.0.1/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww= @@ -1158,8 +1179,9 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.16.0/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE= -github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= +github.com/lucas-clemente/quic-go v0.21.2 h1:8LqqL7nBQFDUINadW0fHV/xSaCQJgmJC0Gv+qUnjd78= +github.com/lucas-clemente/quic-go v0.21.2/go.mod h1:vF5M1XqhBAHgbjKcJOXY3JZz3GP0T3FQhz/uyOUS38Q= github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= @@ -1177,10 +1199,17 @@ github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGD github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= github.com/marten-seemann/qtls v0.9.1/go.mod h1:T1MmAdDPyISzxlK6kjRr0pcZFBVd1OZbBb/j3cvzHhk= -github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc= github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= -github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-15 v0.1.5 h1:Ci4EIUN6Rlb+D6GmLdej/bCQ4nPYNtVXQB+xjiXE1nk= +github.com/marten-seemann/qtls-go1-15 v0.1.5/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco= +github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1 h1:/rpmWuGvceLwwWuaKPdjpR4JJEUH0tq64/I3hvzaNLM= +github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1217,6 +1246,12 @@ github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7 github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -1258,8 +1293,9 @@ github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y9 github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= -github.com/multiformats/go-multiaddr v0.3.1 h1:1bxa+W7j9wZKTZREySx1vPMs2TqrYWjVZ7zE6/XLG1I= github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= +github.com/multiformats/go-multiaddr v0.3.3 h1:vo2OTSAqnENB2rLk79pLtr+uhj+VAzSe3uef5q0lRSs= +github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= @@ -1307,6 +1343,7 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -1321,8 +1358,9 @@ github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c h1:5bFTChQxSKNwy github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c/go.mod h1:7qN3Y0BvzRUf4LofcoJplQL10lsFDb4PYlePTVwrP28= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -1332,16 +1370,19 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 h1:CznVS40zms0Dj5he4ERo+fRPtO0qxUk8lA8Xu3ddet0= github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333/go.mod h1:Ag6rSXkHIckQmjFBCweJEEt1mrTPBv8b9W4aU/NQWfI= @@ -1392,8 +1433,11 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A= github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1408,8 +1452,10 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/node_exporter v1.0.0-rc.0.0.20200428091818-01054558c289/go.mod h1:FGbBv5OPKjch+jNUJmEQpMZytIdyW0NdBtWFcfSKusc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1420,8 +1466,11 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.1.0 h1:jhMy6QXfi3y2HEzFoyuCj40z4OZIIHHPtFyCMftmvKA= github.com/prometheus/procfs v0.1.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= github.com/raulk/go-watchdog v1.0.1 h1:qgm3DIJAeb+2byneLrQJ7kvmDLGxN2vy3apXyGaDKN4= @@ -1663,8 +1712,9 @@ go.uber.org/dig v1.10.0 h1:yLmDDj9/zuDjv3gz8GQGviXMs9TfysIUMUilCpgzUJY= go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= go.uber.org/fx v1.9.0 h1:7OAz8ucp35AU8eydejpYG7QrbE8rLKzGhHbZlJi5LYY= go.uber.org/fx v1.9.0/go.mod h1:mFdUyAUuJ3w4jAckiKSKbldsxy1ojpAMJ+dVZg5Y0Aw= -go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -1716,8 +1766,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf h1:B2n+Zi5QeYRDAEodEu72OS36gmTWjgpXr2+cWcBW90o= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1800,10 +1851,13 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 h1:0PC75Fz/kyMGhL0e1QnypqK2kQMqKt9csD1GnMJR+Zk= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1821,6 +1875,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1886,17 +1941,25 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q= +golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= @@ -1955,7 +2018,9 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200711155855-7342f9734a7d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201112185108-eeaa07dd7696/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2037,8 +2102,10 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2065,8 +2132,9 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= From c25ed49f0d85253e534612d2e1e14fa499fb72c4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 11:49:42 +0300 Subject: [PATCH 41/79] code cosmetics: rename variables for better readability and some comments --- blockstore/badger/blockstore.go | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index a0b51d8df61..5f22e3ae89d 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -355,7 +355,7 @@ func (b *Blockstore) movingGC() error { panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbPath, backupPath, err)) //nolint } - if err = symlink(newPath, dbPath); err != nil { + if err = os.Symlink(newPath, dbPath); err != nil { // same here; the db path is pointing to the void. panic and let the user fix. panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", newPath, dbPath, err)) //nolint } @@ -367,26 +367,6 @@ func (b *Blockstore) movingGC() error { return nil } -// symlink creates a symlink from path to linkTo; the link is relative if the two are -// in the same directory -func symlink(path, linkTo string) error { - resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) - if err != nil { - return fmt.Errorf("error resolving links in %s: %w", path, err) - } - - resolvedLinkDir, err := filepath.EvalSymlinks(filepath.Dir(linkTo)) - if err != nil { - return fmt.Errorf("error resolving links in %s: %w", linkTo, err) - } - - if resolvedPathDir == resolvedLinkDir { - path = filepath.Base(path) - } - - return os.Symlink(path, linkTo) -} - // doCopy copies a badger blockstore to another, with an optional filter; if the filter // is not nil, then only cids that satisfy the filter will be copied. func (b *Blockstore) doCopy(from, to *badger.DB) error { @@ -982,4 +962,4 @@ func (b *Blockstore) StorageKey(dst []byte, cid cid.Cid) []byte { // WARNING: THIS IS COMPLETELY UNSAFE; DONT USE THIS IN PRODUCTION CODE func (b *Blockstore) DB() *badger.DB { return b.db -} +} \ No newline at end of file From 21b1059ba504b58d213384533d5657014c8f1b6d Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 11:56:23 +0300 Subject: [PATCH 42/79] make relative links when the canonical and new db paths are in the same directory --- blockstore/badger/blockstore.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 5f22e3ae89d..16d02a4f917 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -355,7 +355,7 @@ func (b *Blockstore) movingGC() error { panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbPath, backupPath, err)) //nolint } - if err = os.Symlink(newPath, dbPath); err != nil { + if err = b.symlink(newPath, dbPath); err != nil { // same here; the db path is pointing to the void. panic and let the user fix. panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", newPath, dbPath, err)) //nolint } @@ -367,6 +367,18 @@ func (b *Blockstore) movingGC() error { return nil } +// symlink creates a symlink from path to linkPath; the link is relative if the two are +// in the same directory +func (b *Blockstore) symlink(path, linkTo string) error { + pathDir := filepath.Dir(path) + linkDir := filepath.Dir(linkTo) + if pathDir == linkDir { + path = filepath.Base(path) + } + + return os.Symlink(path, linkTo) +} + // doCopy copies a badger blockstore to another, with an optional filter; if the filter // is not nil, then only cids that satisfy the filter will be copied. func (b *Blockstore) doCopy(from, to *badger.DB) error { From 18eadd338ebdc930fb842a80fecc303e6ada9b50 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 11:56:35 +0300 Subject: [PATCH 43/79] extend test to check the validity of relative links From b46b26f1aea6372d4e596fd3d912afaf54c2e221 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 16:15:39 +0300 Subject: [PATCH 44/79] improve detection of relative links --- blockstore/badger/blockstore.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 16d02a4f917..a02c7544e56 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -370,9 +370,17 @@ func (b *Blockstore) movingGC() error { // symlink creates a symlink from path to linkPath; the link is relative if the two are // in the same directory func (b *Blockstore) symlink(path, linkTo string) error { - pathDir := filepath.Dir(path) - linkDir := filepath.Dir(linkTo) - if pathDir == linkDir { + resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) + if err != nil { + return fmt.Errorf("error resolving links in %s: %w", path, err) + } + + resolvedLinkDir, err := filepath.EvalSymlinks(filepath.Dir(linkTo)) + if err != nil { + return fmt.Errorf("error resolving links in %s: %W", linkTo, err) + } + + if resolvedPathDir == resolvedLinkDir { path = filepath.Base(path) } From 73c161a29570f44093c4dd8655436b23afc633ec Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 16:20:25 +0300 Subject: [PATCH 45/79] fix format specifier --- blockstore/badger/blockstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index a02c7544e56..2e34f724d8e 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -377,7 +377,7 @@ func (b *Blockstore) symlink(path, linkTo string) error { resolvedLinkDir, err := filepath.EvalSymlinks(filepath.Dir(linkTo)) if err != nil { - return fmt.Errorf("error resolving links in %s: %W", linkTo, err) + return fmt.Errorf("error resolving links in %s: %w", linkTo, err) } if resolvedPathDir == resolvedLinkDir { From 9133f819e06e6d5076a46eac1c01ffa4db536321 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 28 Jul 2021 17:11:04 +0300 Subject: [PATCH 46/79] fix typo Co-authored-by: Jakub Sztandera --- blockstore/badger/blockstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 2e34f724d8e..b537364ab60 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -367,7 +367,7 @@ func (b *Blockstore) movingGC() error { return nil } -// symlink creates a symlink from path to linkPath; the link is relative if the two are +// symlink creates a symlink from path to linkTo; the link is relative if the two are // in the same directory func (b *Blockstore) symlink(path, linkTo string) error { resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) From 2b5bcfdb7f5685a01238fcf1c091fca96aa75da6 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 29 Jul 2021 08:35:53 +0300 Subject: [PATCH 47/79] make symlink helper freestanding --- blockstore/badger/blockstore.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index b537364ab60..59fd18d1af4 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -355,7 +355,7 @@ func (b *Blockstore) movingGC() error { panic(fmt.Errorf("error renaming old badger db dir from %s to %s: %w; USER ACTION REQUIRED", dbPath, backupPath, err)) //nolint } - if err = b.symlink(newPath, dbPath); err != nil { + if err = symlink(newPath, dbPath); err != nil { // same here; the db path is pointing to the void. panic and let the user fix. panic(fmt.Errorf("error symlinking new badger db dir from %s to %s: %w; USER ACTION REQUIRED", newPath, dbPath, err)) //nolint } @@ -369,7 +369,7 @@ func (b *Blockstore) movingGC() error { // symlink creates a symlink from path to linkTo; the link is relative if the two are // in the same directory -func (b *Blockstore) symlink(path, linkTo string) error { +func symlink(path, linkTo string) error { resolvedPathDir, err := filepath.EvalSymlinks(filepath.Dir(path)) if err != nil { return fmt.Errorf("error resolving links in %s: %w", path, err) From 0d0652750796dc956d52c4cc936f6d2f70d380ec Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 29 Jul 2021 15:28:08 +0530 Subject: [PATCH 48/79] more logging in data transfer and markets --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 6c20ebbe9fb..f54cfedfaf2 100644 --- a/go.mod +++ b/go.mod @@ -33,10 +33,10 @@ require ( github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 - github.com/filecoin-project/go-data-transfer v1.7.1 + github.com/filecoin-project/go-data-transfer v1.7.2 github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.6.1 + github.com/filecoin-project/go-fil-markets v1.6.2 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 diff --git a/go.sum b/go.sum index ca71b27d2d8..71769207d0d 100644 --- a/go.sum +++ b/go.sum @@ -277,8 +277,8 @@ github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMX github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ= github.com/filecoin-project/go-data-transfer v1.0.1/go.mod h1:UxvfUAY9v3ub0a21BSK9u3pB2aq30Y0KMsG+w9/ysyo= github.com/filecoin-project/go-data-transfer v1.7.0/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= -github.com/filecoin-project/go-data-transfer v1.7.1 h1:Co4bTenvCc3WnOhQWyXRt59FLZvxwH8UeF0ZCOc1ik0= -github.com/filecoin-project/go-data-transfer v1.7.1/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= +github.com/filecoin-project/go-data-transfer v1.7.2 h1:iL3q5pxSloA7V2QucFofoVN3lquULz+Ml0KrNqMT5ZU= +github.com/filecoin-project/go-data-transfer v1.7.2/go.mod h1:GLRr5BmLEqsLwXfiRDG7uJvph22KGL2M4iOuF8EINaU= github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= @@ -288,8 +288,8 @@ github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+ github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.6.1 h1:8xdFyWrELfOzwcGa229bLu/olD+1l4sEWFIsZR7oz5U= -github.com/filecoin-project/go-fil-markets v1.6.1/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= +github.com/filecoin-project/go-fil-markets v1.6.2 h1:ib1sGUOF+hf50YwP7+p9yoK+9g84YcXzvuenxd6MYoE= +github.com/filecoin-project/go-fil-markets v1.6.2/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= From 7b1a82a3ccc1952c9d762eb93226ccd2a910085d Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Thu, 29 Jul 2021 20:04:50 +0530 Subject: [PATCH 49/79] update deps for logging --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f54cfedfaf2..d5a18fd3225 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 - github.com/filecoin-project/go-statemachine v1.0.0 + github.com/filecoin-project/go-statemachine v1.0.1 github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.14 diff --git a/go.sum b/go.sum index 71769207d0d..6815cfa9881 100644 --- a/go.sum +++ b/go.sum @@ -315,8 +315,8 @@ github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48/ github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 h1:veGrNABg/9I7prngrowkhwbvW5d5JN55MNKmbsr5FqA= github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= -github.com/filecoin-project/go-statemachine v1.0.0 h1:b8FpFewPSklyAIUqH0oHt4nvKf03bU7asop1bJpjAtQ= -github.com/filecoin-project/go-statemachine v1.0.0/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= +github.com/filecoin-project/go-statemachine v1.0.1 h1:LQ60+JDVjMdLxXmVFM2jjontzOYnfVE7u02CXV3WKSw= +github.com/filecoin-project/go-statemachine v1.0.1/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= github.com/filecoin-project/go-statestore v0.1.1 h1:ufMFq00VqnT2CAuDpcGnwLnCX1I/c3OROw/kXVNSTZk= github.com/filecoin-project/go-statestore v0.1.1/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI= From 22461f30e9f7a06ca5dcaa51c6075acde4a344c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 10:55:37 +0100 Subject: [PATCH 50/79] support MARKETS_API_INFO env var; support markets-repo, markets-api-url flags. --- cli/auth.go | 4 +-- cli/cmd.go | 5 ++- cli/util/api.go | 86 +++++++++++++------------------------------------ 3 files changed, 26 insertions(+), 69 deletions(-) diff --git a/cli/auth.go b/cli/auth.go index 286eb978bbf..ccf5dcc8bf8 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -113,7 +113,7 @@ var AuthApiInfoToken = &cli.Command{ ti, ok := cctx.App.Metadata["repoType"] if !ok { - log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?") + log.Errorf("unknown repo type, are you sure you want to use GetAPI?") ti = repo.FullNode } t, ok := ti.(repo.RepoType) @@ -128,7 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - currentEnv, _, _ := cliutil.EnvsForAPIInfos(t) + currentEnv, _ := cliutil.EnvsForRepo(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil }, diff --git a/cli/cmd.go b/cli/cmd.go index 7e4a7636c36..bbbf55be663 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -44,7 +44,7 @@ func GetFullNodeServices(ctx *cli.Context) (ServicesAPI, error) { var GetAPIInfo = cliutil.GetAPIInfo var GetRawAPI = cliutil.GetRawAPI -var GetAPI = cliutil.GetCommonAPI +var GetAPI = cliutil.GetAPI var DaemonContext = cliutil.DaemonContext var ReqContext = cliutil.ReqContext @@ -54,7 +54,6 @@ var GetFullNodeAPIV1 = cliutil.GetFullNodeAPIV1 var GetGatewayAPI = cliutil.GetGatewayAPI var GetStorageMinerAPI = cliutil.GetStorageMinerAPI -var GetMarketsAPI = cliutil.GetMarketsAPI var GetWorkerAPI = cliutil.GetWorkerAPI var CommonCommands = []*cli.Command{ @@ -91,4 +90,4 @@ var Commands = []*cli.Command{ func WithCategory(cat string, cmd *cli.Command) *cli.Command { cmd.Category = strings.ToUpper(cat) return cmd -} +} \ No newline at end of file diff --git a/cli/util/api.go b/cli/util/api.go index 207283fd102..fca667b5ac9 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -2,7 +2,6 @@ package cliutil import ( "context" - "errors" "fmt" "net/http" "net/url" @@ -28,9 +27,9 @@ const ( metadataTraceContext = "traceContext" ) -// flagsForAPI returns flags passed on the command line with the listen address -// of the API server (only used by the tests), in the order of precedence they -// should be applied for the requested kind of node. +// The flags passed on the command line with the listen address of the API +// server (only used by the tests), in the order of precedence they should be +// applied for the requested kind of node. func flagsForAPI(t repo.RepoType) []string { switch t { case repo.FullNode: @@ -63,23 +62,23 @@ func flagsForRepo(t repo.RepoType) []string { } } -// EnvsForAPIInfos returns the environment variables to use in order of precedence +// EnvsForRepo returns the environment variables to use in order of precedence // to determine the API endpoint of the specified node type. // // It returns the current variables and deprecated ones separately, so that // the user can log a warning when deprecated ones are found to be in use. -func EnvsForAPIInfos(t repo.RepoType) (primary string, fallbacks []string, deprecated []string) { +func EnvsForRepo(t repo.RepoType) (current []string, deprecated []string) { switch t { case repo.FullNode: - return "FULLNODE_API_INFO", nil, nil + return []string{"FULLNODE_API_INFO"}, nil case repo.StorageMiner: // TODO remove deprecated deprecation period - return "MINER_API_INFO", nil, []string{"STORAGE_API_INFO"} + return []string{"MINER_API_INFO"}, []string{"STORAGE_API_INFO"} case repo.Worker: - return "WORKER_API_INFO", nil, nil + return []string{"WORKER_API_INFO"}, nil case repo.Markets: // support split markets-miner and monolith deployments. - return "MARKETS_API_INFO", []string{"MINER_API_INFO"}, nil + return []string{"MARKETS_API_INFO, MINER_API_INFO"}, nil default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } @@ -107,33 +106,29 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { return APIInfo{Addr: strma}, nil } - // - // Note: it is not correct/intuitive to prefer environment variables over - // CLI flags (repo flags below). - // - primaryEnv, fallbacksEnvs, deprecatedEnvs := EnvsForAPIInfos(t) - env, ok := os.LookupEnv(primaryEnv) - if ok { - return ParseApiInfo(env), nil + currentEnv, deprecatedEnv := EnvsForRepo(t) + for _, env := range currentEnv { + env, ok := os.LookupEnv(env) + if ok { + return ParseApiInfo(env), nil + } } - for _, env := range deprecatedEnvs { + for _, env := range deprecatedEnv { env, ok := os.LookupEnv(env) if ok { - log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, primaryEnv) + log.Warnf("Use deprecation env(%s) value, please use env(%s) instead.", env, currentEnv) return ParseApiInfo(env), nil } } repoFlags := flagsForRepo(t) for _, f := range repoFlags { - // cannot use ctx.IsSet because it ignores default values - path := ctx.String(f) - if path == "" { + if !ctx.IsSet(f) { continue } - p, err := homedir.Expand(path) + p, err := homedir.Expand(ctx.String(f)) if err != nil { return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err) } @@ -143,15 +138,6 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) } - exists, err := r.Exists() - if err != nil { - return APIInfo{}, xerrors.Errorf("repo.Exists returned an error: %w", err) - } - - if !exists { - return APIInfo{}, errors.New("repo directory does not exist. Make sure your configuration is correct") - } - ma, err := r.APIEndpoint() if err != nil { return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) @@ -168,14 +154,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } - for _, env := range fallbacksEnvs { - env, ok := os.LookupEnv(env) - if ok { - return ParseApiInfo(env), nil - } - } - - return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t) + return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %s", t) } func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { @@ -196,10 +175,10 @@ func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http. return addr, ainfo.AuthHeader(), nil } -func GetCommonAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { +func GetAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { ti, ok := ctx.App.Metadata["repoType"] if !ok { - log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?") + log.Errorf("unknown repo type, are you sure you want to use GetAPI?") ti = repo.FullNode } t, ok := ti.(repo.RepoType) @@ -317,27 +296,6 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { return client.NewWorkerRPCV0(ctx.Context, addr, headers) } -func GetMarketsAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) { - // to support lotus-miner cli tests. - if tn, ok := ctx.App.Metadata["testnode-storage"]; ok { - return tn.(api.StorageMiner), func() {}, nil - } - - addr, headers, err := GetRawAPI(ctx, repo.Markets, "v0") - if err != nil { - return nil, nil, err - } - - if IsVeryVerbose { - _, _ = fmt.Fprintln(ctx.App.Writer, "using markets API v0 endpoint:", addr) - } - - // the markets node is a specialised miner's node, supporting only the - // markets API, which is a subset of the miner API. All non-markets - // operations will error out with "unsupported". - return client.NewStorageMinerRPCV0(ctx.Context, addr, headers) -} - func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") if err != nil { From a1aed960a9a149e7fb5e492ce78fbb69af5436c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 12:37:29 +0100 Subject: [PATCH 51/79] target markets API for markets commands. --- cli/auth.go | 3 ++- cli/cmd.go | 3 ++- cli/util/api.go | 20 ++++++++++++++++++-- cmd/lotus-miner/dagstore.go | 30 ++++++++++++++++++++++++++++++ cmd/lotus-miner/main.go | 22 +++++++--------------- 5 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 cmd/lotus-miner/dagstore.go diff --git a/cli/auth.go b/cli/auth.go index ccf5dcc8bf8..88cbdbb66e1 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -113,7 +113,7 @@ var AuthApiInfoToken = &cli.Command{ ti, ok := cctx.App.Metadata["repoType"] if !ok { - log.Errorf("unknown repo type, are you sure you want to use GetAPI?") + log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?") ti = repo.FullNode } t, ok := ti.(repo.RepoType) @@ -128,6 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented + // WARN: this is unable to tell currentEnv, _ := cliutil.EnvsForRepo(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil diff --git a/cli/cmd.go b/cli/cmd.go index bbbf55be663..9ad2e120582 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -44,7 +44,7 @@ func GetFullNodeServices(ctx *cli.Context) (ServicesAPI, error) { var GetAPIInfo = cliutil.GetAPIInfo var GetRawAPI = cliutil.GetRawAPI -var GetAPI = cliutil.GetAPI +var GetAPI = cliutil.GetCommonAPI var DaemonContext = cliutil.DaemonContext var ReqContext = cliutil.ReqContext @@ -54,6 +54,7 @@ var GetFullNodeAPIV1 = cliutil.GetFullNodeAPIV1 var GetGatewayAPI = cliutil.GetGatewayAPI var GetStorageMinerAPI = cliutil.GetStorageMinerAPI +var GetMarketsAPI = cliutil.GetMarketsAPI var GetWorkerAPI = cliutil.GetWorkerAPI var CommonCommands = []*cli.Command{ diff --git a/cli/util/api.go b/cli/util/api.go index fca667b5ac9..76289ec7cd2 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -175,10 +175,10 @@ func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http. return addr, ainfo.AuthHeader(), nil } -func GetAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { +func GetCommonAPI(ctx *cli.Context) (api.CommonNet, jsonrpc.ClientCloser, error) { ti, ok := ctx.App.Metadata["repoType"] if !ok { - log.Errorf("unknown repo type, are you sure you want to use GetAPI?") + log.Errorf("unknown repo type, are you sure you want to use GetCommonAPI?") ti = repo.FullNode } t, ok := ti.(repo.RepoType) @@ -296,6 +296,22 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { return client.NewWorkerRPCV0(ctx.Context, addr, headers) } +func GetMarketsAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) { + addr, headers, err := GetRawAPI(ctx, repo.Markets, "v0") + if err != nil { + return nil, nil, err + } + + if IsVeryVerbose { + _, _ = fmt.Fprintln(ctx.App.Writer, "using markets API v0 endpoint:", addr) + } + + // the markets node is a specialised miner's node, supporting only the + // markets API, which is a subset of the miner API. All non-markets + // operations will error out with "unsupported". + return client.NewStorageMinerRPCV0(ctx.Context, addr, headers) +} + func GetGatewayAPI(ctx *cli.Context) (api.Gateway, jsonrpc.ClientCloser, error) { addr, headers, err := GetRawAPI(ctx, repo.FullNode, "v1") if err != nil { diff --git a/cmd/lotus-miner/dagstore.go b/cmd/lotus-miner/dagstore.go new file mode 100644 index 00000000000..a50d99d99bd --- /dev/null +++ b/cmd/lotus-miner/dagstore.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/urfave/cli/v2" +) + +var dagstoreCmd = &cli.Command{ + Name: "dagstore", + Usage: "Manage the DAG store", + Subcommands: []*cli.Command{ + dagstoreListShardsCmd, + dagstoreGarbageCollectCmd, + }, +} + +var dagstoreListShardsCmd = &cli.Command{ + Name: "list-shards", + Usage: "List shards known to the DAG store", + Action: func(cctx *cli.Context) error { + return nil + }, +} + +var dagstoreGarbageCollectCmd = &cli.Command{ + Name: "gc", + Usage: "Garbage collect the DAG store", + Action: func(cctx *cli.Context) error { + return nil + }, +} diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 2916fce1fc0..1d85f30708e 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -22,10 +22,7 @@ import ( var log = logging.Logger("main") -const ( - FlagMinerRepo = "miner-repo" - FlagMarketsRepo = "markets-repo" -) +const FlagMinerRepo = "miner-repo" // TODO remove after deprecation period const FlagMinerRepoDeprecation = "storagerepo" @@ -79,10 +76,10 @@ func main() { } app := &cli.App{ - Name: "lotus-miner", - Usage: "Filecoin decentralized storage network miner", - Version: build.UserVersion(), - EnableBashCompletion: true, + Name: "lotus-miner", + Usage: "Filecoin decentralized storage network miner", + Version: build.UserVersion(), + Commands: append(local, lcli.CommonCommands...), Flags: []cli.Flag{ &cli.StringFlag{ Name: "actor", @@ -109,18 +106,13 @@ func main() { Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME Usage: fmt.Sprintf("Specify miner repo path. flag(%s) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON", FlagMinerRepoDeprecation), }, - &cli.StringFlag{ - Name: FlagMarketsRepo, - EnvVars: []string{"LOTUS_MARKETS_PATH"}, - Usage: fmt.Sprintf("Markets repo path"), - }, &cli.BoolFlag{ Name: "call-on-markets", Usage: "(experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous", }, cliutil.FlagVeryVerbose, }, - Commands: append(local, lcli.CommonCommands...), + EnableBashCompletion: true, Before: func(c *cli.Context) error { // this command is explicitly called on markets, inform // common commands by overriding the repoType. @@ -156,4 +148,4 @@ func getActorAddress(ctx context.Context, cctx *cli.Context) (maddr address.Addr } return maddr, nil -} +} \ No newline at end of file From 2c9edb1d1aaa8b7dcf259d05becfdbc5249a493d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 12:51:26 +0100 Subject: [PATCH 52/79] refactor miner info command. --- cli/auth.go | 1 - cmd/lotus-miner/dagstore.go | 30 ------------------------------ cmd/lotus-miner/info.go | 35 ++++++++++++++++++++++------------- 3 files changed, 22 insertions(+), 44 deletions(-) delete mode 100644 cmd/lotus-miner/dagstore.go diff --git a/cli/auth.go b/cli/auth.go index 88cbdbb66e1..33b0d25c880 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,6 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - // WARN: this is unable to tell currentEnv, _ := cliutil.EnvsForRepo(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil diff --git a/cmd/lotus-miner/dagstore.go b/cmd/lotus-miner/dagstore.go deleted file mode 100644 index a50d99d99bd..00000000000 --- a/cmd/lotus-miner/dagstore.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "github.com/urfave/cli/v2" -) - -var dagstoreCmd = &cli.Command{ - Name: "dagstore", - Usage: "Manage the DAG store", - Subcommands: []*cli.Command{ - dagstoreListShardsCmd, - dagstoreGarbageCollectCmd, - }, -} - -var dagstoreListShardsCmd = &cli.Command{ - Name: "list-shards", - Usage: "List shards known to the DAG store", - Action: func(cctx *cli.Context) error { - return nil - }, -} - -var dagstoreGarbageCollectCmd = &cli.Command{ - Name: "gc", - Usage: "Garbage collect the DAG store", - Action: func(cctx *cli.Context) error { - return nil - }, -} diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 878361dacb6..67f8180b725 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -50,7 +50,13 @@ var infoCmd = &cli.Command{ } func infoCmdAct(cctx *cli.Context) error { - nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + minerApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + + marketsApi, closer, err := lcli.GetMarketsAPI(cctx) if err != nil { return err } @@ -64,12 +70,19 @@ func infoCmdAct(cctx *cli.Context) error { ctx := lcli.ReqContext(cctx) - subsystems, err := nodeApi.RuntimeSubsystems(ctx) + subsystems, err := minerApi.RuntimeSubsystems(ctx) + if err != nil { + return err + } + + fmt.Println("Enabled subsystems (from miner API):", subsystems) + + subsystems, err = marketsApi.RuntimeSubsystems(ctx) if err != nil { return err } - fmt.Println("Enabled subsystems:", subsystems) + fmt.Println("Enabled subsystems (from markets API):", subsystems) fmt.Print("Chain: ") @@ -103,18 +116,14 @@ func infoCmdAct(cctx *cli.Context) error { fmt.Println() - if subsystems.Has(api.SubsystemSectorStorage) { - err := handleMiningInfo(ctx, cctx, fullapi, nodeApi) - if err != nil { - return err - } + err = handleMiningInfo(ctx, cctx, fullapi, minerApi) + if err != nil { + return err } - if subsystems.Has(api.SubsystemMarkets) { - err := handleMarketsInfo(ctx, nodeApi) - if err != nil { - return err - } + err = handleMarketsInfo(ctx, marketsApi) + if err != nil { + return err } return nil From 43d48f37b6e52b3a71839c53abb916299225bec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 12:54:23 +0100 Subject: [PATCH 53/79] polish. --- cli/util/api.go | 6 +++--- cmd/lotus-miner/main.go | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index 76289ec7cd2..4ddaac88a22 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -27,9 +27,9 @@ const ( metadataTraceContext = "traceContext" ) -// The flags passed on the command line with the listen address of the API -// server (only used by the tests), in the order of precedence they should be -// applied for the requested kind of node. +// flagsForAPI returns flags passed on the command line with the listen address +// of the API server (only used by the tests), in the order of precedence they +// should be applied for the requested kind of node. func flagsForAPI(t repo.RepoType) []string { switch t { case repo.FullNode: diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 1d85f30708e..28bc3e63780 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -76,10 +76,10 @@ func main() { } app := &cli.App{ - Name: "lotus-miner", - Usage: "Filecoin decentralized storage network miner", - Version: build.UserVersion(), - Commands: append(local, lcli.CommonCommands...), + Name: "lotus-miner", + Usage: "Filecoin decentralized storage network miner", + Version: build.UserVersion(), + EnableBashCompletion: true, Flags: []cli.Flag{ &cli.StringFlag{ Name: "actor", @@ -112,7 +112,7 @@ func main() { }, cliutil.FlagVeryVerbose, }, - EnableBashCompletion: true, + Commands: append(local, lcli.CommonCommands...), Before: func(c *cli.Context) error { // this command is explicitly called on markets, inform // common commands by overriding the repoType. From 1527ed46bc38a929850e838c690831a3afebdf92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 13:21:55 +0100 Subject: [PATCH 54/79] fix tests. --- cli/util/api.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index 4ddaac88a22..4413fd3bb86 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -117,7 +117,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { for _, env := range deprecatedEnv { env, ok := os.LookupEnv(env) if ok { - log.Warnf("Use deprecation env(%s) value, please use env(%s) instead.", env, currentEnv) + log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, currentEnv) return ParseApiInfo(env), nil } } @@ -125,6 +125,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { if !ctx.IsSet(f) { + fmt.Println("not set", f) continue } @@ -154,7 +155,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } - return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %s", t) + return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t) } func GetRawAPI(ctx *cli.Context, t repo.RepoType, version string) (string, http.Header, error) { @@ -297,6 +298,11 @@ func GetWorkerAPI(ctx *cli.Context) (api.Worker, jsonrpc.ClientCloser, error) { } func GetMarketsAPI(ctx *cli.Context) (api.StorageMiner, jsonrpc.ClientCloser, error) { + // to support lotus-miner cli tests. + if tn, ok := ctx.App.Metadata["testnode-storage"]; ok { + return tn.(api.StorageMiner), func() {}, nil + } + addr, headers, err := GetRawAPI(ctx, repo.Markets, "v0") if err != nil { return nil, nil, err From a94ab050bf79eaef2f127964e0e46c4ac6bd008f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 13:38:08 +0100 Subject: [PATCH 55/79] fix docs, add flag. --- cli/util/api.go | 1 - cmd/lotus-miner/main.go | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cli/util/api.go b/cli/util/api.go index 4413fd3bb86..c6e3ae9be2f 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -125,7 +125,6 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { if !ctx.IsSet(f) { - fmt.Println("not set", f) continue } diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 28bc3e63780..3e413c6a6ff 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -23,6 +23,7 @@ import ( var log = logging.Logger("main") const FlagMinerRepo = "miner-repo" +const FlagMarketsRepo = "markets-repo" // TODO remove after deprecation period const FlagMinerRepoDeprecation = "storagerepo" @@ -106,6 +107,11 @@ func main() { Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME Usage: fmt.Sprintf("Specify miner repo path. flag(%s) and env(LOTUS_STORAGE_PATH) are DEPRECATION, will REMOVE SOON", FlagMinerRepoDeprecation), }, + &cli.StringFlag{ + Name: FlagMarketsRepo, + EnvVars: []string{"LOTUS_MARKETS_PATH"}, + Usage: fmt.Sprintf("Markets repo path"), + }, &cli.BoolFlag{ Name: "call-on-markets", Usage: "(experimental; may be removed) call this command against a markets node; use only with common commands like net, auth, pprof, etc. whose target may be ambiguous", From 3733fa9cc2ed4faef120b9095c9d4d72844b8efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 13:49:47 +0100 Subject: [PATCH 56/79] add RepoType#String; adjust repo parsing logic. --- cli/util/api.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/util/api.go b/cli/util/api.go index c6e3ae9be2f..bf34f4421d7 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -124,7 +124,9 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { - if !ctx.IsSet(f) { + // cannot use ctx.IsSet because it ignores default values + f := ctx.String(f) + if f == "" { continue } From 23cd561f2e51171251e5f9d6bf2231669747dd5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 14:36:04 +0100 Subject: [PATCH 57/79] bugfix. --- cli/util/api.go | 8 ++++---- cmd/lotus-miner/info.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cli/util/api.go b/cli/util/api.go index bf34f4421d7..766969dfabf 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -78,7 +78,7 @@ func EnvsForRepo(t repo.RepoType) (current []string, deprecated []string) { return []string{"WORKER_API_INFO"}, nil case repo.Markets: // support split markets-miner and monolith deployments. - return []string{"MARKETS_API_INFO, MINER_API_INFO"}, nil + return []string{"MARKETS_API_INFO", "MINER_API_INFO"}, nil default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } @@ -125,12 +125,12 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { repoFlags := flagsForRepo(t) for _, f := range repoFlags { // cannot use ctx.IsSet because it ignores default values - f := ctx.String(f) - if f == "" { + path := ctx.String(f) + if path == "" { continue } - p, err := homedir.Expand(ctx.String(f)) + p, err := homedir.Expand(path) if err != nil { return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", f, err) } diff --git a/cmd/lotus-miner/info.go b/cmd/lotus-miner/info.go index 67f8180b725..f37952057ff 100644 --- a/cmd/lotus-miner/info.go +++ b/cmd/lotus-miner/info.go @@ -386,6 +386,7 @@ func handleMarketsInfo(ctx context.Context, nodeApi api.StorageMiner) error { return sorted[i].status > sorted[j].status }) + fmt.Println() fmt.Printf("Storage Deals: %d, %s\n", total.count, types.SizeStr(types.NewInt(total.bytes))) tw := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) From 04b358f3406332a7855e76e5199a5822cc08ded4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 16:10:04 +0100 Subject: [PATCH 58/79] use fallback api infos last; init service with markets-path. --- cli/auth.go | 2 +- cli/util/api.go | 37 +++++++++++++++++++++++-------------- cmd/lotus-miner/main.go | 6 ++++-- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/cli/auth.go b/cli/auth.go index 33b0d25c880..342d5e3aa36 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - currentEnv, _ := cliutil.EnvsForRepo(t) + currentEnv, _ := cliutil.EnvsForAPIInfos(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil }, diff --git a/cli/util/api.go b/cli/util/api.go index 766969dfabf..37df41a87ab 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -62,23 +62,23 @@ func flagsForRepo(t repo.RepoType) []string { } } -// EnvsForRepo returns the environment variables to use in order of precedence +// EnvsForAPIInfos returns the environment variables to use in order of precedence // to determine the API endpoint of the specified node type. // // It returns the current variables and deprecated ones separately, so that // the user can log a warning when deprecated ones are found to be in use. -func EnvsForRepo(t repo.RepoType) (current []string, deprecated []string) { +func EnvsForAPIInfos(t repo.RepoType) (primary string, fallbacks []string, deprecated []string) { switch t { case repo.FullNode: - return []string{"FULLNODE_API_INFO"}, nil + return "FULLNODE_API_INFO", nil, nil case repo.StorageMiner: // TODO remove deprecated deprecation period - return []string{"MINER_API_INFO"}, []string{"STORAGE_API_INFO"} + return "MINER_API_INFO", nil, []string{"STORAGE_API_INFO"} case repo.Worker: - return []string{"WORKER_API_INFO"}, nil + return "WORKER_API_INFO", nil, nil case repo.Markets: // support split markets-miner and monolith deployments. - return []string{"MARKETS_API_INFO", "MINER_API_INFO"}, nil + return "MARKETS_API_INFO", []string{"MINER_API_INFO"}, nil default: panic(fmt.Sprintf("Unknown repo type: %v", t)) } @@ -106,18 +106,20 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { return APIInfo{Addr: strma}, nil } - currentEnv, deprecatedEnv := EnvsForRepo(t) - for _, env := range currentEnv { - env, ok := os.LookupEnv(env) - if ok { - return ParseApiInfo(env), nil - } + // + // Note: it is not correct/intuitive to prefer environment variables over + // CLI flags (repo flags below). + // + primaryEnv, fallbacksEnvs, deprecatedEnvs := EnvsForAPIInfos(t) + env, ok := os.LookupEnv(primaryEnv) + if ok { + return ParseApiInfo(env), nil } - for _, env := range deprecatedEnv { + for _, env := range deprecatedEnvs { env, ok := os.LookupEnv(env) if ok { - log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, currentEnv) + log.Warnf("Using deprecated env(%s) value, please use env(%s) instead.", env, primaryEnv) return ParseApiInfo(env), nil } } @@ -156,6 +158,13 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { }, nil } + for _, env := range fallbacksEnvs { + env, ok := os.LookupEnv(env) + if ok { + return ParseApiInfo(env), nil + } + } + return APIInfo{}, fmt.Errorf("could not determine API endpoint for node type: %v", t) } diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 3e413c6a6ff..836e9d97353 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -22,8 +22,10 @@ import ( var log = logging.Logger("main") -const FlagMinerRepo = "miner-repo" -const FlagMarketsRepo = "markets-repo" +const ( + FlagMinerRepo = "miner-repo" + FlagMarketsRepo = "markets-repo" +) // TODO remove after deprecation period const FlagMinerRepoDeprecation = "storagerepo" From 8c326d7badb786bfc86cf756003c578ac5ba8d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 29 Jul 2021 16:18:43 +0100 Subject: [PATCH 59/79] fix compilation error. --- cli/auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/auth.go b/cli/auth.go index 342d5e3aa36..286eb978bbf 100644 --- a/cli/auth.go +++ b/cli/auth.go @@ -128,7 +128,7 @@ var AuthApiInfoToken = &cli.Command{ // TODO: Log in audit log when it is implemented - currentEnv, _ := cliutil.EnvsForAPIInfos(t) + currentEnv, _, _ := cliutil.EnvsForAPIInfos(t) fmt.Printf("%s=%s:%s\n", currentEnv, string(token), ainfo.Addr) return nil }, From 13e9d7c71c1394671b6dd84d0f583cb99e4f542c Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 1 Aug 2021 18:59:43 +0300 Subject: [PATCH 60/79] add lotus-shed splitstore clear command --- cmd/lotus-shed/splitstore.go | 85 ++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index c2363c65583..5e9cebfc209 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -11,6 +11,7 @@ import ( "github.com/dgraph-io/badger/v2" "github.com/urfave/cli/v2" + "go.uber.org/multierr" "golang.org/x/sync/errgroup" "golang.org/x/xerrors" @@ -29,6 +30,7 @@ var splitstoreCmd = &cli.Command{ Description: "splitstore utilities", Subcommands: []*cli.Command{ splitstoreRollbackCmd, + splitstoreClearCmd, splitstoreCheckCmd, splitstoreInfoCmd, }, @@ -118,6 +120,65 @@ var splitstoreRollbackCmd = &cli.Command{ }, } +var splitstoreClearCmd = &cli.Command{ + Name: "clear", + Description: "clears a splitstore installation for restart from snapshot", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + r, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return xerrors.Errorf("error opening fs repo: %w", err) + } + + exists, err := r.Exists() + if err != nil { + return err + } + if !exists { + return xerrors.Errorf("lotus repo doesn't exist") + } + + lr, err := r.Lock(repo.FullNode) + if err != nil { + return xerrors.Errorf("error locking repo: %w", err) + } + defer lr.Close() //nolint:errcheck + + cfg, err := lr.Config() + if err != nil { + return xerrors.Errorf("error getting config: %w", err) + } + + fncfg, ok := cfg.(*config.FullNode) + if !ok { + return xerrors.Errorf("wrong config type: %T", cfg) + } + + if !fncfg.Chainstore.EnableSplitstore { + return xerrors.Errorf("splitstore is not enabled") + } + + fmt.Println("clearing splitstore directory...") + err = clearSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error clearing splitstore directory: %w", err) + } + + fmt.Println("deleting splitstore keys from metadata datastore...") + err = deleteSplitstoreKeys(lr) + if err != nil { + return xerrors.Errorf("error deleting splitstore keys: %w", err) + } + + return nil + }, +} + func copyHotstoreToColdstore(lr repo.LockedRepo, gcColdstore bool) error { repoPath := lr.Path() dataPath := filepath.Join(repoPath, "datastore") @@ -224,6 +285,30 @@ func deleteSplitstoreDir(lr repo.LockedRepo) error { return os.RemoveAll(path) } +func clearSplitstoreDir(lr repo.LockedRepo) error { + path, err := lr.SplitstorePath() + if err != nil { + return xerrors.Errorf("error getting splitstore path: %w", err) + } + + entries, err := os.ReadDir(path) + if err != nil { + return xerrors.Errorf("error reading splitstore directory %s: %W", path, err) + } + + var result error + for _, e := range entries { + target := filepath.Join(path, e.Name()) + err = os.RemoveAll(target) + if err != nil { + log.Errorf("error removing %s: %s", target, err) + result = multierr.Append(result, err) + } + } + + return result +} + func deleteSplitstoreKeys(lr repo.LockedRepo) error { ds, err := lr.Datastore(context.TODO(), "/metadata") if err != nil { From f312ba376cf2ab05e244fb4f4b186ee917b6b818 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 1 Aug 2021 19:01:09 +0300 Subject: [PATCH 61/79] document splitstore clear shed command --- blockstore/splitstore/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/blockstore/splitstore/README.md b/blockstore/splitstore/README.md index 4efd6f61d1d..f69a056ca43 100644 --- a/blockstore/splitstore/README.md +++ b/blockstore/splitstore/README.md @@ -119,6 +119,7 @@ TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577) It can also optionally compact/gc the coldstore after the copy (with the `--gc-coldstore` flag) and automatically rewrite the lotus config to disable splitstore (with the `--rewrite-config` flag). Note: the node *must be stopped* before running this command. +- `clear` -- clears a splitstore installation for restart from snapshot. - `check` -- asynchronously runs a basic healthcheck on the splitstore. The results are appended to `/datastore/splitstore/check.txt`. - `info` -- prints some basic information about the splitstore. From 3983dadf3a8ba059e20d44de8d590c5de81c243d Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 3 Aug 2021 15:32:53 +0300 Subject: [PATCH 62/79] add option to only clear splistore keys --- cmd/lotus-shed/splitstore.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 5e9cebfc209..49d703184c6 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -128,6 +128,10 @@ var splitstoreClearCmd = &cli.Command{ Name: "repo", Value: "~/.lotus", }, + &cli.BoolFlag{ + Name: "keys-only", + Usage: "only delete splitstore keys", + }, }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) @@ -163,10 +167,12 @@ var splitstoreClearCmd = &cli.Command{ return xerrors.Errorf("splitstore is not enabled") } - fmt.Println("clearing splitstore directory...") - err = clearSplitstoreDir(lr) - if err != nil { - return xerrors.Errorf("error clearing splitstore directory: %w", err) + if !cctx.Bool("keys-only") { + fmt.Println("clearing splitstore directory...") + err = clearSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error clearing splitstore directory: %w", err) + } } fmt.Println("deleting splitstore keys from metadata datastore...") From d95fcd55bff5dc0f3d8404de16898f749af87d77 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 3 Aug 2021 15:39:48 +0300 Subject: [PATCH 63/79] clear splitstore dir before deleting, only warn if the latter fails to address situations with symlinks --- cmd/lotus-shed/splitstore.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 49d703184c6..4f668888eaf 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -93,10 +93,16 @@ var splitstoreRollbackCmd = &cli.Command{ return xerrors.Errorf("error copying hotstore to coldstore: %w", err) } + fmt.Println("clearing splitstore directory...") + err = clearSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error clearing splitstore directory: %w", err) + } + fmt.Println("deleting splitstore directory...") err = deleteSplitstoreDir(lr) if err != nil { - return xerrors.Errorf("error deleting splitstore directory: %w", err) + log.Warnf("error deleting splitstore directory: %s", err) } fmt.Println("deleting splitstore keys from metadata datastore...") From 230f81661c8e9d8f387cdb85f450e9770e548f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 12 Aug 2021 11:15:00 +0100 Subject: [PATCH 64/79] make lotus-miner net commands hit markets subsystem. --- cli/cmd.go | 2 +- cmd/lotus-miner/main.go | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cli/cmd.go b/cli/cmd.go index 9ad2e120582..6e5d6a8fbf4 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -58,7 +58,7 @@ var GetMarketsAPI = cliutil.GetMarketsAPI var GetWorkerAPI = cliutil.GetWorkerAPI var CommonCommands = []*cli.Command{ - NetCmd, + // NetCmd: no longer a common command, since lotus-miner nodes without a markets subsystem no longer run a libp2p node AuthCmd, LogCmd, WaitApiCmd, diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 836e9d97353..3c432a962e4 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -5,16 +5,17 @@ import ( "fmt" "github.com/fatih/color" - cliutil "github.com/filecoin-project/lotus/cli/util" logging "github.com/ipfs/go-log/v2" "github.com/urfave/cli/v2" "go.opencensus.io/trace" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" lcli "github.com/filecoin-project/lotus/cli" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/lib/lotuslog" "github.com/filecoin-project/lotus/lib/tracing" "github.com/filecoin-project/lotus/node/repo" @@ -78,6 +79,20 @@ func main() { } } + // adapt the Net* commands to always hit the node running the markets + // subsystem, as that is the only one that runs a libp2p node. + netCmd := *lcli.NetCmd // make a copy. + prev := netCmd.Before + netCmd.Before = func(c *cli.Context) error { + if prev != nil { + if err := prev(c); err != nil { + return err + } + } + c.App.Metadata["repoType"] = repo.Markets + return nil + } + app := &cli.App{ Name: "lotus-miner", Usage: "Filecoin decentralized storage network miner", @@ -120,7 +135,7 @@ func main() { }, cliutil.FlagVeryVerbose, }, - Commands: append(local, lcli.CommonCommands...), + Commands: append(local, append(lcli.CommonCommands, &netCmd)...), Before: func(c *cli.Context) error { // this command is explicitly called on markets, inform // common commands by overriding the repoType. From e23c3b3e7769bc12bab0d0dd8d387a2d30a407f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 12 Aug 2021 15:38:19 +0100 Subject: [PATCH 65/79] remove commented code. --- cli/cmd.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/cmd.go b/cli/cmd.go index 6e5d6a8fbf4..775911f4233 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -58,7 +58,6 @@ var GetMarketsAPI = cliutil.GetMarketsAPI var GetWorkerAPI = cliutil.GetWorkerAPI var CommonCommands = []*cli.Command{ - // NetCmd: no longer a common command, since lotus-miner nodes without a markets subsystem no longer run a libp2p node AuthCmd, LogCmd, WaitApiCmd, From 931cf9342e9d884bf9319b60a8c917939ab17cac Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 9 Aug 2021 12:17:54 +0200 Subject: [PATCH 66/79] WIP: dont panic if input is bad --- chain/actors/version.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/chain/actors/version.go b/chain/actors/version.go index 778fbda9df2..36e8d17b4fd 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -21,19 +21,19 @@ const ( ) // Converts a network version into an actors adt version. -func VersionForNetwork(version network.Version) Version { +func VersionForNetwork(version network.Version) (Version, error) { switch version { case network.Version0, network.Version1, network.Version2, network.Version3: - return Version0 + return Version0, nil case network.Version4, network.Version5, network.Version6, network.Version6AndAHalf, network.Version7, network.Version8, network.Version9: - return Version2 + return Version2, nil case network.Version10, network.Version11: - return Version3 + return Version3, nil case network.Version12: - return Version4 + return Version4, nil case network.Version13: - return Version5 + return Version5, nil default: - panic(fmt.Sprintf("unsupported network version %d", version)) + return -1, fmt.Errorf("unsupported network version %d", version) } } From eaff65c00f3f6eefcaf09d15a79b87b61fc9f012 Mon Sep 17 00:00:00 2001 From: ZenGround0 Date: Tue, 10 Aug 2021 13:07:30 -0400 Subject: [PATCH 67/79] Remove network version panic --- chain/actors/policy/policy.go | 117 ++++++++++-------- chain/gen/genesis/genesis.go | 5 +- chain/gen/genesis/miners.go | 7 +- chain/vm/invoker.go | 5 +- chain/vm/mkactor.go | 7 +- cmd/lotus-miner/sectors.go | 10 +- .../simulation/blockbuilder/blockbuilder.go | 2 +- .../simulation/stages/funding_stage.go | 5 +- .../simulation/stages/provecommit_stage.go | 21 +++- extern/storage-sealing/commit_batch.go | 19 ++- extern/storage-sealing/states_sealing.go | 29 ++++- node/impl/full/multisig.go | 6 +- node/impl/full/state.go | 5 +- paychmgr/paych.go | 6 +- storage/wdpost_run.go | 8 +- 15 files changed, 179 insertions(+), 73 deletions(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index c06c85d380c..0f1ed266c72 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -4,6 +4,7 @@ import ( "sort" "github.com/filecoin-project/go-state-types/big" + "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" @@ -168,31 +169,26 @@ func SetMinVerifiedDealSize(size abi.StoragePower) { } -func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { +func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) (abi.ChainEpoch, error) { switch ver { case actors.Version0: - - return miner0.MaxSealDuration[t] + return miner0.MaxSealDuration[t], nil case actors.Version2: - - return miner2.MaxProveCommitDuration[t] + return miner2.MaxProveCommitDuration[t], nil case actors.Version3: - - return miner3.MaxProveCommitDuration[t] + return miner3.MaxProveCommitDuration[t], nil case actors.Version4: - - return miner4.MaxProveCommitDuration[t] + return miner4.MaxProveCommitDuration[t], nil case actors.Version5: - - return miner5.MaxProveCommitDuration[t] + return miner5.MaxProveCommitDuration[t], nil default: - panic("unsupported actors version") + return 0, xerrors.Errorf("unsupported actors version") } } @@ -227,31 +223,35 @@ func DealProviderCollateralBounds( size abi.PaddedPieceSize, verified bool, rawBytePower, qaPower, baselinePower abi.StoragePower, circulatingFil abi.TokenAmount, nwVer network.Version, -) (min, max abi.TokenAmount) { - switch actors.VersionForNetwork(nwVer) { +) (min, max abi.TokenAmount, err error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return big.Zero(), big.Zero(), err + } + switch v { case actors.Version0: - - return market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + min, max := market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + return min, max, nil case actors.Version2: - - return market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + min, max := market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil case actors.Version3: - - return market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + min, max := market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil case actors.Version4: - - return market4.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + min, max := market4.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil case actors.Version5: - - return market5.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + min, max := market5.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil default: - panic("unsupported actors version") + return big.Zero(), big.Zero(), xerrors.Errorf("unsupported actors version") } } @@ -310,8 +310,11 @@ func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, e if err != nil { return 0, err } - maxSectors := uint64(GetAddressedSectorsMax(nv)) - return int(maxSectors / sectorsPerPart), nil + maxSectors, err := GetAddressedSectorsMax(nv) + if err != nil { + return 0, err + } + return int(uint64(maxSectors) / sectorsPerPart), nil } func GetDefaultSectorSize() abi.SectorSize { @@ -345,82 +348,94 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) return builtin5.SealProofPoliciesV11[proof].SectorMaxLifetime } -func GetAddressedSectorsMax(nwVer network.Version) int { - switch actors.VersionForNetwork(nwVer) { +func GetAddressedSectorsMax(nwVer network.Version) (int, error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return 0, err + } + switch v { case actors.Version0: - return miner0.AddressedSectorsMax + return miner0.AddressedSectorsMax, nil case actors.Version2: - return miner2.AddressedSectorsMax + return miner2.AddressedSectorsMax, nil case actors.Version3: - return miner3.AddressedSectorsMax + return miner3.AddressedSectorsMax, nil case actors.Version4: - return miner4.AddressedSectorsMax + return miner4.AddressedSectorsMax, nil case actors.Version5: - return miner5.AddressedSectorsMax + return miner5.AddressedSectorsMax, nil default: - panic("unsupported network version") + return 0, xerrors.Errorf("unsupported network version") } } -func GetDeclarationsMax(nwVer network.Version) int { - switch actors.VersionForNetwork(nwVer) { +func GetDeclarationsMax(nwVer network.Version) (int, error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return 0, err + } + switch v { case actors.Version0: - // TODO: Should we instead panic here since the concept doesn't exist yet? - return miner0.AddressedPartitionsMax + // TODO: Should we instead error here since the concept doesn't exist yet? + return miner0.AddressedPartitionsMax, nil case actors.Version2: - return miner2.DeclarationsMax + return miner2.DeclarationsMax, nil case actors.Version3: - return miner3.DeclarationsMax + return miner3.DeclarationsMax, nil case actors.Version4: - return miner4.DeclarationsMax + return miner4.DeclarationsMax, nil case actors.Version5: - return miner5.DeclarationsMax + return miner5.DeclarationsMax, nil default: panic("unsupported network version") } } -func AggregateNetworkFee(nwVer network.Version, aggregateSize int, baseFee abi.TokenAmount) abi.TokenAmount { - switch actors.VersionForNetwork(nwVer) { +func AggregateNetworkFee(nwVer network.Version, aggregateSize int, baseFee abi.TokenAmount) (abi.TokenAmount, error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return big.Zero(), err + } + switch v { case actors.Version0: - return big.Zero() + return big.Zero(), nil case actors.Version2: - return big.Zero() + return big.Zero(), nil case actors.Version3: - return big.Zero() + return big.Zero(), nil case actors.Version4: - return big.Zero() + return big.Zero(), nil case actors.Version5: - return miner5.AggregateNetworkFee(aggregateSize, baseFee) + return miner5.AggregateNetworkFee(aggregateSize, baseFee), nil default: - panic("unsupported network version") + return big.Zero(), xerrors.Errorf("unsupported network version") } } diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 6dec3fea6d4..a94442d6511 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -149,7 +149,10 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge return nil, nil, xerrors.Errorf("making new state tree: %w", err) } - av := actors.VersionForNetwork(template.NetworkVersion) + av, err := actors.VersionForNetwork(template.NetworkVersion) + if err != nil { + return nil, nil, xerrors.Errorf("getting network version: %w", err) + } // Create system actor diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index e6f17d6779a..38d3db518b4 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -81,7 +81,10 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder { func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, miners []genesis.Miner, nv network.Version) (cid.Cid, error) { cst := cbor.NewCborStore(cs.StateBlockstore()) - av := actors.VersionForNetwork(nv) + av, err := actors.VersionForNetwork(nv) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to get network version: %w", err) + } csc := func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) { return big.Zero(), nil @@ -291,7 +294,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid return cid.Undef, xerrors.Errorf("setting power state: %w", err) } - rewact, err := SetupRewardActor(ctx, cs.StateBlockstore(), big.Zero(), actors.VersionForNetwork(nv)) + rewact, err := SetupRewardActor(ctx, cs.StateBlockstore(), big.Zero(), av) if err != nil { return cid.Undef, xerrors.Errorf("setup reward actor: %w", err) } diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index e4b15403187..be35d93c813 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -39,7 +39,10 @@ type ActorPredicate func(vmr.Runtime, rtt.VMActor) error func ActorsVersionPredicate(ver actors.Version) ActorPredicate { return func(rt vmr.Runtime, v rtt.VMActor) error { - aver := actors.VersionForNetwork(rt.NetworkVersion()) + aver, err := actors.VersionForNetwork(rt.NetworkVersion()) + if err != nil { + return xerrors.Errorf("unsupported network version: %w", err) + } if aver != ver { return xerrors.Errorf("actor %s is a version %d actor; chain only supports actor version %d at height %d and nver %d", v.Code(), ver, aver, rt.CurrEpoch(), rt.NetworkVersion()) } diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 9f277bf3e9b..4beee5ce6d6 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -54,7 +54,12 @@ func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, add return nil, address.Undef, aerrors.Escalate(err, "registering actor address") } - act, aerr := makeActor(actors.VersionForNetwork(rt.NetworkVersion()), addr) + av, err := actors.VersionForNetwork(rt.NetworkVersion()) + if err != nil { + return nil, address.Undef, aerrors.Escalate(err, "unsupported network version") + } + + act, aerr := makeActor(av, addr) if aerr != nil { return nil, address.Undef, aerr } diff --git a/cmd/lotus-miner/sectors.go b/cmd/lotus-miner/sectors.go index 5c4581bbc53..fbf84ecff60 100644 --- a/cmd/lotus-miner/sectors.go +++ b/cmd/lotus-miner/sectors.go @@ -561,7 +561,15 @@ var sectorsExtendCmd = &cli.Command{ for l, exts := range extensions { for newExp, numbers := range exts { scount += len(numbers) - if scount > policy.GetAddressedSectorsMax(nv) || len(p.Extensions) == policy.GetDeclarationsMax(nv) { + addressedMax, err := policy.GetAddressedSectorsMax(nv) + if err != nil { + return xerrors.Errorf("failed to get addressed sectors max") + } + declMax, err := policy.GetDeclarationsMax(nv) + if err != nil { + return xerrors.Errorf("failed to get declarations max") + } + if scount > addressedMax || len(p.Extensions) == declMax { params = append(params, p) p = miner3.ExtendSectorExpirationParams{} scount = len(numbers) diff --git a/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go b/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go index 2ffc0bf140b..bd757614bbc 100644 --- a/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go +++ b/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go @@ -271,7 +271,7 @@ func (bb *BlockBuilder) StateManager() *stmgr.StateManager { } // ActorsVersion returns the actors version for the target block. -func (bb *BlockBuilder) ActorsVersion() actors.Version { +func (bb *BlockBuilder) ActorsVersion() (actors.Version, error) { return actors.VersionForNetwork(bb.NetworkVersion()) } diff --git a/cmd/lotus-sim/simulation/stages/funding_stage.go b/cmd/lotus-sim/simulation/stages/funding_stage.go index f57f852931c..faec6a504ef 100644 --- a/cmd/lotus-sim/simulation/stages/funding_stage.go +++ b/cmd/lotus-sim/simulation/stages/funding_stage.go @@ -145,7 +145,10 @@ func (fs *FundingStage) PackMessages(ctx context.Context, bb *blockbuilder.Block store := bb.ActorStore() epoch := bb.Height() - actorsVersion := bb.ActorsVersion() + actorsVersion, err := bb.ActorsVersion() + if err != nil { + return err + } var accounts, multisigs int defer func() { diff --git a/cmd/lotus-sim/simulation/stages/provecommit_stage.go b/cmd/lotus-sim/simulation/stages/provecommit_stage.go index 6cbca7de9fb..8b12fc68aa8 100644 --- a/cmd/lotus-sim/simulation/stages/provecommit_stage.go +++ b/cmd/lotus-sim/simulation/stages/provecommit_stage.go @@ -280,7 +280,11 @@ func (stage *ProveCommitStage) packProveCommitsMiner( // It will drop any pre-commits that have already expired. func (stage *ProveCommitStage) loadMiner(ctx context.Context, bb *blockbuilder.BlockBuilder, addr address.Address) error { epoch := bb.Height() - av := bb.ActorsVersion() + av, err := bb.ActorsVersion() + if err != nil { + return err + } + minerState, err := loadMiner(bb.ActorStore(), bb.ParentStateTree(), addr) if err != nil { return err @@ -291,7 +295,10 @@ func (stage *ProveCommitStage) loadMiner(ctx context.Context, bb *blockbuilder.B var total, dropped int err = minerState.ForEachPrecommittedSector(func(info miner.SectorPreCommitOnChainInfo) error { total++ - msd := policy.GetMaxProveCommitDuration(av, info.Info.SealProof) + msd, err := policy.GetMaxProveCommitDuration(av, info.Info.SealProof) + if err != nil { + return err + } if epoch > info.PreCommitEpoch+msd { dropped++ return nil @@ -327,7 +334,10 @@ func (stage *ProveCommitStage) filterProveCommits( } nextEpoch := bb.Height() - av := bb.ActorsVersion() + av, err := bb.ActorsVersion() + if err != nil { + return nil, err + } good := make([]abi.SectorNumber, 0, len(snos)) for _, sno := range snos { @@ -338,7 +348,10 @@ func (stage *ProveCommitStage) filterProveCommits( if info == nil { continue } - msd := policy.GetMaxProveCommitDuration(av, info.Info.SealProof) + msd, err := policy.GetMaxProveCommitDuration(av, info.Info.SealProof) + if err != nil { + return nil, err + } if nextEpoch > info.PreCommitEpoch+msd { continue } diff --git a/extern/storage-sealing/commit_batch.go b/extern/storage-sealing/commit_batch.go index e9ace820e29..c12a9f9334c 100644 --- a/extern/storage-sealing/commit_batch.go +++ b/extern/storage-sealing/commit_batch.go @@ -338,7 +338,12 @@ func (b *CommitBatcher) processBatch(cfg sealiface.Config) ([]sealiface.CommitBa return []sealiface.CommitBatchRes{res}, xerrors.Errorf("getting network version: %s", err) } - aggFee := big.Div(big.Mul(policy.AggregateNetworkFee(nv, len(infos), bf), aggFeeNum), aggFeeDen) + aggFeeRaw, err := policy.AggregateNetworkFee(nv, len(infos), bf) + if err != nil { + log.Errorf("getting aggregate network fee: %s", err) + return []sealiface.CommitBatchRes{res}, xerrors.Errorf("getting aggregate network fee: %s", err) + } + aggFee := big.Div(big.Mul(aggFeeRaw, aggFeeNum), aggFeeDen) needFunds := big.Add(collateral, aggFee) needFunds, err = collateralSendAmount(b.mctx, b.api, b.maddr, cfg, needFunds) @@ -558,8 +563,18 @@ func (b *CommitBatcher) getCommitCutoff(si SectorInfo) (time.Time, error) { log.Errorf("getting precommit info: %s", err) return time.Now(), err } + av, err := actors.VersionForNetwork(nv) + if err != nil { + log.Errorf("unsupported network vrsion: %s", err) + return time.Now(), err + } + mpcd, err := policy.GetMaxProveCommitDuration(av, si.SectorType) + if err != nil { + log.Errorf("getting max prove commit duration: %s", err) + return time.Now(), err + } - cutoffEpoch := pci.PreCommitEpoch + policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), si.SectorType) + cutoffEpoch := pci.PreCommitEpoch + mpcd for _, p := range si.Pieces { if p.DealInfo == nil { diff --git a/extern/storage-sealing/states_sealing.go b/extern/storage-sealing/states_sealing.go index 5334fc72e74..7bedc1ed382 100644 --- a/extern/storage-sealing/states_sealing.go +++ b/extern/storage-sealing/states_sealing.go @@ -143,7 +143,14 @@ func (m *Sealing) getTicket(ctx statemachine.Context, sector SectorInfo) (abi.Se return nil, 0, allocated, xerrors.Errorf("getTicket: StateNetworkVersion: api error, not proceeding: %+v", err) } - msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) + av, err := actors.VersionForNetwork(nv) + if err != nil { + return nil, 0, allocated, xerrors.Errorf("getTicket: actor version for network error, not proceeding: %w", err) + } + msd, err := policy.GetMaxProveCommitDuration(av, sector.SectorType) + if err != nil { + return nil, 0, allocated, xerrors.Errorf("getTicket: max prove commit duration policy error, not proceeding: %w", err) + } if checkProveCommitExpired(pci.PreCommitEpoch, msd, epoch) { return nil, 0, allocated, xerrors.Errorf("ticket expired for precommitted sector") @@ -223,7 +230,16 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo) return nil } - msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) + av, err := actors.VersionForNetwork(nv) + if err != nil { + log.Errorf("handlePreCommit1: VersionForNetwork error, not proceeding: %w", err) + return nil + } + msd, err := policy.GetMaxProveCommitDuration(av, sector.SectorType) + if err != nil { + log.Errorf("handlePreCommit1: GetMaxProveCommitDuration error, not proceeding: %w", err) + return nil + } // if height > PreCommitEpoch + msd, there is no need to recalculate if checkProveCommitExpired(pci.PreCommitEpoch, msd, height) { @@ -311,7 +327,14 @@ func (m *Sealing) preCommitParams(ctx statemachine.Context, sector SectorInfo) ( return nil, big.Zero(), nil, ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("failed to get network version: %w", err)}) } - msd := policy.GetMaxProveCommitDuration(actors.VersionForNetwork(nv), sector.SectorType) + av, err := actors.VersionForNetwork(nv) + if err != nil { + return nil, big.Zero(), nil, ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("failed to get actors version: %w", err)}) + } + msd, err := policy.GetMaxProveCommitDuration(av, sector.SectorType) + if err != nil { + return nil, big.Zero(), nil, ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("failed to get max prove commit duration: %w", err)}) + } if minExpiration := sector.TicketEpoch + policy.MaxPreCommitRandomnessLookback + msd + miner.MinSectorExpiration; expiration < minExpiration { expiration = minExpiration diff --git a/node/impl/full/multisig.go b/node/impl/full/multisig.go index e44509d7cbb..0d20c3f03ea 100644 --- a/node/impl/full/multisig.go +++ b/node/impl/full/multisig.go @@ -30,8 +30,12 @@ func (a *MsigAPI) messageBuilder(ctx context.Context, from address.Address) (mul if err != nil { return nil, err } + av, err := actors.VersionForNetwork(nver) + if err != nil { + return nil, err + } - return multisig.Message(actors.VersionForNetwork(nver), from), nil + return multisig.Message(av, from), nil } // TODO: remove gp (gasPrice) from arguments diff --git a/node/impl/full/state.go b/node/impl/full/state.go index d8545ae13fe..df08887873c 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -1332,13 +1332,16 @@ func (m *StateModule) StateDealProviderCollateralBounds(ctx context.Context, siz return api.DealCollateralBounds{}, xerrors.Errorf("getting reward baseline power: %w", err) } - min, max := policy.DealProviderCollateralBounds(size, + min, max, err := policy.DealProviderCollateralBounds(size, verified, powClaim.RawBytePower, powClaim.QualityAdjPower, rewPow, circ.FilCirculating, m.StateManager.GetNtwkVersion(ctx, ts.Height())) + if err != nil { + return api.DealCollateralBounds{}, xerrors.Errorf("getting deal provider coll bounds: %w", err) + } return api.DealCollateralBounds{ Min: types.BigDiv(types.BigMul(min, dealProviderCollateralNum), dealProviderCollateralDen), Max: max, diff --git a/paychmgr/paych.go b/paychmgr/paych.go index c4ef3deb01a..ed72c35e0b0 100644 --- a/paychmgr/paych.go +++ b/paychmgr/paych.go @@ -88,7 +88,11 @@ func (ca *channelAccessor) messageBuilder(ctx context.Context, from address.Addr return nil, err } - return paych.Message(actors.VersionForNetwork(nwVersion), from), nil + av, err := actors.VersionForNetwork(nwVersion) + if err != nil { + return nil, err + } + return paych.Message(av, from), nil } func (ca *channelAccessor) getChannelInfo(addr address.Address) (*ChannelInfo, error) { diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 51a0729aff0..20d1eeadc3a 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -739,8 +739,12 @@ func (s *WindowPoStScheduler) batchPartitions(partitions []api.Partition, nv net } // Also respect the AddressedPartitionsMax (which is the same as DeclarationsMax (which is all really just MaxPartitionsPerDeadline)) - if partitionsPerMsg > policy.GetDeclarationsMax(nv) { - partitionsPerMsg = policy.GetDeclarationsMax(nv) + declMax, err := policy.GetDeclarationsMax(nv) + if err != nil { + return nil, xerrors.Errorf("getting max declarations: %w", err) + } + if partitionsPerMsg > declMax { + partitionsPerMsg = declMax } // The number of messages will be: From 2e2b9009fca895c1563a96fbf15bbe47f3db528c Mon Sep 17 00:00:00 2001 From: ZenGround0 Date: Tue, 10 Aug 2021 13:32:00 -0400 Subject: [PATCH 68/79] Fix actor policy codegen --- chain/actors/policy/policy.go | 12 ++++- chain/actors/policy/policy.go.template | 74 +++++++++++++++++--------- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 0f1ed266c72..492f7618354 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -173,18 +173,23 @@ func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) (a switch ver { case actors.Version0: + return miner0.MaxSealDuration[t], nil case actors.Version2: + return miner2.MaxProveCommitDuration[t], nil case actors.Version3: + return miner3.MaxProveCommitDuration[t], nil case actors.Version4: + return miner4.MaxProveCommitDuration[t], nil case actors.Version5: + return miner5.MaxProveCommitDuration[t], nil default: @@ -231,22 +236,27 @@ func DealProviderCollateralBounds( switch v { case actors.Version0: + min, max := market0.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) return min, max, nil case actors.Version2: + min, max := market2.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil case actors.Version3: + min, max := market3.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil case actors.Version4: + min, max := market4.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil case actors.Version5: + min, max := market5.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil @@ -404,7 +414,7 @@ func GetDeclarationsMax(nwVer network.Version) (int, error) { return miner5.DeclarationsMax, nil default: - panic("unsupported network version") + return 0, xerrors.Errorf("unsupported network version") } } diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template index 3257feffd41..264d4299203 100644 --- a/chain/actors/policy/policy.go.template +++ b/chain/actors/policy/policy.go.template @@ -4,6 +4,7 @@ import ( "sort" "github.com/filecoin-project/go-state-types/big" + "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/network" @@ -117,18 +118,18 @@ func SetMinVerifiedDealSize(size abi.StoragePower) { {{end}} } -func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) abi.ChainEpoch { +func GetMaxProveCommitDuration(ver actors.Version, t abi.RegisteredSealProof) (abi.ChainEpoch, error) { switch ver { {{range .versions}} case actors.Version{{.}}: {{if (eq . 0)}} - return miner{{.}}.MaxSealDuration[t] + return miner{{.}}.MaxSealDuration[t], nil {{else}} - return miner{{.}}.MaxProveCommitDuration[t] + return miner{{.}}.MaxProveCommitDuration[t], nil {{end}} {{end}} default: - panic("unsupported actors version") + return 0, xerrors.Errorf("unsupported actors version") } } @@ -150,18 +151,24 @@ func DealProviderCollateralBounds( size abi.PaddedPieceSize, verified bool, rawBytePower, qaPower, baselinePower abi.StoragePower, circulatingFil abi.TokenAmount, nwVer network.Version, -) (min, max abi.TokenAmount) { - switch actors.VersionForNetwork(nwVer) { +) (min, max abi.TokenAmount, err error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return big.Zero(), big.Zero(), err + } + switch v { {{range .versions}} case actors.Version{{.}}: {{if (eq . 0)}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + min, max := market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil, nwVer) + return min, max, nil {{else}} - return market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + min, max := market{{.}}.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil {{end}} {{end}} default: - panic("unsupported actors version") + return big.Zero(), big.Zero(), xerrors.Errorf("unsupported actors version") } } @@ -201,8 +208,11 @@ func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, e if err != nil { return 0, err } - maxSectors := uint64(GetAddressedSectorsMax(nv)) - return int(maxSectors / sectorsPerPart), nil + maxSectors, err := GetAddressedSectorsMax(nv) + if err != nil { + return 0, err + } + return int(uint64(maxSectors) / sectorsPerPart), nil } func GetDefaultSectorSize() abi.SectorSize { @@ -236,44 +246,56 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) return builtin{{.latestVersion}}.SealProofPoliciesV11[proof].SectorMaxLifetime } -func GetAddressedSectorsMax(nwVer network.Version) int { - switch actors.VersionForNetwork(nwVer) { +func GetAddressedSectorsMax(nwVer network.Version) (int, error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return 0, err + } + switch v { {{range .versions}} case actors.Version{{.}}: - return miner{{.}}.AddressedSectorsMax + return miner{{.}}.AddressedSectorsMax, nil {{end}} default: - panic("unsupported network version") + return 0, xerrors.Errorf("unsupported network version") } } -func GetDeclarationsMax(nwVer network.Version) int { - switch actors.VersionForNetwork(nwVer) { +func GetDeclarationsMax(nwVer network.Version) (int, error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return 0, err + } + switch v { {{range .versions}} case actors.Version{{.}}: {{if (eq . 0)}} - // TODO: Should we instead panic here since the concept doesn't exist yet? - return miner{{.}}.AddressedPartitionsMax + // TODO: Should we instead error here since the concept doesn't exist yet? + return miner{{.}}.AddressedPartitionsMax, nil {{else}} - return miner{{.}}.DeclarationsMax + return miner{{.}}.DeclarationsMax, nil {{end}} {{end}} default: - panic("unsupported network version") + return 0, xerrors.Errorf("unsupported network version") } } -func AggregateNetworkFee(nwVer network.Version, aggregateSize int, baseFee abi.TokenAmount) abi.TokenAmount { - switch actors.VersionForNetwork(nwVer) { +func AggregateNetworkFee(nwVer network.Version, aggregateSize int, baseFee abi.TokenAmount) (abi.TokenAmount, error) { + v, err := actors.VersionForNetwork(nwVer) + if err != nil { + return big.Zero(), err + } + switch v { {{range .versions}} case actors.Version{{.}}: {{if (le . 4)}} - return big.Zero() + return big.Zero(), nil {{else}} - return miner{{.}}.AggregateNetworkFee(aggregateSize, baseFee) + return miner{{.}}.AggregateNetworkFee(aggregateSize, baseFee), nil {{end}} {{end}} default: - panic("unsupported network version") + return big.Zero(), xerrors.Errorf("unsupported network version") } } From 8c9321ce7bb81b5a78c41940e3451561bd1bbe37 Mon Sep 17 00:00:00 2001 From: ZenGround0 Date: Tue, 10 Aug 2021 15:50:37 -0400 Subject: [PATCH 69/79] revert pricelist by version to pricelist by epoch --- api/version.go | 4 +- blockstore/badger/blockstore.go | 2 +- build/openrpc/worker.json.gz | Bin 2710 -> 2710 bytes build/params_2k.go | 1 - build/params_butterfly.go | 1 - build/params_calibnet.go | 2 - build/params_interop.go | 1 - build/params_mainnet.go | 1 - build/params_nerpanet.go | 1 - build/params_testground.go | 31 +- chain/actors/version.go | 2 +- chain/messagepool/check.go | 2 +- chain/messagepool/messagepool.go | 3 +- chain/messagepool/selection.go | 2 +- chain/stmgr/forks.go | 1088 +----------------- chain/stmgr/upgrades.go | 1090 +++++++++++++++++++ chain/sync.go | 2 +- chain/vm/gas.go | 28 +- chain/vm/mkactor.go | 2 +- chain/vm/vm.go | 4 +- cli/cmd.go | 2 +- cmd/lotus-miner/main.go | 2 +- documentation/en/api-v0-methods-miner.md | 2 +- documentation/en/api-v0-methods-worker.md | 2 +- documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- 26 files changed, 1146 insertions(+), 1133 deletions(-) create mode 100644 chain/stmgr/upgrades.go diff --git a/api/version.go b/api/version.go index ef59dd10404..687f5135a89 100644 --- a/api/version.go +++ b/api/version.go @@ -54,8 +54,8 @@ func VersionForType(nodeType NodeType) (Version, error) { // semver versions of the rpc api exposed var ( - FullAPIVersion0 = newVer(1, 3, 1) - FullAPIVersion1 = newVer(2, 1, 1) + FullAPIVersion0 = newVer(1, 3, 0) + FullAPIVersion1 = newVer(2, 1, 0) MinerAPIVersion0 = newVer(1, 2, 0) WorkerAPIVersion0 = newVer(1, 1, 0) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 59fd18d1af4..a0b51d8df61 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -982,4 +982,4 @@ func (b *Blockstore) StorageKey(dst []byte, cid cid.Cid) []byte { // WARNING: THIS IS COMPLETELY UNSAFE; DONT USE THIS IN PRODUCTION CODE func (b *Blockstore) DB() *badger.DB { return b.db -} \ No newline at end of file +} diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 9fa491548c83ad0c8ae481a77e828d4089534cba..c1b533b72b946065dbdc580248dfd393126945d0 100644 GIT binary patch delta 100 zcmV-q0Gt1o6_ypSItpBztsO^qR3VQ`ww?b;sQPz6K^dy#oUTwQOOs!7ve)Lm()|~! zU((gU<@SR_0aMgPY77Dp5rA0qlujZMFcv=Bd!@#{yJXa93s0wa)Bgnk0RR8b4U|P$ GdH?`aJua#M delta 100 zcmV-q0Gt1o6_ypSItpBTSUZmHs6rl>Y&-vxQ1$PCf-+ReIbESrmL|XEWUtMArTZ^d zzoe^y%k2k=0;Z^o)EERHA^@@IDV;-!T0E diff --git a/build/params_2k.go b/build/params_2k.go index a1ccb0ce39f..efa38dc0cec 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -28,7 +28,6 @@ var UpgradeAssemblyHeight = abi.ChainEpoch(-5) var UpgradeLiftoffHeight = abi.ChainEpoch(-6) var UpgradeKumquatHeight = abi.ChainEpoch(-7) -var UpgradePricelistOopsHeight = abi.ChainEpoch(-8) var UpgradeCalicoHeight = abi.ChainEpoch(-9) var UpgradePersianHeight = abi.ChainEpoch(-10) var UpgradeOrangeHeight = abi.ChainEpoch(-11) diff --git a/build/params_butterfly.go b/build/params_butterfly.go index 835c7dc7aaf..258f6ab0f2e 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -28,7 +28,6 @@ var UpgradeAssemblyHeight = abi.ChainEpoch(30) const UpgradeTapeHeight = 60 const UpgradeLiftoffHeight = -5 const UpgradeKumquatHeight = 90 -const UpgradePricelistOopsHeight = 119 const UpgradeCalicoHeight = 120 const UpgradePersianHeight = 150 const UpgradeClausHeight = 180 diff --git a/build/params_calibnet.go b/build/params_calibnet.go index fe871bccaad..df334a516a7 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -33,8 +33,6 @@ const UpgradeLiftoffHeight = -5 const UpgradeKumquatHeight = 90 -const UpgradePricelistOopsHeight = 119 - const UpgradeCalicoHeight = 120 const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 1) diff --git a/build/params_interop.go b/build/params_interop.go index b5e49577d3f..921dd0981f8 100644 --- a/build/params_interop.go +++ b/build/params_interop.go @@ -31,7 +31,6 @@ var UpgradeAssemblyHeight = abi.ChainEpoch(-5) var UpgradeLiftoffHeight = abi.ChainEpoch(-6) var UpgradeKumquatHeight = abi.ChainEpoch(-7) -var UpgradePricelistOopsHeight = abi.ChainEpoch(-8) var UpgradeCalicoHeight = abi.ChainEpoch(-9) var UpgradePersianHeight = abi.ChainEpoch(-10) var UpgradeOrangeHeight = abi.ChainEpoch(-11) diff --git a/build/params_mainnet.go b/build/params_mainnet.go index c9750b6e630..1c9b6946267 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -45,7 +45,6 @@ const UpgradeLiftoffHeight = 148888 const UpgradeKumquatHeight = 170000 -const UpgradePricelistOopsHeight = 265199 const UpgradeCalicoHeight = 265200 const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60) diff --git a/build/params_nerpanet.go b/build/params_nerpanet.go index 8879d01b565..3cba64ae233 100644 --- a/build/params_nerpanet.go +++ b/build/params_nerpanet.go @@ -32,7 +32,6 @@ const UpgradeTapeHeight = 60 const UpgradeKumquatHeight = 90 -const UpgradePricelistOopsHeight = 99 const UpgradeCalicoHeight = 100 const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 1) diff --git a/build/params_testground.go b/build/params_testground.go index b12df11e78b..204c74e676b 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -82,22 +82,21 @@ var ( UpgradeBreezeHeight abi.ChainEpoch = -1 BreezeGasTampingDuration abi.ChainEpoch = 0 - UpgradeSmokeHeight abi.ChainEpoch = -1 - UpgradeIgnitionHeight abi.ChainEpoch = -2 - UpgradeRefuelHeight abi.ChainEpoch = -3 - UpgradeTapeHeight abi.ChainEpoch = -4 - UpgradeAssemblyHeight abi.ChainEpoch = 10 - UpgradeLiftoffHeight abi.ChainEpoch = -5 - UpgradeKumquatHeight abi.ChainEpoch = -6 - UpgradePricelistOopsHeight abi.ChainEpoch = -7 - UpgradeCalicoHeight abi.ChainEpoch = -8 - UpgradePersianHeight abi.ChainEpoch = -9 - UpgradeOrangeHeight abi.ChainEpoch = -10 - UpgradeClausHeight abi.ChainEpoch = -11 - UpgradeTrustHeight abi.ChainEpoch = -12 - UpgradeNorwegianHeight abi.ChainEpoch = -13 - UpgradeTurboHeight abi.ChainEpoch = -14 - UpgradeHyperdriveHeight abi.ChainEpoch = -15 + UpgradeSmokeHeight abi.ChainEpoch = -1 + UpgradeIgnitionHeight abi.ChainEpoch = -2 + UpgradeRefuelHeight abi.ChainEpoch = -3 + UpgradeTapeHeight abi.ChainEpoch = -4 + UpgradeAssemblyHeight abi.ChainEpoch = 10 + UpgradeLiftoffHeight abi.ChainEpoch = -5 + UpgradeKumquatHeight abi.ChainEpoch = -6 + UpgradeCalicoHeight abi.ChainEpoch = -8 + UpgradePersianHeight abi.ChainEpoch = -9 + UpgradeOrangeHeight abi.ChainEpoch = -10 + UpgradeClausHeight abi.ChainEpoch = -11 + UpgradeTrustHeight abi.ChainEpoch = -12 + UpgradeNorwegianHeight abi.ChainEpoch = -13 + UpgradeTurboHeight abi.ChainEpoch = -14 + UpgradeHyperdriveHeight abi.ChainEpoch = -15 DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/chain/actors/version.go b/chain/actors/version.go index 36e8d17b4fd..8787089aff1 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -25,7 +25,7 @@ func VersionForNetwork(version network.Version) (Version, error) { switch version { case network.Version0, network.Version1, network.Version2, network.Version3: return Version0, nil - case network.Version4, network.Version5, network.Version6, network.Version6AndAHalf, network.Version7, network.Version8, network.Version9: + case network.Version4, network.Version5, network.Version6, network.Version7, network.Version8, network.Version9: return Version2, nil case network.Version10, network.Version11: return Version3, nil diff --git a/chain/messagepool/check.go b/chain/messagepool/check.go index 9a55c283cd9..283c0d1194e 100644 --- a/chain/messagepool/check.go +++ b/chain/messagepool/check.go @@ -281,7 +281,7 @@ func (mp *MessagePool) checkMessages(ctx context.Context, msgs []*types.Message, // gas checks // 4. Min Gas - minGas := vm.PricelistByVersion(nv).OnChainMessage(m.ChainLength()) + minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength()) check = api.MessageCheckStatus{ Cid: m.Cid(), diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 175cda9fff0..ee2518ed9ac 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -616,7 +616,8 @@ func (mp *MessagePool) addLocal(ctx context.Context, m *types.SignedMessage) err // 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) { - minGas := vm.PricelistByVersion(build.NewestNetworkVersion).OnChainMessage(m.ChainLength()) + epoch := curTs.Height() + minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength()) if err := m.VMMessage().ValidForBlockInclusion(minGas.Total(), build.NewestNetworkVersion); err != nil { return false, xerrors.Errorf("message will not be included in a block: %w", err) diff --git a/chain/messagepool/selection.go b/chain/messagepool/selection.go index 60d75a841ad..611ab8e5fcd 100644 --- a/chain/messagepool/selection.go +++ b/chain/messagepool/selection.go @@ -749,7 +749,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 } curNonce++ - minGas := vm.PricelistByVersion(build.NewestNetworkVersion).OnChainMessage(m.ChainLength()).Total() + minGas := vm.PricelistByEpoch(ts.Height()).OnChainMessage(m.ChainLength()).Total() if m.Message.GasLimit < minGas { break } diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index fb8e407ed78..212272a95aa 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -4,42 +4,27 @@ import ( "bytes" "context" "encoding/binary" - "runtime" "sort" "sync" "time" - "github.com/filecoin-project/specs-actors/v5/actors/migration/nv13" - - "github.com/filecoin-project/go-state-types/rt" + "github.com/ipfs/go-cid" + "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/network" - "github.com/filecoin-project/lotus/blockstore" - "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/go-state-types/rt" + + "github.com/filecoin-project/specs-actors/v3/actors/migration/nv10" + "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/builtin" init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" - "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/state" - "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" - builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" - multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" - power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" - "github.com/filecoin-project/specs-actors/actors/migration/nv3" - adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" - "github.com/filecoin-project/specs-actors/v2/actors/migration/nv4" - "github.com/filecoin-project/specs-actors/v2/actors/migration/nv7" - "github.com/filecoin-project/specs-actors/v3/actors/migration/nv10" - "github.com/filecoin-project/specs-actors/v4/actors/migration/nv12" - "github.com/ipfs/go-cid" - cbor "github.com/ipfs/go-ipld-cbor" - "golang.org/x/xerrors" ) // MigrationCache can be used to cache information used by a migration. This is primarily useful to @@ -125,121 +110,6 @@ func (ml migrationLogger) Log(level rt.LogLevel, msg string, args ...interface{} } } -func DefaultUpgradeSchedule() UpgradeSchedule { - var us UpgradeSchedule - - updates := []Upgrade{{ - Height: build.UpgradeBreezeHeight, - Network: network.Version1, - Migration: UpgradeFaucetBurnRecovery, - }, { - Height: build.UpgradeSmokeHeight, - Network: network.Version2, - Migration: nil, - }, { - Height: build.UpgradeIgnitionHeight, - Network: network.Version3, - Migration: UpgradeIgnition, - }, { - Height: build.UpgradeRefuelHeight, - Network: network.Version3, - Migration: UpgradeRefuel, - }, { - Height: build.UpgradeAssemblyHeight, - Network: network.Version4, - Expensive: true, - Migration: UpgradeActorsV2, - }, { - Height: build.UpgradeTapeHeight, - Network: network.Version5, - Migration: nil, - }, { - Height: build.UpgradeLiftoffHeight, - Network: network.Version5, - Migration: UpgradeLiftoff, - }, { - Height: build.UpgradeKumquatHeight, - Network: network.Version6, - Migration: nil, - }, { - Height: build.UpgradePricelistOopsHeight, - Network: network.Version6AndAHalf, - Migration: nil, - }, { - Height: build.UpgradeCalicoHeight, - Network: network.Version7, - Migration: UpgradeCalico, - }, { - Height: build.UpgradePersianHeight, - Network: network.Version8, - Migration: nil, - }, { - Height: build.UpgradeOrangeHeight, - Network: network.Version9, - Migration: nil, - }, { - Height: build.UpgradeTrustHeight, - Network: network.Version10, - Migration: UpgradeActorsV3, - PreMigrations: []PreMigration{{ - PreMigration: PreUpgradeActorsV3, - StartWithin: 120, - DontStartWithin: 60, - StopWithin: 35, - }, { - PreMigration: PreUpgradeActorsV3, - StartWithin: 30, - DontStartWithin: 15, - StopWithin: 5, - }}, - Expensive: true, - }, { - Height: build.UpgradeNorwegianHeight, - Network: network.Version11, - Migration: nil, - }, { - Height: build.UpgradeTurboHeight, - Network: network.Version12, - Migration: UpgradeActorsV4, - PreMigrations: []PreMigration{{ - PreMigration: PreUpgradeActorsV4, - StartWithin: 120, - DontStartWithin: 60, - StopWithin: 35, - }, { - PreMigration: PreUpgradeActorsV4, - StartWithin: 30, - DontStartWithin: 15, - StopWithin: 5, - }}, - Expensive: true, - }, { - Height: build.UpgradeHyperdriveHeight, - Network: network.Version13, - Migration: UpgradeActorsV5, - PreMigrations: []PreMigration{{ - PreMigration: PreUpgradeActorsV5, - StartWithin: 120, - DontStartWithin: 60, - StopWithin: 35, - }, { - PreMigration: PreUpgradeActorsV5, - StartWithin: 30, - DontStartWithin: 15, - StopWithin: 5, - }}, - Expensive: true}} - - for _, u := range updates { - if u.Height < 0 { - // upgrade disabled - continue - } - us = append(us, u) - } - return us -} - func (us UpgradeSchedule) Validate() error { // Make sure each upgrade is valid. for _, u := range us { @@ -488,469 +358,6 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo return nil } -func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ MigrationCache, em ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, 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, ts, false) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to get tipset at lookback height: %w", err) - } - - lbtree, err := sm.ParentState(lbts) - if err != nil { - return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err) - } - - tree, err := sm.StateTree(root) - if err != nil { - return cid.Undef, xerrors.Errorf("getting state tree: %w", err) - } - - type transfer struct { - From address.Address - To address.Address - Amt abi.TokenAmount - } - - var transfers []transfer - subcalls := make([]types.ExecutionTrace, 0) - transferCb := func(trace types.ExecutionTrace) { - subcalls = append(subcalls, trace) - } - - // Take all excess funds away, put them into the reserve account - err = tree.ForEach(func(addr address.Address, act *types.Actor) error { - switch act.Code { - case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.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: builtin.ReserveAddress, - Amt: act.Balance, - }) - } - case builtin0.StorageMinerActorCodeID: - var st miner0.State - if err := sm.ChainStore().ActorStore(ctx).Get(ctx, act.Head, &st); 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) - } - - if !available.IsZero() { - transfers = append(transfers, transfer{ - From: addr, - To: builtin.ReserveAddress, - Amt: available, - }) - } - } - return nil - }) - if err != nil { - return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err) - } - - // Execute transfers from previous step - for _, t := range transfers { - if err := doTransfer(tree, t.From, t.To, t.Amt, transferCb); err != nil { - return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) - } - } - - // pull up power table to give miners back some funds proportional to their power - var ps power0.State - powAct, err := tree.GetActor(builtin0.StoragePowerActorAddr) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to load power actor: %w", err) - } - - cst := cbor.NewCborStore(sm.ChainStore().StateBlockstore()) - if err := cst.Get(ctx, powAct.Head, &ps); err != nil { - return cid.Undef, xerrors.Errorf("failed to get power actor state: %w", err) - } - - totalPower := ps.TotalBytesCommitted - - var transfersBack []transfer - // Now, we return some funds to places where they are needed - err = tree.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 builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID: - nbalance := big.Min(prevBalance, AccountCap) - if nbalance.Sign() != 0 { - transfersBack = append(transfersBack, transfer{ - From: builtin.ReserveAddress, - To: addr, - Amt: nbalance, - }) - } - case builtin0.StorageMinerActorCodeID: - var st miner0.State - if err := sm.ChainStore().ActorStore(ctx).Get(ctx, act.Head, &st); err != nil { - return xerrors.Errorf("failed to load miner state: %w", err) - } - - var minfo miner0.MinerInfo - if err := cst.Get(ctx, st.Info, &minfo); err != nil { - return xerrors.Errorf("failed to get miner info: %w", err) - } - - sectorsArr, err := adt0.AsArray(sm.ChainStore().ActorStore(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: builtin.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 miner0.State - if err := sm.ChainStore().ActorStore(ctx).Get(ctx, lbact.Head, &lbst); err != nil { - return xerrors.Errorf("failed to load miner state: %w", err) - } - - lbsectors, err := adt0.AsArray(sm.ChainStore().ActorStore(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: builtin.ReserveAddress, - To: minfo.Worker, - Amt: BaseMinerBalance, - }) - } - - } else { - log.Warnf("failed to get miner in lookback state: %s", err) - } - } - return nil - }) - if err != nil { - return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err) - } - - for _, t := range transfersBack { - if err := doTransfer(tree, t.From, t.To, t.Amt, transferCb); err != nil { - return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) - } - } - - // transfer all burnt funds back to the reserve account - burntAct, err := tree.GetActor(builtin0.BurntFundsActorAddr) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to load burnt funds actor: %w", err) - } - if err := doTransfer(tree, builtin0.BurntFundsActorAddr, builtin.ReserveAddress, burntAct.Balance, transferCb); err != nil { - return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err) - } - - // Top up the reimbursement service - reimbAddr, err := address.NewFromString("t0111") - if err != nil { - return cid.Undef, xerrors.Errorf("failed to parse reimbursement service address") - } - - reimb, err := tree.GetActor(reimbAddr) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to load reimbursement account actor: %w", err) - } - - difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance) - if err := doTransfer(tree, builtin.ReserveAddress, reimbAddr, difference, transferCb); err != nil { - return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err) - } - - // Now, a final sanity check to make sure the balances all check out - total := abi.NewTokenAmount(0) - err = tree.ForEach(func(addr address.Address, act *types.Actor) error { - total = types.BigAdd(total, act.Balance) - return nil - }) - if err != nil { - return cid.Undef, xerrors.Errorf("checking final state balance failed: %w", err) - } - - exp := types.FromFil(build.FilBase) - if !exp.Equals(total) { - return cid.Undef, xerrors.Errorf("resultant state tree account balance was not correct: %s", total) - } - - if em != nil { - // record the transfer in execution traces - - fakeMsg := makeFakeMsg(builtin.SystemActorAddr, builtin.SystemActorAddr, big.Zero(), uint64(epoch)) - - if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ - MessageReceipt: *makeFakeRct(), - ActorErr: nil, - ExecutionTrace: types.ExecutionTrace{ - Msg: fakeMsg, - MsgRct: makeFakeRct(), - Error: "", - Duration: 0, - GasCharges: nil, - Subcalls: subcalls, - }, - Duration: 0, - GasCosts: nil, - }, false); err != nil { - return cid.Undef, xerrors.Errorf("recording transfers: %w", err) - } - } - - return tree.Flush(ctx) -} - -func UpgradeIgnition(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - store := sm.cs.ActorStore(ctx) - - if build.UpgradeLiftoffHeight <= epoch { - return cid.Undef, xerrors.Errorf("liftoff height must be beyond ignition height") - } - - nst, err := nv3.MigrateStateTree(ctx, store, root, epoch) - if err != nil { - return cid.Undef, xerrors.Errorf("migrating actors state: %w", err) - } - - tree, err := sm.StateTree(nst) - if err != nil { - return cid.Undef, xerrors.Errorf("getting state tree: %w", err) - } - - err = setNetworkName(ctx, store, tree, "ignition") - if err != nil { - return cid.Undef, xerrors.Errorf("setting network name: %w", err) - } - - split1, err := address.NewFromString("t0115") - if err != nil { - return cid.Undef, xerrors.Errorf("first split address: %w", err) - } - - split2, err := address.NewFromString("t0116") - if err != nil { - return cid.Undef, xerrors.Errorf("second split address: %w", err) - } - - err = resetGenesisMsigs0(ctx, sm, store, tree, build.UpgradeLiftoffHeight) - if err != nil { - return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) - } - - err = splitGenesisMultisig0(ctx, cb, split1, store, tree, 50, epoch, ts) - if err != nil { - return cid.Undef, xerrors.Errorf("splitting first msig: %w", err) - } - - err = splitGenesisMultisig0(ctx, cb, split2, store, tree, 50, epoch, ts) - if err != nil { - return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) - } - - err = nv3.CheckStateTree(ctx, store, nst, epoch, builtin0.TotalFilecoin) - if err != nil { - return cid.Undef, xerrors.Errorf("sanity check after ignition upgrade failed: %w", err) - } - - return tree.Flush(ctx) -} - -func UpgradeRefuel(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - - store := sm.cs.ActorStore(ctx) - tree, err := sm.StateTree(root) - if err != nil { - return cid.Undef, xerrors.Errorf("getting state tree: %w", err) - } - - err = resetMultisigVesting0(ctx, store, tree, builtin.SaftAddress, 0, 0, big.Zero()) - if err != nil { - return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) - } - - err = resetMultisigVesting0(ctx, store, tree, builtin.ReserveAddress, 0, 0, big.Zero()) - if err != nil { - return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) - } - - err = resetMultisigVesting0(ctx, store, tree, builtin.RootVerifierAddress, 0, 0, big.Zero()) - if err != nil { - return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) - } - - return tree.Flush(ctx) -} - -func UpgradeActorsV2(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) - store := store.ActorStore(ctx, buf) - - info, err := store.Put(ctx, new(types.StateInfo0)) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) - } - - newHamtRoot, err := nv4.MigrateStateTree(ctx, store, root, epoch, nv4.DefaultConfig()) - if err != nil { - return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) - } - - newRoot, err := store.Put(ctx, &types.StateRoot{ - Version: types.StateTreeVersion1, - Actors: newHamtRoot, - Info: info, - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) - } - - // perform some basic sanity checks to make sure everything still works. - if newSm, err := state.LoadStateTree(store, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err) - } else if newRoot2, err := newSm.Flush(ctx); err != nil { - return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err) - } else if newRoot2 != newRoot { - return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2) - } else if _, err := newSm.GetActor(builtin0.InitActorAddr); err != nil { - return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err) - } - - { - from := buf - to := buf.Read() - - if err := vm.Copy(ctx, from, to, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) - } - } - - return newRoot, nil -} - -func UpgradeLiftoff(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - tree, err := sm.StateTree(root) - if err != nil { - return cid.Undef, xerrors.Errorf("getting state tree: %w", err) - } - - err = setNetworkName(ctx, sm.cs.ActorStore(ctx), tree, "mainnet") - if err != nil { - return cid.Undef, xerrors.Errorf("setting network name: %w", err) - } - - return tree.Flush(ctx) -} - -func UpgradeCalico(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - if build.BuildType != build.BuildMainnet { - return root, nil - } - - store := sm.cs.ActorStore(ctx) - var stateRoot types.StateRoot - if err := store.Get(ctx, root, &stateRoot); err != nil { - return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) - } - - if stateRoot.Version != types.StateTreeVersion1 { - return cid.Undef, xerrors.Errorf( - "expected state root version 1 for calico upgrade, got %d", - stateRoot.Version, - ) - } - - newHamtRoot, err := nv7.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, nv7.DefaultConfig()) - if err != nil { - return cid.Undef, xerrors.Errorf("running nv7 migration: %w", err) - } - - newRoot, err := store.Put(ctx, &types.StateRoot{ - Version: stateRoot.Version, - Actors: newHamtRoot, - Info: stateRoot.Info, - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) - } - - // perform some basic sanity checks to make sure everything still works. - if newSm, err := state.LoadStateTree(store, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err) - } else if newRoot2, err := newSm.Flush(ctx); err != nil { - return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err) - } else if newRoot2 != newRoot { - return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2) - } else if _, err := newSm.GetActor(builtin0.InitActorAddr); err != nil { - return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err) - } - - return newRoot, nil -} - func terminateActor(ctx context.Context, tree *state.StateTree, addr address.Address, em ExecMonitor, epoch abi.ChainEpoch, ts *types.TipSet) error { a, err := tree.GetActor(addr) if xerrors.Is(err, types.ErrActorNotFound) { @@ -1011,282 +418,8 @@ func terminateActor(ctx context.Context, tree *state.StateTree, addr address.Add return tree.SetActor(init_.Address, ia) } -func UpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - // Use all the CPUs except 3. - workerCount := runtime.NumCPU() - 3 - if workerCount <= 0 { - workerCount = 1 - } - - config := nv10.Config{ - MaxWorkers: uint(workerCount), - JobQueueSize: 1000, - ResultQueueSize: 100, - ProgressLogPeriod: 10 * time.Second, - } - newRoot, err := upgradeActorsV3Common(ctx, sm, cache, root, epoch, ts, config) - if err != nil { - return cid.Undef, xerrors.Errorf("migrating actors v3 state: %w", err) - } - - tree, err := sm.StateTree(newRoot) - if err != nil { - return cid.Undef, xerrors.Errorf("getting state tree: %w", err) - } - - if build.BuildType == build.BuildMainnet { - err := terminateActor(ctx, tree, build.ZeroAddress, cb, epoch, ts) - if err != nil && !xerrors.Is(err, types.ErrActorNotFound) { - return cid.Undef, xerrors.Errorf("deleting zero bls actor: %w", err) - } - - newRoot, err = tree.Flush(ctx) - if err != nil { - return cid.Undef, xerrors.Errorf("flushing state tree: %w", err) - } - } - - return newRoot, nil -} - -func PreUpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { - // Use half the CPUs for pre-migration, but leave at least 3. - workerCount := runtime.NumCPU() - if workerCount <= 4 { - workerCount = 1 - } else { - workerCount /= 2 - } - config := nv10.Config{MaxWorkers: uint(workerCount)} - _, err := upgradeActorsV3Common(ctx, sm, cache, root, epoch, ts, config) - return err -} - -func upgradeActorsV3Common( - ctx context.Context, sm *StateManager, cache MigrationCache, - root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, - config nv10.Config, -) (cid.Cid, error) { - buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) - store := store.ActorStore(ctx, buf) - - // Load the state root. - var stateRoot types.StateRoot - if err := store.Get(ctx, root, &stateRoot); err != nil { - return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) - } - - if stateRoot.Version != types.StateTreeVersion1 { - return cid.Undef, xerrors.Errorf( - "expected state root version 1 for actors v3 upgrade, got %d", - stateRoot.Version, - ) - } - - // Perform the migration - newHamtRoot, err := nv10.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) - if err != nil { - return cid.Undef, xerrors.Errorf("upgrading to actors v3: %w", err) - } - - // Persist the result. - newRoot, err := store.Put(ctx, &types.StateRoot{ - Version: types.StateTreeVersion2, - Actors: newHamtRoot, - Info: stateRoot.Info, - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) - } - - // Persist the new tree. - - { - from := buf - to := buf.Read() - - if err := vm.Copy(ctx, from, to, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) - } - } - - return newRoot, nil -} - -func UpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - // Use all the CPUs except 3. - workerCount := runtime.NumCPU() - 3 - if workerCount <= 0 { - workerCount = 1 - } - - config := nv12.Config{ - MaxWorkers: uint(workerCount), - JobQueueSize: 1000, - ResultQueueSize: 100, - ProgressLogPeriod: 10 * time.Second, - } - - newRoot, err := upgradeActorsV4Common(ctx, sm, cache, root, epoch, ts, config) - if err != nil { - return cid.Undef, xerrors.Errorf("migrating actors v4 state: %w", err) - } - - return newRoot, nil -} - -func PreUpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { - // Use half the CPUs for pre-migration, but leave at least 3. - workerCount := runtime.NumCPU() - if workerCount <= 4 { - workerCount = 1 - } else { - workerCount /= 2 - } - config := nv12.Config{MaxWorkers: uint(workerCount)} - _, err := upgradeActorsV4Common(ctx, sm, cache, root, epoch, ts, config) - return err -} - -func upgradeActorsV4Common( - ctx context.Context, sm *StateManager, cache MigrationCache, - root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, - config nv12.Config, -) (cid.Cid, error) { - buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) - store := store.ActorStore(ctx, buf) - - // Load the state root. - var stateRoot types.StateRoot - if err := store.Get(ctx, root, &stateRoot); err != nil { - return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) - } - - if stateRoot.Version != types.StateTreeVersion2 { - return cid.Undef, xerrors.Errorf( - "expected state root version 2 for actors v4 upgrade, got %d", - stateRoot.Version, - ) - } - - // Perform the migration - newHamtRoot, err := nv12.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) - if err != nil { - return cid.Undef, xerrors.Errorf("upgrading to actors v4: %w", err) - } - - // Persist the result. - newRoot, err := store.Put(ctx, &types.StateRoot{ - Version: types.StateTreeVersion3, - Actors: newHamtRoot, - Info: stateRoot.Info, - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) - } - - // Persist the new tree. - - { - from := buf - to := buf.Read() - - if err := vm.Copy(ctx, from, to, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) - } - } - - return newRoot, nil -} - -func UpgradeActorsV5(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - // Use all the CPUs except 3. - workerCount := runtime.NumCPU() - 3 - if workerCount <= 0 { - workerCount = 1 - } - - config := nv13.Config{ - MaxWorkers: uint(workerCount), - JobQueueSize: 1000, - ResultQueueSize: 100, - ProgressLogPeriod: 10 * time.Second, - } - - newRoot, err := upgradeActorsV5Common(ctx, sm, cache, root, epoch, ts, config) - if err != nil { - return cid.Undef, xerrors.Errorf("migrating actors v5 state: %w", err) - } - - return newRoot, nil -} - -func PreUpgradeActorsV5(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { - // Use half the CPUs for pre-migration, but leave at least 3. - workerCount := runtime.NumCPU() - if workerCount <= 4 { - workerCount = 1 - } else { - workerCount /= 2 - } - config := nv13.Config{MaxWorkers: uint(workerCount)} - _, err := upgradeActorsV5Common(ctx, sm, cache, root, epoch, ts, config) - return err -} - -func upgradeActorsV5Common( - ctx context.Context, sm *StateManager, cache MigrationCache, - root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, - config nv13.Config, -) (cid.Cid, error) { - buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) - store := store.ActorStore(ctx, buf) - - // Load the state root. - var stateRoot types.StateRoot - if err := store.Get(ctx, root, &stateRoot); err != nil { - return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) - } - - if stateRoot.Version != types.StateTreeVersion3 { - return cid.Undef, xerrors.Errorf( - "expected state root version 3 for actors v5 upgrade, got %d", - stateRoot.Version, - ) - } - - // Perform the migration - newHamtRoot, err := nv13.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) - if err != nil { - return cid.Undef, xerrors.Errorf("upgrading to actors v5: %w", err) - } - - // Persist the result. - newRoot, err := store.Put(ctx, &types.StateRoot{ - Version: types.StateTreeVersion4, - Actors: newHamtRoot, - Info: stateRoot.Info, - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) - } - - // Persist the new tree. - - { - from := buf - to := buf.Read() - - if err := vm.Copy(ctx, from, to, newRoot); err != nil { - return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) - } - } - - return newRoot, nil -} - func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, name string) error { - ia, err := tree.GetActor(builtin0.InitActorAddr) + ia, err := tree.GetActor(init_.Address) if err != nil { return xerrors.Errorf("getting init actor: %w", err) } @@ -1305,136 +438,13 @@ func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree, return xerrors.Errorf("writing new init state: %w", err) } - if err := tree.SetActor(builtin0.InitActorAddr, ia); err != nil { + if err := tree.SetActor(init_.Address, ia); err != nil { return xerrors.Errorf("setting init actor: %w", err) } return nil } -func splitGenesisMultisig0(ctx context.Context, em ExecMonitor, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch, ts *types.TipSet) error { - if portions < 1 { - return xerrors.Errorf("cannot split into 0 portions") - } - - mact, err := tree.GetActor(addr) - if err != nil { - return xerrors.Errorf("getting msig actor: %w", err) - } - - mst, err := multisig.Load(store, mact) - if err != nil { - return xerrors.Errorf("getting msig state: %w", err) - } - - signers, err := mst.Signers() - if err != nil { - return xerrors.Errorf("getting msig signers: %w", err) - } - - thresh, err := mst.Threshold() - if err != nil { - return xerrors.Errorf("getting msig threshold: %w", err) - } - - ibal, err := mst.InitialBalance() - if err != nil { - return xerrors.Errorf("getting msig initial balance: %w", err) - } - - se, err := mst.StartEpoch() - if err != nil { - return xerrors.Errorf("getting msig start epoch: %w", err) - } - - ud, err := mst.UnlockDuration() - if err != nil { - return xerrors.Errorf("getting msig unlock duration: %w", err) - } - - pending, err := adt0.MakeEmptyMap(store).Root() - if err != nil { - return xerrors.Errorf("failed to create empty map: %w", err) - } - - newIbal := big.Div(ibal, types.NewInt(portions)) - newState := &multisig0.State{ - Signers: signers, - NumApprovalsThreshold: thresh, - NextTxnID: 0, - InitialBalance: newIbal, - StartEpoch: se, - UnlockDuration: ud, - PendingTxns: pending, - } - - scid, err := store.Put(ctx, newState) - if err != nil { - return xerrors.Errorf("storing new state: %w", err) - } - - newActor := types.Actor{ - Code: builtin0.MultisigActorCodeID, - Head: scid, - Nonce: 0, - Balance: big.Zero(), - } - - i := uint64(0) - subcalls := make([]types.ExecutionTrace, 0, portions) - transferCb := func(trace types.ExecutionTrace) { - subcalls = append(subcalls, trace) - } - - for i < portions { - keyAddr, err := makeKeyAddr(addr, i) - if err != nil { - return xerrors.Errorf("creating key address: %w", err) - } - - idAddr, err := tree.RegisterNewAddress(keyAddr) - if err != nil { - return xerrors.Errorf("registering new address: %w", err) - } - - err = tree.SetActor(idAddr, &newActor) - if err != nil { - return xerrors.Errorf("setting new msig actor state: %w", err) - } - - if err := doTransfer(tree, addr, idAddr, newIbal, transferCb); err != nil { - return xerrors.Errorf("transferring split msig balance: %w", err) - } - - i++ - } - - if em != nil { - // record the transfer in execution traces - - fakeMsg := makeFakeMsg(builtin.SystemActorAddr, addr, big.Zero(), uint64(epoch)) - - if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ - MessageReceipt: *makeFakeRct(), - ActorErr: nil, - ExecutionTrace: types.ExecutionTrace{ - Msg: fakeMsg, - MsgRct: makeFakeRct(), - Error: "", - Duration: 0, - GasCharges: nil, - Subcalls: subcalls, - }, - Duration: 0, - GasCosts: nil, - }, false); err != nil { - return xerrors.Errorf("recording transfers: %w", err) - } - } - - return nil -} - func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, error) { var b bytes.Buffer if err := splitAddr.MarshalCBOR(&b); err != nil { @@ -1457,88 +467,6 @@ func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, erro return addr, nil } -// TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting -func resetGenesisMsigs0(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error { - gb, err := sm.cs.GetGenesis() - if err != nil { - return xerrors.Errorf("getting genesis block: %w", err) - } - - gts, err := types.NewTipSet([]*types.BlockHeader{gb}) - if err != nil { - return xerrors.Errorf("getting genesis tipset: %w", err) - } - - cst := cbor.NewCborStore(sm.cs.StateBlockstore()) - genesisTree, err := state.LoadStateTree(cst, gts.ParentState()) - if err != nil { - return xerrors.Errorf("loading state tree: %w", err) - } - - err = genesisTree.ForEach(func(addr address.Address, genesisActor *types.Actor) error { - if genesisActor.Code == builtin0.MultisigActorCodeID { - currActor, err := tree.GetActor(addr) - if err != nil { - return xerrors.Errorf("loading actor: %w", err) - } - - var currState multisig0.State - if err := store.Get(ctx, currActor.Head, &currState); err != nil { - return xerrors.Errorf("reading multisig state: %w", err) - } - - currState.StartEpoch = startEpoch - - currActor.Head, err = store.Put(ctx, &currState) - if err != nil { - return xerrors.Errorf("writing new multisig state: %w", err) - } - - if err := tree.SetActor(addr, currActor); err != nil { - return xerrors.Errorf("setting multisig actor: %w", err) - } - } - return nil - }) - - if err != nil { - return xerrors.Errorf("iterating over genesis actors: %w", err) - } - - return nil -} - -func resetMultisigVesting0(ctx context.Context, store adt0.Store, tree *state.StateTree, addr address.Address, startEpoch abi.ChainEpoch, duration abi.ChainEpoch, balance abi.TokenAmount) error { - act, err := tree.GetActor(addr) - if err != nil { - return xerrors.Errorf("getting actor: %w", err) - } - - if !builtin.IsMultisigActor(act.Code) { - return xerrors.Errorf("actor wasn't msig: %w", err) - } - - var msigState multisig0.State - if err := store.Get(ctx, act.Head, &msigState); err != nil { - return xerrors.Errorf("reading multisig state: %w", err) - } - - msigState.StartEpoch = startEpoch - msigState.UnlockDuration = duration - msigState.InitialBalance = balance - - act.Head, err = store.Put(ctx, &msigState) - if err != nil { - return xerrors.Errorf("writing new multisig state: %w", err) - } - - if err := tree.SetActor(addr, act); err != nil { - return xerrors.Errorf("setting multisig actor: %w", err) - } - - return nil -} - func makeFakeMsg(from address.Address, to address.Address, amt abi.TokenAmount, nonce uint64) *types.Message { return &types.Message{ From: from, diff --git a/chain/stmgr/upgrades.go b/chain/stmgr/upgrades.go new file mode 100644 index 00000000000..d2ccbad39a4 --- /dev/null +++ b/chain/stmgr/upgrades.go @@ -0,0 +1,1090 @@ +package stmgr + +import ( + "context" + "runtime" + "time" + + "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + "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/network" + + builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner" + multisig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig" + power0 "github.com/filecoin-project/specs-actors/actors/builtin/power" + "github.com/filecoin-project/specs-actors/actors/migration/nv3" + adt0 "github.com/filecoin-project/specs-actors/actors/util/adt" + "github.com/filecoin-project/specs-actors/v2/actors/migration/nv4" + "github.com/filecoin-project/specs-actors/v2/actors/migration/nv7" + "github.com/filecoin-project/specs-actors/v3/actors/migration/nv10" + "github.com/filecoin-project/specs-actors/v4/actors/migration/nv12" + "github.com/filecoin-project/specs-actors/v5/actors/migration/nv13" + + "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" + "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" +) + +func DefaultUpgradeSchedule() UpgradeSchedule { + var us UpgradeSchedule + + updates := []Upgrade{{ + Height: build.UpgradeBreezeHeight, + Network: network.Version1, + Migration: UpgradeFaucetBurnRecovery, + }, { + Height: build.UpgradeSmokeHeight, + Network: network.Version2, + Migration: nil, + }, { + Height: build.UpgradeIgnitionHeight, + Network: network.Version3, + Migration: UpgradeIgnition, + }, { + Height: build.UpgradeRefuelHeight, + Network: network.Version3, + Migration: UpgradeRefuel, + }, { + Height: build.UpgradeAssemblyHeight, + Network: network.Version4, + Expensive: true, + Migration: UpgradeActorsV2, + }, { + Height: build.UpgradeTapeHeight, + Network: network.Version5, + Migration: nil, + }, { + Height: build.UpgradeLiftoffHeight, + Network: network.Version5, + Migration: UpgradeLiftoff, + }, { + Height: build.UpgradeKumquatHeight, + Network: network.Version6, + Migration: nil, + }, { + Height: build.UpgradeCalicoHeight, + Network: network.Version7, + Migration: UpgradeCalico, + }, { + Height: build.UpgradePersianHeight, + Network: network.Version8, + Migration: nil, + }, { + Height: build.UpgradeOrangeHeight, + Network: network.Version9, + Migration: nil, + }, { + Height: build.UpgradeTrustHeight, + Network: network.Version10, + Migration: UpgradeActorsV3, + PreMigrations: []PreMigration{{ + PreMigration: PreUpgradeActorsV3, + StartWithin: 120, + DontStartWithin: 60, + StopWithin: 35, + }, { + PreMigration: PreUpgradeActorsV3, + StartWithin: 30, + DontStartWithin: 15, + StopWithin: 5, + }}, + Expensive: true, + }, { + Height: build.UpgradeNorwegianHeight, + Network: network.Version11, + Migration: nil, + }, { + Height: build.UpgradeTurboHeight, + Network: network.Version12, + Migration: UpgradeActorsV4, + PreMigrations: []PreMigration{{ + PreMigration: PreUpgradeActorsV4, + StartWithin: 120, + DontStartWithin: 60, + StopWithin: 35, + }, { + PreMigration: PreUpgradeActorsV4, + StartWithin: 30, + DontStartWithin: 15, + StopWithin: 5, + }}, + Expensive: true, + }, { + Height: build.UpgradeHyperdriveHeight, + Network: network.Version13, + Migration: UpgradeActorsV5, + PreMigrations: []PreMigration{{ + PreMigration: PreUpgradeActorsV5, + StartWithin: 120, + DontStartWithin: 60, + StopWithin: 35, + }, { + PreMigration: PreUpgradeActorsV5, + StartWithin: 30, + DontStartWithin: 15, + StopWithin: 5, + }}, + Expensive: true}} + + for _, u := range updates { + if u.Height < 0 { + // upgrade disabled + continue + } + us = append(us, u) + } + return us +} + +func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, _ MigrationCache, em ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, 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, ts, false) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to get tipset at lookback height: %w", err) + } + + lbtree, err := sm.ParentState(lbts) + if err != nil { + return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err) + } + + tree, err := sm.StateTree(root) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } + + type transfer struct { + From address.Address + To address.Address + Amt abi.TokenAmount + } + + var transfers []transfer + subcalls := make([]types.ExecutionTrace, 0) + transferCb := func(trace types.ExecutionTrace) { + subcalls = append(subcalls, trace) + } + + // Take all excess funds away, put them into the reserve account + err = tree.ForEach(func(addr address.Address, act *types.Actor) error { + switch act.Code { + case builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.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: builtin.ReserveAddress, + Amt: act.Balance, + }) + } + case builtin0.StorageMinerActorCodeID: + var st miner0.State + if err := sm.ChainStore().ActorStore(ctx).Get(ctx, act.Head, &st); 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) + } + + if !available.IsZero() { + transfers = append(transfers, transfer{ + From: addr, + To: builtin.ReserveAddress, + Amt: available, + }) + } + } + return nil + }) + if err != nil { + return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err) + } + + // Execute transfers from previous step + for _, t := range transfers { + if err := doTransfer(tree, t.From, t.To, t.Amt, transferCb); err != nil { + return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) + } + } + + // pull up power table to give miners back some funds proportional to their power + var ps power0.State + powAct, err := tree.GetActor(builtin0.StoragePowerActorAddr) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to load power actor: %w", err) + } + + cst := cbor.NewCborStore(sm.ChainStore().StateBlockstore()) + if err := cst.Get(ctx, powAct.Head, &ps); err != nil { + return cid.Undef, xerrors.Errorf("failed to get power actor state: %w", err) + } + + totalPower := ps.TotalBytesCommitted + + var transfersBack []transfer + // Now, we return some funds to places where they are needed + err = tree.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 builtin0.AccountActorCodeID, builtin0.MultisigActorCodeID, builtin0.PaymentChannelActorCodeID: + nbalance := big.Min(prevBalance, AccountCap) + if nbalance.Sign() != 0 { + transfersBack = append(transfersBack, transfer{ + From: builtin.ReserveAddress, + To: addr, + Amt: nbalance, + }) + } + case builtin0.StorageMinerActorCodeID: + var st miner0.State + if err := sm.ChainStore().ActorStore(ctx).Get(ctx, act.Head, &st); err != nil { + return xerrors.Errorf("failed to load miner state: %w", err) + } + + var minfo miner0.MinerInfo + if err := cst.Get(ctx, st.Info, &minfo); err != nil { + return xerrors.Errorf("failed to get miner info: %w", err) + } + + sectorsArr, err := adt0.AsArray(sm.ChainStore().ActorStore(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: builtin.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 miner0.State + if err := sm.ChainStore().ActorStore(ctx).Get(ctx, lbact.Head, &lbst); err != nil { + return xerrors.Errorf("failed to load miner state: %w", err) + } + + lbsectors, err := adt0.AsArray(sm.ChainStore().ActorStore(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: builtin.ReserveAddress, + To: minfo.Worker, + Amt: BaseMinerBalance, + }) + } + + } else { + log.Warnf("failed to get miner in lookback state: %s", err) + } + } + return nil + }) + if err != nil { + return cid.Undef, xerrors.Errorf("foreach over state tree failed: %w", err) + } + + for _, t := range transfersBack { + if err := doTransfer(tree, t.From, t.To, t.Amt, transferCb); err != nil { + return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err) + } + } + + // transfer all burnt funds back to the reserve account + burntAct, err := tree.GetActor(builtin0.BurntFundsActorAddr) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to load burnt funds actor: %w", err) + } + if err := doTransfer(tree, builtin0.BurntFundsActorAddr, builtin.ReserveAddress, burntAct.Balance, transferCb); err != nil { + return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err) + } + + // Top up the reimbursement service + reimbAddr, err := address.NewFromString("t0111") + if err != nil { + return cid.Undef, xerrors.Errorf("failed to parse reimbursement service address") + } + + reimb, err := tree.GetActor(reimbAddr) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to load reimbursement account actor: %w", err) + } + + difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance) + if err := doTransfer(tree, builtin.ReserveAddress, reimbAddr, difference, transferCb); err != nil { + return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err) + } + + // Now, a final sanity check to make sure the balances all check out + total := abi.NewTokenAmount(0) + err = tree.ForEach(func(addr address.Address, act *types.Actor) error { + total = types.BigAdd(total, act.Balance) + return nil + }) + if err != nil { + return cid.Undef, xerrors.Errorf("checking final state balance failed: %w", err) + } + + exp := types.FromFil(build.FilBase) + if !exp.Equals(total) { + return cid.Undef, xerrors.Errorf("resultant state tree account balance was not correct: %s", total) + } + + if em != nil { + // record the transfer in execution traces + + fakeMsg := makeFakeMsg(builtin.SystemActorAddr, builtin.SystemActorAddr, big.Zero(), uint64(epoch)) + + if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ + MessageReceipt: *makeFakeRct(), + ActorErr: nil, + ExecutionTrace: types.ExecutionTrace{ + Msg: fakeMsg, + MsgRct: makeFakeRct(), + Error: "", + Duration: 0, + GasCharges: nil, + Subcalls: subcalls, + }, + Duration: 0, + GasCosts: nil, + }, false); err != nil { + return cid.Undef, xerrors.Errorf("recording transfers: %w", err) + } + } + + return tree.Flush(ctx) +} + +func UpgradeIgnition(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + store := sm.cs.ActorStore(ctx) + + if build.UpgradeLiftoffHeight <= epoch { + return cid.Undef, xerrors.Errorf("liftoff height must be beyond ignition height") + } + + nst, err := nv3.MigrateStateTree(ctx, store, root, epoch) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors state: %w", err) + } + + tree, err := sm.StateTree(nst) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } + + err = setNetworkName(ctx, store, tree, "ignition") + if err != nil { + return cid.Undef, xerrors.Errorf("setting network name: %w", err) + } + + split1, err := address.NewFromString("t0115") + if err != nil { + return cid.Undef, xerrors.Errorf("first split address: %w", err) + } + + split2, err := address.NewFromString("t0116") + if err != nil { + return cid.Undef, xerrors.Errorf("second split address: %w", err) + } + + err = resetGenesisMsigs0(ctx, sm, store, tree, build.UpgradeLiftoffHeight) + if err != nil { + return cid.Undef, xerrors.Errorf("resetting genesis msig start epochs: %w", err) + } + + err = splitGenesisMultisig0(ctx, cb, split1, store, tree, 50, epoch, ts) + if err != nil { + return cid.Undef, xerrors.Errorf("splitting first msig: %w", err) + } + + err = splitGenesisMultisig0(ctx, cb, split2, store, tree, 50, epoch, ts) + if err != nil { + return cid.Undef, xerrors.Errorf("splitting second msig: %w", err) + } + + err = nv3.CheckStateTree(ctx, store, nst, epoch, builtin0.TotalFilecoin) + if err != nil { + return cid.Undef, xerrors.Errorf("sanity check after ignition upgrade failed: %w", err) + } + + return tree.Flush(ctx) +} + +func splitGenesisMultisig0(ctx context.Context, em ExecMonitor, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch, ts *types.TipSet) error { + if portions < 1 { + return xerrors.Errorf("cannot split into 0 portions") + } + + mact, err := tree.GetActor(addr) + if err != nil { + return xerrors.Errorf("getting msig actor: %w", err) + } + + mst, err := multisig.Load(store, mact) + if err != nil { + return xerrors.Errorf("getting msig state: %w", err) + } + + signers, err := mst.Signers() + if err != nil { + return xerrors.Errorf("getting msig signers: %w", err) + } + + thresh, err := mst.Threshold() + if err != nil { + return xerrors.Errorf("getting msig threshold: %w", err) + } + + ibal, err := mst.InitialBalance() + if err != nil { + return xerrors.Errorf("getting msig initial balance: %w", err) + } + + se, err := mst.StartEpoch() + if err != nil { + return xerrors.Errorf("getting msig start epoch: %w", err) + } + + ud, err := mst.UnlockDuration() + if err != nil { + return xerrors.Errorf("getting msig unlock duration: %w", err) + } + + pending, err := adt0.MakeEmptyMap(store).Root() + if err != nil { + return xerrors.Errorf("failed to create empty map: %w", err) + } + + newIbal := big.Div(ibal, types.NewInt(portions)) + newState := &multisig0.State{ + Signers: signers, + NumApprovalsThreshold: thresh, + NextTxnID: 0, + InitialBalance: newIbal, + StartEpoch: se, + UnlockDuration: ud, + PendingTxns: pending, + } + + scid, err := store.Put(ctx, newState) + if err != nil { + return xerrors.Errorf("storing new state: %w", err) + } + + newActor := types.Actor{ + Code: builtin0.MultisigActorCodeID, + Head: scid, + Nonce: 0, + Balance: big.Zero(), + } + + i := uint64(0) + subcalls := make([]types.ExecutionTrace, 0, portions) + transferCb := func(trace types.ExecutionTrace) { + subcalls = append(subcalls, trace) + } + + for i < portions { + keyAddr, err := makeKeyAddr(addr, i) + if err != nil { + return xerrors.Errorf("creating key address: %w", err) + } + + idAddr, err := tree.RegisterNewAddress(keyAddr) + if err != nil { + return xerrors.Errorf("registering new address: %w", err) + } + + err = tree.SetActor(idAddr, &newActor) + if err != nil { + return xerrors.Errorf("setting new msig actor state: %w", err) + } + + if err := doTransfer(tree, addr, idAddr, newIbal, transferCb); err != nil { + return xerrors.Errorf("transferring split msig balance: %w", err) + } + + i++ + } + + if em != nil { + // record the transfer in execution traces + + fakeMsg := makeFakeMsg(builtin.SystemActorAddr, addr, big.Zero(), uint64(epoch)) + + if err := em.MessageApplied(ctx, ts, fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{ + MessageReceipt: *makeFakeRct(), + ActorErr: nil, + ExecutionTrace: types.ExecutionTrace{ + Msg: fakeMsg, + MsgRct: makeFakeRct(), + Error: "", + Duration: 0, + GasCharges: nil, + Subcalls: subcalls, + }, + Duration: 0, + GasCosts: nil, + }, false); err != nil { + return xerrors.Errorf("recording transfers: %w", err) + } + } + + return nil +} + +// TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting +func resetGenesisMsigs0(ctx context.Context, sm *StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error { + gb, err := sm.cs.GetGenesis() + if err != nil { + return xerrors.Errorf("getting genesis block: %w", err) + } + + gts, err := types.NewTipSet([]*types.BlockHeader{gb}) + if err != nil { + return xerrors.Errorf("getting genesis tipset: %w", err) + } + + cst := cbor.NewCborStore(sm.cs.StateBlockstore()) + genesisTree, err := state.LoadStateTree(cst, gts.ParentState()) + if err != nil { + return xerrors.Errorf("loading state tree: %w", err) + } + + err = genesisTree.ForEach(func(addr address.Address, genesisActor *types.Actor) error { + if genesisActor.Code == builtin0.MultisigActorCodeID { + currActor, err := tree.GetActor(addr) + if err != nil { + return xerrors.Errorf("loading actor: %w", err) + } + + var currState multisig0.State + if err := store.Get(ctx, currActor.Head, &currState); err != nil { + return xerrors.Errorf("reading multisig state: %w", err) + } + + currState.StartEpoch = startEpoch + + currActor.Head, err = store.Put(ctx, &currState) + if err != nil { + return xerrors.Errorf("writing new multisig state: %w", err) + } + + if err := tree.SetActor(addr, currActor); err != nil { + return xerrors.Errorf("setting multisig actor: %w", err) + } + } + return nil + }) + + if err != nil { + return xerrors.Errorf("iterating over genesis actors: %w", err) + } + + return nil +} + +func resetMultisigVesting0(ctx context.Context, store adt0.Store, tree *state.StateTree, addr address.Address, startEpoch abi.ChainEpoch, duration abi.ChainEpoch, balance abi.TokenAmount) error { + act, err := tree.GetActor(addr) + if err != nil { + return xerrors.Errorf("getting actor: %w", err) + } + + if !builtin.IsMultisigActor(act.Code) { + return xerrors.Errorf("actor wasn't msig: %w", err) + } + + var msigState multisig0.State + if err := store.Get(ctx, act.Head, &msigState); err != nil { + return xerrors.Errorf("reading multisig state: %w", err) + } + + msigState.StartEpoch = startEpoch + msigState.UnlockDuration = duration + msigState.InitialBalance = balance + + act.Head, err = store.Put(ctx, &msigState) + if err != nil { + return xerrors.Errorf("writing new multisig state: %w", err) + } + + if err := tree.SetActor(addr, act); err != nil { + return xerrors.Errorf("setting multisig actor: %w", err) + } + + return nil +} + +func UpgradeRefuel(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + + store := sm.cs.ActorStore(ctx) + tree, err := sm.StateTree(root) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } + + err = resetMultisigVesting0(ctx, store, tree, builtin.SaftAddress, 0, 0, big.Zero()) + if err != nil { + return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) + } + + err = resetMultisigVesting0(ctx, store, tree, builtin.ReserveAddress, 0, 0, big.Zero()) + if err != nil { + return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) + } + + err = resetMultisigVesting0(ctx, store, tree, builtin.RootVerifierAddress, 0, 0, big.Zero()) + if err != nil { + return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err) + } + + return tree.Flush(ctx) +} + +func UpgradeActorsV2(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + info, err := store.Put(ctx, new(types.StateInfo0)) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create new state info for actors v2: %w", err) + } + + newHamtRoot, err := nv4.MigrateStateTree(ctx, store, root, epoch, nv4.DefaultConfig()) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v2: %w", err) + } + + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion1, + Actors: newHamtRoot, + Info: info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // perform some basic sanity checks to make sure everything still works. + if newSm, err := state.LoadStateTree(store, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err) + } else if newRoot2, err := newSm.Flush(ctx); err != nil { + return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err) + } else if newRoot2 != newRoot { + return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2) + } else if _, err := newSm.GetActor(builtin0.InitActorAddr); err != nil { + return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err) + } + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil +} + +func UpgradeLiftoff(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + tree, err := sm.StateTree(root) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } + + err = setNetworkName(ctx, sm.cs.ActorStore(ctx), tree, "mainnet") + if err != nil { + return cid.Undef, xerrors.Errorf("setting network name: %w", err) + } + + return tree.Flush(ctx) +} + +func UpgradeCalico(ctx context.Context, sm *StateManager, _ MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + if build.BuildType != build.BuildMainnet { + return root, nil + } + + store := sm.cs.ActorStore(ctx) + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion1 { + return cid.Undef, xerrors.Errorf( + "expected state root version 1 for calico upgrade, got %d", + stateRoot.Version, + ) + } + + newHamtRoot, err := nv7.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, nv7.DefaultConfig()) + if err != nil { + return cid.Undef, xerrors.Errorf("running nv7 migration: %w", err) + } + + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: stateRoot.Version, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // perform some basic sanity checks to make sure everything still works. + if newSm, err := state.LoadStateTree(store, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("state tree sanity load failed: %w", err) + } else if newRoot2, err := newSm.Flush(ctx); err != nil { + return cid.Undef, xerrors.Errorf("state tree sanity flush failed: %w", err) + } else if newRoot2 != newRoot { + return cid.Undef, xerrors.Errorf("state-root mismatch: %s != %s", newRoot, newRoot2) + } else if _, err := newSm.GetActor(builtin0.InitActorAddr); err != nil { + return cid.Undef, xerrors.Errorf("failed to load init actor after upgrade: %w", err) + } + + return newRoot, nil +} + +func UpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + // Use all the CPUs except 3. + workerCount := runtime.NumCPU() - 3 + if workerCount <= 0 { + workerCount = 1 + } + + config := nv10.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + newRoot, err := upgradeActorsV3Common(ctx, sm, cache, root, epoch, ts, config) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors v3 state: %w", err) + } + + tree, err := sm.StateTree(newRoot) + if err != nil { + return cid.Undef, xerrors.Errorf("getting state tree: %w", err) + } + + if build.BuildType == build.BuildMainnet { + err := terminateActor(ctx, tree, build.ZeroAddress, cb, epoch, ts) + if err != nil && !xerrors.Is(err, types.ErrActorNotFound) { + return cid.Undef, xerrors.Errorf("deleting zero bls actor: %w", err) + } + + newRoot, err = tree.Flush(ctx) + if err != nil { + return cid.Undef, xerrors.Errorf("flushing state tree: %w", err) + } + } + + return newRoot, nil +} + +func PreUpgradeActorsV3(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := runtime.NumCPU() + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + config := nv10.Config{MaxWorkers: uint(workerCount)} + _, err := upgradeActorsV3Common(ctx, sm, cache, root, epoch, ts, config) + return err +} + +func upgradeActorsV3Common( + ctx context.Context, sm *StateManager, cache MigrationCache, + root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, + config nv10.Config, +) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + // Load the state root. + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion1 { + return cid.Undef, xerrors.Errorf( + "expected state root version 1 for actors v3 upgrade, got %d", + stateRoot.Version, + ) + } + + // Perform the migration + newHamtRoot, err := nv10.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v3: %w", err) + } + + // Persist the result. + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion2, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // Persist the new tree. + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil +} + +func UpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + // Use all the CPUs except 3. + workerCount := runtime.NumCPU() - 3 + if workerCount <= 0 { + workerCount = 1 + } + + config := nv12.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + + newRoot, err := upgradeActorsV4Common(ctx, sm, cache, root, epoch, ts, config) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors v4 state: %w", err) + } + + return newRoot, nil +} + +func PreUpgradeActorsV4(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := runtime.NumCPU() + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + config := nv12.Config{MaxWorkers: uint(workerCount)} + _, err := upgradeActorsV4Common(ctx, sm, cache, root, epoch, ts, config) + return err +} + +func upgradeActorsV4Common( + ctx context.Context, sm *StateManager, cache MigrationCache, + root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, + config nv12.Config, +) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + // Load the state root. + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion2 { + return cid.Undef, xerrors.Errorf( + "expected state root version 2 for actors v4 upgrade, got %d", + stateRoot.Version, + ) + } + + // Perform the migration + newHamtRoot, err := nv12.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v4: %w", err) + } + + // Persist the result. + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion3, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // Persist the new tree. + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil +} + +func UpgradeActorsV5(ctx context.Context, sm *StateManager, cache MigrationCache, cb ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + // Use all the CPUs except 3. + workerCount := runtime.NumCPU() - 3 + if workerCount <= 0 { + workerCount = 1 + } + + config := nv13.Config{ + MaxWorkers: uint(workerCount), + JobQueueSize: 1000, + ResultQueueSize: 100, + ProgressLogPeriod: 10 * time.Second, + } + + newRoot, err := upgradeActorsV5Common(ctx, sm, cache, root, epoch, ts, config) + if err != nil { + return cid.Undef, xerrors.Errorf("migrating actors v5 state: %w", err) + } + + return newRoot, nil +} + +func PreUpgradeActorsV5(ctx context.Context, sm *StateManager, cache MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error { + // Use half the CPUs for pre-migration, but leave at least 3. + workerCount := runtime.NumCPU() + if workerCount <= 4 { + workerCount = 1 + } else { + workerCount /= 2 + } + config := nv13.Config{MaxWorkers: uint(workerCount)} + _, err := upgradeActorsV5Common(ctx, sm, cache, root, epoch, ts, config) + return err +} + +func upgradeActorsV5Common( + ctx context.Context, sm *StateManager, cache MigrationCache, + root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet, + config nv13.Config, +) (cid.Cid, error) { + buf := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) + store := store.ActorStore(ctx, buf) + + // Load the state root. + var stateRoot types.StateRoot + if err := store.Get(ctx, root, &stateRoot); err != nil { + return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err) + } + + if stateRoot.Version != types.StateTreeVersion3 { + return cid.Undef, xerrors.Errorf( + "expected state root version 3 for actors v5 upgrade, got %d", + stateRoot.Version, + ) + } + + // Perform the migration + newHamtRoot, err := nv13.MigrateStateTree(ctx, store, stateRoot.Actors, epoch, config, migrationLogger{}, cache) + if err != nil { + return cid.Undef, xerrors.Errorf("upgrading to actors v5: %w", err) + } + + // Persist the result. + newRoot, err := store.Put(ctx, &types.StateRoot{ + Version: types.StateTreeVersion4, + Actors: newHamtRoot, + Info: stateRoot.Info, + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + } + + // Persist the new tree. + + { + from := buf + to := buf.Read() + + if err := vm.Copy(ctx, from, to, newRoot); err != nil { + return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err) + } + } + + return newRoot, nil +} diff --git a/chain/sync.go b/chain/sync.go index 5d3c1d99296..7914cc8d5fd 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -1060,7 +1060,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock } nv := syncer.sm.GetNtwkVersion(ctx, b.Header.Height) - pl := vm.PricelistByVersion(nv) + pl := vm.PricelistByEpoch(baseTs.Height()) var sumGasLimit int64 checkMsg := func(msg types.ChainMsg) error { m := msg.VMMessage() diff --git a/chain/vm/gas.go b/chain/vm/gas.go index b848550f3fd..206a55d3643 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -7,7 +7,7 @@ import ( addr "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/go-state-types/network" + "github.com/filecoin-project/lotus/build" vmr5 "github.com/filecoin-project/specs-actors/v5/actors/runtime" proof5 "github.com/filecoin-project/specs-actors/v5/actors/runtime/proof" "github.com/ipfs/go-cid" @@ -79,8 +79,8 @@ type Pricelist interface { OnVerifyConsensusFault() GasCharge } -var prices = map[network.Version]Pricelist{ - network.Version0: &pricelistV0{ +var prices = map[abi.ChainEpoch]Pricelist{ + abi.ChainEpoch(0): &pricelistV0{ computeGasMulti: 1, storageGasMulti: 1000, @@ -129,7 +129,7 @@ var prices = map[network.Version]Pricelist{ verifyPostDiscount: true, verifyConsensusFault: 495422, }, - network.Version6AndAHalf: &pricelistV0{ + abi.ChainEpoch(build.UpgradeCalicoHeight): &pricelistV0{ computeGasMulti: 1, storageGasMulti: 1300, @@ -207,19 +207,21 @@ var prices = map[network.Version]Pricelist{ }, } -// PricelistByVersion finds the latest prices for the given network version -func PricelistByVersion(version network.Version) Pricelist { - bestVersion := network.Version0 - bestPrice := prices[bestVersion] - for nv, pl := range prices { - // if `nv > bestVersion` and `nv <= version` - if nv > bestVersion && nv <= version { - bestVersion = nv +// PricelistByEpoch finds the latest prices for the given epoch +func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist { + // since we are storing the prices as map or epoch to price + // we need to get the price with the highest epoch that is lower or equal to the `epoch` arg + bestEpoch := abi.ChainEpoch(0) + bestPrice := prices[bestEpoch] + for e, pl := range prices { + // if `e` happened after `bestEpoch` and `e` is earlier or equal to the target `epoch` + if e > bestEpoch && e <= epoch { + bestEpoch = e bestPrice = pl } } if bestPrice == nil { - panic(fmt.Sprintf("bad setup: no gas prices available for version %d", version)) + panic(fmt.Sprintf("bad setup: no gas prices available for epoch %d", epoch)) } return bestPrice } diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 4beee5ce6d6..e461a2b4c51 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -41,7 +41,7 @@ var EmptyObjectCid cid.Cid // TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses. func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, address.Address, aerrors.ActorError) { - if err := rt.chargeGasSafe(PricelistByVersion(rt.NetworkVersion()).OnCreateActor()); err != nil { + if err := rt.chargeGasSafe(PricelistByEpoch(rt.height).OnCreateActor()); err != nil { return nil, address.Undef, err } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 2746d5f17c0..5a31187b7b9 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -135,7 +135,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runti gasAvailable: msg.GasLimit, depth: 0, numActorsCreated: 0, - pricelist: PricelistByVersion(vm.ntwkVersion(ctx, vm.blockHeight)), + pricelist: PricelistByEpoch(vm.blockHeight), allowInternal: true, callerValidated: false, executionTrace: types.ExecutionTrace{Msg: msg}, @@ -424,7 +424,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, return nil, err } - pl := PricelistByVersion(vm.ntwkVersion(ctx, vm.blockHeight)) + pl := PricelistByEpoch(vm.blockHeight) msgGas := pl.OnChainMessage(cmsg.ChainLength()) msgGasCost := msgGas.Total() diff --git a/cli/cmd.go b/cli/cmd.go index 775911f4233..71524d787d2 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -90,4 +90,4 @@ var Commands = []*cli.Command{ func WithCategory(cat string, cmd *cli.Command) *cli.Command { cmd.Category = strings.ToUpper(cat) return cmd -} \ No newline at end of file +} diff --git a/cmd/lotus-miner/main.go b/cmd/lotus-miner/main.go index 3c432a962e4..9cee61b0375 100644 --- a/cmd/lotus-miner/main.go +++ b/cmd/lotus-miner/main.go @@ -171,4 +171,4 @@ func getActorAddress(ctx context.Context, cctx *cli.Context) (maddr address.Addr } return maddr, nil -} \ No newline at end of file +} diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 3b6d5ac5181..86cf62bbcd8 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -201,7 +201,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 131329, + "APIVersion": 131328, "BlockDelay": 42 } ``` diff --git a/documentation/en/api-v0-methods-worker.md b/documentation/en/api-v0-methods-worker.md index 341846759f0..c620113f489 100644 --- a/documentation/en/api-v0-methods-worker.md +++ b/documentation/en/api-v0-methods-worker.md @@ -144,7 +144,7 @@ Perms: admin Inputs: `null` -Response: `131329` +Response: `131328` ## Add diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index bc67382d6e2..6b09ffc2a7b 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -280,7 +280,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 131329, + "APIVersion": 131328, "BlockDelay": 42 } ``` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index cbaed82af3b..20528712ada 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -284,7 +284,7 @@ Response: ```json { "Version": "string value", - "APIVersion": 131329, + "APIVersion": 131328, "BlockDelay": 42 } ``` From 35c8c5885b6a82c3fa744fa211ac9c9a939154b3 Mon Sep 17 00:00:00 2001 From: ZenGround0 Date: Tue, 10 Aug 2021 15:59:20 -0400 Subject: [PATCH 70/79] Update deps to revert version representation --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index d5a18fd3225..e705ecf91c3 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 - github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 + github.com/filecoin-project/go-state-types v0.1.1-0.20210810190654-139e0e79e69e github.com/filecoin-project/go-statemachine v1.0.1 github.com/filecoin-project/go-statestore v0.1.1 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b @@ -49,7 +49,7 @@ require ( github.com/filecoin-project/specs-actors/v2 v2.3.5 github.com/filecoin-project/specs-actors/v3 v3.1.1 github.com/filecoin-project/specs-actors/v4 v4.0.1 - github.com/filecoin-project/specs-actors/v5 v5.0.3 + github.com/filecoin-project/specs-actors/v5 v5.0.4 github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 6815cfa9881..22e10049344 100644 --- a/go.sum +++ b/go.sum @@ -312,8 +312,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200928172055-2df22083d8ab/go github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-state-types v0.1.1-0.20210506134452-99b279731c48/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= -github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 h1:veGrNABg/9I7prngrowkhwbvW5d5JN55MNKmbsr5FqA= -github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= +github.com/filecoin-project/go-state-types v0.1.1-0.20210810190654-139e0e79e69e h1:XAgb6HmgXaGRklNjhZoNMSIYriKLqjWXIqYMotg6iSs= +github.com/filecoin-project/go-state-types v0.1.1-0.20210810190654-139e0e79e69e/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.1 h1:LQ60+JDVjMdLxXmVFM2jjontzOYnfVE7u02CXV3WKSw= github.com/filecoin-project/go-statemachine v1.0.1/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= @@ -339,8 +339,8 @@ github.com/filecoin-project/specs-actors/v4 v4.0.0/go.mod h1:TkHXf/l7Wyw4ZejyXIP github.com/filecoin-project/specs-actors/v4 v4.0.1 h1:AiWrtvJZ63MHGe6rn7tPu4nSUY8bA1KDNszqJaD5+Fg= github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-actors/v5 v5.0.0-20210512015452-4fe3889fff57/go.mod h1:283yBMMUSDB2abcjP/hhrwTkhb9h3sfM6KGrep/ZlBI= -github.com/filecoin-project/specs-actors/v5 v5.0.3 h1:hMQIGfkZ1kN+oVGaDXbpsu9YEUEyL/zWJSeoaZpruu4= -github.com/filecoin-project/specs-actors/v5 v5.0.3/go.mod h1:E0yeEl6Scl6eWeeWmxwQsAufvOAC72H6ELyh2Y62H90= +github.com/filecoin-project/specs-actors/v5 v5.0.4 h1:OY7BdxJWlUfUFXWV/kpNBYGXNPasDIedf42T3sGx08s= +github.com/filecoin-project/specs-actors/v5 v5.0.4/go.mod h1:5BAKRAMsOOlD8+qCw4UvT/lTLInCJ3JwOWZbX8Ipwq4= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= From f34631facc953665e30a038e5e0f6a061c44efcc Mon Sep 17 00:00:00 2001 From: ZenGround0 Date: Tue, 10 Aug 2021 16:31:05 -0400 Subject: [PATCH 71/79] Fix docsgen --- build/openrpc/full.json.gz | Bin 25241 -> 25239 bytes documentation/en/api-v0-methods.md | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 35adbd50b6fa41e2d3a10a4790f6543e342fb6db..110ab177a08b89db8c67c05a671f075cc601c2ab 100644 GIT binary patch delta 1357 zcmV-T1+w~?#Q~Sa0kE7-e_Nj=Y$!i^Qx|6996?v5%4@}n;_559ksjz2dVIN%j=Sv6 zcQic;1KV;!K{o1EbR`yw!TiDi6J?&NDZui=2L7GN@-LcHGVe?*#!*5eoh6pKsKeVv zI;&>Wys$A%jWfJz@*8S&^~pcgw|U(6Jzu@8i;W;J4lUa9d{NgB0d|ufPa`&DvP6u* z3F-sLSUAIE0x$=2$YRT{I!PRP)VVH(3{r4&>xx{FlQDq$H@HR%fk%9mpV#fnQcvcZisbZ;=`Zx1T&RT#VZ{B4b3 zrEoIEhl+SI`_d@biezQofyhs6A{vV{dFjw_Nz>u;-v@M-iLp;5coYTy5bQ-`+YgYP z;u+@hZj+o*F#)%e&QVAKMw1s(Dj7E>5rNV@Bzbg+qsc!<FPrZAW!IVdi|k$^$^cf$sohI9y$ zDI0CditzQhN^b9L?{pA(VfUT_2b8BNh-5@bmXoiulsy^Wd#7pn;H;_WQiFJ#hCh#6LO;Jd>nVAOYu-#Z@0o*eEMSM)^^mPAZ*k zs`KPhxinJg04tI7E@qZW2gQ(HmSxd0CoU1aX^Sg@O>8SIGH!^;iLJ}3?=~iFLiyZcyq$UYqvZ{C!eciHvlS5aB4dp(<2uB`9go{UE%S4mc zS85>3Lc|fy(F8LdEY2y_3v&h5n`^8=-i16rHsrIp4(k$=VOSyp@-VZ7SR(-f`t-A^ PS?34{!^Aan((42O=+uR( delta 1436 zcmV;N1!MY`#Q~Yc0kE7-f48?=pC)W5M|x8iXyP0}S0&49#f;+WD>{-M=p=f4xtNZ- z?9O{MJqiQsaza5i?pAau7K*|A!T=Lxo~kjxa>E85p2_kr8dWmyOl-zcN+X>omb$3J z`$jsiX4A~DF-?tgylV0r>U8z#Kh?K++&4a7y{(ImAg>NB+VXr+1J@9ElN?VYHsrEI zjKK-&1ISo7!(;+52Xn|`+pjuH9C_5aE(Q%!fOG4LT#=J8fciJMMhk&Re3hZs?aOnM zbx$A-;wOMa%`RYYq1^j4^pm1bMg@t#7}D;O?N2Q|Cm2Jw(Ba-fclCFOn2d0d8VI^Y zPRNm~rhNfE{eE$&oPSgcC3Im1(BC2SL}zjC9FPrZAW!Stu^Tk$^$^cf$so26YIVoEd6DN>UaSSIj*Sk)BG^tP@#EQh$QNbdqw;6x%y3?~X*t77lh{%&2d=4VanLgVlMPcG0pOD=Q!jt4 zMkUy?d5l~IGMm;*;nCFt9$IE>nQ@oQSZmr1ck$z9;*acTW^cPL80Q6ofio3srPb+7 zT)o8sjl3lQM|ewm?aHtuecFU8!rS>SbG5L&T=cZO)`81N|>sp-VNe zFlfVz;02l@l}<(Tg{xxfJpTQi8@a;)t?RHbl>vu?)=cpcY6^DRhBb>MPJAz zo+a^u-@(9Jv=jBZs!@Pi-RYByQL;Cvi^Qrv;RnP^Z}T^hLb`v6b&H@T5lS+IbuECB z@ivk^5jE+HL$Nco3`(*rHP03}*L6wgc>t5dKROCMD4M}(?`~y(jNPY2fvuDroWX^3 zogN_o9VZMRN1|OB>0UI>`XFSe9CH9p!36QR;uS&3J1JPL*tBBv35m_R=qM}2M)^^m zP%52os`KN{7XeUY2F?GUSU~j1c*(B;rZtc`l4eZ@bqf2AYi% zQ`v-#6SLWIVjeOU9oB`j&gYXaRv%EdqF?>^g*>v$LeeLlCDJ0hr-|&Mym)J<-~4oyO2fqZHnw%itK(bp9fx>JL1PhvQ2C&Epl(SH9bUM)~5QlslL~5RVi~- zDQ=;rYdF8#taYaitbSFO4dIVZM>tSXB>r#_nSRw*4F|&hMBLM;e^|Pp1=LiV*)utWP>jVJvORJm! diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index 6b09ffc2a7b..4466cde8c88 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4634,7 +4634,7 @@ Inputs: ] ``` -Response: `1300` +Response: `13` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 20528712ada..4d7c4dc3c47 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -4883,7 +4883,7 @@ Inputs: ] ``` -Response: `1300` +Response: `13` ### StateReadState StateReadState returns the indicated actor's state. From f7cfb74a3fbd6bd619dbc7f3540e9798c540f10c Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Fri, 13 Aug 2021 00:02:20 -0400 Subject: [PATCH 72/79] tidy1 --- go.mod | 3 ++- go.sum | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e705ecf91c3..bea2278844a 100644 --- a/go.mod +++ b/go.mod @@ -100,6 +100,7 @@ require ( github.com/ipld/go-car v0.1.1-0.20201119040415-11b6074b6d4d github.com/ipld/go-ipld-prime v0.5.1-0.20201021195245-109253e8a018 github.com/kelseyhightower/envconfig v1.4.0 + github.com/lib/pq v1.10.2 github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-eventbus v0.2.1 github.com/libp2p/go-libp2p v0.14.2 @@ -166,4 +167,4 @@ replace github.com/filecoin-project/lotus => ./ replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi -replace github.com/filecoin-project/test-vectors => ./extern/test-vectors \ No newline at end of file +replace github.com/filecoin-project/test-vectors => ./extern/test-vectors diff --git a/go.sum b/go.sum index 22e10049344..89a1e8d3a60 100644 --- a/go.sum +++ b/go.sum @@ -851,6 +851,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= github.com/libp2p/go-addr-util v0.1.0 h1:acKsntI33w2bTU7tC9a0SaPimJGfSI0bFKC18ChxeVI= From 4bcf159381f1bc10a444d5aafd4ec3d099660042 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Fri, 13 Aug 2021 23:16:03 -0400 Subject: [PATCH 73/79] v1.11.1-rc3 --- CHANGELOG.md | 7 ++++--- build/version.go | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1699114fe75..2a30b7cd61d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ # Lotus changelog -# 1.11.1-rc2 / 2021-08-01 +# 1.11.1-rc3 / 2021-08-13 > Note: for discussion about this release, please comment [here](https://github.com/filecoin-project/lotus/discussions/6904) -This is the second release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. A more organized and detailed release note will be shared in the next few days with future RCs, highlights are: -- **Experimental** [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) +This is the final release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces +many deal making and datastore improvements and new features along with other bug fixes. Highlights are: +- [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) - **Under Testing** [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) - github.com/filecoin-project/lotus: diff --git a/build/version.go b/build/version.go index 4d1468cad6d..5977c512300 100644 --- a/build/version.go +++ b/build/version.go @@ -33,8 +33,8 @@ func buildType() string { } } -// BuildVersion is the local build version, set by build system -const BuildVersion = "1.11.1-rc2" +// BuildVersion is the local build version +const BuildVersion = "1.11.1-rc3" func UserVersion() string { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { From e397a079c101f1e3b412d52e51272b916fe02da5 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Fri, 13 Aug 2021 23:42:59 -0400 Subject: [PATCH 74/79] docsgen --- build/openrpc/full.json.gz | Bin 25239 -> 25239 bytes build/openrpc/miner.json.gz | Bin 9596 -> 9596 bytes build/openrpc/worker.json.gz | Bin 2710 -> 2710 bytes documentation/en/cli-lotus-miner.md | 2 +- documentation/en/cli-lotus-worker.md | 2 +- documentation/en/cli-lotus.md | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 110ab177a08b89db8c67c05a671f075cc601c2ab..0898256728fb636193a4337d87b4b8ba79fdca4f 100644 GIT binary patch delta 23 fcmbP!lyUk|#tFTQ-!}F!CUIo15{|j_nuP%XeIyCK delta 23 fcmbP!lyUk|#tFTQUpDqJCUG1-Vp@FZH46g(fxQZ6 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 1fd8121c9d3ace29f106a38d5085914181d9aaa9..b21950cfd3185bddeee3cbfd7dfa32c801a524ef 100644 GIT binary patch delta 21 dcmez4^~Y;MC!^8Eu2(7?HWuFsXCGl?0045T31t8P delta 21 dcmez4^~Y;MC!@*6u2(7?OfJW!&pyJ)004042`>Nu diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index c1b533b72b946065dbdc580248dfd393126945d0..1f7e4e76063c2a8ca96247ae206aa60a29f44c14 100644 GIT binary patch delta 21 ccmbOxI!$y!3**O)t(;sOoi~EHBdZt~09hjkKmY&$ delta 21 dcmbOxI!$y!3*(24t(;sO=Xs~NMpiK}003BE2Q>fy diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index cde45f3d369..244349faa48 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -7,7 +7,7 @@ USAGE: lotus-miner [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc2 + 1.11.1-rc3 COMMANDS: init Initialize a lotus miner repo diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index ccd8625d01d..e448f8a540f 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -7,7 +7,7 @@ USAGE: lotus-worker [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc2 + 1.11.1-rc3 COMMANDS: run Start lotus worker diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index e9d42f15178..982e61df5a5 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -7,7 +7,7 @@ USAGE: lotus [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc2 + 1.11.1-rc3 COMMANDS: daemon Start a lotus daemon process From 11ff756b2ef7fbd2b37e12e8edc73966d97d4674 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 16 Aug 2021 16:17:52 -0400 Subject: [PATCH 75/79] Add ChangeLog --- CHANGELOG.md | 284 +++++++++++++++++++++++++++------------------------ v1.11.1 | 170 ------------------------------ 2 files changed, 148 insertions(+), 306 deletions(-) delete mode 100644 v1.11.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a30b7cd61d..e991432fac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,187 +1,199 @@ # Lotus changelog +<<<<<<< HEAD # 1.11.1-rc3 / 2021-08-13 +||||||| parent of be7007492 (Add ChangeLog) +# 1.11.1-rc2 / 2021-08-01 +======= +# 1.11.1 / 2021-08-02 +>>>>>>> be7007492 (Add ChangeLog) > Note: for discussion about this release, please comment [here](https://github.com/filecoin-project/lotus/discussions/6904) +<<<<<<< HEAD This is the final release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. Highlights are: - [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) - **Under Testing** [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) +||||||| parent of be7007492 (Add ChangeLog) +This is the second release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. A more organized and detailed release note will be shared in the next few days with future RCs, highlights are: +- **Experimental** [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) +- **Under Testing** [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) +======= +This is a **highly recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. +>>>>>>> be7007492 (Add ChangeLog) -- github.com/filecoin-project/lotus: - - Merge branch 'releases' into release/v1.11.1 - - Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890)) +## Highlights +- ⭐️⭐️⭐️[**lotus-miner market subsystem**](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) is introduced in this release! It is **highly recommended** for storage providers to run markets processes on a separate machine! Doing so, only this machine needs to exposes public ports for deal making. This also means that the other miner operations can now be completely isolated by from the deal making processes and storage providers can stop and restarts the markets process without affecting an ongoing Winning/Window PoSt! + - More details on the concepts, architecture and how to split the market process can be found [here](https://docs.filecoin.io/mine/lotus/split-markets-miners/#concepts). + - Base on your system setup(running on separate machines, same machine and so on), please see the suggested practice by community members [here](https://github.com/filecoin-project/lotus/discussions/7047#discussion-3515335). + - Note: if you are running lotus-worker on a different machine, you will need to set `MARKETS_API_INFO` for certain CLI to work properly. This will be improved by #7072. + - Huge thanks to MinerX fellows for [helping testing the implementation, reporting the issues so they were fixed by now and providing feedbacks](https://github.com/filecoin-project/lotus/discussions/6861) to user docs in the past three weeks! +- Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629)) + - Better control your sector collateral payment by setting `CollateralFromMinerBalance`, `AvailableBalanceBuffer` and `DisableCollateralFallback`. + - `CollateralFromMinerBalance`: whether to use available miner balance for sector collateral instead of sending it with each message, default is `false`. + - `AvailableBalanceBuffer`: minimum available balance to keep in the miner actor before sending it with messages, default is 0FIL. + - `DisableCollateralFallback`: whether to send collateral with messages even if there is no available balance in the miner actor, default is `false`. +- Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697)) + - Set `DealPublishControl` to set the wallet used for sending `PublishStorageDeals` messages, instructions [here](https://docs.filecoin.io/mine/lotus/miner-addresses/#control-addresses). +- Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848)) + - You can now preview the the default and updated node config by running `lotus/lotus-miner config default/updated` + +## New Features + - ⭐️⭐️⭐️ Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356)) + - **⭐️⭐️ Experimental** [Splitstore]((https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md)) (more details coming in v1.11.2! Stay tuned! Join the discussion [here](https://github.com/filecoin-project/lotus/discussions/5788) if you have questions!) : + - Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867)) + - Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854)) + - splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811)) + - fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841)) + - Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833)) + - cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760)) + - Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775)) + - Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817)) + - Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777)) + - Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762)) + - Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756)) + - Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754)) + - Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474)) - lotus-shed: initial export cmd for markets related metadata ([filecoin-project/lotus#6840](https://github.com/filecoin-project/lotus/pull/6840)) - add a very verbose -vv flag to lotus and lotus-miner. ([filecoin-project/lotus#6888](https://github.com/filecoin-project/lotus/pull/6888)) - - Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880)) - - Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854)) - - Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879)) - Add allocated sectorid vis ([filecoin-project/lotus#4638](https://github.com/filecoin-project/lotus/pull/4638)) - - rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886)) - - update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885)) - - Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674)) + - add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640)) + - Run `lotus-miner actor compact-allocated` to compact sector number allocations to reduce the size of the allocated sector number bitfield. + - Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642)) + - Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743)) + - Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696)) + - Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694)) + - Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620)) + - commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650)) + - shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631)) + +## Bug Fixes - Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683)) + - fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724)) + - PriceListByVersion ([filecoin-project/lotus#6766](https://github.com/filecoin-project/lotus/pull/6766)) + - fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802)) + - test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804)) + - wrap close(wait) with sync.Once to avoid panic ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800)) + - fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787)) + - ClientRetrieve stops on cancel([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739)) + - Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066)) + - fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688)) + - Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679)) + - Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680)) + - storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653)) + - Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664)) + - Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658)) + - fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635)) + - remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634)) + - fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625)) + +## Improvements + - Eliminate inefficiency in markets logging ([filecoin-project/lotus#6895](https://github.com/filecoin-project/lotus/pull/6895)) + - rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886)) - fix racy TestSimultanenousTransferLimit. ([filecoin-project/lotus#6862](https://github.com/filecoin-project/lotus/pull/6862)) - - Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867)) - ValidateBlock: Assert that block header height's are greater than parents ([filecoin-project/lotus#6872](https://github.com/filecoin-project/lotus/pull/6872)) - feat: Don't panic when api impl is nil ([filecoin-project/lotus#6857](https://github.com/filecoin-project/lotus/pull/6857)) - - splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811)) - - Fix links in issue templates - - Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856)) - - Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833)) - - Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848)) - - fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724)) - - Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798)) - - Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837)) - add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544)) - - fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841)) - - add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640)) - - PriceListByVersion ([filecoin-project/lotus#6766](https://github.com/filecoin-project/lotus/pull/6766)) - easy way to make install app ([filecoin-project/lotus#5183](https://github.com/filecoin-project/lotus/pull/5183)) - - api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) - - cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760)) - - fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) - - Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775)) - - Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817)) - - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818)) + - api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818)) - add SealProof in SectorBuilder ([filecoin-project/lotus#6815](https://github.com/filecoin-project/lotus/pull/6815)) - - release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828)) - - sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763)) - - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802)) + - sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763)) - ClientFindData: always fetch peer id from chain ([filecoin-project/lotus#6807](https://github.com/filecoin-project/lotus/pull/6807)) - - test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804)) - - ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800)) - - fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787)) - - Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777)) - - Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773)) - - update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764)) - - Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762)) - - Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642)) - test: handle null blocks in TestForkRefuseCall ([filecoin-project/lotus#6758](https://github.com/filecoin-project/lotus/pull/6758)) - - Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757)) - - Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756)) - - Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747)) - - Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754)) - - ([filecoin-project/lotus#6746](https://github.com/filecoin-project/lotus/pull/6746)) - - Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743)) - - Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629)) - - Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356)) - - Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474)) - - ([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739)) - Add more deal details to lotus-miner info ([filecoin-project/lotus#6708](https://github.com/filecoin-project/lotus/pull/6708)) - - Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710)) - - Fix Lotus shed - - Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066)) - add election backtest ([filecoin-project/lotus#5950](https://github.com/filecoin-project/lotus/pull/5950)) - - Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620)) - - Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709)) - - Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697)) - - Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689)) - - Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696)) - - Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694)) - add dollar sign ([filecoin-project/lotus#6690](https://github.com/filecoin-project/lotus/pull/6690)) - get-actor cli spelling fix ([filecoin-project/lotus#6681](https://github.com/filecoin-project/lotus/pull/6681)) - - fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688)) - polish(statetree): accept a context in statetree diff for timeouts ([filecoin-project/lotus#6639](https://github.com/filecoin-project/lotus/pull/6639)) - Add helptext to lotus chain export ([filecoin-project/lotus#6672](https://github.com/filecoin-project/lotus/pull/6672)) - - Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679)) - - Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680)) - add an incremental nonce itest. ([filecoin-project/lotus#6663](https://github.com/filecoin-project/lotus/pull/6663)) - - storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653)) - - Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664)) - - Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658)) - - fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635)) - - commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650)) - commit batch: Initialize the FailedSectors map ([filecoin-project/lotus#6647](https://github.com/filecoin-project/lotus/pull/6647)) - Fast-path retry submitting commit aggregate if commit is still valid ([filecoin-project/lotus#6638](https://github.com/filecoin-project/lotus/pull/6638)) - - remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634)) - Reuse timers in sealing batch logic ([filecoin-project/lotus#6636](https://github.com/filecoin-project/lotus/pull/6636)) - - shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631)) - - fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625)) + +## Dependency Updates + - Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890)) + - update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885)) + - Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674)) + - github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.2): + - github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.2): + - github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1) + - github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210810190654-139e0e79e69e) + - github.com/filecoin-project/go-statemachine (v0.0.0-20200925024713-05bd7c71fbfe -> v1.0.1) + - update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764)) + +## Others + - Master->v1.11.1 ([filecoin-project/lotus#7051](https://github.com/filecoin-project/lotus/pull/7051)) + - v1.11.1-rc2 ([filecoin-project/lotus#6966](https://github.com/filecoin-project/lotus/pull/6966)) + - Backport master -> v1.11.1 ([filecoin-project/lotus#6965](https://github.com/filecoin-project/lotus/pull/6965)) + - Fixes in master -> release ([filecoin-project/lotus#6933](https://github.com/filecoin-project/lotus/pull/6933)) + - Add changelog for v1.11.1-rc1 and bump the version ([filecoin-project/lotus#6900](https://github.com/filecoin-project/lotus/pull/6900)) + - Fix merge release -> v1.11.1 ([filecoin-project/lotus#6897](https://github.com/filecoin-project/lotus/pull/6897)) + - Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880)) + - Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879)) + - Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856)) + - Fix links in issue templates + - Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798) + - Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837)) + - add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544)) + - release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828)) + - Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773)) + - Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757)) + - Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747)) + - Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710)) + - Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709)) + - Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689)) - Update version.go to 1.11.1 ([filecoin-project/lotus#6621](https://github.com/filecoin-project/lotus/pull/6621)) -- github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.0): - - release: v1.7.0 - - Fire a transfer queued event when a transfer is queued in Graphsync (#221) ([filecoin-project/go-data-transfer#221](https://github.com/filecoin-project/go-data-transfer/pull/221)) - - feat: pass ChannelID to ValidatePush & ValidatePull (#220) ([filecoin-project/go-data-transfer#220](https://github.com/filecoin-project/go-data-transfer/pull/220)) - - release: v1.6.1 ([filecoin-project/go-data-transfer#218](https://github.com/filecoin-project/go-data-transfer/pull/218)) - - Remove CID lists (#217) ([filecoin-project/go-data-transfer#217](https://github.com/filecoin-project/go-data-transfer/pull/217)) - - Merge v1.6.0 ([filecoin-project/go-data-transfer#214](https://github.com/filecoin-project/go-data-transfer/pull/214)) - - Remove restart ack timeout (#211) ([filecoin-project/go-data-transfer#211](https://github.com/filecoin-project/go-data-transfer/pull/211)) - - feat: use different extension names to fit multiple hooks data in same graphsync message (#204) ([filecoin-project/go-data-transfer#204](https://github.com/filecoin-project/go-data-transfer/pull/204)) - - fix: map race in GS transport (#208) ([filecoin-project/go-data-transfer#208](https://github.com/filecoin-project/go-data-transfer/pull/208)) - - refactor: simplify graphsync transport (#203) ([filecoin-project/go-data-transfer#203](https://github.com/filecoin-project/go-data-transfer/pull/203)) - - release: v1.5.0 (#200) ([filecoin-project/go-data-transfer#200](https://github.com/filecoin-project/go-data-transfer/pull/200)) -- github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.0): - - release: v1.6.0 - - support padding out smaller files (#536) ([filecoin-project/go-fil-markets#536](https://github.com/filecoin-project/go-fil-markets/pull/536)) - - On overloaded CI 10 seconds just isn't enough (#587) ([filecoin-project/go-fil-markets#587](https://github.com/filecoin-project/go-fil-markets/pull/587)) - - Do not hex-encode CIDs in logs (#561) ([filecoin-project/go-fil-markets#561](https://github.com/filecoin-project/go-fil-markets/pull/561)) - - remove wrong peer check in push deal validation (#585) ([filecoin-project/go-fil-markets#585](https://github.com/filecoin-project/go-fil-markets/pull/585)) - - fix: circleci docs-gen task (#574) ([filecoin-project/go-fil-markets#574](https://github.com/filecoin-project/go-fil-markets/pull/574)) - - Storage market request queued event and validation interface changes (#555) ([filecoin-project/go-fil-markets#555](https://github.com/filecoin-project/go-fil-markets/pull/555)) - - build(deps): bump ws from 6.2.1 to 6.2.2 (#554) ([filecoin-project/go-fil-markets#554](https://github.com/filecoin-project/go-fil-markets/pull/554)) - - release: v1.5.0 ([filecoin-project/go-fil-markets#553](https://github.com/filecoin-project/go-fil-markets/pull/553)) -- github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1): - - New method to pad harder (#6) ([filecoin-project/go-padreader#6](https://github.com/filecoin-project/go-padreader/pull/6)) - - Create SECURITY.md (#5) ([filecoin-project/go-padreader#5](https://github.com/filecoin-project/go-padreader/pull/5)) -- github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210722133031-ad9bfe54c124): - - Add version 6.5 (#30) ([filecoin-project/go-state-types#30](https://github.com/filecoin-project/go-state-types/pull/30)) - - rename file -- github.com/filecoin-project/specs-actors/v5 (v5.0.1 -> v5.0.3): - - Adjust code for subtle change in go-multihash 0.0.15 (#1463) ([filecoin-project/specs-actors#1463](https://github.com/filecoin-project/specs-actors/pull/1463)) - - Bump go state types (#1464) ([filecoin-project/specs-actors#1464](https://github.com/filecoin-project/specs-actors/pull/1464)) - - Create CODEOWNERS (#1465) ([filecoin-project/specs-actors#1465](https://github.com/filecoin-project/specs-actors/pull/1465)) - - Test deterministic offset (#1462) ([filecoin-project/specs-actors#1462](https://github.com/filecoin-project/specs-actors/pull/1462)) - -Contributors + +## Contributors | Contributor | Commits | Lines ± | Files Changed | |-------------|---------|---------|---------------| -| vyzo | 295 | +8700/-5936 | 397 | -| Anton Evangelatov | 94 | +4680/-2965 | 277 | -| Łukasz Magiera | 37 | +3851/-1611 | 146 | -| Mike Greenberg | 1 | +2310/-578 | 8 | -| dirkmc | 7 | +1154/-726 | 29 | -| Jennifer Wang | 9 | +485/-341 | 26 | -| Peter Rabbitson | 18 | +469/-273 | 64 | -| Cory Schwartz | 5 | +576/-135 | 14 | -| hunjixin | 7 | +404/-82 | 19 | -| ZenGround0 | 17 | +284/-135 | 44 | -| Dirk McCormick | 17 | +348/-47 | 17 | -| Raúl Kripalani | 18 | +254/-97 | 62 | -| tchardin | 1 | +261/-33 | 4 | -| Jakub Sztandera | 4 | +254/-16 | 4 | -| Aarsh Shah | 2 | +196/-40 | 28 | -| whyrusleeping | 3 | +150/-9 | 8 | -| Whyrusleeping | 2 | +87/-66 | 10 | -| Aayush Rajasekaran | 10 | +81/-53 | 13 | -| zgfzgf | 2 | +104/-4 | 2 | -| aarshkshah1992 | 4 | +73/-7 | 6 | -| llifezou | 4 | +59/-20 | 4 | -| Steven Allen | 7 | +47/-17 | 9 | -| johnli-helloworld | 3 | +46/-15 | 5 | -| frrist | 1 | +28/-23 | 2 | -| Jennifer | 4 | +31/-2 | 4 | -| wangchao | 1 | +1/-27 | 1 | -| Jiaying Wang | 2 | +7/-21 | 2 | -| hannahhoward | 3 | +21/-2 | 3 | -| chadwick2143 | 1 | +15/-1 | 1 | -| Jerry | 2 | +9/-4 | 2 | +| @vyzo | 313 | +8928/-6010 | 415 | +| @nonsense | 103 | +6041/-4041 | 304 | +| @magik6k | 37 | +3851/-1611 | 146 | +| @ZenGround0 | 24 | +1693/-1394 | 95 | +| @placer14 | 1 | +2310/-578 | 8 | +| @dirkmc | 7 | +1154/-726 | 29 | +| @raulk | 44 | +969/-616 | 141 | +| @jennijuju | 15 | +682/-354 | 47 | +| @ribasushi | 18 | +469/-273 | 64 | +| @coryschwartz | 5 | +576/-135 | 14 | +| @hunjixin | 7 | +404/-82 | 19 | +| @dirkmc | 17 | +348/-47 | 17 | +| @tchardin | 2 | +262/-34 | 5 | +| @aarshkshah1992 | 9 | +233/-63 | 44 | +| @Kubuxu | 4 | +254/-16 | 4 | +| @hannahhoward | 6 | +163/-75 | 8 | +| @whyrusleeping | 4 | +157/-16 | 9 | +| @Whyrusleeping | 2 | +87/-66 | 10 | +| @arajasek | 10 | +81/-53 | 13 | +| @zgfzgf | 2 | +104/-4 | 2 | +| @aarshkshah1992 | 6 | +85/-19 | 10 | +| @llifezou | 4 | +59/-20 | 4 | +| @Stebalien | 7 | +47/-17 | 9 | +| @johnli-helloworld | 3 | +46/-15 | 5 | +| @frrist | 1 | +28/-23 | 2 | +| @hannahhoward | 4 | +46/-5 | 11 | +| @Jennifer | 4 | +31/-2 | 4 | +| @wangchao | 1 | +1/-27 | 1 | +| @jennijuju | 2 | +7/-21 | 2 | +| @chadwick2143 | 1 | +15/-1 | 1 | +| @Jerry | 2 | +9/-4 | 2 | | Steve Loeppky | 2 | +12/-0 | 2 | | David Dias | 1 | +9/-0 | 1 | | dependabot[bot] | 1 | +3/-3 | 1 | | zhoutian527 | 1 | +2/-2 | 1 | | xloem | 1 | +4/-0 | 1 | -| Travis Person | 2 | +2/-2 | 3 | +| @travisperson| 2 | +2/-2 | 3 | | Liviu Damian | 2 | +2/-2 | 2 | -| Jim Pick | 2 | +2/-2 | 2 | +| @jimpick | 2 | +2/-2 | 2 | | Frank | 1 | +3/-0 | 1 | | turuslan | 1 | +1/-1 | 1 | | Kirk Baird | 1 | +0/-0 | 1 | - # 1.11.0 / 2021-07-22 This is a **highly recommended** release of Lotus that have many bug fixes, improvements and new features. diff --git a/v1.11.1 b/v1.11.1 deleted file mode 100644 index 225a346deba..00000000000 --- a/v1.11.1 +++ /dev/null @@ -1,170 +0,0 @@ -- github.com/filecoin-project/lotus: - - Merge branch 'releases' into release/v1.11.1 - - Update to proof v8.0.3 ([filecoin-project/lotus#6890](https://github.com/filecoin-project/lotus/pull/6890)) - - lotus-shed: initial export cmd for markets related metadata ([filecoin-project/lotus#6840](https://github.com/filecoin-project/lotus/pull/6840)) - - add a very verbose -vv flag to lotus and lotus-miner. ([filecoin-project/lotus#6888](https://github.com/filecoin-project/lotus/pull/6888)) - - Update RELEASE_ISSUE_TEMPLATE.md ([filecoin-project/lotus#6880](https://github.com/filecoin-project/lotus/pull/6880)) - - Moving GC for badger ([filecoin-project/lotus#6854](https://github.com/filecoin-project/lotus/pull/6854)) - - Add github actions for staled pr ([filecoin-project/lotus#6879](https://github.com/filecoin-project/lotus/pull/6879)) - - Add allocated sectorid vis ([filecoin-project/lotus#4638](https://github.com/filecoin-project/lotus/pull/4638)) - - rename `cmd/lotus{-storage=>}-miner` to match binary. ([filecoin-project/lotus#6886](https://github.com/filecoin-project/lotus/pull/6886)) - - update to go-fil-market v1.6.0 ([filecoin-project/lotus#6885](https://github.com/filecoin-project/lotus/pull/6885)) - - Bump go-multihash, adjust test for supported version ([filecoin-project/lotus#6674](https://github.com/filecoin-project/lotus/pull/6674)) - - Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683)) - - fix racy TestSimultanenousTransferLimit. ([filecoin-project/lotus#6862](https://github.com/filecoin-project/lotus/pull/6862)) - - Improve splitstore warmup ([filecoin-project/lotus#6867](https://github.com/filecoin-project/lotus/pull/6867)) - - ValidateBlock: Assert that block header height's are greater than parents ([filecoin-project/lotus#6872](https://github.com/filecoin-project/lotus/pull/6872)) - - feat: Don't panic when api impl is nil ([filecoin-project/lotus#6857](https://github.com/filecoin-project/lotus/pull/6857)) - - splitstore shed utils ([filecoin-project/lotus#6811](https://github.com/filecoin-project/lotus/pull/6811)) - - Fix links in issue templates - - Update issue templates and add templates for M1 ([filecoin-project/lotus#6856](https://github.com/filecoin-project/lotus/pull/6856)) - - Splitstore: support on-disk marksets using badger ([filecoin-project/lotus#6833](https://github.com/filecoin-project/lotus/pull/6833)) - - Config UX improvements ([filecoin-project/lotus#6848](https://github.com/filecoin-project/lotus/pull/6848)) - - fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724)) - - Update issue templates to forms ([filecoin-project/lotus#6798](https://github.com/filecoin-project/lotus/pull/6798)) - - Nerpa v13 upgrade ([filecoin-project/lotus#6837](https://github.com/filecoin-project/lotus/pull/6837)) - - add docker-compose file ([filecoin-project/lotus#6544](https://github.com/filecoin-project/lotus/pull/6544)) - - fix warmup by decoupling state from message receipt walk ([filecoin-project/lotus#6841](https://github.com/filecoin-project/lotus/pull/6841)) - - add a command for compacting sector numbers bitfield ([filecoin-project/lotus#4640](https://github.com/filecoin-project/lotus/pull/4640)) - - PriceListByVersion ([filecoin-project/lotus#6766](https://github.com/filecoin-project/lotus/pull/6766)) - - easy way to make install app ([filecoin-project/lotus#5183](https://github.com/filecoin-project/lotus/pull/5183)) - - api: Separate the Net interface from Common ([filecoin-project/lotus#6627](https://github.com/filecoin-project/lotus/pull/6627)) - - cache loaded block messages ([filecoin-project/lotus#6760](https://github.com/filecoin-project/lotus/pull/6760)) - - fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) - - Splitstore: add retention policy option for keeping messages in the hotstore ([filecoin-project/lotus#6775](https://github.com/filecoin-project/lotus/pull/6775)) - - Introduce the LOTUS_CHAIN_BADGERSTORE_DISABLE_FSYNC envvar ([filecoin-project/lotus#6817](https://github.com/filecoin-project/lotus/pull/6817)) - - add StateReadState to gateway api ([filecoin-project/lotus#6818](https://github.com/filecoin-project/lotus/pull/6818)) - - add SealProof in SectorBuilder ([filecoin-project/lotus#6815](https://github.com/filecoin-project/lotus/pull/6815)) - - release -> master ([filecoin-project/lotus#6828](https://github.com/filecoin-project/lotus/pull/6828)) - - sealing: Handle preCommitParams errors more correctly ([filecoin-project/lotus#6763](https://github.com/filecoin-project/lotus/pull/6763)) - - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802)) - - ClientFindData: always fetch peer id from chain ([filecoin-project/lotus#6807](https://github.com/filecoin-project/lotus/pull/6807)) - - test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804)) - - ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800)) - - fixes #6786 segfault ([filecoin-project/lotus#6787](https://github.com/filecoin-project/lotus/pull/6787)) - - Splitstore: add support for protecting out of chain references in the blockstore ([filecoin-project/lotus#6777](https://github.com/filecoin-project/lotus/pull/6777)) - - Resurrect CODEOWNERS, but for maintainers group ([filecoin-project/lotus#6773](https://github.com/filecoin-project/lotus/pull/6773)) - - update go-libp2p-pubsub to v0.5.0 ([filecoin-project/lotus#6764](https://github.com/filecoin-project/lotus/pull/6764)) - - Implement exposed splitstore ([filecoin-project/lotus#6762](https://github.com/filecoin-project/lotus/pull/6762)) - - Add ChainGetMessagesInTipset API ([filecoin-project/lotus#6642](https://github.com/filecoin-project/lotus/pull/6642)) - - test: handle null blocks in TestForkRefuseCall ([filecoin-project/lotus#6758](https://github.com/filecoin-project/lotus/pull/6758)) - - Master disclaimer ([filecoin-project/lotus#6757](https://github.com/filecoin-project/lotus/pull/6757)) - - Splitstore code reorg ([filecoin-project/lotus#6756](https://github.com/filecoin-project/lotus/pull/6756)) - - Create stale.yml ([filecoin-project/lotus#6747](https://github.com/filecoin-project/lotus/pull/6747)) - - Splitstore: Some small fixes ([filecoin-project/lotus#6754](https://github.com/filecoin-project/lotus/pull/6754)) - - ([filecoin-project/lotus#6746](https://github.com/filecoin-project/lotus/pull/6746)) - - Handle the --color flag via proper global state ([filecoin-project/lotus#6743](https://github.com/filecoin-project/lotus/pull/6743)) - - Config for collateral from miner available balance ([filecoin-project/lotus#6629](https://github.com/filecoin-project/lotus/pull/6629)) - - Support standalone miner-market process ([filecoin-project/lotus#6356](https://github.com/filecoin-project/lotus/pull/6356)) - - Splitstore Enhanchements ([filecoin-project/lotus#6474](https://github.com/filecoin-project/lotus/pull/6474)) - - ([filecoin-project/lotus#6739](https://github.com/filecoin-project/lotus/pull/6739)) - - Add more deal details to lotus-miner info ([filecoin-project/lotus#6708](https://github.com/filecoin-project/lotus/pull/6708)) - - Release template: Update all testnet infra at once ([filecoin-project/lotus#6710](https://github.com/filecoin-project/lotus/pull/6710)) - - Fix Lotus shed - - Fix bugs in sectors extend --v1-sectors ([filecoin-project/lotus#6066](https://github.com/filecoin-project/lotus/pull/6066)) - - add election backtest ([filecoin-project/lotus#5950](https://github.com/filecoin-project/lotus/pull/5950)) - - Envvar to disable slash filter ([filecoin-project/lotus#6620](https://github.com/filecoin-project/lotus/pull/6620)) - - Release Template: remove binary validation step ([filecoin-project/lotus#6709](https://github.com/filecoin-project/lotus/pull/6709)) - - Config for deal publishing control addresses ([filecoin-project/lotus#6697](https://github.com/filecoin-project/lotus/pull/6697)) - - Reset of the interop network ([filecoin-project/lotus#6689](https://github.com/filecoin-project/lotus/pull/6689)) - - Enable color by default only if os.Stdout is a TTY ([filecoin-project/lotus#6696](https://github.com/filecoin-project/lotus/pull/6696)) - - Stop outputing ANSI color on non-TTY ([filecoin-project/lotus#6694](https://github.com/filecoin-project/lotus/pull/6694)) - - add dollar sign ([filecoin-project/lotus#6690](https://github.com/filecoin-project/lotus/pull/6690)) - - get-actor cli spelling fix ([filecoin-project/lotus#6681](https://github.com/filecoin-project/lotus/pull/6681)) - - fix "lotus-seed genesis car" error "merkledag: not found" ([filecoin-project/lotus#6688](https://github.com/filecoin-project/lotus/pull/6688)) - - polish(statetree): accept a context in statetree diff for timeouts ([filecoin-project/lotus#6639](https://github.com/filecoin-project/lotus/pull/6639)) - - Add helptext to lotus chain export ([filecoin-project/lotus#6672](https://github.com/filecoin-project/lotus/pull/6672)) - - Get retrieval pricing input should not error out on a deal state fetch ([filecoin-project/lotus#6679](https://github.com/filecoin-project/lotus/pull/6679)) - - Fix more CID double-encoding as hex ([filecoin-project/lotus#6680](https://github.com/filecoin-project/lotus/pull/6680)) - - add an incremental nonce itest. ([filecoin-project/lotus#6663](https://github.com/filecoin-project/lotus/pull/6663)) - - storage: Fix FinalizeSector with sectors in stoage paths ([filecoin-project/lotus#6653](https://github.com/filecoin-project/lotus/pull/6653)) - - Fix tiny error in check-client-datacap ([filecoin-project/lotus#6664](https://github.com/filecoin-project/lotus/pull/6664)) - - Fix: precommit_batch method used the wrong cfg.CommitBatchWait ([filecoin-project/lotus#6658](https://github.com/filecoin-project/lotus/pull/6658)) - - fix ticket expiration check ([filecoin-project/lotus#6635](https://github.com/filecoin-project/lotus/pull/6635)) - - commit batch: AggregateAboveBaseFee config ([filecoin-project/lotus#6650](https://github.com/filecoin-project/lotus/pull/6650)) - - commit batch: Initialize the FailedSectors map ([filecoin-project/lotus#6647](https://github.com/filecoin-project/lotus/pull/6647)) - - Fast-path retry submitting commit aggregate if commit is still valid ([filecoin-project/lotus#6638](https://github.com/filecoin-project/lotus/pull/6638)) - - remove precommit check in handleCommitFailed ([filecoin-project/lotus#6634](https://github.com/filecoin-project/lotus/pull/6634)) - - Reuse timers in sealing batch logic ([filecoin-project/lotus#6636](https://github.com/filecoin-project/lotus/pull/6636)) - - shed tool to estimate aggregate network fees ([filecoin-project/lotus#6631](https://github.com/filecoin-project/lotus/pull/6631)) - - fix prove commit aggregate send token amount ([filecoin-project/lotus#6625](https://github.com/filecoin-project/lotus/pull/6625)) - - Update version.go to 1.11.1 ([filecoin-project/lotus#6621](https://github.com/filecoin-project/lotus/pull/6621)) -- github.com/filecoin-project/go-data-transfer (v1.6.0 -> v1.7.0): - - release: v1.7.0 - - Fire a transfer queued event when a transfer is queued in Graphsync (#221) ([filecoin-project/go-data-transfer#221](https://github.com/filecoin-project/go-data-transfer/pull/221)) - - feat: pass ChannelID to ValidatePush & ValidatePull (#220) ([filecoin-project/go-data-transfer#220](https://github.com/filecoin-project/go-data-transfer/pull/220)) - - release: v1.6.1 ([filecoin-project/go-data-transfer#218](https://github.com/filecoin-project/go-data-transfer/pull/218)) - - Remove CID lists (#217) ([filecoin-project/go-data-transfer#217](https://github.com/filecoin-project/go-data-transfer/pull/217)) - - Merge v1.6.0 ([filecoin-project/go-data-transfer#214](https://github.com/filecoin-project/go-data-transfer/pull/214)) - - Remove restart ack timeout (#211) ([filecoin-project/go-data-transfer#211](https://github.com/filecoin-project/go-data-transfer/pull/211)) - - feat: use different extension names to fit multiple hooks data in same graphsync message (#204) ([filecoin-project/go-data-transfer#204](https://github.com/filecoin-project/go-data-transfer/pull/204)) - - fix: map race in GS transport (#208) ([filecoin-project/go-data-transfer#208](https://github.com/filecoin-project/go-data-transfer/pull/208)) - - refactor: simplify graphsync transport (#203) ([filecoin-project/go-data-transfer#203](https://github.com/filecoin-project/go-data-transfer/pull/203)) - - release: v1.5.0 (#200) ([filecoin-project/go-data-transfer#200](https://github.com/filecoin-project/go-data-transfer/pull/200)) -- github.com/filecoin-project/go-fil-markets (v1.5.0 -> v1.6.0): - - release: v1.6.0 - - support padding out smaller files (#536) ([filecoin-project/go-fil-markets#536](https://github.com/filecoin-project/go-fil-markets/pull/536)) - - On overloaded CI 10 seconds just isn't enough (#587) ([filecoin-project/go-fil-markets#587](https://github.com/filecoin-project/go-fil-markets/pull/587)) - - Do not hex-encode CIDs in logs (#561) ([filecoin-project/go-fil-markets#561](https://github.com/filecoin-project/go-fil-markets/pull/561)) - - remove wrong peer check in push deal validation (#585) ([filecoin-project/go-fil-markets#585](https://github.com/filecoin-project/go-fil-markets/pull/585)) - - fix: circleci docs-gen task (#574) ([filecoin-project/go-fil-markets#574](https://github.com/filecoin-project/go-fil-markets/pull/574)) - - Storage market request queued event and validation interface changes (#555) ([filecoin-project/go-fil-markets#555](https://github.com/filecoin-project/go-fil-markets/pull/555)) - - build(deps): bump ws from 6.2.1 to 6.2.2 (#554) ([filecoin-project/go-fil-markets#554](https://github.com/filecoin-project/go-fil-markets/pull/554)) - - release: v1.5.0 ([filecoin-project/go-fil-markets#553](https://github.com/filecoin-project/go-fil-markets/pull/553)) -- github.com/filecoin-project/go-padreader (v0.0.0-20200903213702-ed5fae088b20 -> v0.0.0-20210723183308-812a16dc01b1): - - New method to pad harder (#6) ([filecoin-project/go-padreader#6](https://github.com/filecoin-project/go-padreader/pull/6)) - - Create SECURITY.md (#5) ([filecoin-project/go-padreader#5](https://github.com/filecoin-project/go-padreader/pull/5)) -- github.com/filecoin-project/go-state-types (v0.1.1-0.20210506134452-99b279731c48 -> v0.1.1-0.20210722133031-ad9bfe54c124): - - Add version 6.5 (#30) ([filecoin-project/go-state-types#30](https://github.com/filecoin-project/go-state-types/pull/30)) - - rename file -- github.com/filecoin-project/specs-actors/v5 (v5.0.1 -> v5.0.3): - - Adjust code for subtle change in go-multihash 0.0.15 (#1463) ([filecoin-project/specs-actors#1463](https://github.com/filecoin-project/specs-actors/pull/1463)) - - Bump go state types (#1464) ([filecoin-project/specs-actors#1464](https://github.com/filecoin-project/specs-actors/pull/1464)) - - Create CODEOWNERS (#1465) ([filecoin-project/specs-actors#1465](https://github.com/filecoin-project/specs-actors/pull/1465)) - - Test deterministic offset (#1462) ([filecoin-project/specs-actors#1462](https://github.com/filecoin-project/specs-actors/pull/1462)) - -Contributors - -| Contributor | Commits | Lines ± | Files Changed | -|-------------|---------|---------|---------------| -| vyzo | 295 | +8700/-5936 | 397 | -| Anton Evangelatov | 94 | +4680/-2965 | 277 | -| Łukasz Magiera | 37 | +3851/-1611 | 146 | -| Mike Greenberg | 1 | +2310/-578 | 8 | -| dirkmc | 7 | +1154/-726 | 29 | -| Jennifer Wang | 9 | +485/-341 | 26 | -| Peter Rabbitson | 18 | +469/-273 | 64 | -| Cory Schwartz | 5 | +576/-135 | 14 | -| hunjixin | 7 | +404/-82 | 19 | -| ZenGround0 | 17 | +284/-135 | 44 | -| Dirk McCormick | 17 | +348/-47 | 17 | -| Raúl Kripalani | 18 | +254/-97 | 62 | -| tchardin | 1 | +261/-33 | 4 | -| Jakub Sztandera | 4 | +254/-16 | 4 | -| Aarsh Shah | 2 | +196/-40 | 28 | -| whyrusleeping | 3 | +150/-9 | 8 | -| Whyrusleeping | 2 | +87/-66 | 10 | -| Aayush Rajasekaran | 10 | +81/-53 | 13 | -| zgfzgf | 2 | +104/-4 | 2 | -| aarshkshah1992 | 4 | +73/-7 | 6 | -| llifezou | 4 | +59/-20 | 4 | -| Steven Allen | 7 | +47/-17 | 9 | -| johnli-helloworld | 3 | +46/-15 | 5 | -| frrist | 1 | +28/-23 | 2 | -| Jennifer | 4 | +31/-2 | 4 | -| wangchao | 1 | +1/-27 | 1 | -| Jiaying Wang | 2 | +7/-21 | 2 | -| hannahhoward | 3 | +21/-2 | 3 | -| chadwick2143 | 1 | +15/-1 | 1 | -| Jerry | 2 | +9/-4 | 2 | -| Steve Loeppky | 2 | +12/-0 | 2 | -| David Dias | 1 | +9/-0 | 1 | -| dependabot[bot] | 1 | +3/-3 | 1 | -| zhoutian527 | 1 | +2/-2 | 1 | -| xloem | 1 | +4/-0 | 1 | -| Travis Person | 2 | +2/-2 | 3 | -| Liviu Damian | 2 | +2/-2 | 2 | -| Jim Pick | 2 | +2/-2 | 2 | -| Frank | 1 | +3/-0 | 1 | -| turuslan | 1 | +1/-1 | 1 | -| Kirk Baird | 1 | +0/-0 | 1 | From 263ae6f99f7979677198559761f68055c086404c Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 16 Aug 2021 16:21:06 -0400 Subject: [PATCH 76/79] update version --- build/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/version.go b/build/version.go index 5977c512300..f1c12b16bf1 100644 --- a/build/version.go +++ b/build/version.go @@ -34,7 +34,7 @@ func buildType() string { } // BuildVersion is the local build version -const BuildVersion = "1.11.1-rc3" +const BuildVersion = "1.11.1" func UserVersion() string { if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" { From c37241c733c3f110bee2acdf95b6d66e80b5b988 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 16 Aug 2021 16:26:50 -0400 Subject: [PATCH 77/79] resolve conflicts and docsgen --- CHANGELOG.md | 19 +------------------ build/openrpc/full.json.gz | Bin 25239 -> 25235 bytes build/openrpc/miner.json.gz | Bin 9596 -> 9593 bytes build/openrpc/worker.json.gz | Bin 2710 -> 2707 bytes documentation/en/cli-lotus-miner.md | 2 +- documentation/en/cli-lotus-worker.md | 2 +- documentation/en/cli-lotus.md | 2 +- 7 files changed, 4 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e991432fac6..9fcd7de20fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,27 +1,10 @@ # Lotus changelog -<<<<<<< HEAD -# 1.11.1-rc3 / 2021-08-13 -||||||| parent of be7007492 (Add ChangeLog) -# 1.11.1-rc2 / 2021-08-01 -======= -# 1.11.1 / 2021-08-02 ->>>>>>> be7007492 (Add ChangeLog) +# 1.11.1 / 2021-08-16 > Note: for discussion about this release, please comment [here](https://github.com/filecoin-project/lotus/discussions/6904) -<<<<<<< HEAD -This is the final release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces -many deal making and datastore improvements and new features along with other bug fixes. Highlights are: -- [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) -- **Under Testing** [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) -||||||| parent of be7007492 (Add ChangeLog) -This is the second release candidate for the **highly-recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. A more organized and detailed release note will be shared in the next few days with future RCs, highlights are: -- **Experimental** [lotus-miner market subsystem](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) -- **Under Testing** [splistore](https://github.com/filecoin-project/lotus/blob/master/blockstore/splitstore/README.md) -======= This is a **highly recommended** but optional Lotus v1.11.1 release that introduces many deal making and datastore improvements and new features along with other bug fixes. ->>>>>>> be7007492 (Add ChangeLog) ## Highlights - ⭐️⭐️⭐️[**lotus-miner market subsystem**](https://docs.filecoin.io/mine/lotus/split-markets-miners/#frontmatter-title) is introduced in this release! It is **highly recommended** for storage providers to run markets processes on a separate machine! Doing so, only this machine needs to exposes public ports for deal making. This also means that the other miner operations can now be completely isolated by from the deal making processes and storage providers can stop and restarts the markets process without affecting an ongoing Winning/Window PoSt! diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 0898256728fb636193a4337d87b4b8ba79fdca4f..2f85885ef6bbacbf0b7dddec2385736b3fbee706 100644 GIT binary patch delta 25100 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index b21950cfd3185bddeee3cbfd7dfa32c801a524ef..9d2f5c2e070ebde54c1c9acea541bf5d72400c3f 100644 GIT binary patch delta 9540 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 delta 9543 zcmV-NCAix8O8iQYhJOdHIWiu5#s<-~V|m8u$FBx~8`kwLwvp*za(HG^$33$w7kQr1 zGc4qpF5XfB=C8m0S~;J{az{+?!UI3espG;GdXEWm=hWSq^d*P`c(LsR(;*by)5Dqg z?@RCkikF9eqaHx6>$oq$*H7dV#Y^BFUJ#000__Ag;OCzK!GE@B_KCWP?py+XBIrvR z;>#X*%jg;2ZnJ^zgK=sYJ!1=9 zxDk`wxopW64+mSv!+dG{*KA2Y_Y4<#JDajE0U zA%@J>MJA-|3GekNdDb(~y;!ny$MhI7$vM2kbiG>u7i}DhfQ`wm(KB|gZJZiwO1IwW zt5+-Dm=K`hVqP5nF9zkG`gn{c2!}HvEkSZw9RS7(Rfm3m@2T*}R$qE?t_hLA!PDxy~Jvw3S#h0YS-_3w(HuR+!<3 ztSe_uuUyAj_P}-sK7RHDSpO4WBldg*n0S8)UTom@WAy#SC;aSD7n58YD1lZEGv|OW z#edo9Wnj~0(_>RBG8gl%-s6i3l#Fl0*#zBpDxY|Rd})k zr+euV`kLMU{n+zYQK#*r#8BX0@PK(dDD#OJKWcpw20eyAV5U{q z4mmuU!7{(C&emWs92uvE3CaIZ08NfBaDNfBfbE#K219TQDdYO91aTbx6f;fz0r$?v z8=WZBh_l)5C<-J`1uYT-pi&|qKQDIJrkMC2_kt`Pu0h!MW`ge;63f{TVfjU^W9lYH zU&Ii|Q5O=Z<U z%|=X26MGy3OgN5=A$Z?Uq#*@W!aVcaf;(vMkP%}yA4YYt_S??3CBl_IjBTDm!D`#z zIde}2a^^lq(Dr5y@vw#5-cO@Td4^jtT)AuzAEJba z(3(Ii#~=RA>sxHco-6Sl4}bNE*Qds2NjDC(Il_%YZINtK$ah5hG(a4I7qv3fJA!=@f}Qk_Gzj(sxkE1B`!q|m za<~l;t{iY1#H*Y_N5D@*zyn3dS>h}Gvla4{L2ZC|WnkMNT?P6b;eS32;SLp1K>Ryg zY}mIvhZI&P(+GyjacE-eaE2{@G*swBOu?+{N6e!5Bu6~{l#37jrAI1BSTk$^m(iAo z2=xF29&c0USa*1Q!%w4=f#bgDkLk01*6B1cdhh1T)7%CV25> zjm{iv+R|NO>~9auxGhZ1N)Ja zuq4=A7Oyp@kbk0*WOxZZ`eAD^$ysKOA_}(b%Gl6bYq!tNaQ~0GCu2oq6PKrg;js1E zcFbG5miowmQt6V=iY-ti8GyN3#fMs6rO5DZNxwwKY+AV#nz=f0G<#$MXAHzWW6Fsl z{)AKH9MP6esf!@1Hl8A4J%6iN1iO(9sKx|Z&pY{c;eWzE+-~PMFOnlm3(dF-^Wiqj zBE>$#+6%_`n8-ed6yCUycuNV@=&-vAn2OsiNFnvx90rXq&UwJp79sbL z|2-;Fk*Z@Es!2^NVxN91dM0m#<1=>5hu! zZ?CLTD-~OOLeYzC8Vt`zzdFtz@BY63``17Jb%%cWKe~N4IrH2P|9EZwasSKfxAWmI z-W%uL&At2n^6uCFqsz(>P|viA$qy&{#)=>;!J_XFJ@amB$U6Z*etiCuUrlJkTOQ8w zihqP=^_h2@cc>l*E|+8k+hvZ=Q`ok0XkIYi%qkbR*Qu1lTJkt7Y%(PJMif00fA$`e zSlrQ|KN|Lo_wYXZOq5p&iqG|o8@xdtg_|vFG3XC^#+&;sW=Q!z=jgw`ImYRD_}DYp z9H3aauZF0dH0&8X*7(%;7qR<)&R?%h@_&yt`rn^_HXcis+VrPdqDO$LPJB*sHMDvp z)>N}cwLmWZAxp<@i7%srSnMn7G*3}jImD#FTXDiE@qqIBx>>D}Lb@IGA(?hoXUH4rRa+JznXeycpnnuT z5RX@giqymveApmD`3l@Yn~C+z!wX`%2zrRi{BjaJ170ftRyDj{^lW_AWhH20fhtP5 zJrNNniUWMXBYw6Gf_CM^A{n4YvWsMZo7o;`knQq}x;&#U&**6-)3mRMn-DyDi9H(k zK~+2CQovHhjmI0!){qdCn~bD@o_`xeE*YX!K)HHGEk%?|5SAPS$Xm6W!}J<@)iQZ5 zybFRUhSYIoSt_i-91%ZvC;Rq2@;tag()6O==^D9LDA6@mZj-_lD!%+6RSh)kq<3{f zDr1WmqqEpXvAi919{YC&dyv*sdoSKm!<m2zPE|gS_X=E^_`vg^uz`T zJEZCk2->a}B@nnBNjT9EX-iEAS|UqJLQ7B}l|El)GG} ztc4k~nDwX@m35!^p3IA4Q7yY2t#}-n8!}FH-quOEA=T^s16bE1MFK!%F*cBZtOBO8 ztr{89mw#vl&4(-3p^oV&4COpa_XNn} zsZ=?e%AwGn2hN4U<_(8%?U^Ms&P|QFLWF(#x;9W8jNJN(wSN#7iWXTqagaGSP6}=X zdnSc@E0#u<2&^dc22I&$@LtZTw3N#lF_vmUm{1o8cWCBKq|5-(E-I9lw$+!M?CcO zC^xY#T&HFfXnz)(RF4*fKuf?h69+BFuN7VS!$r4F6g82>%3mXoF=0d5>k?>BlD;k( zw;95ePe?a`U4|B<6m7QD1JnVoc;98SciHS+Hv5wZ!)b1w;=FD)`&^aH&P5(uNAK`8 zUR@B%(9G?D?SGN%d7+q`=j6kem5kw39FwI=R)rhfw>e=MCqiVa$v#c0^TB#yq@ zNpvdYax^_r)M*dJVneC!^TJeju2f_R-8zb(IM=;`Mo1ytdfm4!n|&uChV@LqakdV8@!z(ntP-Y0&1peMjWqpN@c`nmX#{0w>sivhOO|d zgonX}zkWe@wWh{t@!`ilxi?P+ill08;dt*5on4$u536)2Hw~nq%mbt4E$>1d7ajVY z@+dkzKqGW5!Mb$~+0}aZhP57~q9;p;Spg(%qkkoa#Q9khllITmxG=kPOrE;n3$>DF zPW3~*^x)M_f=h-aS3iinMz(%*QHfmbJy8imMRs#27o#|{T1p`VQ%)^}-Lw=#*t%KO z5XZe!4nMMTP&0$7mDaX5Cfu6Q60tC$rws4u!bA5qG~#5WNM06F@)CP=hAl?))nX#D zV1H^{-!+ zM~bleD;rrWB}%XcwIIXo8!SB~wHn95o125q(gZZV@dK#@l= zS(OTkk}+Z&W$9UM?4^#)?bkaP^!xpu5r1SMpOiF~qoN6gW~qLn^S&956GcqzHK(pK zOPsG)Vw@xhm1lu%%J34J=x_#Y+Ye{t$NQ0UVLJjpCEL9bOr|`vO^#jnv^F!7;&8?Y z-9H@n7P$gMW6_7{Rnz3Fd6=Z8;4qO1YV?oA{|_Yp3jS}DWJj?{3pcJBF&M>syMKZA z7Xsj5(la)g#D1l>it{Q7dhN=P`jyM`;;9l$q)Q;Ndr6vhe3U)vuk2LTbzC>F>e=`( znV`}=if}Asoc3cG)X9?7We*WJIITNUlo{Jy5JC;zdaTGJ5W3(kqC9@Es$%8+OKH_g zI+PF7i~?ordf*WRZsKWPf!ht9@C0qDXV_B^M^p#(&pwBggMk)Eda2&h(p+q=lGh#eGh2mq0PLOwk{D}nl(|^=x=zQ^= zF455?Lq&2`AVh5hJtVR?k3_<_Ov|XS2aHD`@oPc??P^S?*spb?Eo~eMhVB7-BdyBi@sf>UIsCcz-tHJ=|k@)a}DM zjkfO^ZK6mWmWb-QTd@dGC5tW!ybr=iFTIEg-Cqr4hU8HhQBoKj#*)pC+y zE|=R`j07}~--qW#kALYJQUF~95P=JujgASRYwQ6`JPL`44r>>JN=-TQ(X#K0nf{|8 zt~W4*`5gSkWM-7ZB`#F)jL*-<`}90HZqQd`I{RyTws73+1rIvR76+hfE9IC(ad365 zp%iMZmx=C-pw0;DG`x^E14SmT&y#a=jjVGFS9N4g2t*}!#DAT*FEA4bj4!`F<|+9! z)J6){OHftIp$rDrZnI^IS^xu{cn=uGSUVfJz@w0&#_G#`y9-uhpD2S>@|}i6Rm(tu zQnjtkGi9`)B3)8Q)}VUfjdMmGD)L$ej*8vj0v~=L+sq}b(MiTRq>!Is@YlRFJy|+0 z!3!~ps41V%qkkD}a!m0!)KYf1eA30o8)udU_@x7YIsg*jY!Lw-2X+W9mVh|^FHhWE zjfk^bt%0|NCgMgq>(Ki|5aw4`LqO0MzX$k&Z5u2QFkQrGum>Dh*zqQ`ZU3$9n74rK z3~aD*T=a)c_B*=f(4YDw#$bJAGB9_N*(qQkwMjYY@lRL18;cDfg6{8n^CxU2t_=#NmZggfq0lbVl zLw}F_4`rZfZGX9Xxg=Mb=Rxk`XBz3cWf3D z#P7XTdHo$5y;=8V(nTo~NPBiPFjgc~$9e1u5lbAw)RR&^9F?5Xy;DU3GFLiPzFb9) zd$CLkkO~gvAh5AVfwKf#|BWx30&zqgwtqio(gpDIIRps0r;(HjTx%LvS&Pdq(~waAMPEZZ|=9qq)bRd`+Vm@pERm+uL7c+k15`u!=Onq8!KSvFmz&o z3jC~|O&({f@LVA(PTi6J7BKv{RRII%9d)?#zBczJW}f+;>9_58;U@j?f0dna&wrGy zCWeeEOOJzTih)9a?Q%^V?*dkdFbesDvxSI90R(-q9}awfw9h4<$QOty zzZZ|YuYrZ2?STbavL8%YvOT{S9D{Yt^t_qrSdm~ONaQ_qZ{IrZhwaLRR<&4N8KAtg zDbZehk=ziJEZF*?C{k2g4@pT+yMHx0KB-E*U9`mIcraDOw2My{=2+GB6eR%_JBz~h z`u?Ki5SlKd%s3UaQ)X^?`YDB_%y$$vk-Lu;3{&5C6gK?^?xW1o<$920t-qBMsq^}L zQ;~C`2*FMPr8qa*j)j<8U9yeUL+7yXn8I9 zaP!#myKyje+<7@3j&kFy=gqi==lQPTYJ6DW8?L~7aU3-`E<(V24zA#iC-;RX$GOo} zJVG$a9j(lhF))o;!*QSuv1Jm?Lbi+}5M&2H+eQ{}NNA#B0^V%4^nU?3F8Bjtdd|6! zCmng82z3B;@oI(KFf$23*M8^>*B^@wk8%Tu!o5)q9t>eL#(*KjX1FhoU=iy@Lx+3K z#MU&}bb=RbTS!(+-BAa?Xea3q-yyWbu18UUJ(WoUn_&yMjPx1K9^Wq8%LCD7!L17)2DB^}c^R9&kO^K0=Nl##Ho35bV6(F+Hrd;QEi`YD6@QMxSobA&zCrMwwOT`O zeVCLezPCEya{qYg`{wiG+|Z?vlTpXi(35aY zY*y+WDd(V=w`U7oip`x3-O$U^&~`Dgh!t-YNZV@_NxozGXUX!Ter`yTca4^{Se^Bk ztG^B0eiTIYnUN{9k#&uh8cfYV<}kAyZWV_1ajzXKEPo??IhL7~RyNbgIX{{9`~6t< z`NcUea~ID*A5V{tC;grgln>#*A32fdq?d+KfUTyk>(=7XttTPNf-R0f{GNGxm>aC* zF|Dwx#oYpeu78+UrSi+e`Jb399Sx2b!xYw>;$^KW@Oe0k{HopW5EUL{fsL~S5UlWB zSZoR`9)G~a`48mk&8_bA?aJCk#GokLQKGt2B#BOV^%Kel;KgOQJ7?x>Hs?XzC-&ny z_#tj4JT?AB?Eatg*K3pfV~zgz=bsHxt;Gx4-C*-ph{b>MVoUzxRBfX<64g@j+Js@P zJjOdhDe>SMQI`wk@vvvyI6)$izrL5yqi@MJP^FvyvC4LhuVdMQLq0jS8`~d#Hl1aUQ;<&k6w#DjfRO4X`4XJ)s~J4M zVt-=Eb1;5Gf620zMSe=IP8?!y~m zI@~XQYAm3KCgT{IQSVS>=~<4UbZWuS^rdi_OdS2%TE1+5q8yuKoinPU#y~mk*_30N zPga6Vrk=`4m3`YujB>-Iy}55n)!9l25Pxc4LCll&8550ywE@TiUqK3Pr42-gyL#u~ z{{omS9kzF9%55&0g4BzUZKGA))Hiic2g81WQ=kFX-8Zfo=Y}tPb+66Jg2}rJBD$83 zyV?8#(IQ1Ps3!dSfuajyp?h90T2)$l?C4*&HAzi?arkYOy$FQR!&~<+oTz zd)yyQn<%B7EnNLwRsb`;x(Z~3vV2G#R1nxgpt;e3S@VD6trTIjy9Q{(KSl-P(G$CKsYWPdtc9H8Z> ze=xR=(ZOPb%!3m+86Gdk3wQ*lM$h2{V7mds%rL6*Js{rj17m>9M?n_e;Nn6o+qF@3}m`HsKIE;qpmx|cq~Ei^HG;0NAk zcM#if!7xAR8E@yw-`B`P?tdM_<%BOL|L+HnKPY=J8v)ijmkp8BX`R4Z>;7pr7oCRD z3TV-fr`NK(0<(rrnyNB#1gF179zC;d$E>54LLkLg?+Ovmu()~Hifj3zZG`Vm9mU#T zLAt)-8|fDxKg$$c&Y?#Nx%@Ja8PMg@`PD}URuBpI}Z{AfHn zIyoLqN0VtQp2sZdYFgobiHIf*a2Z+4Dsxsdk?Q1T{dmU9o<+%@sFK9QH#kS84P7Mo zxsGZ{04mt{T%4!$34buk(>`NA{I+OQlt81Qy-|8<=_9(PGo1f{* z#R6YhpU$aNOYM$S>Df8NRYKvi{)Kyym*7REV+PhNM?p4ozTnT`3BpI7&(1?8d^FtJ z-MRnXxX!<4kv3N4iHQZTUQ8|OpI1%BXXDSI3O+}sts%_{s;cDxuOilR%d0g~S4N7e zqPUEzt&Z@}l7Ab@T?4O0lQOGMhpkkfd9vJ=y)Gy-K2jyL`Gj3JlvNeSnqhDudv!Ql z9nmUbZ9i1D3Qzl(KLJyR!LE7STp}V?myL~A7Nqdi7Sgp*z@n;h1be~;6IB*QNDH?$ zx!|@LA6fM?1%^XIrwRUap6ncTb|s!pWM7WQ)BFrCKd+>+sAm0jJk*Iq7L83GYnHR;OJ;~w*zEau|L}h4 zbb?Wret)!2B6LqS>nHgcK{xJ0-Tk@`qU|mFi-qIpIJ13puTac_}3a|mG!P(|V;Vi0Mzz}s;AD8WR*gE|1 zAw1g^GB)g)XG%oi3(n38#wfMBO3bOXgR}ySrRQqJeRQl7w47QeCvbQ$nNE%l#)Ij} z!F0KV2PaFk>@TPN2|_4V6w(j5R+Wbw^!t8{i*Y>ZPX`OwKbQ;_*1`A)9vv*q{`3GY z`+rBvfjOL@BP%L*T>$Y0dbdnkAZWk3>%U?=#Y=y`V)n=Nj{E^JHBS57SLIUU)EM@M z{e!{aU@*MtpPUYdr~TtUjh^v~<57Rv*N#VxR?hXKK_t$!(iJd8hh~dWZ{Yof063WR zj14BSU+K7^==(eyb2aNniv>G`)SzE${eO8*E+po!#?o;&kdd_oDLSBdgJdP`1(Q^$ zyT50<>!YC}bwtRN+WRiEZm z+*gAKs3zpMP!c`kVnrMmT_exgxn@i*#GZUL-lNUc`oY5{w2jl@@pyWCeA1tsjDN>H z_G^s}Eo> z8XX&-8N0qAaA8NR`5tXPc*uH>30H!_Pk7INzT57EpUua5#(x{9{l^03S0*CXhpBay zN`Sm9J~l*F8a(TNp~jSP`n$>oO+dUZvn2e}=`6@QzomXKZ-Ume{I_vZ)9fHfwkf?F lCrV8OLYjWcGq&fd)W&_|@$vKH{|^8F|NlHV_HmoU0RXpJkk9}C diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 1f7e4e76063c2a8ca96247ae206aa60a29f44c14..53bb24e5859035b2aa79818daab717d52e5a96a9 100644 GIT binary patch delta 2606 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 Q00030|9ISwOI3OR0M48nr2qf` delta 2609 zcmV-13eNSD6_yo{fPd{HVR!M=!XBtGcO>qAd%=u&n)Fxdg3T#wd~}>E3N~O1J0NXA zeHArve}6yXw`>?N8y!gW)1O>CfVfd2u+<@&ksbIgWOJtASvAh1|1IRVkyKoe5j1YV zR$N@e&_aF(eY+zA+W5+R;y4gBa6`X?h5RlmyVIMubwLz4M1KeRk`9RtjdS9FE0jS4-)1e`O)V_o?|*;_aByFV0Q6+|0&JpmNhsXZ zN@lB*o2?RSs5ECRaNRo#Qw6b70Mpn|sY+3?Ytu!8Kn^ zSHqF!z~zIcN2CJLBtC8WfpkxkVAAZ z;M`q?4r1bBa1f1{0TxJDDGvPxF}}#|wJ^ECi3?ZTx7L!BU(|F!*c(@+?uTMk`W2Kt zHdLgL#th9Sjy5XS{cAuG!rA2J6;b23xR)yaXoti8nLA(zYC~4Hg=lBvPz}!3xb+?4 z)_*d+-yW#j0HVtS)4YXN(mE`GxRi}>iYci?Sh5+Inez|T`11H8tj$!7G;5@}Z%FgF zRRRwvBQE_8@mv_}Pu3TKr#>Zw3Tv0I(BAx(fhcL66rQ$uf(F#Iwzrg+6NEq~y7 zUT2oMnl4CS&~wCn6_4;+TyyU8a*QtesLViC=^`_>6$zr5sohlXUeMb^|e5%t2gzQ?pcj zH}VQOO!|r2#0_~by89>4(YR7FWrHb_UA46jy%Jj!+y*IcK*~tDjEpWrTx@+oK%K_d zugkGuwxK1qH*d|%;1>BTw!DZ?2Nyw@!#$)sLVSpxLaC9A=q)q?213tpTz}D>prf5{pL5TnDz81uEi6T821+BPB<^*%eqtcy z{AgTgGsIT(5pp$p@xi+Acun*W)jwY7;+#6t5ag!B*cQOej@06wV}C714Rm)RqV59F z&0EJF9+fM#^EWMPexvh($J+X;CG6=u&X~r75;|n2(4_-R(IHK1a*{CpKdfO=BX_*Q zX=%S+(QD1qEd3YU)DDvjC!N7}Vgu5}e=8g%6Yc>Z7f`ENg%aL@m1;0<9i z?DmGV8%$1u0D7IrUVpR(*kpT#t}^M|Y(CS&U_!Y`kX0{8>jmjs#?0N4L!1eo%ZKl( zn7L!V??#u#F!J|6tqpTK+lRTGI)}S!wz&(?Hm}5Q5AM}*u8wp27Uy~;C(N}&zY?&1 zdMF{@NQP)(HMK?rOc>f`5X^|3PWRNYa3}0{7h>Vwr+MnsM}LhXY83H~P{c{eLG(;S zTxY?Y5U;mpPQvke%jTs29|9Wc#q-XY>Mj6=LT!F~n4yk*b>!Q($ah+DjC{R~^{?Mi zzpbtGtM<@;q7SfeF2F*AK%x2OdKT}sO6{1}R^U(>zE!Z^E&qOY%b%4TYQ6!r-b*qQ z!ZMgR;M`rZ+kY=<;I%vcGOR4w^_O($5%D0A8pF&gh(r+GYtF2rfxd8s)R^cWDv<=G zC>z}}k4%sv4}b_7!V{8UbLL2-IMVK&jEDk#p@@7yTHT$%-QXU>AM=FN4et+WcWJvuoUA8cux4dL&yrOxd1#?=GVndkKKu5PhtJMV*y}01j3*i+~dd>uL;YU#TLKs)N6Im zHt~t4z5PAApIy=jxd$+~ksN>zq1B=sn(X$BnGwZ04{{{h^5ZDP{eXGJ=}DlG7})EgQnjn5uY*Hg^x@ zFfXpM1meXtjF4Tz)mGlGS2k2h`Ie$+x83cWtsO^qR3VQ`ww?b;sQPz6K^dy#oUTwQ zOOs!7ve)Lm()|~!U((gU<@SR_0aMgPYAOr@5D|b_^ps8_5ik}$+k2(PzPn`9X$w!M Tchmm`00960iP%#MS$Y5frVt>) diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index 244349faa48..a292f6926d3 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -7,7 +7,7 @@ USAGE: lotus-miner [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc3 + 1.11.1 COMMANDS: init Initialize a lotus miner repo diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index e448f8a540f..177c45b92a3 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -7,7 +7,7 @@ USAGE: lotus-worker [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc3 + 1.11.1 COMMANDS: run Start lotus worker diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index 982e61df5a5..a960299ff58 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -7,7 +7,7 @@ USAGE: lotus [global options] command [command options] [arguments...] VERSION: - 1.11.1-rc3 + 1.11.1 COMMANDS: daemon Start a lotus daemon process From ea242b5bade610c17c5a4f63d86042b1db724eaa Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Mon, 16 Aug 2021 16:34:31 -0400 Subject: [PATCH 78/79] Remove reverted pr from changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fcd7de20fb..457b0e1c0e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,7 +54,6 @@ This is a **highly recommended** but optional Lotus v1.11.1 release that introd ## Bug Fixes - Fix padding of deals, which only partially shipped in #5988 ([filecoin-project/lotus#6683](https://github.com/filecoin-project/lotus/pull/6683)) - fix deal concurrency test failures by upgrading graphsync and others ([filecoin-project/lotus#6724](https://github.com/filecoin-project/lotus/pull/6724)) - - PriceListByVersion ([filecoin-project/lotus#6766](https://github.com/filecoin-project/lotus/pull/6766)) - fix: on randomness change, use new rand ([filecoin-project/lotus#6805](https://github.com/filecoin-project/lotus/pull/6805)) - fix: always check if StateSearchMessage returns nil ([filecoin-project/lotus#6802](https://github.com/filecoin-project/lotus/pull/6802)) - test: fix flaky window post tests ([filecoin-project/lotus#6804](https://github.com/filecoin-project/lotus/pull/6804)) - wrap close(wait) with sync.Once to avoid panic ([filecoin-project/lotus#6800](https://github.com/filecoin-project/lotus/pull/6800)) From e467b130c252588b4f8672dc148c0d76a56e3cd8 Mon Sep 17 00:00:00 2001 From: Jennifer Wang Date: Tue, 17 Aug 2021 10:44:38 -0400 Subject: [PATCH 79/79] make go mod happy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index be30d94200f..97c53b85436 100644 --- a/go.mod +++ b/go.mod @@ -168,4 +168,4 @@ replace github.com/filecoin-project/lotus => ./ replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi -replace github.com/filecoin-project/test-vectors => ./extern/test-vectors \ No newline at end of file +replace github.com/filecoin-project/test-vectors => ./extern/test-vectors