Compare commits

..
Author SHA1 Message Date
Travis Person 980023e87b Calibration genesis 2020-10-12 07:50:27 +00:00
Travis Person 36a10f4acc New calibration network info 2020-10-12 07:37:26 +00:00
Travis Person d1b95b02dd Merge pull request #4325 from filecoin-project/asr/calbinet
Introduce tape upgrade to calibration net
2020-10-11 23:47:39 -07:00
Aayush Rajasekaran b273bfc5c3 Set tape upgrade to 15000 2020-10-12 02:33:10 -04:00
Aayush Rajasekaran af14f30e3a Merge branch 'master' into ntwk-calibration 2020-10-12 02:14:51 -04:00
Aayush Rajasekaran de1038ecc3 Merge branch 'master' into ntwk-calibration 2020-10-12 02:11:41 -04:00
Travis Person d0e432ab16 Calibration genesis 2020-10-07 04:05:40 +00:00
Travis Person f5132c3b61 New calibration network info 2020-10-07 02:52:42 +00:00
349 changed files with 5938 additions and 22166 deletions
+2 -26
View File
@@ -34,7 +34,7 @@ commands:
condition: << parameters.linux >>
steps:
- run: sudo apt-get update
- run: sudo apt-get install ocl-icd-opencl-dev libhwloc-dev
- run: sudo apt-get install ocl-icd-opencl-dev
- run: git submodule sync
- run: git submodule update --init
download-params:
@@ -188,14 +188,6 @@ jobs:
command: |
bash <(curl -s https://codecov.io/bash)
test-chain:
<<: *test
test-node:
<<: *test
test-storage:
<<: *test
test-cli:
<<: *test
test-short:
<<: *test
test-window-post:
@@ -276,7 +268,7 @@ jobs:
- run: cd extern/filecoin-ffi && make
- run:
name: "replace lotus, filecoin-ffi, blst and fil-blst deps"
command: cd extern/oni/lotus-soup && go mod edit -replace github.com/filecoin-project/lotus=../../../ && go mod edit -replace github.com/filecoin-project/filecoin-ffi=../../filecoin-ffi && go mod edit -replace github.com/supranational/blst=../../blst
command: cd extern/oni/lotus-soup && go mod edit -replace github.com/filecoin-project/lotus=../../../ && go mod edit -replace github.com/filecoin-project/filecoin-ffi=../../filecoin-ffi && go mod edit -replace github.com/supranational/blst=../../fil-blst/blst && go mod edit -replace github.com/filecoin-project/fil-blst=../../fil-blst
- run:
name: "build lotus-soup testplan"
command: pushd extern/oni/lotus-soup && go build -tags=testground .
@@ -436,22 +428,6 @@ workflows:
- test:
codecov-upload: true
test-suite-name: full
- test-chain:
codecov-upload: true
test-suite-name: chain
packages: "./chain/..."
- test-node:
codecov-upload: true
test-suite-name: node
packages: "./node/..."
- test-storage:
codecov-upload: true
test-suite-name: storage
packages: "./storage/... ./extern/..."
- test-cli:
codecov-upload: true
test-suite-name: cli
packages: "./cli/... ./cmd/... ./api/..."
- test-window-post:
go-test-flags: "-run=TestWindowedPost"
winpost-test: "1"
+1 -5
View File
@@ -1,9 +1,5 @@
comment: off
ignore:
- "**/cbor_gen.go"
- "api/test/**/*"
- "api/test/*"
- "gen/**/*"
- "gen/*"
- "cbor_gen.go"
github_checks:
annotations: false
+6 -5
View File
@@ -1,15 +1,16 @@
[submodule "extern/filecoin-ffi"]
path = extern/filecoin-ffi
url = https://github.com/filecoin-project/filecoin-ffi.git
branch = master
[submodule "extern/serialization-vectors"]
path = extern/serialization-vectors
url = https://github.com/filecoin-project/serialization-vectors.git
url = https://github.com/filecoin-project/serialization-vectors
[submodule "extern/test-vectors"]
path = extern/test-vectors
url = https://github.com/filecoin-project/test-vectors.git
[submodule "extern/fil-blst"]
path = extern/fil-blst
url = https://github.com/filecoin-project/fil-blst.git
[submodule "extern/oni"]
path = extern/oni
url = https://github.com/filecoin-project/oni.git
[submodule "extern/blst"]
path = extern/blst
url = https://github.com/supranational/blst.git
url = https://github.com/filecoin-project/oni
-270
View File
@@ -1,275 +1,5 @@
# Lotus changelog
# 1.1.3 / 2020-11-12
This is an optional release of Lotus that upgrades Lotus dependencies, and includes many performance enhancements, bugfixes, and UX improvements.
## Highlights
- Refactored much of the miner code (https://github.com/filecoin-project/lotus/pull/3618), improving its recovery from restarts and overall sector success rate
- Updated [proofs](https://github.com/filecoin-project/rust-fil-proofs) to v5.3.0, which brings significant performance improvements
- Updated [markets](https://github.com/filecoin-project/go-fil-markets/releases/tag/v1.0.4) to v1.0.4, which reduces failures due to reorgs (https://github.com/filecoin-project/lotus/pull/4730) and uses the newly refactored fund manager (https://github.com/filecoin-project/lotus/pull/4736)
## Changes
#### Core Lotus
- polish: add Equals method to MinerInfo shim (https://github.com/filecoin-project/lotus/pull/4604)
- Fix messagepool accounting (https://github.com/filecoin-project/lotus/pull/4668)
- Prep for gas balancing (https://github.com/filecoin-project/lotus/pull/4651)
- Reduce badger ValueThreshold to 128 (https://github.com/filecoin-project/lotus/pull/4629)
- Config for default max gas fee (https://github.com/filecoin-project/lotus/pull/4652)
- bootstrap: don't return early when one drand resolution fails (https://github.com/filecoin-project/lotus/pull/4626)
- polish: add ClaimsChanged and DiffClaims method to power shim (https://github.com/filecoin-project/lotus/pull/4628)
- Simplify chain event Called API (https://github.com/filecoin-project/lotus/pull/4664)
- Cache deal states for most recent old/new tipset (https://github.com/filecoin-project/lotus/pull/4623)
- Add miner available balance and power info to state miner info (https://github.com/filecoin-project/lotus/pull/4618)
- Call GetHeaviestTipSet() only once when syncing (https://github.com/filecoin-project/lotus/pull/4696)
- modify runtime gasUsed printf (https://github.com/filecoin-project/lotus/pull/4704)
- Rename builtin actor generators (https://github.com/filecoin-project/lotus/pull/4697)
- Move gas multiplier as property of pricelist (https://github.com/filecoin-project/lotus/pull/4728)
- polish: add msig pendingtxn diffing and comp (https://github.com/filecoin-project/lotus/pull/4719)
- Optional chain Bitswap (https://github.com/filecoin-project/lotus/pull/4717)
- rewrite sync manager (https://github.com/filecoin-project/lotus/pull/4599)
- async connect to bootstrappers (https://github.com/filecoin-project/lotus/pull/4785)
- head change coalescer (https://github.com/filecoin-project/lotus/pull/4688)
- move to native badger blockstore; leverage zero-copy View() to deserialize in-place (https://github.com/filecoin-project/lotus/pull/4681)
- badger blockstore: minor improvements (https://github.com/filecoin-project/lotus/pull/4811)
- Do not fail wallet delete because of pre-existing trashed key (https://github.com/filecoin-project/lotus/pull/4589)
- Correctly delete the default wallet address (https://github.com/filecoin-project/lotus/pull/4705)
#### Mining
- worker key should change when set sender found key not equal with the value on chain (https://github.com/filecoin-project/lotus/pull/4595)
- extern/sector-storage: fix GPU usage overwrite bug (https://github.com/filecoin-project/lotus/pull/4627)
- sectorstorage: Fix manager restart edge-case (https://github.com/filecoin-project/lotus/pull/4645)
- storagefsm: Fix GetTicket loop when the sector is already precommitted (https://github.com/filecoin-project/lotus/pull/4643)
- Debug flag to force running sealing scheduler (https://github.com/filecoin-project/lotus/pull/4662)
- Fix worker reenabling, handle multiple restarts in worker (https://github.com/filecoin-project/lotus/pull/4666)
- keep retrying the proof until we run out of sectors to skip (https://github.com/filecoin-project/lotus/pull/4633)
- worker: Commands to pause/resume task processing (https://github.com/filecoin-project/lotus/pull/4615)
- struct name incorrect (https://github.com/filecoin-project/lotus/pull/4699)
- optimize code replace strings with constants (https://github.com/filecoin-project/lotus/pull/4769)
- optimize pledge sector (https://github.com/filecoin-project/lotus/pull/4765)
- Track sealing processes across lotus-miner restarts (https://github.com/filecoin-project/lotus/pull/3618)
- Fix scheduler lockups after storage is freed (https://github.com/filecoin-project/lotus/pull/4778)
- storage: Track worker hostnames with work (https://github.com/filecoin-project/lotus/pull/4779)
- Expand sched-diag; Command to abort sealing calls (https://github.com/filecoin-project/lotus/pull/4804)
#### Markets and Data Transfer
- Flesh out data transfer features (https://github.com/filecoin-project/lotus/pull/4572)
- Fix memory leaks in data transfer (https://github.com/filecoin-project/lotus/pull/4619)
- Handle deal id changes in OnDealSectorCommitted (https://github.com/filecoin-project/lotus/pull/4730)
- Refactor FundManager (https://github.com/filecoin-project/lotus/pull/4736)
- refactor: integrate new FundManager (https://github.com/filecoin-project/lotus/pull/4787)
- Fix race in paych manager when req context is cancelled (https://github.com/filecoin-project/lotus/pull/4803)
- fix race in paych manager add funds (https://github.com/filecoin-project/lotus/pull/4597)
- Fix panic in FundManager (https://github.com/filecoin-project/lotus/pull/4808)
#### UX
- Make EarlyExpiration in sectors list less scary (https://github.com/filecoin-project/lotus/pull/4600)
- Add commands to change the worker key (https://github.com/filecoin-project/lotus/pull/4513)
- Expose ClientDealSize via CLI (https://github.com/filecoin-project/lotus/pull/4569)
- client deal: Cache CommD when creating multiple deals (https://github.com/filecoin-project/lotus/pull/4535)
- miner sectors list: flags for events/seal time (https://github.com/filecoin-project/lotus/pull/4649)
- make IPFS online mode configurable (https://github.com/filecoin-project/lotus/pull/4650)
- Add sync status to miner info command (https://github.com/filecoin-project/lotus/pull/4669)
- Add a StateDecodeParams method (https://github.com/filecoin-project/lotus/pull/4105)
- sched: Interactive RPC Shell (https://github.com/filecoin-project/lotus/pull/4692)
- Add api for getting status given a code (https://github.com/filecoin-project/lotus/pull/4210)
- Update lotus-stats with a richer cli (https://github.com/filecoin-project/lotus/pull/4718)
- Use TSK passed to GasEstimateGasLimit (https://github.com/filecoin-project/lotus/pull/4739)
- match data type for reward state api (https://github.com/filecoin-project/lotus/pull/4745)
- Add `termination-estimate` to get an estimation for how much a termination penalty will be (https://github.com/filecoin-project/lotus/pull/4617)
- Restrict `ParseFIL` input length (https://github.com/filecoin-project/lotus/pull/4780)
- cmd sectors commitIDs len debug (https://github.com/filecoin-project/lotus/pull/4786)
- Add client deal-stats CLI (https://github.com/filecoin-project/lotus/pull/4788)
- Modify printf format (https://github.com/filecoin-project/lotus/pull/4795)
- Updated msig inspect (https://github.com/filecoin-project/lotus/pull/4533)
#### Testing and Tooling
- refactor: share code between CLI tests (https://github.com/filecoin-project/lotus/pull/4598)
- Fix flaky TestCLIDealFlow (https://github.com/filecoin-project/lotus/pull/4608)
- Fix flaky testMiningReal (https://github.com/filecoin-project/lotus/pull/4609)
- Add election run-dummy command (https://github.com/filecoin-project/lotus/pull/4498)
- Fix .gitmodules (https://github.com/filecoin-project/lotus/pull/4713)
- fix metrics wiring.(https://github.com/filecoin-project/lotus/pull/4691)
- shed: Util for creating ID CIDs (https://github.com/filecoin-project/lotus/pull/4726)
- Run kumquat upgrade on devnets (https://github.com/filecoin-project/lotus/pull/4734)
- Make pond work again (https://github.com/filecoin-project/lotus/pull/4775)
- lotus-stats: fix influx flags (https://github.com/filecoin-project/lotus/pull/4810)
#### Dependencies
- update filecoin-ffi in go mod (https://github.com/filecoin-project/lotus/pull/4584)
- Update FFI (https://github.com/filecoin-project/lotus/pull/4613)
- feat: integrate new optional blst backend and verification optimizations from proofs (https://github.com/filecoin-project/lotus/pull/4630)
- Use https for blst submodule (https://github.com/filecoin-project/lotus/pull/4710)
- Update go-bitfield (https://github.com/filecoin-project/lotus/pull/4756)
- Update Yamux (https://github.com/filecoin-project/lotus/pull/4758)
- Update to latest go-bitfield (https://github.com/filecoin-project/lotus/pull/4793)
- Update to latest go-address (https://github.com/filecoin-project/lotus/pull/4798)
# 1.1.2 / 2020-10-24
This is a patch release of Lotus that builds on the fixes involving worker keys that was introduced in v1.1.1. Miners and node operators should update to this release as soon as possible in order to ensure their blocks are propagated and validated.
## Changes
- Handle worker key changes correctly in runtime (https://github.com/filecoin-project/lotus/pull/4579)
# 1.1.1 / 2020-10-24
This is a patch release of Lotus that addresses some issues caused by when miners change their worker keys. Miners and node operators should update to this release as soon as possible, especially any miner who has changed their worker key recently.
## Changes
- Miner finder for interactive client deal CLI (https://github.com/filecoin-project/lotus/pull/4504)
- Disable blockstore bloom filter (https://github.com/filecoin-project/lotus/pull/4512)
- Add api for getting status given a code (https://github.com/filecoin-project/lotus/pull/4210)
- add batch api for push messages (https://github.com/filecoin-project/lotus/pull/4236)
- add measure datastore wrapper around bench chain datastore (https://github.com/filecoin-project/lotus/pull/4302)
- Look at block base fee for PCR (https://github.com/filecoin-project/lotus/pull/4313)
- Add a shed util to determine % of power that has won a block (https://github.com/filecoin-project/lotus/pull/4318)
- Shed/borked cmd (https://github.com/filecoin-project/lotus/pull/4339)
- optimize mining code (https://github.com/filecoin-project/lotus/pull/4379)
- heaviestTipSet reurning nil is a ok (https://github.com/filecoin-project/lotus/pull/4523)
- Remove most v0 actor imports (https://github.com/filecoin-project/lotus/pull/4383)
- Small chain export optimization (https://github.com/filecoin-project/lotus/pull/4536)
- Add block list to pcr (https://github.com/filecoin-project/lotus/pull/4314)
- Fix circ supply default in conformance (https://github.com/filecoin-project/lotus/pull/4449)
- miner: fix init --create-worker-key (https://github.com/filecoin-project/lotus/pull/4475)
- make push and addLocal atomic (https://github.com/filecoin-project/lotus/pull/4500)
- add some methods that oni needs (https://github.com/filecoin-project/lotus/pull/4501)
- MinerGetBaseInfo: if miner is not found in lookback, check current (https://github.com/filecoin-project/lotus/pull/4508)
- Delete wallet from local wallet cache (https://github.com/filecoin-project/lotus/pull/4526)
- Fix lotus-shed ledger list (https://github.com/filecoin-project/lotus/pull/4521)
- Manage sectors by size instead of proof type (https://github.com/filecoin-project/lotus/pull/4511)
- Feat/api request metrics wrapper (https://github.com/filecoin-project/lotus/pull/4516)
- Fix chain sync stopping to sync (https://github.com/filecoin-project/lotus/pull/4541)
- Use the correct lookback for the worker key when creating blocks (https://github.com/filecoin-project/lotus/pull/4539)
- Cleanup test initialization and always validate VRFs in tests (https://github.com/filecoin-project/lotus/pull/4538)
- Add a market WithdrawBalance CLI (https://github.com/filecoin-project/lotus/pull/4524)
- wallet list: Add market balance and ID address flags (https://github.com/filecoin-project/lotus/pull/4555)
- tvx simulate command; tvx extract --ignore-sanity-checks (https://github.com/filecoin-project/lotus/pull/4554)
- lotus-lite: CLI tests for `lotus client` commands (https://github.com/filecoin-project/lotus/pull/4497)
- lite-mode - market storage and retrieval clients (https://github.com/filecoin-project/lotus/pull/4263)
- Chore: update drand to v1.2.0 (https://github.com/filecoin-project/lotus/pull/4420)
- Fix random test failures (https://github.com/filecoin-project/lotus/pull/4559)
- Fix flaky TestTimedBSSimple (https://github.com/filecoin-project/lotus/pull/4561)
- Make wallet market withdraw usable with miner addresses (https://github.com/filecoin-project/lotus/pull/4556)
- Fix flaky TestChainExportImportFull (https://github.com/filecoin-project/lotus/pull/4564)
- Use older randomness for the PoSt commit on specs-actors version 2 (https://github.com/filecoin-project/lotus/pull/4563)
- shed: Commad to decode messages (https://github.com/filecoin-project/lotus/pull/4565)
- Fetch worker key from correct block on sync (https://github.com/filecoin-project/lotus/pull/4573)
# 1.1.0 / 2020-10-20
This is a mandatory release that introduces the first post-liftoff upgrade to the Filecoin network. The changes that break consensus are an upgrade to specs-actors v2.2.0 at epoch 170000.
## Changes
- Introduce Network version 6 (https://github.com/filecoin-project/lotus/pull/4506)
- Update markets v1.0.0 (https://github.com/filecoin-project/lotus/pull/4505)
- Add some extra logging to try and debug sync issues (https://github.com/filecoin-project/lotus/pull/4486)
- Circle: Run tests for some subsystems separately (https://github.com/filecoin-project/lotus/pull/4496)
- Add a terminate sectors command to lotus-shed (https://github.com/filecoin-project/lotus/pull/4507)
- Add a comment to BlockMessages to address #4446 (https://github.com/filecoin-project/lotus/pull/4491)
# 1.0.0 / 2020-10-19
It's 1.0.0! This is an optional release of Lotus that introduces some UX improvements to the 0.10 series.
This very small release is largely cosmetic, and intended to flag the code that the Filecoin mainnet was launched with.
## API changes
- `StateMsgGasCost` has been removed. The equivalent information can be gained by calling `StateReplay`.
- A `GasCost` field has been added to the `InvocResult` type, meaning detailed gas costs will be returned when calling `StateReplay`, `StateCompute`, and `StateCall`.
- The behaviour of `StateReplay` in response to an empty tipset key has been changed. Instead of simply using the heaviest tipset (which is almost guaranteed to be an unsuccessful replay), we search now search the chain for the tipset that included the message, and replay the message in that tipset (we fail if no such tipset is found).
## Changes
- Increase code coverage! (https://github.com/filecoin-project/lotus/pull/4410)
- Mpool: Don't block node startup loading messages (https://github.com/filecoin-project/lotus/pull/4411)
- Improve the UX of multisig approves (https://github.com/filecoin-project/lotus/pull/4398)
- Use build.BlockDelaySecs for deal start buffer (https://github.com/filecoin-project/lotus/pull/4415)
- Conformance: support multiple protocol versions (https://github.com/filecoin-project/lotus/pull/4393)
- Ensure msig inspect cli works with lotus-lite (https://github.com/filecoin-project/lotus/pull/4421)
- Add command to (slowly) prune lotus chain datastore (https://github.com/filecoin-project/lotus/pull/3876)
- Add WalletVerify to lotus-gateway (https://github.com/filecoin-project/lotus/pull/4373)
- Improve StateMsg APIs (https://github.com/filecoin-project/lotus/pull/4429)
- Add endpoints needed by spacegap (https://github.com/filecoin-project/lotus/pull/4426)
- Make audit balances capable of printing robust addresses (https://github.com/filecoin-project/lotus/pull/4423)
- Custom filters for retrieval deals (https://github.com/filecoin-project/lotus/pull/4424)
- Fix message list api (https://github.com/filecoin-project/lotus/pull/4422)
- Replace bootstrap peers (https://github.com/filecoin-project/lotus/pull/4447)
- Don't overwrite previously-configured maxPieceSize for a persisted ask (https://github.com/filecoin-project/lotus/pull/4480)
- State: optimize state snapshot address cache (https://github.com/filecoin-project/lotus/pull/4481)
# 0.10.2 / 2020-10-14
This is an optional release of Lotus that updates markets to 0.9.1, which fixes an issue affecting deals that were mid-transfer when the node was upgraded to 0.9.0. This release also includes some tweaks to default gas values and minor performance improvements.
## Changes
- Use updated stored ask API (https://github.com/filecoin-project/lotus/pull/4384)
- tvx: trace puts to blockstore for inclusion in CAR. (https://github.com/filecoin-project/lotus/pull/4278)
- Add propose remove (https://github.com/filecoin-project/lotus/pull/4311)
- Update to 0.9.1 bugfix release (https://github.com/filecoin-project/lotus/pull/4402)
- Update drand endpoints (https://github.com/filecoin-project/lotus/pull/4125)
- fix: return true when deadlines changed (https://github.com/filecoin-project/lotus/pull/4403)
- sync wait --watch (https://github.com/filecoin-project/lotus/pull/4396)
- reduce garbage in blockstore (https://github.com/filecoin-project/lotus/pull/4406)
- give the TimeCacheBS tests a bit more time (https://github.com/filecoin-project/lotus/pull/4407)
- Improve gas defaults (https://github.com/filecoin-project/lotus/pull/4408)
- Change default gas premium to for 10 block inclusion (https://github.com/filecoin-project/lotus/pull/4222)
# 0.10.1 / 2020-10-14
This is an optional release of Lotus that updates markets to 0.9.0, which adds the ability to restart data transfers. This release also introduces Ledger support, and various UX improvements.
## Changes
- Test the tape upgrade (https://github.com/filecoin-project/lotus/pull/4328)
- Adding in Ledger support (https://github.com/filecoin-project/lotus/pull/4290)
- Improve the UX for lotus-miner sealing workers (https://github.com/filecoin-project/lotus/pull/4329)
- Add a CLI tool for miner's to repay debt (https://github.com/filecoin-project/lotus/pull/4319)
- Rename params_testnet to params_mainnet (https://github.com/filecoin-project/lotus/pull/4336)
- Use seal-duration in calculating the earliest StartEpoch (https://github.com/filecoin-project/lotus/pull/4337)
- Reject deals that are > 7 days in the future in the BasicDealFilter (https://github.com/filecoin-project/lotus/pull/4173)
- Add an API endpoint to calculate the exact circulating supply (https://github.com/filecoin-project/lotus/pull/4148)
- lotus-pcr: ignore all other market messages (https://github.com/filecoin-project/lotus/pull/4341)
- Add message CID to InvocResult (https://github.com/filecoin-project/lotus/pull/4382)
- types: Add CID fields to messages in json marshalers (https://github.com/filecoin-project/lotus/pull/4338)
- fix(sync state): set state height to actual tipset height (https://github.com/filecoin-project/lotus/pull/4347)
- Fix off by one tipset in searchBackForMsg (https://github.com/filecoin-project/lotus/pull/4367)
- fix a panic on startup when we fail to load the tipset (https://github.com/filecoin-project/lotus/pull/4376)
- Avoid having the same message CID show up in execution traces (https://github.com/filecoin-project/lotus/pull/4350)
- feat(markets): update markets 0.9.0 and add data transfer restart (https://github.com/filecoin-project/lotus/pull/4363)
# 0.10.0 / 2020-10-12
This is a consensus-breaking hotfix that addresses an issue in specs-actors v2.0.3 that made it impossible to pledge new 32GiB sectors. The change in Lotus is to update to actors v2.1.0, behind the new network version 5.
## Changes
- make pledge test pass with the race detector (https://github.com/filecoin-project/lotus/pull/4291)
- fix a race in tipset cache usage (https://github.com/filecoin-project/lotus/pull/4282)
- add an api for removing multisig signers (https://github.com/filecoin-project/lotus/pull/4274)
- cli: Don't output errors to stdout (https://github.com/filecoin-project/lotus/pull/4298)
- Fix panic in wallet export when key is not found (https://github.com/filecoin-project/lotus/pull/4299)
- Dump the block validation cache whenever we perform an import (https://github.com/filecoin-project/lotus/pull/4287)
- Fix two races (https://github.com/filecoin-project/lotus/pull/4301)
- sync unmark-bad --all (https://github.com/filecoin-project/lotus/pull/4296)
- decode parameters for multisig transactions in inspect (https://github.com/filecoin-project/lotus/pull/4312)
- Chain is love (https://github.com/filecoin-project/lotus/pull/4321)
- lotus-stats: optmize getting miner power (https://github.com/filecoin-project/lotus/pull/4315)
- implement tape upgrade (https://github.com/filecoin-project/lotus/pull/4322)
# 0.9.1 / 2020-10-10
This release fixes an issue which may cause the actors v2 migration to compute the state incorrectly when more than one migration is running in parallel.
+4 -16
View File
@@ -133,30 +133,18 @@ benchmarks:
lotus-pond: 2k
go build -o lotus-pond ./lotuspond
(cd lotuspond/front && npm i && CI=false npm run build)
.PHONY: lotus-pond
BINS+=lotus-pond
lotus-pond-front:
(cd lotuspond/front && npm i && CI=false npm run build)
.PHONY: lotus-pond-front
lotus-pond-app: lotus-pond-front lotus-pond
.PHONY: lotus-pond-app
lotus-townhall:
rm -f lotus-townhall
go build -o lotus-townhall ./cmd/lotus-townhall
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build
.PHONY: lotus-townhall
BINS+=lotus-townhall
lotus-townhall-front:
(cd ./cmd/lotus-townhall/townhall && npm i && npm run build)
.PHONY: lotus-townhall-front
lotus-townhall-app: lotus-touch lotus-townhall-front
go run github.com/GeertJohan/go.rice/rice append --exec lotus-townhall -i ./cmd/lotus-townhall -i ./build
.PHONY: lotus-townhall-app
lotus-fountain:
rm -f lotus-fountain
go build -o lotus-fountain ./cmd/lotus-fountain
@@ -179,7 +167,7 @@ BINS+=lotus-bench
lotus-stats:
rm -f lotus-stats
go build $(GOFLAGS) -o lotus-stats ./cmd/lotus-stats
go build -o lotus-stats ./cmd/lotus-stats
go run github.com/GeertJohan/go.rice/rice append --exec lotus-stats -i ./build
.PHONY: lotus-stats
BINS+=lotus-stats
+9 -3
View File
@@ -2,7 +2,9 @@
## Reporting a Vulnerability
For *critical* bugs, please consult our Security Policy and Responsible Disclosure Program information at https://github.com/filecoin-project/community/blob/master/SECURITY.md
For *critical* bugs, please send an email to security@filecoin.org.
The bug reporting process differs between bugs that are critical and may crash the network, and others that are unlikely to cause problems if malicious parties know about it. For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
Please try to provide a clear description of any bugs reported, along with how to reproduce the bug if possible. More detailed bug reports (especially those with a PoC included) will help us move forward much faster. Additionally, please avoid reporting bugs that already have open issues. Take a moment to search the issue list of the related GitHub repositories before writing up a new report.
@@ -18,6 +20,10 @@ Here are some examples of bugs we would consider 'critical':
This is not an exhaustive list, but should provide some idea of what we consider 'critical'.
## Reporting a non security bug
## Supported Versions
For non-critical bugs, please simply file a GitHub [issue](https://github.com/filecoin-project/lotus/issues/new?template=bug_report.md).
* TODO: This should be defined and set up by Mainnet launch.
| Version | Supported |
| ------- | ------------------ |
| Testnet | :white_check_mark: |
-5
View File
@@ -4,8 +4,6 @@ import (
"context"
"fmt"
"github.com/google/uuid"
"github.com/filecoin-project/go-jsonrpc/auth"
metrics "github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/network"
@@ -60,9 +58,6 @@ type Common interface {
// trigger graceful shutdown
Shutdown(context.Context) error
// Session returns a random UUID of api provider session
Session(context.Context) (uuid.UUID, error)
Closing(context.Context) (<-chan struct{}, error)
}
+12 -57
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"time"
datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-state-types/network"
"github.com/ipfs/go-cid"
@@ -207,15 +206,6 @@ type FullNode interface {
// based on current chain conditions
MpoolPushMessage(ctx context.Context, msg *types.Message, spec *MessageSendSpec) (*types.SignedMessage, error)
// MpoolBatchPush batch pushes a signed message to mempool.
MpoolBatchPush(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
// MpoolBatchPushUntrusted batch pushes a signed message to mempool from untrusted sources.
MpoolBatchPushUntrusted(context.Context, []*types.SignedMessage) ([]cid.Cid, error)
// MpoolBatchPushMessage batch pushes a unsigned message to mempool.
MpoolBatchPushMessage(context.Context, []*types.Message, *MessageSendSpec) ([]*types.SignedMessage, error)
// MpoolGetNonce gets next nonce for the specified sender.
// Note that this method may not be atomic. Use MpoolPushMessage instead.
MpoolGetNonce(context.Context, address.Address) (uint64, error)
@@ -239,9 +229,7 @@ type FullNode interface {
// MethodGroup: Wallet
// WalletNew creates a new address in the wallet with the given sigType.
// Available key types: bls, secp256k1, secp256k1-ledger
// Support for numerical types: 1 - secp256k1, 2 - BLS is deprecated
WalletNew(context.Context, types.KeyType) (address.Address, error)
WalletNew(context.Context, crypto.SigType) (address.Address, error)
// WalletHas indicates whether the given address is in the wallet.
WalletHas(context.Context, address.Address) (bool, error)
// WalletList lists all the addresses in the wallet.
@@ -286,8 +274,6 @@ type FullNode interface {
ClientListDeals(ctx context.Context) ([]DealInfo, error)
// ClientGetDealUpdates returns the status of updated deals
ClientGetDealUpdates(ctx context.Context) (<-chan DealInfo, error)
// ClientGetDealStatus returns status given a code
ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error)
// ClientHasLocal indicates whether a certain CID is locally stored.
ClientHasLocal(ctx context.Context, root cid.Cid) (bool, error)
// ClientFindData identifies peers that have a certain file, and returns QueryOffers (one per peer).
@@ -301,8 +287,6 @@ type FullNode interface {
ClientRetrieveWithEvents(ctx context.Context, order RetrievalOrder, ref *FileRef) (<-chan marketevents.RetrievalEvent, error)
// ClientQueryAsk returns a signed StorageAsk from the specified miner.
ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error)
// ClientCalcCommP calculates the CommP and data size of the specified CID
ClientDealPieceCID(ctx context.Context, root cid.Cid) (DataCIDSize, error)
// ClientCalcCommP calculates the CommP for a specified file
ClientCalcCommP(ctx context.Context, inpath string) (*CommPRet, error)
// ClientGenCar generates a CAR file for the specified file.
@@ -312,10 +296,6 @@ type FullNode interface {
// ClientListTransfers returns the status of all ongoing transfers of data
ClientListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
ClientDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
// ClientRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
// ClientRetrieveTryRestartInsufficientFunds attempts to restart stalled retrievals on a given payment channel
// which are stuck due to insufficient funds
ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error
@@ -330,22 +310,19 @@ type FullNode interface {
// MethodGroup: State
// The State methods are used to query, inspect, and interact with chain state.
// Most methods take a TipSetKey as a parameter. The state looked up is the state at that tipset.
// All methods take a TipSetKey as a parameter. The state looked up is the state at that tipset.
// A nil TipSetKey can be provided as a param, this will cause the heaviest tipset in the chain to be used.
// StateCall runs the given message and returns its result without any persisted changes.
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
// StateReplay replays a given message, assuming it was included in a block in the specified tipset.
// If no tipset key is provided, the appropriate tipset is looked up.
// StateReplay returns the result of executing the indicated message, assuming it was executed in the indicated tipset.
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
// StateGetActor returns the indicated actor's nonce and balance.
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
// StateReadState returns the indicated actor's state.
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
// StateListMessages looks back and returns all messages with a matching to or from address, stopping at the given height.
StateListMessages(ctx context.Context, match *MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
// StateDecodeParams attempts to decode the provided params, based on the recipient actor address and method number.
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error)
// StateNetworkName returns the name of the network the node is synced to
StateNetworkName(context.Context) (dtypes.NetworkName, error)
@@ -376,8 +353,6 @@ type FullNode interface {
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error)
// StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
// StateMinerSectorAllocated checks if a sector is allocated
StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error)
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
@@ -390,6 +365,8 @@ type FullNode interface {
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
StateSearchMsg(context.Context, cid.Cid) (*MsgLookup, error)
// StateMsgGasCost searches for a message in the chain, and returns details of the messages gas costs, including the penalty and miner tip
StateMsgGasCost(context.Context, cid.Cid, types.TipSetKey) (*MsgGasCost, error)
// StateWaitMsg looks back in the chain for a message. If not found, it blocks until the
// message arrives on chain, and gets to the indicated confidence depth.
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*MsgLookup, error)
@@ -437,12 +414,8 @@ type FullNode interface {
// can issue. It takes the deal size and verified status as parameters.
StateDealProviderCollateralBounds(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (DealCollateralBounds, error)
// StateCirculatingSupply returns the exact circulating supply of Filecoin at the given tipset.
// This is not used anywhere in the protocol itself, and is only for external consumption.
StateCirculatingSupply(context.Context, types.TipSetKey) (abi.TokenAmount, error)
// StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset.
// This is the value reported by the runtime interface to actors code.
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (CirculatingSupply, error)
// StateCirculatingSupply returns the circulating supply of Filecoin at the given tipset
StateCirculatingSupply(context.Context, types.TipSetKey) (CirculatingSupply, error)
// StateNetworkVersion returns the network version at the given tipset
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
@@ -514,10 +487,8 @@ type FullNode interface {
// along with the address removal.
MsigRemoveSigner(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error)
// MarketReserveFunds reserves funds for a deal
MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error)
// MarketReleaseFunds releases funds reserved by MarketReserveFunds
MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error
MarketEnsureAvailable(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error)
// MarketFreeBalance
// MethodGroup: Paych
// The Paych methods are for interacting with and managing payment channels
@@ -612,8 +583,6 @@ type MsgGasCost struct {
TotalCost abi.TokenAmount
}
// BlsMessages[x].cid = Cids[x]
// SecpkMessages[y].cid = Cids[BlsMessages.length + y]
type BlockMessages struct {
BlsMessages []*types.Message
SecpkMessages []*types.SignedMessage
@@ -759,10 +728,8 @@ type RetrievalOrder struct {
}
type InvocResult struct {
MsgCid cid.Cid
Msg *types.Message
MsgRct *types.MessageReceipt
GasCost MsgGasCost
ExecutionTrace types.ExecutionTrace
Error string
Duration time.Duration
@@ -791,9 +758,8 @@ type IpldObject struct {
}
type ActiveSync struct {
WorkerID uint64
Base *types.TipSet
Target *types.TipSet
Base *types.TipSet
Target *types.TipSet
Stage SyncStateStage
Height abi.ChainEpoch
@@ -898,12 +864,6 @@ type DataSize struct {
PieceSize abi.PaddedPieceSize
}
type DataCIDSize struct {
PayloadSize int64
PieceSize abi.PaddedPieceSize
PieceCID cid.Cid
}
type CommPRet struct {
Root cid.Cid
Size abi.UnpaddedPieceSize
@@ -948,8 +908,3 @@ type MsigVesting struct {
StartEpoch abi.ChainEpoch
UnlockDuration abi.ChainEpoch
}
type MessageMatch struct {
To address.Address
From address.Address
}
+1 -21
View File
@@ -3,42 +3,22 @@ package api
import (
"context"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/dline"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
)
type GatewayAPI interface {
ChainHasObj(context.Context, cid.Cid) (bool, error)
ChainHead(ctx context.Context) (*types.TipSet, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)
ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error)
ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
ChainNotify(context.Context) (<-chan []*HeadChange, error)
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error)
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*MarketDeal, error)
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*MsgLookup, error)
}
+3 -12
View File
@@ -5,10 +5,7 @@ import (
"context"
"time"
datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/google/uuid"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-fil-markets/piecestore"
@@ -65,13 +62,11 @@ type StorageMiner interface {
// WorkerConnect tells the node to connect to workers RPC
WorkerConnect(context.Context, string) error
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error)
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error)
storiface.WorkerReturn
WorkerStats(context.Context) (map[uint64]storiface.WorkerStats, error)
WorkerJobs(context.Context) (map[uint64][]storiface.WorkerJob, error)
// SealingSchedDiag dumps internal sealing scheduler state
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error)
SealingAbort(ctx context.Context, call storiface.CallID) error
SealingSchedDiag(context.Context) (interface{}, error)
stores.SectorIndex
@@ -86,10 +81,6 @@ type StorageMiner interface {
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error)
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error)
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error)
// MinerRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
// ClientCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error
DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error
DealsList(ctx context.Context) ([]MarketDeal, error)
+1 -1
View File
@@ -35,7 +35,7 @@ type MsgMeta struct {
}
type WalletAPI interface {
WalletNew(context.Context, types.KeyType) (address.Address, error)
WalletNew(context.Context, crypto.SigType) (address.Address, error)
WalletHas(context.Context, address.Address) (bool, error)
WalletList(context.Context) ([]address.Address, error)
+12 -18
View File
@@ -2,13 +2,15 @@ package api
import (
"context"
"io"
"github.com/google/uuid"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
"github.com/filecoin-project/specs-storage/storage"
"github.com/filecoin-project/lotus/build"
)
@@ -21,26 +23,18 @@ type WorkerAPI interface {
Paths(context.Context) ([]stores.StoragePath, error)
Info(context.Context) (storiface.WorkerInfo, error)
storiface.WorkerCalls
AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error)
// Storage / Other
Remove(ctx context.Context, sector abi.SectorID) error
storage.Sealer
MoveStorage(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error
UnsealPiece(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error
ReadPiece(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (bool, error)
StorageAddLocal(ctx context.Context, path string) error
// SetEnabled marks the worker as enabled/disabled. Not that this setting
// may take a few seconds to propagate to task scheduler
SetEnabled(ctx context.Context, enabled bool) error
Fetch(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error
Enabled(ctx context.Context) (bool, error)
// WaitQuiet blocks until there are no tasks running
WaitQuiet(ctx context.Context) error
// returns a random UUID of worker session, generated randomly when worker
// process starts
ProcessSession(context.Context) (uuid.UUID, error)
// Like ProcessSession, but returns an error when worker is disabled
Session(context.Context) (uuid.UUID, error)
Closing(context.Context) (<-chan struct{}, error)
}
+94 -318
View File
@@ -5,7 +5,8 @@ import (
"io"
"time"
"github.com/google/uuid"
stnetwork "github.com/filecoin-project/go-state-types/network"
"github.com/ipfs/go-cid"
metrics "github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/network"
@@ -14,7 +15,6 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
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"
@@ -24,7 +24,6 @@ import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/dline"
stnetwork "github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
"github.com/filecoin-project/lotus/extern/sector-storage/sealtasks"
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
@@ -68,7 +67,6 @@ type CommonStruct struct {
LogSetLevel func(context.Context, string, string) error `perm:"write"`
Shutdown func(context.Context) error `perm:"admin"`
Session func(context.Context) (uuid.UUID, error) `perm:"read"`
Closing func(context.Context) (<-chan struct{}, error) `perm:"read"`
}
}
@@ -132,14 +130,10 @@ type FullNodeStruct struct {
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
MpoolSub func(context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
MpoolBatchPush func(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
MpoolBatchPushUntrusted func(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
MpoolBatchPushMessage func(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"`
MinerGetBaseInfo func(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
MinerCreateBlock func(context.Context, *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
WalletNew func(context.Context, types.KeyType) (address.Address, error) `perm:"write"`
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
@@ -161,20 +155,16 @@ type FullNodeStruct struct {
ClientMinerQueryOffer func(ctx context.Context, miner address.Address, root cid.Cid, piece *cid.Cid) (api.QueryOffer, error) `perm:"read"`
ClientStartDeal func(ctx context.Context, params *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
ClientGetDealInfo func(context.Context, cid.Cid) (*api.DealInfo, error) `perm:"read"`
ClientGetDealStatus func(context.Context, uint64) (string, error) `perm:"read"`
ClientListDeals func(ctx context.Context) ([]api.DealInfo, error) `perm:"write"`
ClientGetDealUpdates func(ctx context.Context) (<-chan api.DealInfo, error) `perm:"read"`
ClientRetrieve func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) error `perm:"admin"`
ClientRetrieveWithEvents func(ctx context.Context, order api.RetrievalOrder, ref *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
ClientQueryAsk func(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
ClientDealPieceCID func(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) `perm:"read"`
ClientCalcCommP func(ctx context.Context, inpath string) (*api.CommPRet, error) `perm:"read"`
ClientGenCar func(ctx context.Context, ref api.FileRef, outpath string) error `perm:"write"`
ClientDealSize func(ctx context.Context, root cid.Cid) (api.DataSize, error) `perm:"read"`
ClientListDataTransfers func(ctx context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
ClientDataTransferUpdates func(ctx context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
ClientRestartDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"write"`
ClientCancelDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"write"`
ClientRetrieveTryRestartInsufficientFunds func(ctx context.Context, paymentChannel address.Address) error `perm:"write"`
StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"`
@@ -191,7 +181,6 @@ type FullNodeStruct struct {
StateMinerPreCommitDepositForPower func(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) `perm:"read"`
StateMinerInitialPledgeCollateral func(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) `perm:"read"`
StateMinerAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
StateMinerSectorAllocated func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) `perm:"read"`
StateSectorPreCommitInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
StateSectorGetInfo func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
@@ -200,6 +189,7 @@ type FullNodeStruct struct {
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
StateMsgGasCost func(context.Context, cid.Cid, types.TipSetKey) (*api.MsgGasCost, error) `perm:"read"`
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
StateWaitMsgLimited func(context.Context, cid.Cid, uint64, abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
StateSearchMsg func(context.Context, cid.Cid) (*api.MsgLookup, error) `perm:"read"`
@@ -214,15 +204,13 @@ type FullNodeStruct struct {
StateChangedActors func(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) `perm:"read"`
StateGetReceipt func(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
StateListMessages func(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
StateDecodeParams func(context.Context, address.Address, abi.MethodNum, []byte, types.TipSetKey) (interface{}, error) `perm:"read"`
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
StateVerifierStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
StateVerifiedClientStatus func(context.Context, address.Address, types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
StateVerifiedRegistryRootKey func(ctx context.Context, tsk types.TipSetKey) (address.Address, error) `perm:"read"`
StateDealProviderCollateralBounds func(context.Context, abi.PaddedPieceSize, bool, types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
StateCirculatingSupply func(context.Context, types.TipSetKey) (abi.TokenAmount, error) `perm:"read"`
StateVMCirculatingSupplyInternal func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
StateCirculatingSupply func(context.Context, types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
StateNetworkVersion func(context.Context, types.TipSetKey) (stnetwork.Version, error) `perm:"read"`
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
@@ -241,8 +229,7 @@ type FullNodeStruct struct {
MsigSwapCancel func(context.Context, address.Address, address.Address, uint64, address.Address, address.Address) (cid.Cid, error) `perm:"sign"`
MsigRemoveSigner func(ctx context.Context, msig address.Address, proposer address.Address, toRemove address.Address, decrease bool) (cid.Cid, error) `perm:"sign"`
MarketReserveFunds func(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) `perm:"sign"`
MarketReleaseFunds func(ctx context.Context, addr address.Address, amt types.BigInt) error `perm:"sign"`
MarketEnsureAvailable func(context.Context, address.Address, address.Address, types.BigInt) (cid.Cid, error) `perm:"sign"`
PaychGet func(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
PaychGetWaitReady func(context.Context, cid.Cid) (address.Address, error) `perm:"sign"`
@@ -290,8 +277,6 @@ type StorageMinerStruct struct {
MarketGetRetrievalAsk func(ctx context.Context) (*retrievalmarket.Ask, error) `perm:"read"`
MarketListDataTransfers func(ctx context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
MarketDataTransferUpdates func(ctx context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
MarketRestartDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"read"`
MarketCancelDataTransfer func(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error `perm:"read"`
PledgeSector func(context.Context) error `perm:"write"`
@@ -307,37 +292,24 @@ type StorageMinerStruct struct {
SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"`
SectorMarkForUpgrade func(ctx context.Context, id abi.SectorNumber) error `perm:"admin"`
WorkerConnect func(context.Context, string) error `perm:"admin" retry:"true"` // TODO: worker perm
WorkerStats func(context.Context) (map[uuid.UUID]storiface.WorkerStats, error) `perm:"admin"`
WorkerJobs func(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"`
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"`
WorkerJobs func(context.Context) (map[uint64][]storiface.WorkerJob, error) `perm:"admin"`
ReturnAddPiece func(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err string) error `perm:"admin" retry:"true"`
ReturnSealPreCommit1 func(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err string) error `perm:"admin" retry:"true"`
ReturnSealPreCommit2 func(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err string) error `perm:"admin" retry:"true"`
ReturnSealCommit1 func(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err string) error `perm:"admin" retry:"true"`
ReturnSealCommit2 func(ctx context.Context, callID storiface.CallID, proof storage.Proof, err string) error `perm:"admin" retry:"true"`
ReturnFinalizeSector func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
ReturnReleaseUnsealed func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
ReturnMoveStorage func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
ReturnUnsealPiece func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
ReturnReadPiece func(ctx context.Context, callID storiface.CallID, ok bool, err string) error `perm:"admin" retry:"true"`
ReturnFetch func(ctx context.Context, callID storiface.CallID, err string) error `perm:"admin" retry:"true"`
SealingSchedDiag func(context.Context) (interface{}, error) `perm:"admin"`
SealingSchedDiag func(context.Context, bool) (interface{}, error) `perm:"admin"`
SealingAbort func(ctx context.Context, call storiface.CallID) error `perm:"admin"`
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
StorageStat func(context.Context, stores.ID) (fsutil.FsStat, error) `perm:"admin"`
StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin"`
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType, bool) error `perm:"admin"`
StorageDropSector func(context.Context, stores.ID, abi.SectorID, storiface.SectorFileType) error `perm:"admin"`
StorageFindSector func(context.Context, abi.SectorID, storiface.SectorFileType, abi.SectorSize, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"`
StorageBestAlloc func(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, sealing storiface.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
StorageLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error `perm:"admin"`
StorageTryLock func(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) `perm:"admin"`
StorageList func(context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
StorageLocal func(context.Context) (map[stores.ID]string, error) `perm:"admin"`
StorageStat func(context.Context, stores.ID) (fsutil.FsStat, error) `perm:"admin"`
StorageAttach func(context.Context, stores.StorageInfo, fsutil.FsStat) error `perm:"admin"`
StorageDeclareSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType, bool) error `perm:"admin"`
StorageDropSector func(context.Context, stores.ID, abi.SectorID, stores.SectorFileType) error `perm:"admin"`
StorageFindSector func(context.Context, abi.SectorID, stores.SectorFileType, abi.RegisteredSealProof, bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
StorageInfo func(context.Context, stores.ID) (stores.StorageInfo, error) `perm:"admin"`
StorageBestAlloc func(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, sealing stores.PathType) ([]stores.StorageInfo, error) `perm:"admin"`
StorageReportHealth func(ctx context.Context, id stores.ID, report stores.HealthReport) error `perm:"admin"`
StorageLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error `perm:"admin"`
StorageTryLock func(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) `perm:"admin"`
DealsImportData func(ctx context.Context, dealPropCid cid.Cid, file string) error `perm:"write"`
DealsList func(ctx context.Context) ([]api.MarketDeal, error) `perm:"read"`
@@ -373,65 +345,46 @@ type WorkerStruct struct {
Paths func(context.Context) ([]stores.StoragePath, error) `perm:"admin"`
Info func(context.Context) (storiface.WorkerInfo, error) `perm:"admin"`
AddPiece func(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) `perm:"admin"`
SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) `perm:"admin"`
SealPreCommit2 func(ctx context.Context, sector abi.SectorID, pc1o storage.PreCommit1Out) (storiface.CallID, error) `perm:"admin"`
SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) `perm:"admin"`
SealCommit2 func(ctx context.Context, sector abi.SectorID, c1o storage.Commit1Out) (storiface.CallID, error) `perm:"admin"`
FinalizeSector func(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) (storiface.CallID, error) `perm:"admin"`
ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) (storiface.CallID, error) `perm:"admin"`
MoveStorage func(ctx context.Context, sector abi.SectorID, types storiface.SectorFileType) (storiface.CallID, error) `perm:"admin"`
UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) (storiface.CallID, error) `perm:"admin"`
ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (storiface.CallID, error) `perm:"admin"`
Fetch func(context.Context, abi.SectorID, storiface.SectorFileType, storiface.PathType, storiface.AcquireMode) (storiface.CallID, error) `perm:"admin"`
AddPiece func(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error) `perm:"admin"`
SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"`
SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"`
SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"`
SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"`
FinalizeSector func(context.Context, abi.SectorID, []storage.Range) error `perm:"admin"`
ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error `perm:"admin"`
Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
MoveStorage func(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error `perm:"admin"`
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"`
StorageAddLocal func(ctx context.Context, path string) error `perm:"admin"`
UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"`
ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) (bool, error) `perm:"admin"`
SetEnabled func(ctx context.Context, enabled bool) error `perm:"admin"`
Enabled func(ctx context.Context) (bool, error) `perm:"admin"`
Fetch func(context.Context, abi.SectorID, stores.SectorFileType, stores.PathType, stores.AcquireMode) error `perm:"admin"`
WaitQuiet func(ctx context.Context) error `perm:"admin"`
ProcessSession func(context.Context) (uuid.UUID, error) `perm:"admin"`
Session func(context.Context) (uuid.UUID, error) `perm:"admin"`
Closing func(context.Context) (<-chan struct{}, error) `perm:"admin"`
}
}
type GatewayStruct struct {
Internal struct {
ChainGetBlockMessages func(ctx context.Context, c cid.Cid) (*api.BlockMessages, error)
ChainGetMessage func(ctx context.Context, mc cid.Cid) (*types.Message, error)
ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
ChainHasObj func(context.Context, cid.Cid) (bool, error)
ChainHead func(ctx context.Context) (*types.TipSet, error)
ChainNotify func(ctx context.Context) (<-chan []*api.HeadChange, error)
ChainReadObj func(context.Context, cid.Cid) ([]byte, error)
GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateDealProviderCollateralBounds func(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
StateGetReceipt func(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error)
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateListMiners func(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
StateMinerInfo func(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error)
StateMinerProvingDeadline func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
StateMarketBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
StateMarketStorageDeal func(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
StateNetworkVersion func(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error)
StateVerifiedClientStatus func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
StateWaitMsg func(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
// TODO: does the gateway need perms?
ChainGetTipSet func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
ChainGetTipSetByHeight func(ctx context.Context, h abi.ChainEpoch, tsk types.TipSetKey) (*types.TipSet, error)
ChainHead func(ctx context.Context) (*types.TipSet, error)
GasEstimateMessageGas func(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
MpoolPush func(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
MsigGetAvailableBalance func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
MsigGetVested func(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
StateAccountKey func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateGetActor func(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
StateLookupID func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
StateWaitMsg func(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error)
}
}
type WalletStruct struct {
Internal struct {
WalletNew func(context.Context, types.KeyType) (address.Address, error) `perm:"write"`
WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"`
WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"`
WalletList func(context.Context) ([]address.Address, error) `perm:"write"`
WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"`
@@ -521,10 +474,6 @@ func (c *CommonStruct) Shutdown(ctx context.Context) error {
return c.Internal.Shutdown(ctx)
}
func (c *CommonStruct) Session(ctx context.Context) (uuid.UUID, error) {
return c.Internal.Session(ctx)
}
func (c *CommonStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
return c.Internal.Closing(ctx)
}
@@ -563,10 +512,6 @@ func (c *FullNodeStruct) ClientGetDealInfo(ctx context.Context, deal cid.Cid) (*
return c.Internal.ClientGetDealInfo(ctx, deal)
}
func (c *FullNodeStruct) ClientGetDealStatus(ctx context.Context, statusCode uint64) (string, error) {
return c.Internal.ClientGetDealStatus(ctx, statusCode)
}
func (c *FullNodeStruct) ClientListDeals(ctx context.Context) ([]api.DealInfo, error) {
return c.Internal.ClientListDeals(ctx)
}
@@ -586,11 +531,6 @@ func (c *FullNodeStruct) ClientRetrieveWithEvents(ctx context.Context, order api
func (c *FullNodeStruct) ClientQueryAsk(ctx context.Context, p peer.ID, miner address.Address) (*storagemarket.StorageAsk, error) {
return c.Internal.ClientQueryAsk(ctx, p, miner)
}
func (c *FullNodeStruct) ClientDealPieceCID(ctx context.Context, root cid.Cid) (api.DataCIDSize, error) {
return c.Internal.ClientDealPieceCID(ctx, root)
}
func (c *FullNodeStruct) ClientCalcCommP(ctx context.Context, inpath string) (*api.CommPRet, error) {
return c.Internal.ClientCalcCommP(ctx, inpath)
}
@@ -611,14 +551,6 @@ func (c *FullNodeStruct) ClientDataTransferUpdates(ctx context.Context) (<-chan
return c.Internal.ClientDataTransferUpdates(ctx)
}
func (c *FullNodeStruct) ClientRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
return c.Internal.ClientRestartDataTransfer(ctx, transferID, otherPeer, isInitiator)
}
func (c *FullNodeStruct) ClientCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
return c.Internal.ClientCancelDataTransfer(ctx, transferID, otherPeer, isInitiator)
}
func (c *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(ctx context.Context, paymentChannel address.Address) error {
return c.Internal.ClientRetrieveTryRestartInsufficientFunds(ctx, paymentChannel)
}
@@ -671,18 +603,6 @@ func (c *FullNodeStruct) MpoolPushMessage(ctx context.Context, msg *types.Messag
return c.Internal.MpoolPushMessage(ctx, msg, spec)
}
func (c *FullNodeStruct) MpoolBatchPush(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) {
return c.Internal.MpoolBatchPush(ctx, smsgs)
}
func (c *FullNodeStruct) MpoolBatchPushUntrusted(ctx context.Context, smsgs []*types.SignedMessage) ([]cid.Cid, error) {
return c.Internal.MpoolBatchPushUntrusted(ctx, smsgs)
}
func (c *FullNodeStruct) MpoolBatchPushMessage(ctx context.Context, msgs []*types.Message, spec *api.MessageSendSpec) ([]*types.SignedMessage, error) {
return c.Internal.MpoolBatchPushMessage(ctx, msgs, spec)
}
func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate, error) {
return c.Internal.MpoolSub(ctx)
}
@@ -711,7 +631,7 @@ func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.Chain
return c.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
}
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
func (c *FullNodeStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
return c.Internal.WalletNew(ctx, typ)
}
@@ -931,10 +851,6 @@ func (c *FullNodeStruct) StateMinerAvailableBalance(ctx context.Context, maddr a
return c.Internal.StateMinerAvailableBalance(ctx, maddr, tsk)
}
func (c *FullNodeStruct) StateMinerSectorAllocated(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (bool, error) {
return c.Internal.StateMinerSectorAllocated(ctx, maddr, s, tsk)
}
func (c *FullNodeStruct) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) {
return c.Internal.StateSectorPreCommitInfo(ctx, maddr, n, tsk)
}
@@ -967,6 +883,10 @@ func (c *FullNodeStruct) StateReadState(ctx context.Context, addr address.Addres
return c.Internal.StateReadState(ctx, addr, tsk)
}
func (c *FullNodeStruct) StateMsgGasCost(ctx context.Context, msgc cid.Cid, tsk types.TipSetKey) (*api.MsgGasCost, error) {
return c.Internal.StateMsgGasCost(ctx, msgc, tsk)
}
func (c *FullNodeStruct) StateWaitMsg(ctx context.Context, msgc cid.Cid, confidence uint64) (*api.MsgLookup, error) {
return c.Internal.StateWaitMsg(ctx, msgc, confidence)
}
@@ -1019,14 +939,10 @@ func (c *FullNodeStruct) StateGetReceipt(ctx context.Context, msg cid.Cid, tsk t
return c.Internal.StateGetReceipt(ctx, msg, tsk)
}
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *api.MessageMatch, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) {
return c.Internal.StateListMessages(ctx, match, tsk, toht)
}
func (c *FullNodeStruct) StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) {
return c.Internal.StateDecodeParams(ctx, toAddr, method, params, tsk)
}
func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (*api.ComputeStateOutput, error) {
return c.Internal.StateCompute(ctx, height, msgs, tsk)
}
@@ -1047,14 +963,10 @@ func (c *FullNodeStruct) StateDealProviderCollateralBounds(ctx context.Context,
return c.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
}
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (abi.TokenAmount, error) {
func (c *FullNodeStruct) StateCirculatingSupply(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
return c.Internal.StateCirculatingSupply(ctx, tsk)
}
func (c *FullNodeStruct) StateVMCirculatingSupplyInternal(ctx context.Context, tsk types.TipSetKey) (api.CirculatingSupply, error) {
return c.Internal.StateVMCirculatingSupplyInternal(ctx, tsk)
}
func (c *FullNodeStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
return c.Internal.StateNetworkVersion(ctx, tsk)
}
@@ -1119,12 +1031,8 @@ func (c *FullNodeStruct) MsigRemoveSigner(ctx context.Context, msig address.Addr
return c.Internal.MsigRemoveSigner(ctx, msig, proposer, toRemove, decrease)
}
func (c *FullNodeStruct) MarketReserveFunds(ctx context.Context, wallet address.Address, addr address.Address, amt types.BigInt) (cid.Cid, error) {
return c.Internal.MarketReserveFunds(ctx, wallet, addr, amt)
}
func (c *FullNodeStruct) MarketReleaseFunds(ctx context.Context, addr address.Address, amt types.BigInt) error {
return c.Internal.MarketReleaseFunds(ctx, addr, amt)
func (c *FullNodeStruct) MarketEnsureAvailable(ctx context.Context, addr, wallet address.Address, amt types.BigInt) (cid.Cid, error) {
return c.Internal.MarketEnsureAvailable(ctx, addr, wallet, amt)
}
func (c *FullNodeStruct) PaychGet(ctx context.Context, from, to address.Address, amt types.BigInt) (*api.ChannelInfo, error) {
@@ -1263,80 +1171,32 @@ func (c *StorageMinerStruct) WorkerConnect(ctx context.Context, url string) erro
return c.Internal.WorkerConnect(ctx, url)
}
func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (map[uuid.UUID]storiface.WorkerStats, error) {
func (c *StorageMinerStruct) WorkerStats(ctx context.Context) (map[uint64]storiface.WorkerStats, error) {
return c.Internal.WorkerStats(ctx)
}
func (c *StorageMinerStruct) WorkerJobs(ctx context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) {
func (c *StorageMinerStruct) WorkerJobs(ctx context.Context) (map[uint64][]storiface.WorkerJob, error) {
return c.Internal.WorkerJobs(ctx)
}
func (c *StorageMinerStruct) ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err string) error {
return c.Internal.ReturnAddPiece(ctx, callID, pi, err)
}
func (c *StorageMinerStruct) ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storage.PreCommit1Out, err string) error {
return c.Internal.ReturnSealPreCommit1(ctx, callID, p1o, err)
}
func (c *StorageMinerStruct) ReturnSealPreCommit2(ctx context.Context, callID storiface.CallID, sealed storage.SectorCids, err string) error {
return c.Internal.ReturnSealPreCommit2(ctx, callID, sealed, err)
}
func (c *StorageMinerStruct) ReturnSealCommit1(ctx context.Context, callID storiface.CallID, out storage.Commit1Out, err string) error {
return c.Internal.ReturnSealCommit1(ctx, callID, out, err)
}
func (c *StorageMinerStruct) ReturnSealCommit2(ctx context.Context, callID storiface.CallID, proof storage.Proof, err string) error {
return c.Internal.ReturnSealCommit2(ctx, callID, proof, err)
}
func (c *StorageMinerStruct) ReturnFinalizeSector(ctx context.Context, callID storiface.CallID, err string) error {
return c.Internal.ReturnFinalizeSector(ctx, callID, err)
}
func (c *StorageMinerStruct) ReturnReleaseUnsealed(ctx context.Context, callID storiface.CallID, err string) error {
return c.Internal.ReturnReleaseUnsealed(ctx, callID, err)
}
func (c *StorageMinerStruct) ReturnMoveStorage(ctx context.Context, callID storiface.CallID, err string) error {
return c.Internal.ReturnMoveStorage(ctx, callID, err)
}
func (c *StorageMinerStruct) ReturnUnsealPiece(ctx context.Context, callID storiface.CallID, err string) error {
return c.Internal.ReturnUnsealPiece(ctx, callID, err)
}
func (c *StorageMinerStruct) ReturnReadPiece(ctx context.Context, callID storiface.CallID, ok bool, err string) error {
return c.Internal.ReturnReadPiece(ctx, callID, ok, err)
}
func (c *StorageMinerStruct) ReturnFetch(ctx context.Context, callID storiface.CallID, err string) error {
return c.Internal.ReturnFetch(ctx, callID, err)
}
func (c *StorageMinerStruct) SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) {
return c.Internal.SealingSchedDiag(ctx, doSched)
}
func (c *StorageMinerStruct) SealingAbort(ctx context.Context, call storiface.CallID) error {
return c.Internal.SealingAbort(ctx, call)
func (c *StorageMinerStruct) SealingSchedDiag(ctx context.Context) (interface{}, error) {
return c.Internal.SealingSchedDiag(ctx)
}
func (c *StorageMinerStruct) StorageAttach(ctx context.Context, si stores.StorageInfo, st fsutil.FsStat) error {
return c.Internal.StorageAttach(ctx, si, st)
}
func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft storiface.SectorFileType, primary bool) error {
func (c *StorageMinerStruct) StorageDeclareSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType, primary bool) error {
return c.Internal.StorageDeclareSector(ctx, storageId, s, ft, primary)
}
func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft storiface.SectorFileType) error {
func (c *StorageMinerStruct) StorageDropSector(ctx context.Context, storageId stores.ID, s abi.SectorID, ft stores.SectorFileType) error {
return c.Internal.StorageDropSector(ctx, storageId, s, ft)
}
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types storiface.SectorFileType, ssize abi.SectorSize, allowFetch bool) ([]stores.SectorStorageInfo, error) {
return c.Internal.StorageFindSector(ctx, si, types, ssize, allowFetch)
func (c *StorageMinerStruct) StorageFindSector(ctx context.Context, si abi.SectorID, types stores.SectorFileType, spt abi.RegisteredSealProof, allowFetch bool) ([]stores.SectorStorageInfo, error) {
return c.Internal.StorageFindSector(ctx, si, types, spt, allowFetch)
}
func (c *StorageMinerStruct) StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) {
@@ -1355,19 +1215,19 @@ func (c *StorageMinerStruct) StorageInfo(ctx context.Context, id stores.ID) (sto
return c.Internal.StorageInfo(ctx, id)
}
func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate storiface.SectorFileType, ssize abi.SectorSize, pt storiface.PathType) ([]stores.StorageInfo, error) {
return c.Internal.StorageBestAlloc(ctx, allocate, ssize, pt)
func (c *StorageMinerStruct) StorageBestAlloc(ctx context.Context, allocate stores.SectorFileType, spt abi.RegisteredSealProof, pt stores.PathType) ([]stores.StorageInfo, error) {
return c.Internal.StorageBestAlloc(ctx, allocate, spt, pt)
}
func (c *StorageMinerStruct) StorageReportHealth(ctx context.Context, id stores.ID, report stores.HealthReport) error {
return c.Internal.StorageReportHealth(ctx, id, report)
}
func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error {
func (c *StorageMinerStruct) StorageLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) error {
return c.Internal.StorageLock(ctx, sector, read, write)
}
func (c *StorageMinerStruct) StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) {
func (c *StorageMinerStruct) StorageTryLock(ctx context.Context, sector abi.SectorID, read stores.SectorFileType, write stores.SectorFileType) (bool, error) {
return c.Internal.StorageTryLock(ctx, sector, read, write)
}
@@ -1415,14 +1275,6 @@ func (c *StorageMinerStruct) MarketDataTransferUpdates(ctx context.Context) (<-c
return c.Internal.MarketDataTransferUpdates(ctx)
}
func (c *StorageMinerStruct) MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
return c.Internal.MarketRestartDataTransfer(ctx, transferID, otherPeer, isInitiator)
}
func (c *StorageMinerStruct) MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
return c.Internal.MarketCancelDataTransfer(ctx, transferID, otherPeer, isInitiator)
}
func (c *StorageMinerStruct) DealsImportData(ctx context.Context, dealPropCid cid.Cid, file string) error {
return c.Internal.DealsImportData(ctx, dealPropCid, file)
}
@@ -1513,84 +1365,64 @@ func (w *WorkerStruct) Info(ctx context.Context) (storiface.WorkerInfo, error) {
return w.Internal.Info(ctx)
}
func (w *WorkerStruct) AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (storiface.CallID, error) {
func (w *WorkerStruct) AddPiece(ctx context.Context, sector abi.SectorID, pieceSizes []abi.UnpaddedPieceSize, newPieceSize abi.UnpaddedPieceSize, pieceData storage.Data) (abi.PieceInfo, error) {
return w.Internal.AddPiece(ctx, sector, pieceSizes, newPieceSize, pieceData)
}
func (w *WorkerStruct) SealPreCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storiface.CallID, error) {
func (w *WorkerStruct) SealPreCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) {
return w.Internal.SealPreCommit1(ctx, sector, ticket, pieces)
}
func (w *WorkerStruct) SealPreCommit2(ctx context.Context, sector abi.SectorID, pc1o storage.PreCommit1Out) (storiface.CallID, error) {
return w.Internal.SealPreCommit2(ctx, sector, pc1o)
func (w *WorkerStruct) SealPreCommit2(ctx context.Context, sector abi.SectorID, p1o storage.PreCommit1Out) (storage.SectorCids, error) {
return w.Internal.SealPreCommit2(ctx, sector, p1o)
}
func (w *WorkerStruct) SealCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storiface.CallID, error) {
func (w *WorkerStruct) SealCommit1(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) {
return w.Internal.SealCommit1(ctx, sector, ticket, seed, pieces, cids)
}
func (w *WorkerStruct) SealCommit2(ctx context.Context, sector abi.SectorID, c1o storage.Commit1Out) (storiface.CallID, error) {
func (w *WorkerStruct) SealCommit2(ctx context.Context, sector abi.SectorID, c1o storage.Commit1Out) (storage.Proof, error) {
return w.Internal.SealCommit2(ctx, sector, c1o)
}
func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) (storiface.CallID, error) {
func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) error {
return w.Internal.FinalizeSector(ctx, sector, keepUnsealed)
}
func (w *WorkerStruct) ReleaseUnsealed(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) (storiface.CallID, error) {
func (w *WorkerStruct) ReleaseUnsealed(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error {
return w.Internal.ReleaseUnsealed(ctx, sector, safeToFree)
}
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID, types storiface.SectorFileType) (storiface.CallID, error) {
return w.Internal.MoveStorage(ctx, sector, types)
}
func (w *WorkerStruct) UnsealPiece(ctx context.Context, sector abi.SectorID, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, ticket abi.SealRandomness, c cid.Cid) (storiface.CallID, error) {
return w.Internal.UnsealPiece(ctx, sector, offset, size, ticket, c)
}
func (w *WorkerStruct) ReadPiece(ctx context.Context, sink io.Writer, sector abi.SectorID, offset storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (storiface.CallID, error) {
return w.Internal.ReadPiece(ctx, sink, sector, offset, size)
}
func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType storiface.SectorFileType, ptype storiface.PathType, am storiface.AcquireMode) (storiface.CallID, error) {
return w.Internal.Fetch(ctx, id, fileType, ptype, am)
}
func (w *WorkerStruct) Remove(ctx context.Context, sector abi.SectorID) error {
return w.Internal.Remove(ctx, sector)
}
func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID, types stores.SectorFileType) error {
return w.Internal.MoveStorage(ctx, sector, types)
}
func (w *WorkerStruct) StorageAddLocal(ctx context.Context, path string) error {
return w.Internal.StorageAddLocal(ctx, path)
}
func (w *WorkerStruct) SetEnabled(ctx context.Context, enabled bool) error {
return w.Internal.SetEnabled(ctx, enabled)
func (w *WorkerStruct) UnsealPiece(ctx context.Context, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize, randomness abi.SealRandomness, c cid.Cid) error {
return w.Internal.UnsealPiece(ctx, id, index, size, randomness, c)
}
func (w *WorkerStruct) Enabled(ctx context.Context) (bool, error) {
return w.Internal.Enabled(ctx)
func (w *WorkerStruct) ReadPiece(ctx context.Context, writer io.Writer, id abi.SectorID, index storiface.UnpaddedByteIndex, size abi.UnpaddedPieceSize) (bool, error) {
return w.Internal.ReadPiece(ctx, writer, id, index, size)
}
func (w *WorkerStruct) WaitQuiet(ctx context.Context) error {
return w.Internal.WaitQuiet(ctx)
func (w *WorkerStruct) Fetch(ctx context.Context, id abi.SectorID, fileType stores.SectorFileType, ptype stores.PathType, am stores.AcquireMode) error {
return w.Internal.Fetch(ctx, id, fileType, ptype, am)
}
func (w *WorkerStruct) ProcessSession(ctx context.Context) (uuid.UUID, error) {
return w.Internal.ProcessSession(ctx)
func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) {
return w.Internal.Closing(ctx)
}
func (w *WorkerStruct) Session(ctx context.Context) (uuid.UUID, error) {
return w.Internal.Session(ctx)
}
func (g GatewayStruct) ChainGetBlockMessages(ctx context.Context, c cid.Cid) (*api.BlockMessages, error) {
return g.Internal.ChainGetBlockMessages(ctx, c)
}
func (g GatewayStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*types.Message, error) {
return g.Internal.ChainGetMessage(ctx, mc)
func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
return g.Internal.ChainHead(ctx)
}
func (g GatewayStruct) ChainGetTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
@@ -1601,22 +1433,6 @@ func (g GatewayStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEp
return g.Internal.ChainGetTipSetByHeight(ctx, h, tsk)
}
func (g GatewayStruct) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
return g.Internal.ChainHasObj(ctx, c)
}
func (g GatewayStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
return g.Internal.ChainHead(ctx)
}
func (g GatewayStruct) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) {
return g.Internal.ChainNotify(ctx)
}
func (g GatewayStruct) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
return g.Internal.ChainReadObj(ctx, c)
}
func (g GatewayStruct) GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error) {
return g.Internal.GasEstimateMessageGas(ctx, msg, spec, tsk)
}
@@ -1637,59 +1453,19 @@ func (g GatewayStruct) StateAccountKey(ctx context.Context, addr address.Address
return g.Internal.StateAccountKey(ctx, addr, tsk)
}
func (g GatewayStruct) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) {
return g.Internal.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
}
func (g GatewayStruct) StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error) {
return g.Internal.StateGetActor(ctx, actor, ts)
}
func (g GatewayStruct) StateGetReceipt(ctx context.Context, c cid.Cid, tsk types.TipSetKey) (*types.MessageReceipt, error) {
return g.Internal.StateGetReceipt(ctx, c, tsk)
}
func (g GatewayStruct) StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error) {
return g.Internal.StateLookupID(ctx, addr, tsk)
}
func (g GatewayStruct) StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error) {
return g.Internal.StateListMiners(ctx, tsk)
}
func (g GatewayStruct) StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error) {
return g.Internal.StateMarketBalance(ctx, addr, tsk)
}
func (g GatewayStruct) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error) {
return g.Internal.StateMarketStorageDeal(ctx, dealId, tsk)
}
func (g GatewayStruct) StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (miner.MinerInfo, error) {
return g.Internal.StateMinerInfo(ctx, actor, tsk)
}
func (g GatewayStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) {
return g.Internal.StateMinerProvingDeadline(ctx, addr, tsk)
}
func (g GatewayStruct) StateMinerPower(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*api.MinerPower, error) {
return g.Internal.StateMinerPower(ctx, addr, tsk)
}
func (g GatewayStruct) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (stnetwork.Version, error) {
return g.Internal.StateNetworkVersion(ctx, tsk)
}
func (g GatewayStruct) StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error) {
return g.Internal.StateVerifiedClientStatus(ctx, addr, tsk)
}
func (g GatewayStruct) StateWaitMsg(ctx context.Context, msg cid.Cid, confidence uint64) (*api.MsgLookup, error) {
return g.Internal.StateWaitMsg(ctx, msg, confidence)
}
func (c *WalletStruct) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
func (c *WalletStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) {
return c.Internal.WalletNew(ctx, typ)
}
-1
View File
@@ -87,7 +87,6 @@ func init() {
addExample(abi.RegisteredPoStProof_StackedDrgWindow32GiBV1)
addExample(abi.ChainEpoch(10101))
addExample(crypto.SigTypeBLS)
addExample(types.KTBLS)
addExample(int64(9))
addExample(12.3)
addExample(123)
+4 -1
View File
@@ -3,6 +3,7 @@ package test
import (
"context"
"fmt"
"os"
"sync/atomic"
"testing"
"time"
@@ -16,6 +17,8 @@ import (
)
func TestCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
for _, height := range []abi.ChainEpoch{
1, // before
162, // while sealing
@@ -89,7 +92,7 @@ func testCCUpgrade(t *testing.T, b APIBuilder, blocktime time.Duration, upgradeH
t.Fatal(err)
}
MakeDeal(t, ctx, 6, client, miner, false, false)
makeDeal(t, ctx, 6, client, miner, false, false)
// Validate upgrade
+29 -31
View File
@@ -16,12 +16,15 @@ import (
"github.com/ipfs/go-cid"
files "github.com/ipfs/go-ipfs-files"
logging "github.com/ipfs/go-log/v2"
"github.com/ipld/go-car"
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/lotus/miner"
dag "github.com/ipfs/go-merkledag"
dstest "github.com/ipfs/go-merkledag/test"
unixfile "github.com/ipfs/go-unixfs/file"
@@ -31,7 +34,18 @@ import (
ipld "github.com/ipfs/go-ipld-format"
)
var MineNext = miner.MineReq{
InjectNulls: 0,
Done: func(bool, abi.ChainEpoch, error) {},
}
func init() {
logging.SetAllLoggers(logging.LevelInfo)
build.InsecurePoStValidation = true
}
func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport, fastRet bool) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, OneFull, OneMiner)
@@ -60,7 +74,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
}
}()
MakeDeal(t, ctx, 6, client, miner, carExport, fastRet)
makeDeal(t, ctx, 6, client, miner, carExport, fastRet)
atomic.AddInt64(&mine, -1)
fmt.Println("shutting down mining")
@@ -68,6 +82,7 @@ func TestDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration, carExport
}
func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, OneFull, OneMiner)
@@ -97,21 +112,24 @@ func TestDoubleDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
}
}()
MakeDeal(t, ctx, 6, client, miner, false, false)
MakeDeal(t, ctx, 7, client, miner, false, false)
makeDeal(t, ctx, 6, client, miner, false, false)
makeDeal(t, ctx, 7, client, miner, false, false)
atomic.AddInt64(&mine, -1)
fmt.Println("shutting down mining")
<-done
}
func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode, miner TestStorageNode, carExport, fastRet bool) {
res, data, err := CreateClientFile(ctx, client, rseed)
func makeDeal(t *testing.T, ctx context.Context, rseed int, client *impl.FullNodeAPI, miner TestStorageNode, carExport, fastRet bool) {
data := make([]byte, 1600)
rand.New(rand.NewSource(int64(rseed))).Read(data)
r := bytes.NewReader(data)
fcid, err := client.ClientImportLocal(ctx, r)
if err != nil {
t.Fatal(err)
}
fcid := res.Root
fmt.Println("FILE CID: ", fcid)
deal := startDeal(t, ctx, miner, client, fcid, fastRet)
@@ -127,29 +145,8 @@ func MakeDeal(t *testing.T, ctx context.Context, rseed int, client api.FullNode,
testRetrieval(t, ctx, client, fcid, &info.PieceCID, carExport, data)
}
func CreateClientFile(ctx context.Context, client api.FullNode, rseed int) (*api.ImportRes, []byte, error) {
data := make([]byte, 1600)
rand.New(rand.NewSource(int64(rseed))).Read(data)
dir, err := ioutil.TempDir(os.TempDir(), "test-make-deal-")
if err != nil {
return nil, nil, err
}
path := filepath.Join(dir, "sourcefile.dat")
err = ioutil.WriteFile(path, data, 0644)
if err != nil {
return nil, nil, err
}
res, err := client.ClientImport(ctx, api.FileRef{Path: path})
if err != nil {
return nil, nil, err
}
return res, data, nil
}
func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, OneFull, OneMiner)
@@ -204,6 +201,7 @@ func TestFastRetrievalDealFlow(t *testing.T, b APIBuilder, blocktime time.Durati
}
func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, OneFull, OneMiner)
@@ -278,7 +276,7 @@ func TestSenondDealRetrieval(t *testing.T, b APIBuilder, blocktime time.Duration
<-done
}
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, fcid cid.Cid, fastRet bool) *cid.Cid {
func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client *impl.FullNodeAPI, fcid cid.Cid, fastRet bool) *cid.Cid {
maddr, err := miner.ActorAddress(ctx)
if err != nil {
t.Fatal(err)
@@ -305,7 +303,7 @@ func startDeal(t *testing.T, ctx context.Context, miner TestStorageNode, client
return deal
}
func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client api.FullNode, deal *cid.Cid, noseal bool) {
func waitDealSealed(t *testing.T, ctx context.Context, miner TestStorageNode, client *impl.FullNodeAPI, deal *cid.Cid, noseal bool) {
loop:
for {
di, err := client.ClientGetDealInfo(ctx, *deal)
@@ -378,7 +376,7 @@ func startSealingWaiting(t *testing.T, ctx context.Context, miner TestStorageNod
}
}
func testRetrieval(t *testing.T, ctx context.Context, client api.FullNode, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) {
func testRetrieval(t *testing.T, ctx context.Context, client *impl.FullNodeAPI, fcid cid.Cid, piece *cid.Cid, carExport bool, data []byte) {
offers, err := client.ClientFindData(ctx, fcid, piece)
if err != nil {
t.Fatal(err)
+11 -5
View File
@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"math/rand"
"os"
"sync/atomic"
"testing"
"time"
@@ -58,11 +59,14 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
newHeads, err := api.ChainNotify(ctx)
require.NoError(t, err)
at := (<-newHeads)[0].Val.Height()
initHead := (<-newHeads)[0]
if initHead.Val.Height() != 2 {
<-newHeads
}
h1, err := api.ChainHead(ctx)
require.NoError(t, err)
require.Equal(t, int64(at), int64(h1.Height()))
require.Equal(t, abi.ChainEpoch(2), h1.Height())
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
require.NoError(t, err)
@@ -71,19 +75,21 @@ func (ts *testSuite) testMiningReal(t *testing.T) {
h2, err := api.ChainHead(ctx)
require.NoError(t, err)
require.Greater(t, int64(h2.Height()), int64(h1.Height()))
require.Equal(t, abi.ChainEpoch(3), h2.Height())
MineUntilBlock(ctx, t, apis[0], sn[0], nil)
require.NoError(t, err)
<-newHeads
h3, err := api.ChainHead(ctx)
h2, err = api.ChainHead(ctx)
require.NoError(t, err)
require.Greater(t, int64(h3.Height()), int64(h2.Height()))
require.Equal(t, abi.ChainEpoch(4), h2.Height())
}
func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExport bool) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
// test making a deal with a fresh miner, and see if it starts to mine
ctx := context.Background()
+10 -5
View File
@@ -3,10 +3,14 @@ package test
import (
"context"
"fmt"
"os"
"sync/atomic"
"testing"
"time"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid"
@@ -18,15 +22,16 @@ import (
"github.com/filecoin-project/lotus/api/apibstore"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
)
func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
_ = os.Setenv("BELLMAN_NO_GPU", "1")
ctx := context.Background()
n, sn := b(t, TwoFull, OneMiner)
@@ -53,7 +58,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
bm.MineBlocks()
// send some funds to register the receiver
receiverAddr, err := paymentReceiver.WalletNew(ctx, types.KTSecp256k1)
receiverAddr, err := paymentReceiver.WalletNew(ctx, wallet.ActSigType("secp256k1"))
if err != nil {
t.Fatal(err)
}
@@ -223,7 +228,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
}
// wait for the settlement period to pass before collecting
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, policy.PaychSettleDelay)
waitForBlocks(ctx, t, bm, paymentReceiver, receiverAddr, paych0.SettleDelay)
creatorPreCollectBalance, err := paymentCreator.WalletBalance(ctx, createrAddr)
if err != nil {
@@ -279,7 +284,7 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *BlockMiner, paymentRec
// Add a real block
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
To: builtin.BurntFundsActorAddr,
To: builtin0.BurntFundsActorAddr,
From: receiverAddr,
Value: types.NewInt(0),
}, nil)
-114
View File
@@ -1,114 +0,0 @@
package test
import (
"context"
"fmt"
"testing"
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/stmgr"
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
"github.com/filecoin-project/lotus/node"
"github.com/filecoin-project/lotus/node/impl"
"github.com/stretchr/testify/require"
)
func TestTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration) {
t.Run("before", func(t *testing.T) { testTapeFix(t, b, blocktime, false) })
t.Run("after", func(t *testing.T) { testTapeFix(t, b, blocktime, true) })
}
func testTapeFix(t *testing.T, b APIBuilder, blocktime time.Duration, after bool) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
upgradeSchedule := stmgr.UpgradeSchedule{{
Network: build.ActorUpgradeNetworkVersion,
Height: 1,
Migration: stmgr.UpgradeActorsV2,
}}
if after {
upgradeSchedule = append(upgradeSchedule, stmgr.Upgrade{
Network: network.Version5,
Height: 2,
})
}
n, sn := b(t, []FullNodeOpts{{Opts: func(_ []TestNode) node.Option {
return node.Override(new(stmgr.UpgradeSchedule), upgradeSchedule)
}}}, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
addrinfo, err := client.NetAddrsListen(ctx)
if err != nil {
t.Fatal(err)
}
if err := miner.NetConnect(ctx, addrinfo); err != nil {
t.Fatal(err)
}
build.Clock.Sleep(time.Second)
done := make(chan struct{})
go func() {
defer close(done)
for ctx.Err() == nil {
build.Clock.Sleep(blocktime)
if err := sn[0].MineOne(ctx, MineNext); err != nil {
if ctx.Err() != nil {
// context was canceled, ignore the error.
return
}
t.Error(err)
}
}
}()
defer func() {
cancel()
<-done
}()
err = miner.PledgeSector(ctx)
require.NoError(t, err)
// Wait till done.
var sectorNo abi.SectorNumber
for {
s, err := miner.SectorsList(ctx) // Note - the test builder doesn't import genesis sectors into FSM
require.NoError(t, err)
fmt.Printf("Sectors: %d\n", len(s))
if len(s) == 1 {
sectorNo = s[0]
break
}
build.Clock.Sleep(100 * time.Millisecond)
}
fmt.Printf("All sectors is fsm\n")
// If before, we expect the precommit to fail
successState := api.SectorState(sealing.CommitFailed)
failureState := api.SectorState(sealing.Proving)
if after {
// otherwise, it should succeed.
successState, failureState = failureState, successState
}
for {
st, err := miner.SectorsStatus(ctx, sectorNo, false)
require.NoError(t, err)
if st.State == successState {
break
}
require.NotEqual(t, failureState, st.State)
build.Clock.Sleep(100 * time.Millisecond)
fmt.Println("WaitSeal")
}
}
+1 -67
View File
@@ -2,38 +2,22 @@ package test
import (
"context"
"fmt"
"os"
"testing"
"time"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
logging "github.com/ipfs/go-log/v2"
"github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/miner"
"github.com/filecoin-project/lotus/node"
)
func init() {
logging.SetAllLoggers(logging.LevelInfo)
err := os.Setenv("BELLMAN_NO_GPU", "1")
if err != nil {
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
}
build.InsecurePoStValidation = true
}
type TestNode struct {
api.FullNode
// ListenAddr is the address on which an API server is listening, if an
@@ -90,7 +74,6 @@ func TestApis(t *testing.T, b APIBuilder) {
t.Run("testConnectTwo", ts.testConnectTwo)
t.Run("testMining", ts.testMining)
t.Run("testMiningReal", ts.testMiningReal)
t.Run("testSearchMsg", ts.testSearchMsg)
}
func DefaultFullOpts(nFull int) []FullNodeOpts {
@@ -113,8 +96,7 @@ var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
return FullNodeOpts{
Opts: func(nodes []TestNode) node.Option {
return node.Override(new(stmgr.UpgradeSchedule), stmgr.UpgradeSchedule{{
// Skip directly to tape height so precommits work.
Network: network.Version5,
Network: build.ActorUpgradeNetworkVersion,
Height: upgradeHeight,
Migration: stmgr.UpgradeActorsV2,
}})
@@ -122,11 +104,6 @@ var FullNodeWithUpgradeAt = func(upgradeHeight abi.ChainEpoch) FullNodeOpts {
}
}
var MineNext = miner.MineReq{
InjectNulls: 0,
Done: func(bool, abi.ChainEpoch, error) {},
}
func (ts *testSuite) testVersion(t *testing.T) {
build.RunningNodeType = build.NodeFull
@@ -141,49 +118,6 @@ func (ts *testSuite) testVersion(t *testing.T) {
require.Equal(t, v.Version, build.BuildVersion)
}
func (ts *testSuite) testSearchMsg(t *testing.T) {
apis, miners := ts.makeNodes(t, OneFull, OneMiner)
api := apis[0]
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
senderAddr, err := api.WalletDefaultAddress(ctx)
if err != nil {
t.Fatal(err)
}
msg := &types.Message{
From: senderAddr,
To: senderAddr,
Value: big.Zero(),
}
bm := NewBlockMiner(ctx, t, miners[0], 100*time.Millisecond)
bm.MineBlocks()
defer bm.Stop()
sm, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
t.Fatal(err)
}
res, err := api.StateWaitMsg(ctx, sm.Cid(), 1)
if err != nil {
t.Fatal(err)
}
if res.Receipt.ExitCode != 0 {
t.Fatal("did not successfully send message")
}
searchRes, err := api.StateSearchMsg(ctx, sm.Cid())
if err != nil {
t.Fatal(err)
}
if searchRes.TipSet != res.TipSet {
t.Fatalf("search ts: %s, different from wait ts: %s", searchRes.TipSet, res.TipSet)
}
}
func (ts *testSuite) testID(t *testing.T) {
ctx := context.Background()
apis, _ := ts.makeNodes(t, OneFull, OneMiner)
+8
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"sync/atomic"
"os"
"strings"
"testing"
"time"
@@ -23,6 +24,13 @@ import (
"github.com/filecoin-project/lotus/node/impl"
)
func init() {
err := os.Setenv("BELLMAN_NO_GPU", "1")
if err != nil {
panic(fmt.Sprintf("failed to set BELLMAN_NO_GPU env variable: %s", err))
}
}
func TestPledgeSector(t *testing.T, b APIBuilder, blocktime time.Duration, nSectors int) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
+4 -15
View File
@@ -1,15 +1,4 @@
/dns4/bootstrap-0.mainnet.filops.net/tcp/1347/p2p/12D3KooWCVe8MmsEMes2FzgTpt9fXtmCY7wrq91GRiaC8PHSCCBj
/dns4/bootstrap-1.mainnet.filops.net/tcp/1347/p2p/12D3KooWCwevHg1yLCvktf2nvLu7L9894mcrJR4MsBCcm4syShVc
/dns4/bootstrap-2.mainnet.filops.net/tcp/1347/p2p/12D3KooWEWVwHGn2yR36gKLozmb4YjDJGerotAPGxmdWZx2nxMC4
/dns4/bootstrap-3.mainnet.filops.net/tcp/1347/p2p/12D3KooWKhgq8c7NQ9iGjbyK7v7phXvG6492HQfiDaGHLHLQjk7R
/dns4/bootstrap-4.mainnet.filops.net/tcp/1347/p2p/12D3KooWL6PsFNPhYftrJzGgF5U18hFoaVhfGk7xwzD8yVrHJ3Uc
/dns4/bootstrap-5.mainnet.filops.net/tcp/1347/p2p/12D3KooWLFynvDQiUpXoHroV1YxKHhPJgysQGH2k3ZGwtWzR4dFH
/dns4/bootstrap-6.mainnet.filops.net/tcp/1347/p2p/12D3KooWP5MwCiqdMETF9ub1P3MbCvQCcfconnYHbWg6sUJcDRQQ
/dns4/bootstrap-7.mainnet.filops.net/tcp/1347/p2p/12D3KooWRs3aY1p3juFjPy8gPN95PEQChm2QKGUCAdcDCC4EBMKf
/dns4/bootstrap-8.mainnet.filops.net/tcp/1347/p2p/12D3KooWScFR7385LTyR4zU1bYdzSiiAb5rnNABfVahPvVSzyTkR
/dns4/lotus-bootstrap.forceup.cn/tcp/41778/p2p/12D3KooWFQsv3nRMUevZNWWsY1Wu6NUzUbawnWU5NcRhgKuJA37C
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
/dns4/bootstrap-0.calibration.fildev.network/tcp/1347/p2p/12D3KooWA3bLx1ntQ2nSVXZRQnL4NEtwVdadk9TUrvZQKUGu9qnh
/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWR51XjrKbGFz9y1c8hKw3oguqGvQJNvxPDcPC9UXhkP6K
/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWKKb2C1khuxBBbk21dXe8hdEZ1FETqgB3TEVRNm5ZZxWT
/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWDCQH94idHfDBeoVGCkQVQL7DZp98ZvuRd33F76wJAgfd
+10 -1
View File
@@ -35,7 +35,6 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
"https://api.drand.sh",
"https://api2.drand.sh",
"https://api3.drand.sh",
"https://drand.cloudflare.com",
},
Relays: []string{
"/dnsaddr/api.drand.sh/",
@@ -69,6 +68,16 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
},
DrandIncentinet: {
Servers: []string{
"https://pl-eu.incentinet.drand.sh",
"https://pl-us.incentinet.drand.sh",
"https://pl-sin.incentinet.drand.sh",
},
Relays: []string{
"/dnsaddr/pl-eu.incentinet.drand.sh/",
"/dnsaddr/pl-us.incentinet.drand.sh/",
"/dnsaddr/pl-sin.incentinet.drand.sh/",
},
ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`,
},
}
Binary file not shown.
-2
View File
@@ -22,8 +22,6 @@ const UpgradeTapeHeight = -4
var UpgradeActorsV2Height = abi.ChainEpoch(10)
var UpgradeLiftoffHeight = abi.ChainEpoch(-5)
const UpgradeKumquatHeight = 15
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
}
+31
View File
@@ -1,13 +1,36 @@
package build
import (
"sort"
"github.com/filecoin-project/go-address"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/go-state-types/abi"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
func DefaultSectorSize() abi.SectorSize {
szs := make([]abi.SectorSize, 0, len(miner0.SupportedProofTypes))
for spt := range miner0.SupportedProofTypes {
ss, err := spt.SectorSize()
if err != nil {
panic(err)
}
szs = append(szs, ss)
}
sort.Slice(szs, func(i, j int) bool {
return szs[i] < szs[j]
})
return szs[0]
}
// Core network constants
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
@@ -16,6 +39,14 @@ func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
return protocol.ID("/fil/kad/" + string(netName))
}
func UseNewestNetwork() bool {
// TODO: Put these in a container we can iterate over
if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 && UpgradeActorsV2Height <= 0 {
return true
}
return false
}
func SetAddressNetwork(n address.Network) {
address.CurrentNetwork = n
}
+7 -7
View File
@@ -7,12 +7,12 @@ import (
"os"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/go-state-types/network"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
)
// /////
@@ -25,14 +25,14 @@ const UnixfsLinksPerLevel = 1024
// Consensus / Network
const AllowableClockDriftSecs = uint64(1)
const NewestNetworkVersion = network.Version6
const NewestNetworkVersion = network.Version5
const ActorUpgradeNetworkVersion = network.Version4
// Epochs
const ForkLengthThreshold = Finality
// Blocks (e)
var BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
var BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
// Epochs
const Finality = policy.ChainFinality
@@ -116,4 +116,4 @@ const PackingEfficiencyDenom = 5
// Actor consts
// TODO: Pull from actors when its made not private
var MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
var MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
+4 -6
View File
@@ -12,8 +12,7 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
)
@@ -22,14 +21,14 @@ var (
UnixfsChunkSize = uint64(1 << 20)
UnixfsLinksPerLevel = 1024
BlocksPerEpoch = uint64(builtin2.ExpectedLeadersPerEpoch)
BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
BlockMessageLimit = 512
BlockGasLimit = int64(100_000_000_000)
BlockGasTarget = int64(BlockGasLimit / 2)
BaseFeeMaxChangeDenom = int64(8) // 12.5%
InitialBaseFee = int64(100e6)
MinimumBaseFee = int64(100)
BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
BlockDelaySecs = uint64(builtin.EpochDurationSeconds)
PropagationDelaySecs = uint64(6)
AllowableClockDriftSecs = uint64(1)
@@ -73,7 +72,7 @@ var (
// Actor consts
// TODO: Pull from actors when its made not private
MinDealDuration = abi.ChainEpoch(180 * builtin2.EpochsInDay)
MinDealDuration = abi.ChainEpoch(180 * builtin.EpochsInDay)
PackingEfficiencyNum int64 = 4
PackingEfficiencyDenom int64 = 5
@@ -87,7 +86,6 @@ var (
UpgradeTapeHeight abi.ChainEpoch = -4
UpgradeActorsV2Height abi.ChainEpoch = 10
UpgradeLiftoffHeight abi.ChainEpoch = -5
UpgradeKumquatHeight abi.ChainEpoch = -6
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
@@ -5,58 +5,47 @@
package build
import (
"math"
"os"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors/policy"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
)
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandIncentinet,
UpgradeSmokeHeight: DrandMainnet,
0: DrandMainnet,
}
const UpgradeBreezeHeight = 41280
const UpgradeBreezeHeight = -1
const BreezeGasTampingDuration = 120
const UpgradeSmokeHeight = 51000
const UpgradeSmokeHeight = -2
const UpgradeIgnitionHeight = 94000
const UpgradeRefuelHeight = 130800
const UpgradeIgnitionHeight = -3
const UpgradeRefuelHeight = -4
var UpgradeActorsV2Height = abi.ChainEpoch(138720)
const UpgradeActorsV2Height = 30
const UpgradeTapeHeight = 140760
const UpgradeTapeHeight = 45
// This signals our tentative epoch for mainnet launch. Can make it later, but not earlier.
// Miners, clients, developers, custodians all need time to prepare.
// We still have upgrades and state changes to do, but can happen after signaling timing here.
const UpgradeLiftoffHeight = 148888
const UpgradeKumquatHeight = 170000
func init() {
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 40))
policy.SetConsensusMinerMinPower(abi.NewStoragePower(10 << 30))
policy.SetSupportedProofTypes(
abi.RegisteredSealProof_StackedDrg512MiBV1,
abi.RegisteredSealProof_StackedDrg32GiBV1,
abi.RegisteredSealProof_StackedDrg64GiBV1,
)
if os.Getenv("LOTUS_USE_TEST_ADDRESSES") != "1" {
SetAddressNetwork(address.Mainnet)
}
SetAddressNetwork(address.Testnet)
if os.Getenv("LOTUS_DISABLE_V2_ACTOR_MIGRATION") == "1" {
UpgradeActorsV2Height = math.MaxInt64
}
Devnet = false
Devnet = true
}
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
const BlockDelaySecs = uint64(builtin0.EpochDurationSeconds)
const PropagationDelaySecs = uint64(6)
+4 -4
View File
@@ -29,7 +29,7 @@ func buildType() string {
}
// BuildVersion is the local build version, set by build system
const BuildVersion = "1.1.3-pre2"
const BuildVersion = "0.9.1"
func UserVersion() string {
return BuildVersion + buildType() + CurrentCommit
@@ -83,9 +83,9 @@ func VersionForType(nodeType NodeType) (Version, error) {
// semver versions of the rpc api exposed
var (
FullAPIVersion = newVer(0, 17, 0)
MinerAPIVersion = newVer(0, 17, 0)
WorkerAPIVersion = newVer(0, 16, 0)
FullAPIVersion = newVer(0, 16, 0)
MinerAPIVersion = newVer(0, 15, 0)
WorkerAPIVersion = newVer(0, 15, 0)
)
//nolint:varcheck,deadcode
+36 -37
View File
@@ -12,9 +12,8 @@ import (
typegen "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/go-state-types/abi"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
"github.com/filecoin-project/specs-actors/actors/runtime"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
bstore "github.com/filecoin-project/lotus/lib/blockstore"
)
@@ -23,24 +22,24 @@ func TestDiffAdtArray(t *testing.T) {
ctxstoreA := newContextStore()
ctxstoreB := newContextStore()
arrA := adt2.MakeEmptyArray(ctxstoreA)
arrB := adt2.MakeEmptyArray(ctxstoreB)
arrA := adt0.MakeEmptyArray(ctxstoreA)
arrB := adt0.MakeEmptyArray(ctxstoreB)
require.NoError(t, arrA.Set(0, builtin2.CBORBytes([]byte{0}))) // delete
require.NoError(t, arrA.Set(0, runtime.CBORBytes([]byte{0}))) // delete
require.NoError(t, arrA.Set(1, builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, arrB.Set(1, builtin2.CBORBytes([]byte{1})))
require.NoError(t, arrA.Set(1, runtime.CBORBytes([]byte{0}))) // modify
require.NoError(t, arrB.Set(1, runtime.CBORBytes([]byte{1})))
require.NoError(t, arrA.Set(2, builtin2.CBORBytes([]byte{1}))) // delete
require.NoError(t, arrA.Set(2, runtime.CBORBytes([]byte{1}))) // delete
require.NoError(t, arrA.Set(3, builtin2.CBORBytes([]byte{0}))) // noop
require.NoError(t, arrB.Set(3, builtin2.CBORBytes([]byte{0})))
require.NoError(t, arrA.Set(3, runtime.CBORBytes([]byte{0}))) // noop
require.NoError(t, arrB.Set(3, runtime.CBORBytes([]byte{0})))
require.NoError(t, arrA.Set(4, builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, arrB.Set(4, builtin2.CBORBytes([]byte{6})))
require.NoError(t, arrA.Set(4, runtime.CBORBytes([]byte{0}))) // modify
require.NoError(t, arrB.Set(4, runtime.CBORBytes([]byte{6})))
require.NoError(t, arrB.Set(5, builtin2.CBORBytes{8})) // add
require.NoError(t, arrB.Set(6, builtin2.CBORBytes{9})) // add
require.NoError(t, arrB.Set(5, runtime.CBORBytes{8})) // add
require.NoError(t, arrB.Set(6, runtime.CBORBytes{9})) // add
changes := new(TestDiffArray)
@@ -77,24 +76,24 @@ func TestDiffAdtMap(t *testing.T) {
ctxstoreA := newContextStore()
ctxstoreB := newContextStore()
mapA := adt2.MakeEmptyMap(ctxstoreA)
mapB := adt2.MakeEmptyMap(ctxstoreB)
mapA := adt0.MakeEmptyMap(ctxstoreA)
mapB := adt0.MakeEmptyMap(ctxstoreB)
require.NoError(t, mapA.Put(abi.UIntKey(0), builtin2.CBORBytes([]byte{0}))) // delete
require.NoError(t, mapA.Put(abi.UIntKey(0), runtime.CBORBytes([]byte{0}))) // delete
require.NoError(t, mapA.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(abi.UIntKey(1), builtin2.CBORBytes([]byte{1})))
require.NoError(t, mapA.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(abi.UIntKey(1), runtime.CBORBytes([]byte{1})))
require.NoError(t, mapA.Put(abi.UIntKey(2), builtin2.CBORBytes([]byte{1}))) // delete
require.NoError(t, mapA.Put(abi.UIntKey(2), runtime.CBORBytes([]byte{1}))) // delete
require.NoError(t, mapA.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0}))) // noop
require.NoError(t, mapB.Put(abi.UIntKey(3), builtin2.CBORBytes([]byte{0})))
require.NoError(t, mapA.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0}))) // noop
require.NoError(t, mapB.Put(abi.UIntKey(3), runtime.CBORBytes([]byte{0})))
require.NoError(t, mapA.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(abi.UIntKey(4), builtin2.CBORBytes([]byte{6})))
require.NoError(t, mapA.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{0}))) // modify
require.NoError(t, mapB.Put(abi.UIntKey(4), runtime.CBORBytes([]byte{6})))
require.NoError(t, mapB.Put(abi.UIntKey(5), builtin2.CBORBytes{8})) // add
require.NoError(t, mapB.Put(abi.UIntKey(6), builtin2.CBORBytes{9})) // add
require.NoError(t, mapB.Put(abi.UIntKey(5), runtime.CBORBytes{8})) // add
require.NoError(t, mapB.Put(abi.UIntKey(6), runtime.CBORBytes{9})) // add
changes := new(TestDiffMap)
@@ -145,7 +144,7 @@ func (t *TestDiffMap) AsKey(key string) (abi.Keyer, error) {
}
func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error {
v := new(builtin2.CBORBytes)
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
@@ -162,13 +161,13 @@ func (t *TestDiffMap) Add(key string, val *typegen.Deferred) error {
}
func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error {
vFrom := new(builtin2.CBORBytes)
vFrom := new(runtime.CBORBytes)
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
if err != nil {
return err
}
vTo := new(builtin2.CBORBytes)
vTo := new(runtime.CBORBytes)
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
if err != nil {
return err
@@ -195,7 +194,7 @@ func (t *TestDiffMap) Modify(key string, from, to *typegen.Deferred) error {
}
func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
v := new(builtin2.CBORBytes)
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
@@ -213,7 +212,7 @@ func (t *TestDiffMap) Remove(key string, val *typegen.Deferred) error {
type adtMapDiffResult struct {
key uint64
val builtin2.CBORBytes
val runtime.CBORBytes
}
type TestAdtMapDiffModified struct {
@@ -223,7 +222,7 @@ type TestAdtMapDiffModified struct {
type adtArrayDiffResult struct {
key uint64
val builtin2.CBORBytes
val runtime.CBORBytes
}
type TestDiffArray struct {
@@ -240,7 +239,7 @@ type TestAdtArrayDiffModified struct {
}
func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
v := new(builtin2.CBORBytes)
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
@@ -253,13 +252,13 @@ func (t *TestDiffArray) Add(key uint64, val *typegen.Deferred) error {
}
func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error {
vFrom := new(builtin2.CBORBytes)
vFrom := new(runtime.CBORBytes)
err := vFrom.UnmarshalCBOR(bytes.NewReader(from.Raw))
if err != nil {
return err
}
vTo := new(builtin2.CBORBytes)
vTo := new(runtime.CBORBytes)
err = vTo.UnmarshalCBOR(bytes.NewReader(to.Raw))
if err != nil {
return err
@@ -281,7 +280,7 @@ func (t *TestDiffArray) Modify(key uint64, from, to *typegen.Deferred) error {
}
func (t *TestDiffArray) Remove(key uint64, val *typegen.Deferred) error {
v := new(builtin2.CBORBytes)
v := new(runtime.CBORBytes)
err := v.UnmarshalCBOR(bytes.NewReader(val.Raw))
if err != nil {
return err
-2
View File
@@ -24,8 +24,6 @@ func init() {
})
}
var Methods = builtin2.MethodsAccount
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
case builtin0.AccountActorCodeID:
+3 -21
View File
@@ -2,46 +2,28 @@ package builtin
import (
"github.com/filecoin-project/go-address"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/types"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
smoothing0 "github.com/filecoin-project/specs-actors/actors/util/smoothing"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
smoothing2 "github.com/filecoin-project/specs-actors/v2/actors/util/smoothing"
)
var SystemActorAddr = builtin0.SystemActorAddr
var BurntFundsActorAddr = builtin0.BurntFundsActorAddr
var CronActorAddr = builtin0.CronActorAddr
var SaftAddress = makeAddress("t0122")
var ReserveAddress = makeAddress("t090")
var RootVerifierAddress = makeAddress("t080")
var (
ExpectedLeadersPerEpoch = builtin0.ExpectedLeadersPerEpoch
)
const (
EpochDurationSeconds = builtin0.EpochDurationSeconds
EpochsInDay = builtin0.EpochsInDay
SecondsInDay = builtin0.SecondsInDay
)
const (
MethodSend = builtin2.MethodSend
MethodConstructor = builtin2.MethodConstructor
)
// TODO: Why does actors have 2 different versions of this?
type SectorInfo = proof0.SectorInfo
type PoStProof = proof0.PoStProof
-10
View File
@@ -1,10 +0,0 @@
package cron
import (
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
)
var (
Address = builtin2.CronActorAddr
Methods = builtin2.MethodsCron
)
+1 -4
View File
@@ -26,10 +26,7 @@ func init() {
})
}
var (
Address = builtin2.InitActorAddr
Methods = builtin2.MethodsInit
)
var Address = builtin0.InitActorAddr
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
+1 -5
View File
@@ -27,10 +27,7 @@ func init() {
})
}
var (
Address = builtin2.StorageMarketActorAddr
Methods = builtin2.MethodsMarket
)
var Address = builtin0.StorageMarketActorAddr
func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code {
@@ -81,7 +78,6 @@ type DealProposals interface {
type PublishStorageDealsParams = market0.PublishStorageDealsParams
type PublishStorageDealsReturn = market0.PublishStorageDealsReturn
type VerifyDealsForActivationParams = market0.VerifyDealsForActivationParams
type WithdrawBalanceParams = market0.WithdrawBalanceParams
type ClientDealProposal = market0.ClientDealProposal
+10 -6
View File
@@ -7,9 +7,9 @@ import (
"github.com/filecoin-project/go-state-types/exitcode"
)
type DeadlinesDiff map[uint64]DeadlineDiff
type DeadlinesDiff map[uint64]*DeadlineDiff
func DiffDeadlines(pre, cur State) (DeadlinesDiff, error) {
func DiffDeadlines(pre, cur State) (*DeadlinesDiff, error) {
changed, err := pre.DeadlinesChanged(cur)
if err != nil {
return nil, err
@@ -18,7 +18,11 @@ func DiffDeadlines(pre, cur State) (DeadlinesDiff, error) {
return nil, nil
}
dlDiff := make(DeadlinesDiff)
numDl, err := pre.NumDeadlines()
if err != nil {
return nil, err
}
dlDiff := make(DeadlinesDiff, numDl)
if err := pre.ForEachDeadline(func(idx uint64, preDl Deadline) error {
curDl, err := cur.LoadDeadline(idx)
if err != nil {
@@ -35,12 +39,12 @@ func DiffDeadlines(pre, cur State) (DeadlinesDiff, error) {
}); err != nil {
return nil, err
}
return dlDiff, nil
return &dlDiff, nil
}
type DeadlineDiff map[uint64]*PartitionDiff
func DiffDeadline(pre, cur Deadline) (DeadlineDiff, error) {
func DiffDeadline(pre, cur Deadline) (*DeadlineDiff, error) {
changed, err := pre.PartitionsChanged(cur)
if err != nil {
return nil, err
@@ -100,7 +104,7 @@ func DiffDeadline(pre, cur Deadline) (DeadlineDiff, error) {
return nil, err
}
return partDiff, nil
return &partDiff, nil
}
type PartitionDiff struct {
-22
View File
@@ -1,7 +1,6 @@
package miner
import (
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
@@ -31,8 +30,6 @@ func init() {
})
}
var Methods = builtin2.MethodsMiner
// Unchanged between v0 and v2 actors
var WPoStProvingPeriod = miner0.WPoStProvingPeriod
var WPoStPeriodDeadlines = miner0.WPoStPeriodDeadlines
@@ -77,7 +74,6 @@ type State interface {
DeadlinesChanged(State) (bool, error)
Info() (MinerInfo, error)
MinerInfoChanged(State) (bool, error)
DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error)
@@ -152,20 +148,6 @@ type MinerInfo struct {
ConsensusFaultElapsed abi.ChainEpoch
}
func (mi MinerInfo) IsController(addr address.Address) bool {
if addr == mi.Owner || addr == mi.Worker {
return true
}
for _, ca := range mi.ControlAddresses {
if addr == ca {
return true
}
}
return false
}
type SectorExpiration struct {
OnTime abi.ChainEpoch
@@ -200,7 +182,3 @@ type LockedFunds struct {
InitialPledgeRequirement abi.TokenAmount
PreCommitDeposits abi.TokenAmount
}
func (lf LockedFunds) TotalLockedFunds() abi.TokenAmount {
return big.Add(lf.VestingFunds, big.Add(lf.InitialPledgeRequirement, lf.PreCommitDeposits))
}
+4 -21
View File
@@ -47,16 +47,8 @@ type partition0 struct {
store adt.Store
}
func (s *state0) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
defer func() {
if r := recover(); r != nil {
err = xerrors.Errorf("failed to get available balance: %w", r)
available = abi.NewTokenAmount(0)
}
}()
// this panics if the miner doesnt have enough funds to cover their locked pledge
available = s.GetAvailableBalance(bal)
return available, err
func (s *state0) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
return s.GetAvailableBalance(bal), nil
}
func (s *state0) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
@@ -274,16 +266,7 @@ func (s *state0) DeadlinesChanged(other State) (bool, error) {
return true, nil
}
return !s.State.Deadlines.Equals(other0.Deadlines), nil
}
func (s *state0) MinerInfoChanged(other State) (bool, error) {
other0, ok := other.(*state0)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Info.Equals(other0.State.Info), nil
return s.State.Deadlines.Equals(other0.Deadlines), nil
}
func (s *state0) Info() (MinerInfo, error) {
@@ -379,7 +362,7 @@ func (d *deadline0) PartitionsChanged(other Deadline) (bool, error) {
return true, nil
}
return !d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
return d.Deadline.Partitions.Equals(other0.Deadline.Partitions), nil
}
func (d *deadline0) PostSubmissions() (bitfield.BitField, error) {
+4 -21
View File
@@ -45,16 +45,8 @@ type partition2 struct {
store adt.Store
}
func (s *state2) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
defer func() {
if r := recover(); r != nil {
err = xerrors.Errorf("failed to get available balance: %w", r)
available = abi.NewTokenAmount(0)
}
}()
// this panics if the miner doesnt have enough funds to cover their locked pledge
available, err = s.GetAvailableBalance(bal)
return available, err
func (s *state2) AvailableBalance(bal abi.TokenAmount) (abi.TokenAmount, error) {
return s.GetAvailableBalance(bal)
}
func (s *state2) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
@@ -273,16 +265,7 @@ func (s *state2) DeadlinesChanged(other State) (bool, error) {
return true, nil
}
return !s.State.Deadlines.Equals(other2.Deadlines), nil
}
func (s *state2) MinerInfoChanged(other State) (bool, error) {
other0, ok := other.(*state2)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Info.Equals(other0.State.Info), nil
return s.State.Deadlines.Equals(other2.Deadlines), nil
}
func (s *state2) Info() (MinerInfo, error) {
@@ -378,7 +361,7 @@ func (d *deadline2) PartitionsChanged(other Deadline) (bool, error) {
return true, nil
}
return !d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
return d.Deadline.Partitions.Equals(other2.Deadline.Partitions), nil
}
func (d *deadline2) PostSubmissions() (bitfield.BitField, error) {
-134
View File
@@ -1,134 +0,0 @@
package multisig
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/chain/actors/adt"
)
type PendingTransactionChanges struct {
Added []TransactionChange
Modified []TransactionModification
Removed []TransactionChange
}
type TransactionChange struct {
TxID int64
Tx Transaction
}
type TransactionModification struct {
TxID int64
From Transaction
To Transaction
}
func DiffPendingTransactions(pre, cur State) (*PendingTransactionChanges, error) {
results := new(PendingTransactionChanges)
if changed, err := pre.PendingTxnChanged(cur); err != nil {
return nil, err
} else if !changed { // if nothing has changed then return an empty result and bail.
return results, nil
}
pret, err := pre.transactions()
if err != nil {
return nil, err
}
curt, err := cur.transactions()
if err != nil {
return nil, err
}
if err := adt.DiffAdtMap(pret, curt, &transactionDiffer{results, pre, cur}); err != nil {
return nil, err
}
return results, nil
}
type transactionDiffer struct {
Results *PendingTransactionChanges
pre, after State
}
func (t *transactionDiffer) AsKey(key string) (abi.Keyer, error) {
txID, err := abi.ParseIntKey(key)
if err != nil {
return nil, err
}
return abi.IntKey(txID), nil
}
func (t *transactionDiffer) Add(key string, val *cbg.Deferred) error {
txID, err := abi.ParseIntKey(key)
if err != nil {
return err
}
tx, err := t.after.decodeTransaction(val)
if err != nil {
return err
}
t.Results.Added = append(t.Results.Added, TransactionChange{
TxID: txID,
Tx: tx,
})
return nil
}
func (t *transactionDiffer) Modify(key string, from, to *cbg.Deferred) error {
txID, err := abi.ParseIntKey(key)
if err != nil {
return err
}
txFrom, err := t.pre.decodeTransaction(from)
if err != nil {
return err
}
txTo, err := t.after.decodeTransaction(to)
if err != nil {
return err
}
if approvalsChanged(txFrom.Approved, txTo.Approved) {
t.Results.Modified = append(t.Results.Modified, TransactionModification{
TxID: txID,
From: txFrom,
To: txTo,
})
}
return nil
}
func approvalsChanged(from, to []address.Address) bool {
if len(from) != len(to) {
return true
}
for idx := range from {
if from[idx] != to[idx] {
return true
}
}
return false
}
func (t *transactionDiffer) Remove(key string, val *cbg.Deferred) error {
txID, err := abi.ParseIntKey(key)
if err != nil {
return err
}
tx, err := t.pre.decodeTransaction(val)
if err != nil {
return err
}
t.Results.Removed = append(t.Results.Removed, TransactionChange{
TxID: txID,
Tx: tx,
})
return nil
}
-4
View File
@@ -9,15 +9,12 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
multisig2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)
var Methods = builtin2.MethodsMultisig
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
case actors.Version0:
@@ -48,7 +45,6 @@ type MessageBuilder interface {
// this type is the same between v0 and v2
type ProposalHashData = multisig2.ProposalHashData
type ProposeReturn = multisig2.ProposeReturn
func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
params := multisig2.TxnIDParams{ID: multisig2.TxnID(id)}
-5
View File
@@ -1,7 +1,6 @@
package multisig
import (
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
@@ -48,10 +47,6 @@ type State interface {
Signers() ([]address.Address, error)
ForEachPendingTxn(func(id int64, txn Transaction) error) error
PendingTxnChanged(State) (bool, error)
transactions() (adt.Map, error)
decodeTransaction(val *cbg.Deferred) (Transaction, error)
}
type Transaction = msig0.Transaction
-24
View File
@@ -1,20 +1,17 @@
package multisig
import (
"bytes"
"encoding/binary"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/adt"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
multisig0 "github.com/filecoin-project/specs-actors/v2/actors/builtin/multisig"
)
var _ State = (*state0)(nil)
@@ -71,24 +68,3 @@ func (s *state0) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
return cb(txid, (Transaction)(out))
})
}
func (s *state0) PendingTxnChanged(other State) (bool, error) {
other0, ok := other.(*state0)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.PendingTxns.Equals(other0.PendingTxns), nil
}
func (s *state0) transactions() (adt.Map, error) {
return adt0.AsMap(s.store, s.PendingTxns)
}
func (s *state0) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
var tx multisig0.Transaction
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Transaction{}, err
}
return tx, nil
}
-23
View File
@@ -1,13 +1,11 @@
package multisig
import (
"bytes"
"encoding/binary"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/adt"
@@ -70,24 +68,3 @@ func (s *state2) ForEachPendingTxn(cb func(id int64, txn Transaction) error) err
return cb(txid, (Transaction)(out))
})
}
func (s *state2) PendingTxnChanged(other State) (bool, error) {
other2, ok := other.(*state2)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.PendingTxns.Equals(other2.PendingTxns), nil
}
func (s *state2) transactions() (adt.Map, error) {
return adt2.AsMap(s.store, s.PendingTxns)
}
func (s *state2) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
var tx msig2.Transaction
if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Transaction{}, err
}
return tx, nil
}
-4
View File
@@ -7,12 +7,8 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
)
var Methods = builtin2.MethodsPaych
func Message(version actors.Version, from address.Address) MessageBuilder {
switch version {
case actors.Version0:
-117
View File
@@ -1,117 +0,0 @@
package power
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/chain/actors/adt"
)
type ClaimChanges struct {
Added []ClaimInfo
Modified []ClaimModification
Removed []ClaimInfo
}
type ClaimModification struct {
Miner address.Address
From Claim
To Claim
}
type ClaimInfo struct {
Miner address.Address
Claim Claim
}
func DiffClaims(pre, cur State) (*ClaimChanges, error) {
results := new(ClaimChanges)
prec, err := pre.claims()
if err != nil {
return nil, err
}
curc, err := cur.claims()
if err != nil {
return nil, err
}
if err := adt.DiffAdtMap(prec, curc, &claimDiffer{results, pre, cur}); err != nil {
return nil, err
}
return results, nil
}
type claimDiffer struct {
Results *ClaimChanges
pre, after State
}
func (c *claimDiffer) AsKey(key string) (abi.Keyer, error) {
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return nil, err
}
return abi.AddrKey(addr), nil
}
func (c *claimDiffer) Add(key string, val *cbg.Deferred) error {
ci, err := c.after.decodeClaim(val)
if err != nil {
return err
}
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
c.Results.Added = append(c.Results.Added, ClaimInfo{
Miner: addr,
Claim: ci,
})
return nil
}
func (c *claimDiffer) Modify(key string, from, to *cbg.Deferred) error {
ciFrom, err := c.pre.decodeClaim(from)
if err != nil {
return err
}
ciTo, err := c.after.decodeClaim(to)
if err != nil {
return err
}
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
if ciFrom != ciTo {
c.Results.Modified = append(c.Results.Modified, ClaimModification{
Miner: addr,
From: ciFrom,
To: ciTo,
})
}
return nil
}
func (c *claimDiffer) Remove(key string, val *cbg.Deferred) error {
ci, err := c.after.decodeClaim(val)
if err != nil {
return err
}
addr, err := address.NewFromBytes([]byte(key))
if err != nil {
return err
}
c.Results.Removed = append(c.Results.Removed, ClaimInfo{
Miner: addr,
Claim: ci,
})
return nil
}
+1 -18
View File
@@ -2,9 +2,7 @@ package power
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
@@ -27,10 +25,7 @@ func init() {
})
}
var (
Address = builtin2.StoragePowerActorAddr
Methods = builtin2.MethodsPower
)
var Address = builtin0.StoragePowerActorAddr
func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code {
@@ -57,11 +52,6 @@ type State interface {
MinerNominalPowerMeetsConsensusMinimum(address.Address) (bool, error)
ListAllMiners() ([]address.Address, error)
ForEachClaim(func(miner address.Address, claim Claim) error) error
ClaimsChanged(State) (bool, error)
// Diff helpers. Used by Diff* functions internally.
claims() (adt.Map, error)
decodeClaim(*cbg.Deferred) (Claim, error)
}
type Claim struct {
@@ -71,10 +61,3 @@ type Claim struct {
// Sum of quality adjusted power for a miner's sectors.
QualityAdjPower abi.StoragePower
}
func AddClaims(a Claim, b Claim) Claim {
return Claim{
RawBytePower: big.Add(a.RawBytePower, b.RawBytePower),
QualityAdjPower: big.Add(a.QualityAdjPower, b.QualityAdjPower),
}
}
-28
View File
@@ -1,12 +1,9 @@
package power
import (
"bytes"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
@@ -118,28 +115,3 @@ func (s *state0) ForEachClaim(cb func(miner address.Address, claim Claim) error)
})
})
}
func (s *state0) ClaimsChanged(other State) (bool, error) {
other0, ok := other.(*state0)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Claims.Equals(other0.State.Claims), nil
}
func (s *state0) claims() (adt.Map, error) {
return adt0.AsMap(s.store, s.Claims)
}
func (s *state0) decodeClaim(val *cbg.Deferred) (Claim, error) {
var ci power0.Claim
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Claim{}, err
}
return fromV0Claim(ci), nil
}
func fromV0Claim(v0 power0.Claim) Claim {
return (Claim)(v0)
}
-31
View File
@@ -1,12 +1,9 @@
package power
import (
"bytes"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
@@ -118,31 +115,3 @@ func (s *state2) ForEachClaim(cb func(miner address.Address, claim Claim) error)
})
})
}
func (s *state2) ClaimsChanged(other State) (bool, error) {
other2, ok := other.(*state2)
if !ok {
// treat an upgrade as a change, always
return true, nil
}
return !s.State.Claims.Equals(other2.State.Claims), nil
}
func (s *state2) claims() (adt.Map, error) {
return adt2.AsMap(s.store, s.Claims)
}
func (s *state2) decodeClaim(val *cbg.Deferred) (Claim, error) {
var ci power2.Claim
if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
return Claim{}, err
}
return fromV2Claim(ci), nil
}
func fromV2Claim(v2 power2.Claim) Claim {
return Claim{
RawBytePower: v2.RawBytePower,
QualityAdjPower: v2.QualityAdjPower,
}
}
+1 -4
View File
@@ -24,10 +24,7 @@ func init() {
})
}
var (
Address = builtin2.RewardActorAddr
Methods = builtin2.MethodsReward
)
var Address = builtin0.RewardActorAddr
func Load(store adt.Store, act *types.Actor) (st State, err error) {
switch act.Code {
+3 -3
View File
@@ -28,7 +28,7 @@ type state2 struct {
store adt.Store
}
func (s *state2) ThisEpochReward() (abi.TokenAmount, error) {
func (s *state2) ThisEpochReward() (abi.StoragePower, error) {
return s.State.ThisEpochReward, nil
}
@@ -55,11 +55,11 @@ func (s *state2) EffectiveNetworkTime() (abi.ChainEpoch, error) {
return s.State.EffectiveNetworkTime, nil
}
func (s *state2) CumsumBaseline() (reward2.Spacetime, error) {
func (s *state2) CumsumBaseline() (abi.StoragePower, error) {
return s.State.CumsumBaseline, nil
}
func (s *state2) CumsumRealized() (reward2.Spacetime, error) {
func (s *state2) CumsumRealized() (abi.StoragePower, error) {
return s.State.CumsumRealized, nil
}
+1 -4
View File
@@ -24,10 +24,7 @@ func init() {
})
}
var (
Address = builtin2.VerifiedRegistryActorAddr
Methods = builtin2.MethodsVerifiedRegistry
)
var Address = builtin0.VerifiedRegistryActorAddr
func Load(store adt.Store, act *types.Actor) (State, error) {
switch act.Code {
-36
View File
@@ -1,8 +1,6 @@
package policy
import (
"sort"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors"
@@ -13,14 +11,12 @@ import (
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
)
const (
ChainFinality = miner0.ChainFinality
SealRandomnessLookback = ChainFinality
PaychSettleDelay = paych2.SettleDelay
)
// SetSupportedProofTypes sets supported proof types, across all actor versions.
@@ -118,35 +114,3 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
return ChainFinality
}
func GetMaxSectorExpirationExtension() abi.ChainEpoch {
return miner0.MaxSectorExpirationExtension
}
// TODO: we'll probably need to abstract over this better in the future.
func GetMaxPoStPartitions(p abi.RegisteredPoStProof) (int, error) {
sectorsPerPart, err := builtin2.PoStProofWindowPoStPartitionSectors(p)
if err != nil {
return 0, err
}
return int(miner2.AddressedSectorsMax / sectorsPerPart), nil
}
func GetDefaultSectorSize() abi.SectorSize {
// supported proof types are the same across versions.
szs := make([]abi.SectorSize, 0, len(miner2.SupportedProofTypes))
for spt := range miner2.SupportedProofTypes {
ss, err := spt.SectorSize()
if err != nil {
panic(err)
}
szs = append(szs, ss)
}
sort.Slice(szs, func(i, j int) bool {
return szs[i] < szs[j]
})
return szs[0]
}
-20
View File
@@ -6,13 +6,9 @@ import (
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-state-types/abi"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
verifreg0 "github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
paych2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/paych"
verifreg2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/verifreg"
)
@@ -46,25 +42,9 @@ func TestSupportedProofTypes(t *testing.T) {
func TestAssumptions(t *testing.T) {
require.EqualValues(t, miner0.SupportedProofTypes, miner2.SupportedProofTypes)
require.Equal(t, miner0.PreCommitChallengeDelay, miner2.PreCommitChallengeDelay)
require.Equal(t, miner0.MaxSectorExpirationExtension, miner2.MaxSectorExpirationExtension)
require.Equal(t, miner0.ChainFinality, miner2.ChainFinality)
require.Equal(t, miner0.WPoStChallengeWindow, miner2.WPoStChallengeWindow)
require.Equal(t, miner0.WPoStProvingPeriod, miner2.WPoStProvingPeriod)
require.Equal(t, miner0.WPoStPeriodDeadlines, miner2.WPoStPeriodDeadlines)
require.Equal(t, miner0.AddressedSectorsMax, miner2.AddressedSectorsMax)
require.Equal(t, paych0.SettleDelay, paych2.SettleDelay)
require.True(t, verifreg0.MinVerifiedDealSize.Equals(verifreg2.MinVerifiedDealSize))
}
func TestPartitionSizes(t *testing.T) {
for p := range abi.PoStSealProofTypes {
sizeNew, err := builtin2.PoStProofWindowPoStPartitionSectors(p)
require.NoError(t, err)
sizeOld, err := builtin0.PoStProofWindowPoStPartitionSectors(p)
if err != nil {
// new proof type.
continue
}
require.Equal(t, sizeOld, sizeNew)
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ func VersionForNetwork(version network.Version) Version {
switch version {
case network.Version0, network.Version1, network.Version2, network.Version3:
return Version0
case network.Version4, network.Version5, network.Version6:
case network.Version4, network.Version5:
return Version2
default:
panic(fmt.Sprintf("unsupported network version %d", version))
+1 -6
View File
@@ -65,11 +65,6 @@ type DrandBeacon struct {
localCache map[uint64]types.BeaconEntry
}
// DrandHTTPClient interface overrides the user agent used by drand
type DrandHTTPClient interface {
SetUserAgent(string)
}
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes.DrandConfig) (*DrandBeacon, error) {
if genesisTs == 0 {
panic("what are you doing this cant be zero")
@@ -89,7 +84,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
if err != nil {
return nil, xerrors.Errorf("could not create http drand client: %w", err)
}
hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.BuildVersion)
clients = append(clients, hc)
}
@@ -98,6 +92,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
dclient.WithChainInfo(drandChain),
dclient.WithCacheSize(1024),
dclient.WithLogger(dlogger),
dclient.WithAutoWatch(),
}
if ps != nil {
+1 -1
View File
@@ -12,7 +12,7 @@ import (
)
func TestPrintGroupInfo(t *testing.T) {
server := build.DrandConfigs[build.DrandDevnet].Servers[0]
server := build.DrandConfigs[build.DrandIncentinet].Servers[0]
c, err := hclient.New(server, nil, nil)
assert.NoError(t, err)
cg := c.(interface {
+22 -13
View File
@@ -459,7 +459,7 @@ type messageEvents struct {
hcAPI headChangeAPI
lk sync.RWMutex
matchers map[triggerID]MsgMatchFunc
matchers map[triggerID][]MsgMatchFunc
}
func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) messageEvents {
@@ -467,7 +467,7 @@ func newMessageEvents(ctx context.Context, hcAPI headChangeAPI, cs eventAPI) mes
ctx: ctx,
cs: cs,
hcAPI: hcAPI,
matchers: make(map[triggerID]MsgMatchFunc),
matchers: map[triggerID][]MsgMatchFunc{},
}
}
@@ -482,23 +482,32 @@ func (me *messageEvents) checkNewCalls(ts *types.TipSet) (map[triggerID]eventDat
me.lk.RLock()
defer me.lk.RUnlock()
// For each message in the tipset
res := make(map[triggerID]eventData)
me.messagesForTs(pts, func(msg *types.Message) {
// TODO: provide receipts
// Run each trigger's matcher against the message
for tid, matchFn := range me.matchers {
matched, err := matchFn(msg)
if err != nil {
log.Errorf("event matcher failed: %s", err)
continue
for tid, matchFns := range me.matchers {
var matched bool
var once bool
for _, matchFn := range matchFns {
matchOne, ok, err := matchFn(msg)
if err != nil {
log.Errorf("event matcher failed: %s", err)
continue
}
matched = ok
once = matchOne
if matched {
break
}
}
// If there was a match, include the message in the results for the
// trigger
if matched {
res[tid] = msg
if once {
break
}
}
}
})
@@ -546,7 +555,7 @@ func (me *messageEvents) messagesForTs(ts *types.TipSet, consume func(*types.Mes
// `curH`-`ts.Height` = `confidence`
type MsgHandler func(msg *types.Message, rec *types.MessageReceipt, ts *types.TipSet, curH abi.ChainEpoch) (more bool, err error)
type MsgMatchFunc func(msg *types.Message) (matched bool, err error)
type MsgMatchFunc func(msg *types.Message) (matchOnce bool, matched bool, err error)
// Called registers a callback which is triggered when a specified method is
// called on an actor, or a timeout is reached.
@@ -598,7 +607,7 @@ func (me *messageEvents) Called(check CheckFunc, msgHnd MsgHandler, rev RevertHa
me.lk.Lock()
defer me.lk.Unlock()
me.matchers[id] = mf
me.matchers[id] = append(me.matchers[id], mf)
return nil
}
+3 -3
View File
@@ -572,9 +572,9 @@ func TestAtChainedConfidenceNull(t *testing.T) {
require.Equal(t, false, reverted)
}
func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (matched bool, err error) {
return func(msg *types.Message) (matched bool, err error) {
return to == msg.To && m == msg.Method, nil
func matchAddrMethod(to address.Address, m abi.MethodNum) func(msg *types.Message) (matchOnce bool, matched bool, err error) {
return func(msg *types.Message) (matchOnce bool, matched bool, err error) {
return true, to == msg.To && m == msg.Method, nil
}
}
-69
View File
@@ -1,69 +0,0 @@
package test
import (
"context"
"sync"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/lib/blockstore"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
)
type MockAPI struct {
bs blockstore.Blockstore
lk sync.Mutex
ts map[types.TipSetKey]*types.Actor
stateGetActorCalled int
}
func NewMockAPI(bs blockstore.Blockstore) *MockAPI {
return &MockAPI{
bs: bs,
ts: make(map[types.TipSetKey]*types.Actor),
}
}
func (m *MockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
return m.bs.Has(c)
}
func (m *MockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
blk, err := m.bs.Get(c)
if err != nil {
return nil, xerrors.Errorf("blockstore get: %w", err)
}
return blk.RawData(), nil
}
func (m *MockAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
m.lk.Lock()
defer m.lk.Unlock()
m.stateGetActorCalled++
return m.ts[tsk], nil
}
func (m *MockAPI) StateGetActorCallCount() int {
m.lk.Lock()
defer m.lk.Unlock()
return m.stateGetActorCalled
}
func (m *MockAPI) ResetCallCounts() {
m.lk.Lock()
defer m.lk.Unlock()
m.stateGetActorCalled = 0
}
func (m *MockAPI) SetActor(tsk types.TipSetKey, act *types.Actor) {
m.lk.Lock()
defer m.lk.Unlock()
m.ts[tsk] = act
}
-32
View File
@@ -1,32 +0,0 @@
package test
import (
"context"
"testing"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
"github.com/filecoin-project/specs-actors/v2/actors/util/adt"
"github.com/stretchr/testify/require"
)
func CreateEmptyMarketState(t *testing.T, store adt.Store) *market.State {
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
require.NoError(t, err)
emptyMap, err := adt.MakeEmptyMap(store).Root()
require.NoError(t, err)
return market.ConstructState(emptyArrayCid, emptyMap, emptyMap)
}
func CreateDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market.DealState) cid.Cid {
root := adt.MakeEmptyArray(store)
for dealID, dealState := range deals {
err := root.Set(uint64(dealID), dealState)
require.NoError(t, err)
}
rootCid, err := root.Root()
require.NoError(t, err)
return rootCid
}
-27
View File
@@ -1,27 +0,0 @@
package test
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
)
var dummyCid cid.Cid
func init() {
dummyCid, _ = cid.Parse("bafkqaaa")
}
func MockTipset(minerAddr address.Address, timestamp uint64) (*types.TipSet, error) {
return types.NewTipSet([]*types.BlockHeader{{
Miner: minerAddr,
Height: 5,
ParentStateRoot: dummyCid,
Messages: dummyCid,
ParentMessageReceipts: dummyCid,
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
Timestamp: timestamp,
}})
}
+131 -78
View File
@@ -4,26 +4,28 @@ import (
"context"
"testing"
test "github.com/filecoin-project/lotus/chain/events/state/mock"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/go-bitfield"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
"github.com/ipfs/go-cid"
cbornode "github.com/ipfs/go-ipld-cbor"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
tutils "github.com/filecoin-project/specs-actors/v2/support/testing"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/util/adt"
tutils "github.com/filecoin-project/specs-actors/support/testing"
"github.com/filecoin-project/lotus/chain/types"
bstore "github.com/filecoin-project/lotus/lib/blockstore"
)
@@ -34,27 +36,60 @@ func init() {
dummyCid, _ = cid.Parse("bafkqaaa")
}
type mockAPI struct {
ts map[types.TipSetKey]*types.Actor
bs bstore.Blockstore
}
func newMockAPI(bs bstore.Blockstore) *mockAPI {
return &mockAPI{
bs: bs,
ts: make(map[types.TipSetKey]*types.Actor),
}
}
func (m mockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
return m.bs.Has(c)
}
func (m mockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
blk, err := m.bs.Get(c)
if err != nil {
return nil, xerrors.Errorf("blockstore get: %w", err)
}
return blk.RawData(), nil
}
func (m mockAPI) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
return m.ts[tsk], nil
}
func (m mockAPI) setActor(tsk types.TipSetKey, act *types.Actor) {
m.ts[tsk] = act
}
func TestMarketPredicates(t *testing.T) {
ctx := context.Background()
bs := bstore.NewTemporarySync()
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
oldDeal1 := &market2.DealState{
oldDeal1 := &market0.DealState{
SectorStartEpoch: 1,
LastUpdatedEpoch: 2,
SlashEpoch: 0,
}
oldDeal2 := &market2.DealState{
oldDeal2 := &market0.DealState{
SectorStartEpoch: 4,
LastUpdatedEpoch: 5,
SlashEpoch: 0,
}
oldDeals := map[abi.DealID]*market2.DealState{
oldDeals := map[abi.DealID]*market0.DealState{
abi.DealID(1): oldDeal1,
abi.DealID(2): oldDeal2,
}
oldProp1 := &market2.DealProposal{
oldProp1 := &market0.DealProposal{
PieceCID: dummyCid,
PieceSize: 0,
VerifiedDeal: false,
@@ -66,7 +101,7 @@ func TestMarketPredicates(t *testing.T) {
ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(),
}
oldProp2 := &market2.DealProposal{
oldProp2 := &market0.DealProposal{
PieceCID: dummyCid,
PieceSize: 0,
VerifiedDeal: false,
@@ -78,7 +113,7 @@ func TestMarketPredicates(t *testing.T) {
ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(),
}
oldProps := map[abi.DealID]*market2.DealProposal{
oldProps := map[abi.DealID]*market0.DealProposal{
abi.DealID(1): oldProp1,
abi.DealID(2): oldProp2,
}
@@ -92,7 +127,7 @@ func TestMarketPredicates(t *testing.T) {
oldStateC := createMarketState(ctx, t, store, oldDeals, oldProps, oldBalances)
newDeal1 := &market2.DealState{
newDeal1 := &market0.DealState{
SectorStartEpoch: 1,
LastUpdatedEpoch: 3,
SlashEpoch: 0,
@@ -101,19 +136,19 @@ func TestMarketPredicates(t *testing.T) {
// deal 2 removed
// added
newDeal3 := &market2.DealState{
newDeal3 := &market0.DealState{
SectorStartEpoch: 1,
LastUpdatedEpoch: 2,
SlashEpoch: 3,
}
newDeals := map[abi.DealID]*market2.DealState{
newDeals := map[abi.DealID]*market0.DealState{
abi.DealID(1): newDeal1,
// deal 2 was removed
abi.DealID(3): newDeal3,
}
// added
newProp3 := &market2.DealProposal{
newProp3 := &market0.DealProposal{
PieceCID: dummyCid,
PieceSize: 0,
VerifiedDeal: false,
@@ -125,7 +160,7 @@ func TestMarketPredicates(t *testing.T) {
ProviderCollateral: big.Zero(),
ClientCollateral: big.Zero(),
}
newProps := map[abi.DealID]*market2.DealProposal{
newProps := map[abi.DealID]*market0.DealProposal{
abi.DealID(1): oldProp1, // 1 was persisted
// prop 2 was removed
abi.DealID(3): newProp3, // new
@@ -142,14 +177,14 @@ func TestMarketPredicates(t *testing.T) {
minerAddr, err := address.NewFromString("t00")
require.NoError(t, err)
oldState, err := test.MockTipset(minerAddr, 1)
oldState, err := mockTipset(minerAddr, 1)
require.NoError(t, err)
newState, err := test.MockTipset(minerAddr, 2)
newState, err := mockTipset(minerAddr, 2)
require.NoError(t, err)
api := test.NewMockAPI(bs)
api.SetActor(oldState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: oldStateC})
api.SetActor(newState.Key(), &types.Actor{Code: builtin2.StorageMarketActorCodeID, Head: newStateC})
api := newMockAPI(bs)
api.setActor(oldState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: oldStateC})
api.setActor(newState.Key(), &types.Actor{Code: builtin0.StorageMarketActorCodeID, Head: newStateC})
t.Run("deal ID predicate", func(t *testing.T) {
preds := NewStatePredicates(api)
@@ -204,11 +239,11 @@ func TestMarketPredicates(t *testing.T) {
t.Fatal("No state change so this should not be called")
return false, nil, nil
})
marketState0 := test.CreateEmptyMarketState(t, store)
marketState0 := createEmptyMarketState(t, store)
marketCid, err := store.Put(ctx, marketState0)
require.NoError(t, err)
marketState, err := market.Load(store, &types.Actor{
Code: builtin2.StorageMarketActorCodeID,
Code: builtin0.StorageMarketActorCodeID,
Head: marketCid,
})
require.NoError(t, err)
@@ -317,11 +352,11 @@ func TestMarketPredicates(t *testing.T) {
t.Fatal("No state change so this should not be called")
return false, nil, nil
})
marketState0 := test.CreateEmptyMarketState(t, store)
marketState0 := createEmptyMarketState(t, store)
marketCid, err := store.Put(ctx, marketState0)
require.NoError(t, err)
marketState, err := market.Load(store, &types.Actor{
Code: builtin2.StorageMarketActorCodeID,
Code: builtin0.StorageMarketActorCodeID,
Head: marketCid,
})
require.NoError(t, err)
@@ -335,7 +370,7 @@ func TestMarketPredicates(t *testing.T) {
func TestMinerSectorChange(t *testing.T) {
ctx := context.Background()
bs := bstore.NewTemporarySync()
store := adt2.WrapStore(ctx, cbornode.NewCborStore(bs))
store := adt.WrapStore(ctx, cbornode.NewCborStore(bs))
nextID := uint64(0)
nextIDAddrF := func() address.Address {
@@ -344,12 +379,12 @@ func TestMinerSectorChange(t *testing.T) {
}
owner, worker := nextIDAddrF(), nextIDAddrF()
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner2.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner2.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner2.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
si0 := newSectorOnChainInfo(0, tutils.MakeCID("0", &miner0.SealedCIDPrefix), big.NewInt(0), abi.ChainEpoch(0), abi.ChainEpoch(10))
si1 := newSectorOnChainInfo(1, tutils.MakeCID("1", &miner0.SealedCIDPrefix), big.NewInt(1), abi.ChainEpoch(1), abi.ChainEpoch(11))
si2 := newSectorOnChainInfo(2, tutils.MakeCID("2", &miner0.SealedCIDPrefix), big.NewInt(2), abi.ChainEpoch(2), abi.ChainEpoch(11))
oldMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si0, si1, si2})
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner2.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
si3 := newSectorOnChainInfo(3, tutils.MakeCID("3", &miner0.SealedCIDPrefix), big.NewInt(3), abi.ChainEpoch(3), abi.ChainEpoch(12))
// 0 delete
// 1 extend
// 2 same
@@ -359,14 +394,14 @@ func TestMinerSectorChange(t *testing.T) {
newMinerC := createMinerState(ctx, t, store, owner, worker, []miner.SectorOnChainInfo{si1Ext, si2, si3})
minerAddr := nextIDAddrF()
oldState, err := test.MockTipset(minerAddr, 1)
oldState, err := mockTipset(minerAddr, 1)
require.NoError(t, err)
newState, err := test.MockTipset(minerAddr, 2)
newState, err := mockTipset(minerAddr, 2)
require.NoError(t, err)
api := test.NewMockAPI(bs)
api.SetActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin2.StorageMinerActorCodeID})
api.SetActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin2.StorageMinerActorCodeID})
api := newMockAPI(bs)
api.setActor(oldState.Key(), &types.Actor{Head: oldMinerC, Code: builtin0.StorageMinerActorCodeID})
api.setActor(newState.Key(), &types.Actor{Head: newMinerC, Code: builtin0.StorageMinerActorCodeID})
preds := NewStatePredicates(api)
@@ -414,16 +449,29 @@ func TestMinerSectorChange(t *testing.T) {
require.Equal(t, si1Ext, sectorChanges.Extended[0].From)
}
func mockTipset(minerAddr address.Address, timestamp uint64) (*types.TipSet, error) {
return types.NewTipSet([]*types.BlockHeader{{
Miner: minerAddr,
Height: 5,
ParentStateRoot: dummyCid,
Messages: dummyCid,
ParentMessageReceipts: dummyCid,
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
Timestamp: timestamp,
}})
}
type balance struct {
available abi.TokenAmount
locked abi.TokenAmount
}
func createMarketState(ctx context.Context, t *testing.T, store adt2.Store, deals map[abi.DealID]*market2.DealState, props map[abi.DealID]*market2.DealProposal, balances map[address.Address]balance) cid.Cid {
dealRootCid := test.CreateDealAMT(ctx, t, store, deals)
func createMarketState(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState, props map[abi.DealID]*market0.DealProposal, balances map[address.Address]balance) cid.Cid {
dealRootCid := createDealAMT(ctx, t, store, deals)
propRootCid := createProposalAMT(ctx, t, store, props)
balancesCids := createBalanceTable(ctx, t, store, balances)
state := test.CreateEmptyMarketState(t, store)
state := createEmptyMarketState(t, store)
state.States = dealRootCid
state.Proposals = propRootCid
state.EscrowTable = balancesCids[0]
@@ -434,8 +482,27 @@ func createMarketState(ctx context.Context, t *testing.T, store adt2.Store, deal
return stateC
}
func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, props map[abi.DealID]*market2.DealProposal) cid.Cid {
root := adt2.MakeEmptyArray(store)
func createEmptyMarketState(t *testing.T, store adt.Store) *market0.State {
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
require.NoError(t, err)
emptyMap, err := adt.MakeEmptyMap(store).Root()
require.NoError(t, err)
return market0.ConstructState(emptyArrayCid, emptyMap, emptyMap)
}
func createDealAMT(ctx context.Context, t *testing.T, store adt.Store, deals map[abi.DealID]*market0.DealState) cid.Cid {
root := adt.MakeEmptyArray(store)
for dealID, dealState := range deals {
err := root.Set(uint64(dealID), dealState)
require.NoError(t, err)
}
rootCid, err := root.Root()
require.NoError(t, err)
return rootCid
}
func createProposalAMT(ctx context.Context, t *testing.T, store adt.Store, props map[abi.DealID]*market0.DealProposal) cid.Cid {
root := adt.MakeEmptyArray(store)
for dealID, prop := range props {
err := root.Set(uint64(dealID), prop)
require.NoError(t, err)
@@ -445,16 +512,16 @@ func createProposalAMT(ctx context.Context, t *testing.T, store adt2.Store, prop
return rootCid
}
func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, balances map[address.Address]balance) [2]cid.Cid {
escrowMapRoot := adt2.MakeEmptyMap(store)
func createBalanceTable(ctx context.Context, t *testing.T, store adt.Store, balances map[address.Address]balance) [2]cid.Cid {
escrowMapRoot := adt.MakeEmptyMap(store)
escrowMapRootCid, err := escrowMapRoot.Root()
require.NoError(t, err)
escrowRoot, err := adt2.AsBalanceTable(store, escrowMapRootCid)
escrowRoot, err := adt.AsBalanceTable(store, escrowMapRootCid)
require.NoError(t, err)
lockedMapRoot := adt2.MakeEmptyMap(store)
lockedMapRoot := adt.MakeEmptyMap(store)
lockedMapRootCid, err := lockedMapRoot.Root()
require.NoError(t, err)
lockedRoot, err := adt2.AsBalanceTable(store, lockedMapRootCid)
lockedRoot, err := adt.AsBalanceTable(store, lockedMapRootCid)
require.NoError(t, err)
for addr, balance := range balances {
@@ -471,7 +538,7 @@ func createBalanceTable(ctx context.Context, t *testing.T, store adt2.Store, bal
return [2]cid.Cid{escrowRootCid, lockedRootCid}
}
func createMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
func createMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address, sectors []miner.SectorOnChainInfo) cid.Cid {
rootCid := createSectorsAMT(ctx, t, store, sectors)
state := createEmptyMinerState(ctx, t, store, owner, worker)
@@ -482,20 +549,20 @@ func createMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner
return stateC
}
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store, owner, worker address.Address) *miner2.State {
emptyArrayCid, err := adt2.MakeEmptyArray(store).Root()
func createEmptyMinerState(ctx context.Context, t *testing.T, store adt.Store, owner, worker address.Address) *miner0.State {
emptyArrayCid, err := adt.MakeEmptyArray(store).Root()
require.NoError(t, err)
emptyMap, err := adt2.MakeEmptyMap(store).Root()
emptyMap, err := adt.MakeEmptyMap(store).Root()
require.NoError(t, err)
emptyDeadline, err := store.Put(store.Context(), miner2.ConstructDeadline(emptyArrayCid))
emptyDeadline, err := store.Put(store.Context(), miner0.ConstructDeadline(emptyArrayCid))
require.NoError(t, err)
emptyVestingFunds := miner2.ConstructVestingFunds()
emptyVestingFunds := miner0.ConstructVestingFunds()
emptyVestingFundsCid, err := store.Put(store.Context(), emptyVestingFunds)
require.NoError(t, err)
emptyDeadlines := miner2.ConstructDeadlines(emptyDeadline)
emptyDeadlines := miner0.ConstructDeadlines(emptyDeadline)
emptyDeadlinesCid, err := store.Put(store.Context(), emptyDeadlines)
require.NoError(t, err)
@@ -505,30 +572,16 @@ func createEmptyMinerState(ctx context.Context, t *testing.T, store adt2.Store,
emptyBitfieldCid, err := store.Put(store.Context(), emptyBitfield)
require.NoError(t, err)
state, err := miner2.ConstructState(minerInfo, 123, 4, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
state, err := miner0.ConstructState(minerInfo, 123, emptyBitfieldCid, emptyArrayCid, emptyMap, emptyDeadlinesCid, emptyVestingFundsCid)
require.NoError(t, err)
return state
}
func createSectorsAMT(ctx context.Context, t *testing.T, store adt2.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
root := adt2.MakeEmptyArray(store)
func createSectorsAMT(ctx context.Context, t *testing.T, store adt.Store, sectors []miner.SectorOnChainInfo) cid.Cid {
root := adt.MakeEmptyArray(store)
for _, sector := range sectors {
sector := miner2.SectorOnChainInfo{
SectorNumber: sector.SectorNumber,
SealProof: sector.SealProof,
SealedCID: sector.SealedCID,
DealIDs: sector.DealIDs,
Activation: sector.Activation,
Expiration: sector.Expiration,
DealWeight: sector.DealWeight,
VerifiedDealWeight: sector.VerifiedDealWeight,
InitialPledge: sector.InitialPledge,
ExpectedDayReward: sector.ExpectedDayReward,
ExpectedStoragePledge: sector.ExpectedStoragePledge,
ReplacedSectorAge: 0,
ReplacedDayReward: big.NewInt(0),
}
sector := (miner0.SectorOnChainInfo)(sector)
err := root.Set(uint64(sector.SectorNumber), &sector)
require.NoError(t, err)
}
@@ -561,8 +614,8 @@ const (
)
// returns a unique SectorPreCommitInfo with each invocation with SectorNumber set to `sectorNo`.
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner2.SectorPreCommitInfo {
return &miner2.SectorPreCommitInfo{
func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiration abi.ChainEpoch) *miner0.SectorPreCommitInfo {
return &miner0.SectorPreCommitInfo{
SealProof: abi.RegisteredSealProof_StackedDrg32GiBV1,
SectorNumber: sectorNo,
SealedCID: sealed,
@@ -572,7 +625,7 @@ func newSectorPreCommitInfo(sectorNo abi.SectorNumber, sealed cid.Cid, expiratio
}
}
func dealEquality(expected market2.DealState, actual market.DealState) bool {
func dealEquality(expected market0.DealState, actual market.DealState) bool {
return expected.LastUpdatedEpoch == actual.LastUpdatedEpoch &&
expected.SectorStartEpoch == actual.SectorStartEpoch &&
expected.SlashEpoch == actual.SlashEpoch
+3 -3
View File
@@ -34,11 +34,11 @@ func (me *messageEvents) CheckMsg(ctx context.Context, smsg types.ChainMsg, hnd
}
func (me *messageEvents) MatchMsg(inmsg *types.Message) MsgMatchFunc {
return func(msg *types.Message) (matched bool, err error) {
return func(msg *types.Message) (matchOnce bool, matched bool, err error) {
if msg.From == inmsg.From && msg.Nonce == inmsg.Nonce && !inmsg.Equals(msg) {
return false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
return true, false, xerrors.Errorf("matching msg %s from %s, nonce %d: got duplicate origin/nonce msg %d", inmsg.Cid(), inmsg.From, inmsg.Nonce, msg.Nonce)
}
return inmsg.Equals(msg), nil
return true, inmsg.Equals(msg), nil
}
}
+16 -25
View File
@@ -4,16 +4,17 @@ import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"sync/atomic"
"time"
"github.com/filecoin-project/specs-actors/actors/runtime/proof"
"github.com/google/uuid"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/google/uuid"
block "github.com/ipfs/go-block-format"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
@@ -25,8 +26,6 @@ import (
"go.opencensus.io/trace"
"golang.org/x/xerrors"
proof2 "github.com/filecoin-project/specs-actors/v2/actors/runtime/proof"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors/policy"
@@ -51,7 +50,7 @@ const msgsPerBlock = 20
//nolint:deadcode,varcheck
var log = logging.Logger("gen")
var ValidWpostForTesting = []proof2.PoStProof{{
var ValidWpostForTesting = []proof.PoStProof{{
ProofBytes: []byte("valid proof"),
}}
@@ -139,20 +138,12 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return nil, xerrors.Errorf("failed to get metadata datastore: %w", err)
}
bs, err := lr.Blockstore(repo.BlockstoreChain)
bds, err := lr.Datastore("/chain")
if err != nil {
return nil, err
return nil, xerrors.Errorf("failed to get blocks datastore: %w", err)
}
defer func() {
if c, ok := bs.(io.Closer); ok {
if err := c.Close(); err != nil {
log.Warnf("failed to close blockstore: %s", err)
}
}
}()
bs = mybs{bs}
bs := mybs{blockstore.NewBlockstore(bds)}
ks, err := lr.KeyStore()
if err != nil {
@@ -164,14 +155,14 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
}
banker, err := w.WalletNew(context.Background(), types.KTSecp256k1)
banker, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
return nil, xerrors.Errorf("failed to generate banker key: %w", err)
}
receievers := make([]address.Address, msgsPerBlock)
for r := range receievers {
receievers[r], err = w.WalletNew(context.Background(), types.KTBLS)
receievers[r], err = w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil {
return nil, xerrors.Errorf("failed to generate receiver key: %w", err)
}
@@ -245,7 +236,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return nil, xerrors.Errorf("make genesis block failed: %w", err)
}
cs := store.NewChainStore(bs, bs, ds, sys, j)
cs := store.NewChainStore(bs, ds, sys, j)
genfb := &types.FullBlock{Header: genb.Genesis}
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
@@ -476,7 +467,7 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners
func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticket *types.Ticket,
eticket *types.ElectionProof, bvals []types.BeaconEntry, height abi.ChainEpoch,
wpost []proof2.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
wpost []proof.PoStProof, msgs []*types.SignedMessage) (*types.FullBlock, error) {
var ts uint64
if cg.Timestamper != nil {
@@ -614,7 +605,7 @@ func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*cr
type WinningPoStProver interface {
GenerateCandidates(context.Context, abi.PoStRandomness, uint64) ([]uint64, error)
ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error)
ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error)
}
type wppProvider struct{}
@@ -623,7 +614,7 @@ func (wpp *wppProvider) GenerateCandidates(ctx context.Context, _ abi.PoStRandom
return []uint64{0}, nil
}
func (wpp *wppProvider) ComputeProof(context.Context, []proof2.SectorInfo, abi.PoStRandomness) ([]proof2.PoStProof, error) {
func (wpp *wppProvider) ComputeProof(context.Context, []proof.SectorInfo, abi.PoStRandomness) ([]proof.PoStProof, error) {
return ValidWpostForTesting, nil
}
@@ -690,15 +681,15 @@ type genFakeVerifier struct{}
var _ ffiwrapper.Verifier = (*genFakeVerifier)(nil)
func (m genFakeVerifier) VerifySeal(svi proof2.SealVerifyInfo) (bool, error) {
func (m genFakeVerifier) VerifySeal(svi proof.SealVerifyInfo) (bool, error) {
return true, nil
}
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof2.WinningPoStVerifyInfo) (bool, error) {
func (m genFakeVerifier) VerifyWinningPoSt(ctx context.Context, info proof.WinningPoStVerifyInfo) (bool, error) {
panic("not supported")
}
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof2.WindowPoStVerifyInfo) (bool, error) {
func (m genFakeVerifier) VerifyWindowPoSt(ctx context.Context, info proof.WindowPoStVerifyInfo) (bool, error) {
panic("not supported")
}
+1 -1
View File
@@ -482,7 +482,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
}
// temp chainstore
cs := store.NewChainStore(bs, bs, datastore.NewMapDatastore(), sys, j)
cs := store.NewChainStore(bs, datastore.NewMapDatastore(), sys, j)
// Verify PreSealed Data
stateroot, err = VerifyPreSealedData(ctx, cs, stateroot, template, keyIDs)
+15 -16
View File
@@ -24,12 +24,11 @@ import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin"
miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
power0 "github.com/filecoin-project/specs-actors/actors/builtin/power"
reward0 "github.com/filecoin-project/specs-actors/actors/builtin/reward"
runtime2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
@@ -48,7 +47,7 @@ func MinerAddress(genesisIndex uint64) address.Address {
}
type fakedSigSyscalls struct {
runtime2.Syscalls
runtime.Syscalls
}
func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer address.Address, plaintext []byte) error {
@@ -56,9 +55,9 @@ func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer
}
func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
return func(ctx context.Context, rt *vm.Runtime) runtime2.Syscalls {
return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime.Syscalls {
return &fakedSigSyscalls{
base(ctx, rt),
base(ctx, cstate, cst),
}
}
}
@@ -115,7 +114,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
}
params := mustEnc(constructorParams)
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin0.MethodsPower.CreateMiner, params)
rval, err := doExecValue(ctx, vm, power.Address, m.Owner, m.PowerBalance, builtin.MethodsPower.CreateMiner, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
}
@@ -147,7 +146,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
if m.MarketBalance.GreaterThan(big.Zero()) {
params := mustEnc(&minerInfos[i].maddr)
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin0.MethodsMarket.AddBalance, params)
_, err := doExecValue(ctx, vm, market.Address, m.Worker, m.MarketBalance, builtin.MethodsMarket.AddBalance, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner (add balance): %w", err)
}
@@ -159,7 +158,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
publish := func(params *market.PublishStorageDealsParams) error {
fmt.Printf("publishing %d storage deals on miner %s with worker %s\n", len(params.Deals), params.Deals[0].Proposal.Provider, m.Worker)
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin0.MethodsMarket.PublishStorageDeals, mustEnc(params))
ret, err := doExecValue(ctx, vm, market.Address, m.Worker, big.Zero(), builtin.MethodsMarket.PublishStorageDeals, mustEnc(params))
if err != nil {
return xerrors.Errorf("failed to create genesis miner (publish deals): %w", err)
}
@@ -291,17 +290,17 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
pledge = big.Add(pcd, pledge)
fmt.Println(types.FIL(pledge))
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin0.MethodsMiner.PreCommitSector, mustEnc(params))
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, m.Worker, pledge, builtin.MethodsMiner.PreCommitSector, mustEnc(params))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
}
// Commit one-by-one, otherwise pledge math tends to explode
confirmParams := &builtin0.ConfirmSectorProofsParams{
confirmParams := &builtin.ConfirmSectorProofsParams{
Sectors: []abi.SectorNumber{preseal.SectorID},
}
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin0.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
_, err = doExecValue(ctx, vm, minerInfos[i].maddr, power.Address, big.Zero(), builtin.MethodsMiner.ConfirmSectorProofsValid, mustEnc(confirmParams))
if err != nil {
return cid.Undef, xerrors.Errorf("failed to confirm presealed sectors: %w", err)
}
@@ -350,7 +349,7 @@ func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization cry
}
func currentTotalPower(ctx context.Context, vm *vm.VM, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin0.MethodsPower.CurrentTotalPower, nil)
pwret, err := doExecValue(ctx, vm, power.Address, maddr, big.Zero(), builtin.MethodsPower.CurrentTotalPower, nil)
if err != nil {
return nil, err
}
@@ -374,7 +373,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
market.Address,
maddr,
abi.NewTokenAmount(0),
builtin0.MethodsMarket.VerifyDealsForActivation,
builtin.MethodsMarket.VerifyDealsForActivation,
mustEnc(params),
)
if err != nil {
@@ -388,7 +387,7 @@ func dealWeight(ctx context.Context, vm *vm.VM, maddr address.Address, dealIDs [
}
func currentEpochBlockReward(ctx context.Context, vm *vm.VM, maddr address.Address) (*reward0.ThisEpochRewardReturn, error) {
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin0.MethodsReward.ThisEpochReward, nil)
rwret, err := doExecValue(ctx, vm, reward.Address, maddr, big.Zero(), builtin.MethodsReward.ThisEpochReward, nil)
if err != nil {
return nil, err
}
@@ -406,7 +405,7 @@ func circSupply(ctx context.Context, vmi *vm.VM, maddr address.Address) abi.Toke
rt := unsafeVM.MakeRuntime(ctx, &types.Message{
GasLimit: 1_000_000_000,
From: maddr,
})
}, maddr, 0, 0, 0)
return rt.TotalFilCircSupply()
}
+6 -21
View File
@@ -50,27 +50,12 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
return ret.Return, nil
}
// TODO: Get from build
// TODO: make a list/schedule of these.
var GenesisNetworkVersion = func() network.Version {
// returns the version _before_ the first upgrade.
if build.UpgradeBreezeHeight >= 0 {
return network.Version0
}
if build.UpgradeSmokeHeight >= 0 {
return network.Version1
}
if build.UpgradeIgnitionHeight >= 0 {
return network.Version2
}
if build.UpgradeActorsV2Height >= 0 {
return network.Version3
}
if build.UpgradeLiftoffHeight >= 0 {
return network.Version3
}
return build.ActorUpgradeNetworkVersion - 1 // genesis requires actors v0.
}()
var GenesisNetworkVersion = func() network.Version { // TODO: Get from build/
if build.UseNewestNetwork() { // TODO: Get from build/
return build.NewestNetworkVersion // TODO: Get from build/
} // TODO: Get from build/
return network.Version1 // TODO: Get from build/
}() // TODO: Get from build/
func genesisNetworkVersion(context.Context, abi.ChainEpoch) network.Version { // TODO: Get from build/
return GenesisNetworkVersion // TODO: Get from build/
+19 -10
View File
@@ -4,14 +4,17 @@ import (
"context"
"github.com/filecoin-project/go-state-types/crypto"
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/specs-actors/actors/util/adt"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/lib/sigs/bls"
)
@@ -27,12 +30,7 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA
return nil, xerrors.Errorf("failed to load tipset state: %w", err)
}
_, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, sm, pts, bt.Epoch)
if err != nil {
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
}
worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, lbst, bt.Miner)
worker, err := stmgr.GetMinerWorkerRaw(ctx, sm, st, bt.Miner)
if err != nil {
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
}
@@ -116,12 +114,23 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA
}
next.ParentBaseFee = baseFee
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
tree, err := state.LoadStateTree(cst, st)
if err != nil {
return nil, xerrors.Errorf("failed to load state tree: %w", err)
}
waddr, err := vm.ResolveToKeyAddr(tree, cst, worker)
if err != nil {
return nil, xerrors.Errorf("failed to resolve miner address to key address: %w", err)
}
nosigbytes, err := next.SigningBytes()
if err != nil {
return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err)
}
sig, err := w.WalletSign(ctx, worker, nosigbytes, api.MsgMeta{
sig, err := w.WalletSign(ctx, waddr, nosigbytes, api.MsgMeta{
Type: api.MTBlock,
})
if err != nil {
@@ -172,8 +181,8 @@ func aggregateSignatures(sigs []crypto.Signature) (*crypto.Signature, error) {
}, nil
}
func toArray(store blockadt.Store, cids []cid.Cid) (cid.Cid, error) {
arr := blockadt.MakeEmptyArray(store)
func toArray(store adt.Store, cids []cid.Cid) (cid.Cid, error) {
arr := adt.MakeEmptyArray(store)
for i, c := range cids {
oc := cbg.CborCid(c)
if err := arr.Set(uint64(i), &oc); err != nil {
-112
View File
@@ -1,112 +0,0 @@
// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
package market
import (
"fmt"
"io"
cbg "github.com/whyrusleeping/cbor-gen"
xerrors "golang.org/x/xerrors"
)
var _ = xerrors.Errorf
var lengthBufFundedAddressState = []byte{131}
func (t *FundedAddressState) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
if _, err := w.Write(lengthBufFundedAddressState); err != nil {
return err
}
scratch := make([]byte, 9)
// t.Addr (address.Address) (struct)
if err := t.Addr.MarshalCBOR(w); err != nil {
return err
}
// t.AmtReserved (big.Int) (struct)
if err := t.AmtReserved.MarshalCBOR(w); err != nil {
return err
}
// t.MsgCid (cid.Cid) (struct)
if t.MsgCid == nil {
if _, err := w.Write(cbg.CborNull); err != nil {
return err
}
} else {
if err := cbg.WriteCidBuf(scratch, w, *t.MsgCid); err != nil {
return xerrors.Errorf("failed to write cid field t.MsgCid: %w", err)
}
}
return nil
}
func (t *FundedAddressState) UnmarshalCBOR(r io.Reader) error {
*t = FundedAddressState{}
br := cbg.GetPeeker(r)
scratch := make([]byte, 8)
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
if err != nil {
return err
}
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.Addr (address.Address) (struct)
{
if err := t.Addr.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.Addr: %w", err)
}
}
// t.AmtReserved (big.Int) (struct)
{
if err := t.AmtReserved.UnmarshalCBOR(br); err != nil {
return xerrors.Errorf("unmarshaling t.AmtReserved: %w", err)
}
}
// t.MsgCid (cid.Cid) (struct)
{
b, err := br.ReadByte()
if err != nil {
return err
}
if b != cbg.CborNull[0] {
if err := br.UnreadByte(); err != nil {
return err
}
c, err := cbg.ReadCid(br)
if err != nil {
return xerrors.Errorf("failed to read cid field t.MsgCid: %w", err)
}
t.MsgCid = &c
}
}
return nil
}
-707
View File
@@ -1,707 +0,0 @@
package market
import (
"context"
"sync"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl/full"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log"
"go.uber.org/fx"
"golang.org/x/xerrors"
)
var log = logging.Logger("market_adapter")
// API is the fx dependencies need to run a fund manager
type FundManagerAPI struct {
fx.In
full.StateAPI
full.MpoolAPI
}
// fundManagerAPI is the specific methods called by the FundManager
// (used by the tests)
type fundManagerAPI interface {
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error)
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error)
}
// FundManager keeps track of funds in a set of addresses
type FundManager struct {
ctx context.Context
shutdown context.CancelFunc
api fundManagerAPI
str *Store
lk sync.Mutex
fundedAddrs map[address.Address]*fundedAddress
}
func NewFundManager(lc fx.Lifecycle, api FundManagerAPI, ds dtypes.MetadataDS) *FundManager {
fm := newFundManager(&api, ds)
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
return fm.Start()
},
OnStop: func(ctx context.Context) error {
fm.Stop()
return nil
},
})
return fm
}
// newFundManager is used by the tests
func newFundManager(api fundManagerAPI, ds datastore.Batching) *FundManager {
ctx, cancel := context.WithCancel(context.Background())
return &FundManager{
ctx: ctx,
shutdown: cancel,
api: api,
str: newStore(ds),
fundedAddrs: make(map[address.Address]*fundedAddress),
}
}
func (fm *FundManager) Stop() {
fm.shutdown()
}
func (fm *FundManager) Start() error {
fm.lk.Lock()
defer fm.lk.Unlock()
// TODO:
// To save memory:
// - in State() only load addresses with in-progress messages
// - load the others just-in-time from getFundedAddress
// - delete(fm.fundedAddrs, addr) when the queue has been processed
return fm.str.forEach(func(state *FundedAddressState) {
fa := newFundedAddress(fm, state.Addr)
fa.state = state
fm.fundedAddrs[fa.state.Addr] = fa
fa.start()
})
}
// Creates a fundedAddress if it doesn't already exist, and returns it
func (fm *FundManager) getFundedAddress(addr address.Address) *fundedAddress {
fm.lk.Lock()
defer fm.lk.Unlock()
fa, ok := fm.fundedAddrs[addr]
if !ok {
fa = newFundedAddress(fm, addr)
fm.fundedAddrs[addr] = fa
}
return fa
}
// Reserve adds amt to `reserved`. If there are not enough available funds for
// the address, submits a message on chain to top up available funds.
// Returns the cid of the message that was submitted on chain, or cid.Undef if
// the required funds were already available.
func (fm *FundManager) Reserve(ctx context.Context, wallet, addr address.Address, amt abi.TokenAmount) (cid.Cid, error) {
return fm.getFundedAddress(addr).reserve(ctx, wallet, amt)
}
// Subtract from `reserved`.
func (fm *FundManager) Release(addr address.Address, amt abi.TokenAmount) error {
return fm.getFundedAddress(addr).release(amt)
}
// Withdraw unreserved funds. Only succeeds if there are enough unreserved
// funds for the address.
// Returns the cid of the message that was submitted on chain.
func (fm *FundManager) Withdraw(ctx context.Context, wallet, addr address.Address, amt abi.TokenAmount) (cid.Cid, error) {
return fm.getFundedAddress(addr).withdraw(ctx, wallet, amt)
}
// FundedAddressState keeps track of the state of an address with funds in the
// datastore
type FundedAddressState struct {
Addr address.Address
// AmtReserved is the amount that must be kept in the address (cannot be
// withdrawn)
AmtReserved abi.TokenAmount
// MsgCid is the cid of an in-progress on-chain message
MsgCid *cid.Cid
}
// fundedAddress keeps track of the state and request queues for a
// particular address
type fundedAddress struct {
ctx context.Context
env *fundManagerEnvironment
str *Store
lk sync.Mutex
state *FundedAddressState
// Note: These request queues are ephemeral, they are not saved to store
reservations []*fundRequest
releases []*fundRequest
withdrawals []*fundRequest
// Used by the tests
onProcessStartListener func() bool
}
func newFundedAddress(fm *FundManager, addr address.Address) *fundedAddress {
return &fundedAddress{
ctx: fm.ctx,
env: &fundManagerEnvironment{api: fm.api},
str: fm.str,
state: &FundedAddressState{
Addr: addr,
AmtReserved: abi.NewTokenAmount(0),
},
}
}
// If there is an in-progress on-chain message, don't submit any more messages
// on chain until it completes
func (a *fundedAddress) start() {
a.lk.Lock()
defer a.lk.Unlock()
if a.state.MsgCid != nil {
a.debugf("restart: wait for %s", a.state.MsgCid)
a.startWaitForResults(*a.state.MsgCid)
}
}
func (a *fundedAddress) reserve(ctx context.Context, wallet address.Address, amt abi.TokenAmount) (cid.Cid, error) {
return a.requestAndWait(ctx, wallet, amt, &a.reservations)
}
func (a *fundedAddress) release(amt abi.TokenAmount) error {
_, err := a.requestAndWait(context.Background(), address.Undef, amt, &a.releases)
return err
}
func (a *fundedAddress) withdraw(ctx context.Context, wallet address.Address, amt abi.TokenAmount) (cid.Cid, error) {
return a.requestAndWait(ctx, wallet, amt, &a.withdrawals)
}
func (a *fundedAddress) requestAndWait(ctx context.Context, wallet address.Address, amt abi.TokenAmount, reqs *[]*fundRequest) (cid.Cid, error) {
// Create a request and add it to the request queue
req := newFundRequest(ctx, wallet, amt)
a.lk.Lock()
*reqs = append(*reqs, req)
a.lk.Unlock()
// Process the queue
go a.process()
// Wait for the results
select {
case <-ctx.Done():
return cid.Undef, ctx.Err()
case r := <-req.Result:
return r.msgCid, r.err
}
}
// Used by the tests
func (a *fundedAddress) onProcessStart(fn func() bool) {
a.lk.Lock()
defer a.lk.Unlock()
a.onProcessStartListener = fn
}
// Process queued requests
func (a *fundedAddress) process() {
a.lk.Lock()
defer a.lk.Unlock()
// Used by the tests
if a.onProcessStartListener != nil {
done := a.onProcessStartListener()
if !done {
return
}
a.onProcessStartListener = nil
}
// Check if we're still waiting for the response to a message
if a.state.MsgCid != nil {
return
}
// Check if there's anything to do
haveReservations := len(a.reservations) > 0 || len(a.releases) > 0
haveWithdrawals := len(a.withdrawals) > 0
if !haveReservations && !haveWithdrawals {
return
}
// Process reservations / releases
if haveReservations {
res, err := a.processReservations(a.reservations, a.releases)
if err == nil {
a.applyStateChange(res.msgCid, res.amtReserved)
}
a.reservations = filterOutProcessedReqs(a.reservations)
a.releases = filterOutProcessedReqs(a.releases)
}
// If there was no message sent on chain by adding reservations, and all
// reservations have completed processing, process withdrawals
if haveWithdrawals && a.state.MsgCid == nil && len(a.reservations) == 0 {
withdrawalCid, err := a.processWithdrawals(a.withdrawals)
if err == nil && withdrawalCid != cid.Undef {
a.applyStateChange(&withdrawalCid, types.EmptyInt)
}
a.withdrawals = filterOutProcessedReqs(a.withdrawals)
}
// If a message was sent on-chain
if a.state.MsgCid != nil {
// Start waiting for results of message (async)
a.startWaitForResults(*a.state.MsgCid)
}
// Process any remaining queued requests
go a.process()
}
// Filter out completed requests
func filterOutProcessedReqs(reqs []*fundRequest) []*fundRequest {
filtered := make([]*fundRequest, 0, len(reqs))
for _, req := range reqs {
if !req.Completed() {
filtered = append(filtered, req)
}
}
return filtered
}
// Apply the results of processing queues and save to the datastore
func (a *fundedAddress) applyStateChange(msgCid *cid.Cid, amtReserved abi.TokenAmount) {
a.state.MsgCid = msgCid
if !amtReserved.Nil() {
a.state.AmtReserved = amtReserved
}
a.saveState()
}
// Clear the pending message cid so that a new message can be sent
func (a *fundedAddress) clearWaitState() {
a.state.MsgCid = nil
a.saveState()
}
// Save state to datastore
func (a *fundedAddress) saveState() {
// Not much we can do if saving to the datastore fails, just log
err := a.str.save(a.state)
if err != nil {
log.Errorf("saving state to store for addr %s: %w", a.state.Addr, err)
}
}
// The result of processing the reservation / release queues
type processResult struct {
// Requests that completed without adding funds
covered []*fundRequest
// Requests that added funds
added []*fundRequest
// The new reserved amount
amtReserved abi.TokenAmount
// The message cid, if a message was submitted on-chain
msgCid *cid.Cid
}
// process reservations and releases, and return the resulting changes to state
func (a *fundedAddress) processReservations(reservations []*fundRequest, releases []*fundRequest) (pr *processResult, prerr error) {
// When the function returns
defer func() {
// If there's an error, mark all requests as errored
if prerr != nil {
for _, req := range append(reservations, releases...) {
req.Complete(cid.Undef, prerr)
}
return
}
// Complete all release requests
for _, req := range releases {
req.Complete(cid.Undef, nil)
}
// Complete all requests that were covered by released amounts
for _, req := range pr.covered {
req.Complete(cid.Undef, nil)
}
// If a message was sent
if pr.msgCid != nil {
// Complete all add funds requests
for _, req := range pr.added {
req.Complete(*pr.msgCid, nil)
}
}
}()
// Split reservations into those that are covered by released amounts,
// and those to add to the reserved amount.
// Note that we process requests from the same wallet in batches. So some
// requests may not be included in covered if they don't match the first
// covered request's wallet. These will be processed on a subsequent
// invocation of processReservations.
toCancel, toAdd, reservedDelta := splitReservations(reservations, releases)
// Apply the reserved delta to the reserved amount
reserved := types.BigAdd(a.state.AmtReserved, reservedDelta)
if reserved.LessThan(abi.NewTokenAmount(0)) {
reserved = abi.NewTokenAmount(0)
}
res := &processResult{
amtReserved: reserved,
covered: toCancel,
}
// Work out the amount to add to the balance
amtToAdd := abi.NewTokenAmount(0)
if len(toAdd) > 0 && reserved.GreaterThan(abi.NewTokenAmount(0)) {
// Get available funds for address
avail, err := a.env.AvailableFunds(a.ctx, a.state.Addr)
if err != nil {
return res, err
}
// amount to add = new reserved amount - available
amtToAdd = types.BigSub(reserved, avail)
a.debugf("reserved %d - avail %d = to add %d", reserved, avail, amtToAdd)
}
// If there's nothing to add to the balance, bail out
if amtToAdd.LessThanEqual(abi.NewTokenAmount(0)) {
res.covered = append(res.covered, toAdd...)
return res, nil
}
// Add funds to address
a.debugf("add funds %d", amtToAdd)
addFundsCid, err := a.env.AddFunds(a.ctx, toAdd[0].Wallet, a.state.Addr, amtToAdd)
if err != nil {
return res, err
}
// Mark reservation requests as complete
res.added = toAdd
// Save the message CID to state
res.msgCid = &addFundsCid
return res, nil
}
// Split reservations into those that are under the total release amount
// (covered) and those that exceed it (to add).
// Note that we process requests from the same wallet in batches. So some
// requests may not be included in covered if they don't match the first
// covered request's wallet.
func splitReservations(reservations []*fundRequest, releases []*fundRequest) ([]*fundRequest, []*fundRequest, abi.TokenAmount) {
toCancel := make([]*fundRequest, 0, len(reservations))
toAdd := make([]*fundRequest, 0, len(reservations))
toAddAmt := abi.NewTokenAmount(0)
// Sum release amounts
releaseAmt := abi.NewTokenAmount(0)
for _, req := range releases {
releaseAmt = types.BigAdd(releaseAmt, req.Amount())
}
// We only want to combine requests that come from the same wallet
batchWallet := address.Undef
for _, req := range reservations {
amt := req.Amount()
// If the amount to add to the reserve is cancelled out by a release
if amt.LessThanEqual(releaseAmt) {
// Cancel the request and update the release total
releaseAmt = types.BigSub(releaseAmt, amt)
toCancel = append(toCancel, req)
continue
}
// The amount to add is greater that the release total so we want
// to send an add funds request
// The first time the wallet will be undefined
if batchWallet == address.Undef {
batchWallet = req.Wallet
}
// If this request's wallet is the same as the batch wallet,
// the requests will be combined
if batchWallet == req.Wallet {
delta := types.BigSub(amt, releaseAmt)
toAddAmt = types.BigAdd(toAddAmt, delta)
releaseAmt = abi.NewTokenAmount(0)
toAdd = append(toAdd, req)
}
}
// The change in the reserved amount is "amount to add" - "amount to release"
reservedDelta := types.BigSub(toAddAmt, releaseAmt)
return toCancel, toAdd, reservedDelta
}
// process withdrawal queue
func (a *fundedAddress) processWithdrawals(withdrawals []*fundRequest) (msgCid cid.Cid, prerr error) {
// If there's an error, mark all withdrawal requests as errored
defer func() {
if prerr != nil {
for _, req := range withdrawals {
req.Complete(cid.Undef, prerr)
}
}
}()
// Get the net available balance
avail, err := a.env.AvailableFunds(a.ctx, a.state.Addr)
if err != nil {
return cid.Undef, err
}
netAvail := types.BigSub(avail, a.state.AmtReserved)
// Fit as many withdrawals as possible into the available balance, and fail
// the rest
withdrawalAmt := abi.NewTokenAmount(0)
allowedAmt := abi.NewTokenAmount(0)
allowed := make([]*fundRequest, 0, len(withdrawals))
var batchWallet address.Address
for _, req := range withdrawals {
amt := req.Amount()
if amt.IsZero() {
// If the context for the request was cancelled, bail out
req.Complete(cid.Undef, err)
continue
}
// If the amount would exceed the available amount, complete the
// request with an error
newWithdrawalAmt := types.BigAdd(withdrawalAmt, amt)
if newWithdrawalAmt.GreaterThan(netAvail) {
err := xerrors.Errorf("insufficient funds for withdrawal of %d", amt)
a.debugf("%s", err)
req.Complete(cid.Undef, err)
continue
}
// If this is the first allowed withdrawal request in this batch, save
// its wallet address
if batchWallet == address.Undef {
batchWallet = req.Wallet
}
// If the request wallet doesn't match the batch wallet, bail out
// (the withdrawal will be processed after the current batch has
// completed)
if req.Wallet != batchWallet {
continue
}
// Include this withdrawal request in the batch
withdrawalAmt = newWithdrawalAmt
a.debugf("withdraw %d", amt)
allowed = append(allowed, req)
allowedAmt = types.BigAdd(allowedAmt, amt)
}
// Check if there is anything to withdraw.
// Note that if the context for a request is cancelled,
// req.Amount() returns zero
if allowedAmt.Equals(abi.NewTokenAmount(0)) {
// Mark allowed requests as complete
for _, req := range allowed {
req.Complete(cid.Undef, nil)
}
return cid.Undef, nil
}
// Withdraw funds
a.debugf("withdraw funds %d", allowedAmt)
withdrawFundsCid, err := a.env.WithdrawFunds(a.ctx, allowed[0].Wallet, a.state.Addr, allowedAmt)
if err != nil {
return cid.Undef, err
}
// Mark allowed requests as complete
for _, req := range allowed {
req.Complete(withdrawFundsCid, nil)
}
// Save the message CID to state
return withdrawFundsCid, nil
}
// asynchonously wait for results of message
func (a *fundedAddress) startWaitForResults(msgCid cid.Cid) {
go func() {
err := a.env.WaitMsg(a.ctx, msgCid)
if err != nil {
// We don't really care about the results here, we're just waiting
// so as to only process one on-chain message at a time
log.Errorf("waiting for results of message %s for addr %s: %w", msgCid, a.state.Addr, err)
}
a.lk.Lock()
a.debugf("complete wait")
a.clearWaitState()
a.lk.Unlock()
a.process()
}()
}
func (a *fundedAddress) debugf(args ...interface{}) {
fmtStr := args[0].(string)
args = args[1:]
log.Debugf(a.state.Addr.String()+": "+fmtStr, args...)
}
// The result of a fund request
type reqResult struct {
msgCid cid.Cid
err error
}
// A request to change funds
type fundRequest struct {
ctx context.Context
amt abi.TokenAmount
completed chan struct{}
Wallet address.Address
Result chan reqResult
}
func newFundRequest(ctx context.Context, wallet address.Address, amt abi.TokenAmount) *fundRequest {
return &fundRequest{
ctx: ctx,
amt: amt,
Wallet: wallet,
Result: make(chan reqResult),
completed: make(chan struct{}),
}
}
// Amount returns zero if the context has expired
func (frp *fundRequest) Amount() abi.TokenAmount {
if frp.ctx.Err() != nil {
return abi.NewTokenAmount(0)
}
return frp.amt
}
// Complete is called with the message CID when the funds request has been
// started or with the error if there was an error
func (frp *fundRequest) Complete(msgCid cid.Cid, err error) {
select {
case <-frp.completed:
case <-frp.ctx.Done():
case frp.Result <- reqResult{msgCid: msgCid, err: err}:
}
close(frp.completed)
}
// Completed indicates if Complete has already been called
func (frp *fundRequest) Completed() bool {
select {
case <-frp.completed:
return true
default:
return false
}
}
// fundManagerEnvironment simplifies some API calls
type fundManagerEnvironment struct {
api fundManagerAPI
}
func (env *fundManagerEnvironment) AvailableFunds(ctx context.Context, addr address.Address) (abi.TokenAmount, error) {
bal, err := env.api.StateMarketBalance(ctx, addr, types.EmptyTSK)
if err != nil {
return abi.NewTokenAmount(0), err
}
return types.BigSub(bal.Escrow, bal.Locked), nil
}
func (env *fundManagerEnvironment) AddFunds(
ctx context.Context,
wallet address.Address,
addr address.Address,
amt abi.TokenAmount,
) (cid.Cid, error) {
params, err := actors.SerializeParams(&addr)
if err != nil {
return cid.Undef, err
}
smsg, aerr := env.api.MpoolPushMessage(ctx, &types.Message{
To: market.Address,
From: wallet,
Value: amt,
Method: market.Methods.AddBalance,
Params: params,
}, nil)
if aerr != nil {
return cid.Undef, aerr
}
return smsg.Cid(), nil
}
func (env *fundManagerEnvironment) WithdrawFunds(
ctx context.Context,
wallet address.Address,
addr address.Address,
amt abi.TokenAmount,
) (cid.Cid, error) {
params, err := actors.SerializeParams(&market.WithdrawBalanceParams{
ProviderOrClientAddress: addr,
Amount: amt,
})
if err != nil {
return cid.Undef, xerrors.Errorf("serializing params: %w", err)
}
smsg, aerr := env.api.MpoolPushMessage(ctx, &types.Message{
To: market.Address,
From: wallet,
Value: types.NewInt(0),
Method: market.Methods.WithdrawBalance,
Params: params,
}, nil)
if aerr != nil {
return cid.Undef, aerr
}
return smsg.Cid(), nil
}
func (env *fundManagerEnvironment) WaitMsg(ctx context.Context, c cid.Cid) error {
_, err := env.api.StateWaitMsg(ctx, c, build.MessageConfidence)
return err
}
-758
View File
@@ -1,758 +0,0 @@
package market
import (
"bytes"
"context"
"sync"
"testing"
"time"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
tutils "github.com/filecoin-project/specs-actors/v2/support/testing"
"github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore"
ds_sync "github.com/ipfs/go-datastore/sync"
"github.com/stretchr/testify/require"
)
// TestFundManagerBasic verifies that the basic fund manager operations work
func TestFundManagerBasic(t *testing.T) {
s := setup(t)
defer s.fm.Stop()
// Reserve 10
// balance: 0 -> 10
// reserved: 0 -> 10
amt := abi.NewTokenAmount(10)
sentinel, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
msg := s.mockApi.getSentMessage(sentinel)
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
s.mockApi.completeMsg(sentinel)
// Reserve 7
// balance: 10 -> 17
// reserved: 10 -> 17
amt = abi.NewTokenAmount(7)
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
msg = s.mockApi.getSentMessage(sentinel)
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
s.mockApi.completeMsg(sentinel)
// Release 5
// balance: 17
// reserved: 17 -> 12
amt = abi.NewTokenAmount(5)
err = s.fm.Release(s.acctAddr, amt)
require.NoError(t, err)
// Withdraw 2
// balance: 17 -> 15
// reserved: 12
amt = abi.NewTokenAmount(2)
sentinel, err = s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
msg = s.mockApi.getSentMessage(sentinel)
checkWithdrawMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
s.mockApi.completeMsg(sentinel)
// Reserve 3
// balance: 15
// reserved: 12 -> 15
// Note: reserved (15) is <= balance (15) so should not send on-chain
// message
msgCount := s.mockApi.messageCount()
amt = abi.NewTokenAmount(3)
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
require.Equal(t, msgCount, s.mockApi.messageCount())
require.Equal(t, sentinel, cid.Undef)
// Reserve 1
// balance: 15 -> 16
// reserved: 15 -> 16
// Note: reserved (16) is above balance (15) so *should* send on-chain
// message to top up balance
amt = abi.NewTokenAmount(1)
topUp := abi.NewTokenAmount(1)
sentinel, err = s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
s.mockApi.completeMsg(sentinel)
msg = s.mockApi.getSentMessage(sentinel)
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, topUp)
// Withdraw 1
// balance: 16
// reserved: 16
// Note: Expect failure because there is no available balance to withdraw:
// balance - reserved = 16 - 16 = 0
amt = abi.NewTokenAmount(1)
sentinel, err = s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
require.Error(t, err)
}
// TestFundManagerParallel verifies that operations can be run in parallel
func TestFundManagerParallel(t *testing.T) {
s := setup(t)
defer s.fm.Stop()
// Reserve 10
amt := abi.NewTokenAmount(10)
sentinelReserve10, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
// Wait until all the subsequent requests are queued up
queueReady := make(chan struct{})
fa := s.fm.getFundedAddress(s.acctAddr)
fa.onProcessStart(func() bool {
if len(fa.withdrawals) == 1 && len(fa.reservations) == 2 && len(fa.releases) == 1 {
close(queueReady)
return true
}
return false
})
// Withdraw 5 (should not run until after reserves / releases)
withdrawReady := make(chan error)
go func() {
amt = abi.NewTokenAmount(5)
_, err := s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
withdrawReady <- err
}()
reserveSentinels := make(chan cid.Cid)
// Reserve 3
go func() {
amt := abi.NewTokenAmount(3)
sentinelReserve3, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
reserveSentinels <- sentinelReserve3
}()
// Reserve 5
go func() {
amt := abi.NewTokenAmount(5)
sentinelReserve5, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
reserveSentinels <- sentinelReserve5
}()
// Release 2
go func() {
amt := abi.NewTokenAmount(2)
err = s.fm.Release(s.acctAddr, amt)
require.NoError(t, err)
}()
// Everything is queued up
<-queueReady
// Complete the "Reserve 10" message
s.mockApi.completeMsg(sentinelReserve10)
msg := s.mockApi.getSentMessage(sentinelReserve10)
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, abi.NewTokenAmount(10))
// The other requests should now be combined and be submitted on-chain as
// a single message
rs1 := <-reserveSentinels
rs2 := <-reserveSentinels
require.Equal(t, rs1, rs2)
// Withdraw should not have been called yet, because reserve / release
// requests run first
select {
case <-withdrawReady:
require.Fail(t, "Withdraw should run after reserve / release")
default:
}
// Complete the message
s.mockApi.completeMsg(rs1)
msg = s.mockApi.getSentMessage(rs1)
// "Reserve 3" +3
// "Reserve 5" +5
// "Release 2" -2
// Result: 6
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, abi.NewTokenAmount(6))
// Expect withdraw to fail because not enough available funds
err = <-withdrawReady
require.Error(t, err)
}
// TestFundManagerReserveByWallet verifies that reserve requests are grouped by wallet
func TestFundManagerReserveByWallet(t *testing.T) {
s := setup(t)
defer s.fm.Stop()
walletAddrA, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
require.NoError(t, err)
walletAddrB, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
require.NoError(t, err)
// Wait until all the reservation requests are queued up
walletAQueuedUp := make(chan struct{})
queueReady := make(chan struct{})
fa := s.fm.getFundedAddress(s.acctAddr)
fa.onProcessStart(func() bool {
if len(fa.reservations) == 1 {
close(walletAQueuedUp)
}
if len(fa.reservations) == 3 {
close(queueReady)
return true
}
return false
})
type reserveResult struct {
ws cid.Cid
err error
}
results := make(chan *reserveResult)
amtA1 := abi.NewTokenAmount(1)
go func() {
// Wallet A: Reserve 1
sentinelA1, err := s.fm.Reserve(s.ctx, walletAddrA, s.acctAddr, amtA1)
results <- &reserveResult{
ws: sentinelA1,
err: err,
}
}()
amtB1 := abi.NewTokenAmount(2)
amtB2 := abi.NewTokenAmount(3)
go func() {
// Wait for reservation for wallet A to be queued up
<-walletAQueuedUp
// Wallet B: Reserve 2
go func() {
sentinelB1, err := s.fm.Reserve(s.ctx, walletAddrB, s.acctAddr, amtB1)
results <- &reserveResult{
ws: sentinelB1,
err: err,
}
}()
// Wallet B: Reserve 3
sentinelB2, err := s.fm.Reserve(s.ctx, walletAddrB, s.acctAddr, amtB2)
results <- &reserveResult{
ws: sentinelB2,
err: err,
}
}()
// All reservation requests are queued up
<-queueReady
resA := <-results
sentinelA1 := resA.ws
// Should send to wallet A
msg := s.mockApi.getSentMessage(sentinelA1)
checkAddMessageFields(t, msg, walletAddrA, s.acctAddr, amtA1)
// Complete wallet A message
s.mockApi.completeMsg(sentinelA1)
resB1 := <-results
resB2 := <-results
require.NoError(t, resB1.err)
require.NoError(t, resB2.err)
sentinelB1 := resB1.ws
sentinelB2 := resB2.ws
// Should send different message to wallet B
require.NotEqual(t, sentinelA1, sentinelB1)
// Should be single message combining amount 1 and 2
require.Equal(t, sentinelB1, sentinelB2)
msg = s.mockApi.getSentMessage(sentinelB1)
checkAddMessageFields(t, msg, walletAddrB, s.acctAddr, types.BigAdd(amtB1, amtB2))
}
// TestFundManagerWithdrawal verifies that as many withdraw operations as
// possible are processed
func TestFundManagerWithdrawalLimit(t *testing.T) {
s := setup(t)
defer s.fm.Stop()
// Reserve 10
amt := abi.NewTokenAmount(10)
sentinelReserve10, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
// Complete the "Reserve 10" message
s.mockApi.completeMsg(sentinelReserve10)
// Release 10
err = s.fm.Release(s.acctAddr, amt)
require.NoError(t, err)
// Queue up withdraw requests
queueReady := make(chan struct{})
fa := s.fm.getFundedAddress(s.acctAddr)
withdrawalReqTotal := 3
withdrawalReqEnqueued := 0
withdrawalReqQueue := make(chan func(), withdrawalReqTotal)
fa.onProcessStart(func() bool {
// If a new withdrawal request was enqueued
if len(fa.withdrawals) > withdrawalReqEnqueued {
withdrawalReqEnqueued++
// Pop the next request and run it
select {
case fn := <-withdrawalReqQueue:
go fn()
default:
}
}
// Once all the requests have arrived, we're ready to process the queue
if withdrawalReqEnqueued == withdrawalReqTotal {
close(queueReady)
return true
}
return false
})
type withdrawResult struct {
reqIndex int
ws cid.Cid
err error
}
withdrawRes := make(chan *withdrawResult)
// Queue up three "Withdraw 5" requests
enqueuedCount := 0
for i := 0; i < withdrawalReqTotal; i++ {
withdrawalReqQueue <- func() {
idx := enqueuedCount
enqueuedCount++
amt := abi.NewTokenAmount(5)
ws, err := s.fm.Withdraw(s.ctx, s.walletAddr, s.acctAddr, amt)
withdrawRes <- &withdrawResult{reqIndex: idx, ws: ws, err: err}
}
}
// Start the first request
fn := <-withdrawalReqQueue
go fn()
// All withdrawal requests are queued up and ready to be processed
<-queueReady
// Organize results in request order
results := make([]*withdrawResult, withdrawalReqTotal)
for i := 0; i < 3; i++ {
res := <-withdrawRes
results[res.reqIndex] = res
}
// Available 10
// Withdraw 5
// Expect Success
require.NoError(t, results[0].err)
// Available 5
// Withdraw 5
// Expect Success
require.NoError(t, results[1].err)
// Available 0
// Withdraw 5
// Expect FAIL
require.Error(t, results[2].err)
// Expect withdrawal requests that fit under reserved amount to be combined
// into a single message on-chain
require.Equal(t, results[0].ws, results[1].ws)
}
// TestFundManagerWithdrawByWallet verifies that withdraw requests are grouped by wallet
func TestFundManagerWithdrawByWallet(t *testing.T) {
s := setup(t)
defer s.fm.Stop()
walletAddrA, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
require.NoError(t, err)
walletAddrB, err := s.wllt.WalletNew(context.Background(), types.KTSecp256k1)
require.NoError(t, err)
// Reserve 10
reserveAmt := abi.NewTokenAmount(10)
sentinelReserve, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, reserveAmt)
require.NoError(t, err)
s.mockApi.completeMsg(sentinelReserve)
time.Sleep(10 * time.Millisecond)
// Release 10
err = s.fm.Release(s.acctAddr, reserveAmt)
require.NoError(t, err)
type withdrawResult struct {
ws cid.Cid
err error
}
results := make(chan *withdrawResult)
// Wait until withdrawals are queued up
walletAQueuedUp := make(chan struct{})
queueReady := make(chan struct{})
withdrawalCount := 0
fa := s.fm.getFundedAddress(s.acctAddr)
fa.onProcessStart(func() bool {
if len(fa.withdrawals) == withdrawalCount {
return false
}
withdrawalCount = len(fa.withdrawals)
if withdrawalCount == 1 {
close(walletAQueuedUp)
} else if withdrawalCount == 3 {
close(queueReady)
return true
}
return false
})
amtA1 := abi.NewTokenAmount(1)
go func() {
// Wallet A: Withdraw 1
sentinelA1, err := s.fm.Withdraw(s.ctx, walletAddrA, s.acctAddr, amtA1)
results <- &withdrawResult{
ws: sentinelA1,
err: err,
}
}()
amtB1 := abi.NewTokenAmount(2)
amtB2 := abi.NewTokenAmount(3)
go func() {
// Wait until withdraw for wallet A is queued up
<-walletAQueuedUp
// Wallet B: Withdraw 2
go func() {
sentinelB1, err := s.fm.Withdraw(s.ctx, walletAddrB, s.acctAddr, amtB1)
results <- &withdrawResult{
ws: sentinelB1,
err: err,
}
}()
// Wallet B: Withdraw 3
sentinelB2, err := s.fm.Withdraw(s.ctx, walletAddrB, s.acctAddr, amtB2)
results <- &withdrawResult{
ws: sentinelB2,
err: err,
}
}()
// Withdrawals are queued up
<-queueReady
// Should withdraw from wallet A first
resA1 := <-results
sentinelA1 := resA1.ws
msg := s.mockApi.getSentMessage(sentinelA1)
checkWithdrawMessageFields(t, msg, walletAddrA, s.acctAddr, amtA1)
// Complete wallet A message
s.mockApi.completeMsg(sentinelA1)
resB1 := <-results
resB2 := <-results
require.NoError(t, resB1.err)
require.NoError(t, resB2.err)
sentinelB1 := resB1.ws
sentinelB2 := resB2.ws
// Should send different message for wallet B from wallet A
require.NotEqual(t, sentinelA1, sentinelB1)
// Should be single message combining amount 1 and 2
require.Equal(t, sentinelB1, sentinelB2)
msg = s.mockApi.getSentMessage(sentinelB1)
checkWithdrawMessageFields(t, msg, walletAddrB, s.acctAddr, types.BigAdd(amtB1, amtB2))
}
// TestFundManagerRestart verifies that waiting for incomplete requests resumes
// on restart
func TestFundManagerRestart(t *testing.T) {
s := setup(t)
defer s.fm.Stop()
acctAddr2 := tutils.NewActorAddr(t, "addr2")
// Address 1: Reserve 10
amt := abi.NewTokenAmount(10)
sentinelAddr1, err := s.fm.Reserve(s.ctx, s.walletAddr, s.acctAddr, amt)
require.NoError(t, err)
msg := s.mockApi.getSentMessage(sentinelAddr1)
checkAddMessageFields(t, msg, s.walletAddr, s.acctAddr, amt)
// Address 2: Reserve 7
amt2 := abi.NewTokenAmount(7)
sentinelAddr2Res7, err := s.fm.Reserve(s.ctx, s.walletAddr, acctAddr2, amt2)
require.NoError(t, err)
msg2 := s.mockApi.getSentMessage(sentinelAddr2Res7)
checkAddMessageFields(t, msg2, s.walletAddr, acctAddr2, amt2)
// Complete "Address 1: Reserve 10"
s.mockApi.completeMsg(sentinelAddr1)
// Give the completed state a moment to be stored before restart
time.Sleep(time.Millisecond * 10)
// Restart
mockApiAfter := s.mockApi
fmAfter := newFundManager(mockApiAfter, s.ds)
err = fmAfter.Start()
require.NoError(t, err)
amt3 := abi.NewTokenAmount(9)
reserveSentinel := make(chan cid.Cid)
go func() {
// Address 2: Reserve 9
sentinel3, err := fmAfter.Reserve(s.ctx, s.walletAddr, acctAddr2, amt3)
require.NoError(t, err)
reserveSentinel <- sentinel3
}()
// Expect no message to be sent, because still waiting for previous
// message "Address 2: Reserve 7" to complete on-chain
select {
case <-reserveSentinel:
require.Fail(t, "Expected no message to be sent")
case <-time.After(10 * time.Millisecond):
}
// Complete "Address 2: Reserve 7"
mockApiAfter.completeMsg(sentinelAddr2Res7)
// Expect waiting message to now be sent
sentinel3 := <-reserveSentinel
msg3 := mockApiAfter.getSentMessage(sentinel3)
checkAddMessageFields(t, msg3, s.walletAddr, acctAddr2, amt3)
}
type scaffold struct {
ctx context.Context
ds *ds_sync.MutexDatastore
wllt *wallet.LocalWallet
walletAddr address.Address
acctAddr address.Address
mockApi *mockFundManagerAPI
fm *FundManager
}
func setup(t *testing.T) *scaffold {
ctx := context.Background()
wllt, err := wallet.NewWallet(wallet.NewMemKeyStore())
if err != nil {
t.Fatal(err)
}
walletAddr, err := wllt.WalletNew(context.Background(), types.KTSecp256k1)
if err != nil {
t.Fatal(err)
}
acctAddr := tutils.NewActorAddr(t, "addr")
mockApi := newMockFundManagerAPI(walletAddr)
dstore := ds_sync.MutexWrap(ds.NewMapDatastore())
fm := newFundManager(mockApi, dstore)
return &scaffold{
ctx: ctx,
ds: dstore,
wllt: wllt,
walletAddr: walletAddr,
acctAddr: acctAddr,
mockApi: mockApi,
fm: fm,
}
}
func checkAddMessageFields(t *testing.T, msg *types.Message, from address.Address, to address.Address, amt abi.TokenAmount) {
require.Equal(t, from, msg.From)
require.Equal(t, market.Address, msg.To)
require.Equal(t, amt, msg.Value)
var paramsTo address.Address
err := paramsTo.UnmarshalCBOR(bytes.NewReader(msg.Params))
require.NoError(t, err)
require.Equal(t, to, paramsTo)
}
func checkWithdrawMessageFields(t *testing.T, msg *types.Message, from address.Address, addr address.Address, amt abi.TokenAmount) {
require.Equal(t, from, msg.From)
require.Equal(t, market.Address, msg.To)
require.Equal(t, abi.NewTokenAmount(0), msg.Value)
var params market.WithdrawBalanceParams
err := params.UnmarshalCBOR(bytes.NewReader(msg.Params))
require.NoError(t, err)
require.Equal(t, addr, params.ProviderOrClientAddress)
require.Equal(t, amt, params.Amount)
}
type sentMsg struct {
msg *types.SignedMessage
ready chan struct{}
}
type mockFundManagerAPI struct {
wallet address.Address
lk sync.Mutex
escrow map[address.Address]abi.TokenAmount
sentMsgs map[cid.Cid]*sentMsg
completedMsgs map[cid.Cid]struct{}
waitingFor map[cid.Cid]chan struct{}
}
func newMockFundManagerAPI(wallet address.Address) *mockFundManagerAPI {
return &mockFundManagerAPI{
wallet: wallet,
escrow: make(map[address.Address]abi.TokenAmount),
sentMsgs: make(map[cid.Cid]*sentMsg),
completedMsgs: make(map[cid.Cid]struct{}),
waitingFor: make(map[cid.Cid]chan struct{}),
}
}
func (mapi *mockFundManagerAPI) MpoolPushMessage(ctx context.Context, message *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
mapi.lk.Lock()
defer mapi.lk.Unlock()
smsg := &types.SignedMessage{Message: *message}
mapi.sentMsgs[smsg.Cid()] = &sentMsg{msg: smsg, ready: make(chan struct{})}
return smsg, nil
}
func (mapi *mockFundManagerAPI) getSentMessage(c cid.Cid) *types.Message {
mapi.lk.Lock()
defer mapi.lk.Unlock()
for i := 0; i < 1000; i++ {
if pending, ok := mapi.sentMsgs[c]; ok {
return &pending.msg.Message
}
time.Sleep(time.Millisecond)
}
panic("expected message to be sent")
}
func (mapi *mockFundManagerAPI) messageCount() int {
mapi.lk.Lock()
defer mapi.lk.Unlock()
return len(mapi.sentMsgs)
}
func (mapi *mockFundManagerAPI) completeMsg(msgCid cid.Cid) {
mapi.lk.Lock()
pmsg, ok := mapi.sentMsgs[msgCid]
if ok {
if pmsg.msg.Message.Method == market.Methods.AddBalance {
var escrowAcct address.Address
err := escrowAcct.UnmarshalCBOR(bytes.NewReader(pmsg.msg.Message.Params))
if err != nil {
panic(err)
}
escrow := mapi.getEscrow(escrowAcct)
before := escrow
escrow = types.BigAdd(escrow, pmsg.msg.Message.Value)
mapi.escrow[escrowAcct] = escrow
log.Debugf("%s: escrow %d -> %d", escrowAcct, before, escrow)
} else {
var params market.WithdrawBalanceParams
err := params.UnmarshalCBOR(bytes.NewReader(pmsg.msg.Message.Params))
if err != nil {
panic(err)
}
escrowAcct := params.ProviderOrClientAddress
escrow := mapi.getEscrow(escrowAcct)
before := escrow
escrow = types.BigSub(escrow, params.Amount)
mapi.escrow[escrowAcct] = escrow
log.Debugf("%s: escrow %d -> %d", escrowAcct, before, escrow)
}
}
mapi.completedMsgs[msgCid] = struct{}{}
ready, ok := mapi.waitingFor[msgCid]
mapi.lk.Unlock()
if ok {
close(ready)
}
}
func (mapi *mockFundManagerAPI) StateMarketBalance(ctx context.Context, a address.Address, key types.TipSetKey) (api.MarketBalance, error) {
mapi.lk.Lock()
defer mapi.lk.Unlock()
return api.MarketBalance{
Locked: abi.NewTokenAmount(0),
Escrow: mapi.getEscrow(a),
}, nil
}
func (mapi *mockFundManagerAPI) getEscrow(a address.Address) abi.TokenAmount {
escrow := mapi.escrow[a]
if escrow.Nil() {
return abi.NewTokenAmount(0)
}
return escrow
}
func (mapi *mockFundManagerAPI) StateWaitMsg(ctx context.Context, c cid.Cid, confidence uint64) (*api.MsgLookup, error) {
res := &api.MsgLookup{
Message: c,
Receipt: types.MessageReceipt{
ExitCode: 0,
Return: nil,
},
}
ready := make(chan struct{})
mapi.lk.Lock()
_, ok := mapi.completedMsgs[c]
if !ok {
mapi.waitingFor[c] = ready
}
mapi.lk.Unlock()
if !ok {
select {
case <-ctx.Done():
case <-ready:
}
}
return res, nil
}
+168
View File
@@ -0,0 +1,168 @@
package market
import (
"context"
"sync"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"go.uber.org/fx"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/events"
"github.com/filecoin-project/lotus/chain/events/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/node/impl/full"
)
var log = logging.Logger("market_adapter")
// API is the dependencies need to run a fund manager
type API struct {
fx.In
full.ChainAPI
full.StateAPI
full.MpoolAPI
}
// FundMgr monitors available balances and adds funds when EnsureAvailable is called
type FundMgr struct {
api fundMgrAPI
lk sync.RWMutex
available map[address.Address]types.BigInt
}
// StartFundManager creates a new fund manager and sets up event hooks to manage state changes
func StartFundManager(lc fx.Lifecycle, api API) *FundMgr {
fm := newFundMgr(&api)
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
ev := events.NewEvents(ctx, &api)
preds := state.NewStatePredicates(&api)
dealDiffFn := preds.OnStorageMarketActorChanged(preds.OnBalanceChanged(preds.AvailableBalanceChangedForAddresses(fm.getAddresses)))
match := func(oldTs, newTs *types.TipSet) (bool, events.StateChange, error) {
return dealDiffFn(ctx, oldTs.Key(), newTs.Key())
}
return ev.StateChanged(fm.checkFunc, fm.stateChanged, fm.revert, 0, events.NoTimeout, match)
},
})
return fm
}
type fundMgrAPI interface {
StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error)
MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)
StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
}
func newFundMgr(api fundMgrAPI) *FundMgr {
return &FundMgr{
api: api,
available: map[address.Address]types.BigInt{},
}
}
// checkFunc tells the events api to simply proceed (we always want to watch)
func (fm *FundMgr) checkFunc(ts *types.TipSet) (done bool, more bool, err error) {
return false, true, nil
}
// revert handles reverts to balances
func (fm *FundMgr) revert(ctx context.Context, ts *types.TipSet) error {
// TODO: Is it ok to just ignore this?
log.Warn("balance change reverted; TODO: actually handle this!")
return nil
}
// stateChanged handles balance changes monitored on the chain from one tipset to the next
func (fm *FundMgr) stateChanged(ts *types.TipSet, ts2 *types.TipSet, states events.StateChange, h abi.ChainEpoch) (more bool, err error) {
changedBalances, ok := states.(state.ChangedBalances)
if !ok {
panic("Expected state.ChangedBalances")
}
// overwrite our in memory cache with new values from chain (chain is canonical)
fm.lk.Lock()
for addr, balanceChange := range changedBalances {
if fm.available[addr].Int != nil {
log.Infof("State balance change recorded, prev: %s, new: %s", fm.available[addr].String(), balanceChange.To.String())
}
fm.available[addr] = balanceChange.To
}
fm.lk.Unlock()
return true, nil
}
func (fm *FundMgr) getAddresses() []address.Address {
fm.lk.RLock()
defer fm.lk.RUnlock()
addrs := make([]address.Address, 0, len(fm.available))
for addr := range fm.available {
addrs = append(addrs, addr)
}
return addrs
}
// EnsureAvailable looks at the available balance in escrow for a given
// address, and if less than the passed in amount, adds the difference
func (fm *FundMgr) EnsureAvailable(ctx context.Context, addr, wallet address.Address, amt types.BigInt) (cid.Cid, error) {
idAddr, err := fm.api.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
return cid.Undef, err
}
fm.lk.Lock()
defer fm.lk.Unlock()
bal, err := fm.api.StateMarketBalance(ctx, addr, types.EmptyTSK)
if err != nil {
return cid.Undef, err
}
stateAvail := types.BigSub(bal.Escrow, bal.Locked)
avail, ok := fm.available[idAddr]
if !ok {
avail = stateAvail
}
toAdd := types.BigSub(amt, avail)
if toAdd.LessThan(types.NewInt(0)) {
toAdd = types.NewInt(0)
}
fm.available[idAddr] = big.Add(avail, toAdd)
log.Infof("Funds operation w/ Expected Balance: %s, In State: %s, Requested: %s, Adding: %s", avail.String(), stateAvail.String(), amt.String(), toAdd.String())
if toAdd.LessThanEqual(big.Zero()) {
return cid.Undef, nil
}
params, err := actors.SerializeParams(&addr)
if err != nil {
fm.available[idAddr] = avail
return cid.Undef, err
}
smsg, err := fm.api.MpoolPushMessage(ctx, &types.Message{
To: market.Address,
From: wallet,
Value: toAdd,
Method: builtin.MethodsMarket.AddBalance,
Params: params,
}, nil)
if err != nil {
fm.available[idAddr] = avail
return cid.Undef, err
}
return smsg.Cid(), nil
}
+199
View File
@@ -0,0 +1,199 @@
package market
import (
"context"
"errors"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/specs-actors/actors/builtin"
tutils "github.com/filecoin-project/specs-actors/support/testing"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/types"
)
type fakeAPI struct {
returnedBalance api.MarketBalance
returnedBalanceErr error
signature crypto.Signature
receivedMessage *types.Message
pushMessageErr error
lookupIDErr error
}
func (fapi *fakeAPI) StateLookupID(_ context.Context, addr address.Address, _ types.TipSetKey) (address.Address, error) {
return addr, fapi.lookupIDErr
}
func (fapi *fakeAPI) StateMarketBalance(context.Context, address.Address, types.TipSetKey) (api.MarketBalance, error) {
return fapi.returnedBalance, fapi.returnedBalanceErr
}
func (fapi *fakeAPI) MpoolPushMessage(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec) (*types.SignedMessage, error) {
fapi.receivedMessage = msg
return &types.SignedMessage{
Message: *msg,
Signature: fapi.signature,
}, fapi.pushMessageErr
}
func addFundsMsg(toAdd abi.TokenAmount, addr address.Address, wallet address.Address) *types.Message {
params, _ := actors.SerializeParams(&addr)
return &types.Message{
To: market.Address,
From: wallet,
Value: toAdd,
Method: builtin.MethodsMarket.AddBalance,
Params: params,
}
}
type expectedResult struct {
addAmt abi.TokenAmount
shouldAdd bool
err error
cachedAvailable abi.TokenAmount
}
func TestAddFunds(t *testing.T) {
ctx := context.Background()
testCases := map[string]struct {
returnedBalanceErr error
returnedBalance api.MarketBalance
addAmounts []abi.TokenAmount
pushMessageErr error
expectedResults []expectedResult
lookupIDErr error
}{
"succeeds, trivial case": {
returnedBalance: api.MarketBalance{Escrow: abi.NewTokenAmount(0), Locked: abi.NewTokenAmount(0)},
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
expectedResults: []expectedResult{
{
addAmt: abi.NewTokenAmount(100),
shouldAdd: true,
err: nil,
},
},
},
"succeeds, money already present": {
returnedBalance: api.MarketBalance{Escrow: abi.NewTokenAmount(150), Locked: abi.NewTokenAmount(50)},
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
expectedResults: []expectedResult{
{
shouldAdd: false,
err: nil,
cachedAvailable: abi.NewTokenAmount(100),
},
},
},
"succeeds, multiple adds": {
returnedBalance: api.MarketBalance{Escrow: abi.NewTokenAmount(150), Locked: abi.NewTokenAmount(50)},
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100), abi.NewTokenAmount(200), abi.NewTokenAmount(250), abi.NewTokenAmount(250)},
expectedResults: []expectedResult{
{
shouldAdd: false,
err: nil,
},
{
addAmt: abi.NewTokenAmount(100),
shouldAdd: true,
err: nil,
cachedAvailable: abi.NewTokenAmount(200),
},
{
addAmt: abi.NewTokenAmount(50),
shouldAdd: true,
err: nil,
cachedAvailable: abi.NewTokenAmount(250),
},
{
shouldAdd: false,
err: nil,
cachedAvailable: abi.NewTokenAmount(250),
},
},
},
"error on market balance": {
returnedBalanceErr: errors.New("something went wrong"),
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
expectedResults: []expectedResult{
{
err: errors.New("something went wrong"),
},
},
},
"error on push message": {
returnedBalance: api.MarketBalance{Escrow: abi.NewTokenAmount(0), Locked: abi.NewTokenAmount(0)},
pushMessageErr: errors.New("something went wrong"),
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
expectedResults: []expectedResult{
{
err: errors.New("something went wrong"),
cachedAvailable: abi.NewTokenAmount(0),
},
},
},
"error looking up address": {
lookupIDErr: errors.New("something went wrong"),
addAmounts: []abi.TokenAmount{abi.NewTokenAmount(100)},
expectedResults: []expectedResult{
{
err: errors.New("something went wrong"),
},
},
},
}
for testCase, data := range testCases {
//nolint:scopelint
t.Run(testCase, func(t *testing.T) {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
sig := make([]byte, 100)
_, err := rand.Read(sig)
require.NoError(t, err)
fapi := &fakeAPI{
returnedBalance: data.returnedBalance,
returnedBalanceErr: data.returnedBalanceErr,
signature: crypto.Signature{
Type: crypto.SigTypeUnknown,
Data: sig,
},
pushMessageErr: data.pushMessageErr,
lookupIDErr: data.lookupIDErr,
}
fundMgr := newFundMgr(fapi)
addr := tutils.NewIDAddr(t, uint64(rand.Uint32()))
wallet := tutils.NewIDAddr(t, uint64(rand.Uint32()))
for i, amount := range data.addAmounts {
fapi.receivedMessage = nil
_, err := fundMgr.EnsureAvailable(ctx, addr, wallet, amount)
expected := data.expectedResults[i]
if expected.err == nil {
require.NoError(t, err)
if expected.shouldAdd {
expectedMessage := addFundsMsg(expected.addAmt, addr, wallet)
require.Equal(t, expectedMessage, fapi.receivedMessage)
} else {
require.Nil(t, fapi.receivedMessage)
}
} else {
require.EqualError(t, err, expected.err.Error())
}
if !expected.cachedAvailable.Nil() {
require.Equal(t, expected.cachedAvailable, fundMgr.available[addr])
}
}
})
}
}
-90
View File
@@ -1,90 +0,0 @@
package market
import (
"bytes"
cborrpc "github.com/filecoin-project/go-cbor-util"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
dsq "github.com/ipfs/go-datastore/query"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
const dsKeyAddr = "Addr"
type Store struct {
ds datastore.Batching
}
func newStore(ds dtypes.MetadataDS) *Store {
ds = namespace.Wrap(ds, datastore.NewKey("/fundmgr/"))
return &Store{
ds: ds,
}
}
// save the state to the datastore
func (ps *Store) save(state *FundedAddressState) error {
k := dskeyForAddr(state.Addr)
b, err := cborrpc.Dump(state)
if err != nil {
return err
}
return ps.ds.Put(k, b)
}
// get the state for the given address
func (ps *Store) get(addr address.Address) (*FundedAddressState, error) {
k := dskeyForAddr(addr)
data, err := ps.ds.Get(k)
if err != nil {
return nil, err
}
var state FundedAddressState
err = cborrpc.ReadCborRPC(bytes.NewReader(data), &state)
if err != nil {
return nil, err
}
return &state, nil
}
// forEach calls iter with each address in the datastore
func (ps *Store) forEach(iter func(*FundedAddressState)) error {
res, err := ps.ds.Query(dsq.Query{Prefix: dsKeyAddr})
if err != nil {
return err
}
defer res.Close() //nolint:errcheck
for {
res, ok := res.NextSync()
if !ok {
break
}
if res.Error != nil {
return err
}
var stored FundedAddressState
if err := stored.UnmarshalCBOR(bytes.NewReader(res.Value)); err != nil {
return err
}
iter(&stored)
}
return nil
}
// The datastore key used to identify the address state
func dskeyForAddr(addr address.Address) datastore.Key {
return datastore.KeyWithNamespaces([]string{dsKeyAddr, addr.String()})
}
+1 -2
View File
@@ -6,7 +6,6 @@ import (
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/go-address"
@@ -69,7 +68,7 @@ func failedGuess(msg *types.SignedMessage) int64 {
func GuessGasUsed(ctx context.Context, tsk types.TipSetKey, msg *types.SignedMessage, al ActorLookup) (int64, error) {
// MethodSend is the same in all versions.
if msg.Message.Method == builtin.MethodSend {
if msg.Message.Method == builtin0.MethodSend {
switch msg.Message.From.Protocol() {
case address.BLS:
return 1298450, nil
+40 -65
View File
@@ -181,15 +181,9 @@ func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
return types.BigAdd(minPrice, types.NewInt(1))
}
func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, maxFee abi.TokenAmount) {
func CapGasFee(msg *types.Message, maxFee abi.TokenAmount) {
if maxFee.Equals(big.Zero()) {
mf, err := mff()
if err != nil {
log.Errorf("failed to get default max gas fee: %+v", err)
mf = big.Zero()
}
maxFee = mf
maxFee = types.NewInt(build.FilecoinPrecision / 10)
}
gl := types.NewInt(uint64(msg.GasLimit))
@@ -374,23 +368,11 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName, j journ
return err
})
mp.curTsLk.Lock()
mp.lk.Lock()
if err := mp.loadLocal(); err != nil {
log.Errorf("loading local messages: %+v", err)
}
go func() {
err := mp.loadLocal()
mp.lk.Unlock()
mp.curTsLk.Unlock()
if err != nil {
log.Errorf("loading local messages: %+v", err)
}
log.Info("mpool ready")
mp.runLoop()
}()
go mp.runLoop()
return mp, nil
}
@@ -436,14 +418,9 @@ func (mp *MessagePool) runLoop() {
}
}
func (mp *MessagePool) addLocal(m *types.SignedMessage) error {
func (mp *MessagePool) addLocal(m *types.SignedMessage, msgb []byte) error {
mp.localAddrs[m.Message.From] = struct{}{}
msgb, err := m.Serialize()
if err != nil {
return xerrors.Errorf("error serializing message: %w", err)
}
if err := mp.localMsgs.Put(datastore.NewKey(string(m.Cid().Bytes())), msgb); err != nil {
return xerrors.Errorf("persisting local message: %w", err)
}
@@ -516,6 +493,11 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
<-mp.addSema
}()
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, err
}
mp.curTsLk.Lock()
publish, err := mp.addTs(m, mp.curTs, true, false)
if err != nil {
@@ -524,19 +506,18 @@ func (mp *MessagePool) Push(m *types.SignedMessage) (cid.Cid, error) {
}
mp.curTsLk.Unlock()
if publish {
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, xerrors.Errorf("error serializing message: %w", err)
}
mp.lk.Lock()
if err := mp.addLocal(m, msgb); err != nil {
mp.lk.Unlock()
return cid.Undef, err
}
mp.lk.Unlock()
if publish {
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
if err != nil {
return cid.Undef, xerrors.Errorf("error publishing message: %w", err)
}
}
return m.Cid(), nil
return m.Cid(), err
}
func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
@@ -675,19 +656,7 @@ func (mp *MessagePool) addTs(m *types.SignedMessage, curTs *types.TipSet, local,
return false, err
}
err = mp.addLocked(m, !local, untrusted)
if err != nil {
return false, err
}
if local {
err = mp.addLocal(m)
if err != nil {
return false, xerrors.Errorf("error persisting local message: %w", err)
}
}
return publish, nil
return publish, mp.addLocked(m, !local, untrusted)
}
func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
@@ -696,11 +665,10 @@ func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
return err
}
curTs := mp.curTs
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
if curTs == nil {
return xerrors.Errorf("current tipset not loaded")
}
curTs := mp.curTs
snonce, err := mp.getStateNonce(m.Message.From, curTs)
if err != nil {
@@ -711,6 +679,9 @@ func (mp *MessagePool) addLoaded(m *types.SignedMessage) error {
return xerrors.Errorf("minimum expected nonce is %d: %w", snonce, ErrNonceTooLow)
}
mp.lk.Lock()
defer mp.lk.Unlock()
_, err = mp.verifyMsgBeforeAdd(m, curTs, true)
if err != nil {
return err
@@ -854,6 +825,11 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) {
<-mp.addSema
}()
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, err
}
mp.curTsLk.Lock()
publish, err := mp.addTs(m, mp.curTs, false, true)
if err != nil {
@@ -862,19 +838,18 @@ func (mp *MessagePool) PushUntrusted(m *types.SignedMessage) (cid.Cid, error) {
}
mp.curTsLk.Unlock()
if publish {
msgb, err := m.Serialize()
if err != nil {
return cid.Undef, xerrors.Errorf("error serializing message: %w", err)
}
mp.lk.Lock()
if err := mp.addLocal(m, msgb); err != nil {
mp.lk.Unlock()
return cid.Undef, err
}
mp.lk.Unlock()
if publish {
err = mp.api.PubSubPublish(build.MessagesTopic(mp.netName), msgb)
if err != nil {
return cid.Undef, xerrors.Errorf("error publishing message: %w", err)
}
}
return m.Cid(), nil
return m.Cid(), err
}
func (mp *MessagePool) Remove(from address.Address, nonce uint64, applied bool) {
+22 -23
View File
@@ -8,18 +8,17 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log/v2"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log/v2"
)
func init() {
@@ -144,7 +143,7 @@ func (tma *testMpoolAPI) GetActorAfter(addr address.Address, ts *types.TipSet) (
}
return &types.Actor{
Code: builtin2.StorageMarketActorCodeID,
Code: builtin.StorageMarketActorCodeID,
Nonce: nonce,
Balance: balance,
}, nil
@@ -233,7 +232,7 @@ func TestMessagePool(t *testing.T) {
a := tma.nextBlock()
sender, err := w.WalletNew(context.Background(), types.KTSecp256k1)
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil {
t.Fatal(err)
}
@@ -274,7 +273,7 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
a := tma.nextBlock()
sender, err := w.WalletNew(context.Background(), types.KTBLS)
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil {
t.Fatal(err)
}
@@ -324,7 +323,7 @@ func TestRevertMessages(t *testing.T) {
a := tma.nextBlock()
b := tma.nextBlock()
sender, err := w.WalletNew(context.Background(), types.KTBLS)
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil {
t.Fatal(err)
}
@@ -387,7 +386,7 @@ func TestPruningSimple(t *testing.T) {
a := tma.nextBlock()
tma.applyBlock(t, a)
sender, err := w.WalletNew(context.Background(), types.KTBLS)
sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil {
t.Fatal(err)
}
@@ -434,7 +433,7 @@ func TestLoadLocal(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -444,14 +443,14 @@ func TestLoadLocal(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
msgs := make(map[cid.Cid]struct{})
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
@@ -506,7 +505,7 @@ func TestClearAll(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -516,14 +515,14 @@ func TestClearAll(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m)
@@ -560,7 +559,7 @@ func TestClearNonLocal(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -570,7 +569,7 @@ func TestClearNonLocal(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -578,7 +577,7 @@ func TestClearNonLocal(t *testing.T) {
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
_, err := mp.Push(m)
@@ -621,7 +620,7 @@ func TestUpdates(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -631,7 +630,7 @@ func TestUpdates(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -644,7 +643,7 @@ func TestUpdates(t *testing.T) {
t.Fatal(err)
}
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
+1 -15
View File
@@ -2,7 +2,6 @@ package messagepool
import (
"context"
"time"
"github.com/ipfs/go-cid"
pubsub "github.com/libp2p/go-libp2p-pubsub"
@@ -10,16 +9,9 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
)
var (
HeadChangeCoalesceMinDelay = 2 * time.Second
HeadChangeCoalesceMaxDelay = 6 * time.Second
HeadChangeCoalesceMergeInterval = time.Second
)
type Provider interface {
SubscribeHeadChanges(func(rev, app []*types.TipSet) error) *types.TipSet
PutMessage(m types.ChainMsg) (cid.Cid, error)
@@ -42,13 +34,7 @@ func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
}
func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
mpp.sm.ChainStore().SubscribeHeadChanges(
store.WrapHeadChangeCoalescer(
cb,
HeadChangeCoalesceMinDelay,
HeadChangeCoalesceMaxDelay,
HeadChangeCoalesceMergeInterval,
))
mpp.sm.ChainStore().SubscribeHeadChanges(cb)
return mpp.sm.ChainStore().GetHeaviestTipSet()
}
+6 -8
View File
@@ -5,13 +5,11 @@ import (
"testing"
"time"
"github.com/ipfs/go-datastore"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/ipfs/go-datastore"
)
func TestRepubMessages(t *testing.T) {
@@ -35,7 +33,7 @@ func TestRepubMessages(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -45,12 +43,12 @@ func TestRepubMessages(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
+4 -4
View File
@@ -12,7 +12,6 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
tbig "github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
@@ -752,10 +751,11 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
balance = new(big.Int).Sub(balance, required)
value := m.Message.Value.Int
if balance.Cmp(value) < 0 {
break
if balance.Cmp(value) >= 0 {
// Note: we only account for the value if the balance doesn't drop below 0
// otherwise the message will fail and the miner can reap the gas rewards
balance = new(big.Int).Sub(balance, value)
}
balance = new(big.Int).Sub(balance, value)
gasReward := mp.getGasReward(m, baseFee)
rewards = append(rewards, gasReward)
+35 -35
View File
@@ -13,18 +13,18 @@ import (
"sort"
"testing"
"github.com/filecoin-project/go-address"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/messagepool/gasguess"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/lotus/api"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
@@ -77,7 +77,7 @@ func TestMessageChains(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -87,7 +87,7 @@ func TestMessageChains(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -95,7 +95,7 @@ func TestMessageChains(t *testing.T) {
block := tma.nextBlock()
ts := mock.TipSet(block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
@@ -315,7 +315,7 @@ func TestMessageChainSkipping(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -325,7 +325,7 @@ func TestMessageChainSkipping(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -333,7 +333,7 @@ func TestMessageChainSkipping(t *testing.T) {
block := tma.nextBlock()
ts := mock.TipSet(block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
baseFee := types.NewInt(0)
tma.setBalance(a1, 1) // in FIL
@@ -391,7 +391,7 @@ func TestBasicMessageSelection(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -401,7 +401,7 @@ func TestBasicMessageSelection(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -410,7 +410,7 @@ func TestBasicMessageSelection(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -535,7 +535,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -545,7 +545,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -554,7 +554,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -598,7 +598,7 @@ func TestPriorityMessageSelection(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -608,7 +608,7 @@ func TestPriorityMessageSelection(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -617,7 +617,7 @@ func TestPriorityMessageSelection(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -677,7 +677,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -687,7 +687,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -696,7 +696,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -746,7 +746,7 @@ func TestPriorityMessageSelection3(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -756,7 +756,7 @@ func TestPriorityMessageSelection3(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -765,7 +765,7 @@ func TestPriorityMessageSelection3(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -843,7 +843,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -853,7 +853,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -862,7 +862,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -910,7 +910,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
t.Fatal(err)
}
a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1)
a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -920,7 +920,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
t.Fatal(err)
}
a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1)
a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -929,7 +929,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
tma.setBalance(a1, 1) // in FIL
tma.setBalance(a2, 1) // in FIL
@@ -994,7 +994,7 @@ func TestOptimalMessageSelection3(t *testing.T) {
t.Fatal(err)
}
a, err := w.WalletNew(context.Background(), types.KTSecp256k1)
a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -1007,7 +1007,7 @@ func TestOptimalMessageSelection3(t *testing.T) {
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
for _, a := range actors {
tma.setBalance(a, 1) // in FIL
@@ -1074,7 +1074,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
t.Fatal(err)
}
a, err := w.WalletNew(context.Background(), types.KTSecp256k1)
a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
@@ -1087,7 +1087,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
ts := mock.TipSet(block)
tma.applyBlock(t, block)
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin.StorageMarketActorCodeID, M: 2}]
baseFee := types.NewInt(0)
for _, a := range actors {
@@ -1344,7 +1344,7 @@ readLoop:
t.Fatal(err)
}
a, err := w.WalletNew(context.Background(), types.KTSecp256k1)
a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil {
t.Fatal(err)
}
+5 -4
View File
@@ -9,6 +9,7 @@ import (
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/stretchr/testify/require"
ds_sync "github.com/ipfs/go-datastore/sync"
@@ -46,13 +47,13 @@ func TestMessageSignerSignMessage(t *testing.T) {
ctx := context.Background()
w, _ := wallet.NewWallet(wallet.NewMemKeyStore())
from1, err := w.WalletNew(ctx, types.KTSecp256k1)
from1, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
require.NoError(t, err)
from2, err := w.WalletNew(ctx, types.KTSecp256k1)
from2, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
require.NoError(t, err)
to1, err := w.WalletNew(ctx, types.KTSecp256k1)
to1, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
require.NoError(t, err)
to2, err := w.WalletNew(ctx, types.KTSecp256k1)
to2, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1)
require.NoError(t, err)
type msgSpec struct {
+21 -46
View File
@@ -26,18 +26,16 @@ var log = logging.Logger("statetree")
// StateTree stores actors state by their ID.
type StateTree struct {
root adt.Map
version types.StateTreeVersion
info cid.Cid
Store cbor.IpldStore
lookupIDFun func(address.Address) (address.Address, error)
root adt.Map
version types.StateTreeVersion
info cid.Cid
Store cbor.IpldStore
snaps *stateSnaps
}
type stateSnaps struct {
layers []*stateSnapLayer
lastMaybeNonEmptyResolveCache int
layers []*stateSnapLayer
}
type stateSnapLayer struct {
@@ -69,12 +67,7 @@ func (ss *stateSnaps) addLayer() {
func (ss *stateSnaps) dropLayer() {
ss.layers[len(ss.layers)-1] = nil // allow it to be GCed
ss.layers = ss.layers[:len(ss.layers)-1]
if ss.lastMaybeNonEmptyResolveCache == len(ss.layers) {
ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1
}
}
func (ss *stateSnaps) mergeLastLayer() {
@@ -93,13 +86,7 @@ func (ss *stateSnaps) mergeLastLayer() {
}
func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, bool) {
for i := ss.lastMaybeNonEmptyResolveCache; i >= 0; i-- {
if len(ss.layers[i].resolveCache) == 0 {
if ss.lastMaybeNonEmptyResolveCache == i {
ss.lastMaybeNonEmptyResolveCache = i - 1
}
continue
}
for i := len(ss.layers) - 1; i >= 0; i-- {
resa, ok := ss.layers[i].resolveCache[addr]
if ok {
return resa, true
@@ -110,7 +97,6 @@ func (ss *stateSnaps) resolveAddress(addr address.Address) (address.Address, boo
func (ss *stateSnaps) cacheResolveAddress(addr, resa address.Address) {
ss.layers[len(ss.layers)-1].resolveCache[addr] = resa
ss.lastMaybeNonEmptyResolveCache = len(ss.layers) - 1
}
func (ss *stateSnaps) getActor(addr address.Address) (*types.Actor, error) {
@@ -174,15 +160,13 @@ func NewStateTree(cst cbor.IpldStore, ver types.StateTreeVersion) (*StateTree, e
return nil, err
}
s := &StateTree{
return &StateTree{
root: root,
info: info,
version: ver,
Store: cst,
snaps: newStateSnaps(),
}
s.lookupIDFun = s.lookupIDinternal
return s, nil
}, nil
}
func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
@@ -206,15 +190,13 @@ func LoadStateTree(cst cbor.IpldStore, c cid.Cid) (*StateTree, error) {
return nil, err
}
s := &StateTree{
return &StateTree{
root: nd,
info: root.Info,
version: root.Version,
Store: cst,
snaps: newStateSnaps(),
}
s.lookupIDFun = s.lookupIDinternal
return s, nil
}, nil
default:
return nil, xerrors.Errorf("unsupported state tree version: %d", root.Version)
}
@@ -231,7 +213,17 @@ func (st *StateTree) SetActor(addr address.Address, act *types.Actor) error {
return nil
}
func (st *StateTree) lookupIDinternal(addr address.Address) (address.Address, error) {
// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`.
func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
if addr.Protocol() == address.ID {
return addr, nil
}
resa, ok := st.snaps.resolveAddress(addr)
if ok {
return resa, nil
}
act, err := st.GetActor(init_.Address)
if err != nil {
return address.Undef, xerrors.Errorf("getting init actor: %w", err)
@@ -249,23 +241,6 @@ func (st *StateTree) lookupIDinternal(addr address.Address) (address.Address, er
if err != nil {
return address.Undef, xerrors.Errorf("resolve address %s: %w", addr, err)
}
return a, err
}
// LookupID gets the ID address of this actor's `addr` stored in the `InitActor`.
func (st *StateTree) LookupID(addr address.Address) (address.Address, error) {
if addr.Protocol() == address.ID {
return addr, nil
}
resa, ok := st.snaps.resolveAddress(addr)
if ok {
return resa, nil
}
a, err := st.lookupIDFun(addr)
if err != nil {
return a, err
}
st.snaps.cacheResolveAddress(addr, a)
+14 -111
View File
@@ -10,7 +10,7 @@ import (
address "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/network"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
@@ -18,7 +18,7 @@ import (
func BenchmarkStateTreeSet(b *testing.B) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, types.StateTreeVersion1)
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
b.Fatal(err)
}
@@ -33,8 +33,8 @@ func BenchmarkStateTreeSet(b *testing.B) {
}
err = st.SetActor(a, &types.Actor{
Balance: types.NewInt(1258812523),
Code: builtin2.StorageMinerActorCodeID,
Head: builtin2.AccountActorCodeID,
Code: builtin.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID,
Nonce: uint64(i),
})
if err != nil {
@@ -60,8 +60,8 @@ func BenchmarkStateTreeSetFlush(b *testing.B) {
}
err = st.SetActor(a, &types.Actor{
Balance: types.NewInt(1258812523),
Code: builtin2.StorageMinerActorCodeID,
Head: builtin2.AccountActorCodeID,
Code: builtin.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID,
Nonce: uint64(i),
})
if err != nil {
@@ -73,103 +73,6 @@ func BenchmarkStateTreeSetFlush(b *testing.B) {
}
}
func TestResolveCache(t *testing.T) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
if err != nil {
t.Fatal(err)
}
nonId := address.NewForTestGetter()()
id, _ := address.NewIDAddress(1000)
st.lookupIDFun = func(a address.Address) (address.Address, error) {
if a == nonId {
return id, nil
}
return address.Undef, types.ErrActorNotFound
}
err = st.SetActor(nonId, &types.Actor{Nonce: 1})
if err != nil {
t.Fatal(err)
}
{
err = st.Snapshot(context.TODO())
if err != nil {
t.Fatal(err)
}
act, err := st.GetActor(nonId)
if err != nil {
t.Fatal(err)
}
if act.Nonce != 1 {
t.Fatalf("expected nonce 1, got %d", act.Nonce)
}
err = st.SetActor(nonId, &types.Actor{Nonce: 2})
if err != nil {
t.Fatal(err)
}
act, err = st.GetActor(nonId)
if err != nil {
t.Fatal(err)
}
if act.Nonce != 2 {
t.Fatalf("expected nonce 2, got %d", act.Nonce)
}
if err := st.Revert(); err != nil {
t.Fatal(err)
}
st.ClearSnapshot()
}
act, err := st.GetActor(nonId)
if err != nil {
t.Fatal(err)
}
if act.Nonce != 1 {
t.Fatalf("expected nonce 1, got %d", act.Nonce)
}
{
err = st.Snapshot(context.TODO())
if err != nil {
t.Fatal(err)
}
act, err := st.GetActor(nonId)
if err != nil {
t.Fatal(err)
}
if act.Nonce != 1 {
t.Fatalf("expected nonce 1, got %d", act.Nonce)
}
err = st.SetActor(nonId, &types.Actor{Nonce: 2})
if err != nil {
t.Fatal(err)
}
act, err = st.GetActor(nonId)
if err != nil {
t.Fatal(err)
}
if act.Nonce != 2 {
t.Fatalf("expected nonce 2, got %d", act.Nonce)
}
st.ClearSnapshot()
}
act, err = st.GetActor(nonId)
if err != nil {
t.Fatal(err)
}
if act.Nonce != 2 {
t.Fatalf("expected nonce 2, got %d", act.Nonce)
}
}
func BenchmarkStateTree10kGetActor(b *testing.B) {
cst := cbor.NewMemCborStore()
st, err := NewStateTree(cst, VersionForNetwork(build.NewestNetworkVersion))
@@ -183,8 +86,8 @@ func BenchmarkStateTree10kGetActor(b *testing.B) {
}
err = st.SetActor(a, &types.Actor{
Balance: types.NewInt(1258812523 + uint64(i)),
Code: builtin2.StorageMinerActorCodeID,
Head: builtin2.AccountActorCodeID,
Code: builtin.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID,
Nonce: uint64(i),
})
if err != nil {
@@ -226,8 +129,8 @@ func TestSetCache(t *testing.T) {
act := &types.Actor{
Balance: types.NewInt(0),
Code: builtin2.StorageMinerActorCodeID,
Head: builtin2.AccountActorCodeID,
Code: builtin.StorageMinerActorCodeID,
Head: builtin.AccountActorCodeID,
Nonce: 0,
}
@@ -270,7 +173,7 @@ func TestSnapshots(t *testing.T) {
t.Fatal(err)
}
if err := st.SetActor(addrs[0], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(55)}); err != nil {
if err := st.SetActor(addrs[0], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(55)}); err != nil {
t.Fatal(err)
}
@@ -279,7 +182,7 @@ func TestSnapshots(t *testing.T) {
t.Fatal(err)
}
if err := st.SetActor(addrs[1], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(77)}); err != nil {
if err := st.SetActor(addrs[1], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(77)}); err != nil {
t.Fatal(err)
}
@@ -290,7 +193,7 @@ func TestSnapshots(t *testing.T) {
}
// more operations in top level call...
if err := st.SetActor(addrs[2], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(123)}); err != nil {
if err := st.SetActor(addrs[2], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(123)}); err != nil {
t.Fatal(err)
}
@@ -299,7 +202,7 @@ func TestSnapshots(t *testing.T) {
t.Fatal(err)
}
if err := st.SetActor(addrs[3], &types.Actor{Code: builtin2.AccountActorCodeID, Head: builtin2.AccountActorCodeID, Balance: types.NewInt(5)}); err != nil {
if err := st.SetActor(addrs[3], &types.Actor{Code: builtin.AccountActorCodeID, Head: builtin.AccountActorCodeID, Balance: types.NewInt(5)}); err != nil {
t.Fatal(err)
}
+2 -7
View File
@@ -61,10 +61,9 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
Rand: store.NewChainRand(sm.cs, ts.Cids()),
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetVMCirculatingSupply,
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: types.NewInt(0),
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
vmi, err := sm.newVM(ctx, vmopt)
@@ -114,7 +113,6 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
}
return &api.InvocResult{
MsgCid: msg.Cid(),
Msg: msg,
MsgRct: &ret.MessageReceipt,
ExecutionTrace: ret.ExecutionTrace,
@@ -176,10 +174,9 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetVMCirculatingSupply,
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: ts.Blocks()[0].ParentBaseFee,
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
vmi, err := sm.newVM(ctx, vmopt)
if err != nil {
@@ -231,10 +228,8 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
}
return &api.InvocResult{
MsgCid: msg.Cid(),
Msg: msg,
MsgRct: &ret.MessageReceipt,
GasCost: MakeMsgGasCost(msg, ret),
ExecutionTrace: ret.ExecutionTrace,
Error: errs,
Duration: ret.Duration,
+51 -113
View File
@@ -86,10 +86,6 @@ func DefaultUpgradeSchedule() UpgradeSchedule {
Height: build.UpgradeLiftoffHeight,
Network: network.Version5,
Migration: UpgradeLiftoff,
}, {
Height: build.UpgradeKumquatHeight,
Network: network.Version6,
Migration: nil,
}}
if build.UpgradeActorsV2Height == math.MaxInt64 { // disable actors upgrade
@@ -172,7 +168,7 @@ func (sm *StateManager) hasExpensiveFork(ctx context.Context, height abi.ChainEp
return ok
}
func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmount, cb func(trace types.ExecutionTrace)) error {
func doTransfer(cb ExecCallback, tree types.StateTree, from, to address.Address, amt abi.TokenAmount) error {
fromAct, err := tree.GetActor(from)
if err != nil {
return xerrors.Errorf("failed to get 'from' actor for transfer: %w", err)
@@ -205,6 +201,7 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo
From: from,
To: to,
Value: amt,
Nonce: math.MaxUint64,
}
fakeRct := &types.MessageReceipt{
ExitCode: 0,
@@ -212,14 +209,22 @@ func doTransfer(tree types.StateTree, from, to address.Address, amt abi.TokenAmo
GasUsed: 0,
}
cb(types.ExecutionTrace{
Msg: fakeMsg,
MsgRct: fakeRct,
Error: "",
Duration: 0,
GasCharges: nil,
Subcalls: nil,
})
if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{
MessageReceipt: *fakeRct,
ActorErr: nil,
ExecutionTrace: types.ExecutionTrace{
Msg: fakeMsg,
MsgRct: fakeRct,
Error: "",
Duration: 0,
GasCharges: nil,
Subcalls: nil,
},
Duration: 0,
GasCosts: vm.ZeroGasOutputs(),
}); err != nil {
return xerrors.Errorf("recording transfer: %w", err)
}
}
return nil
@@ -260,6 +265,11 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
return cid.Undef, xerrors.Errorf("loading state tree failed: %w", err)
}
ReserveAddress, err := address.NewFromString("t090")
if err != nil {
return cid.Undef, xerrors.Errorf("failed to parse reserve address: %w", err)
}
tree, err := sm.StateTree(root)
if err != nil {
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
@@ -272,10 +282,6 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
}
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 {
@@ -289,7 +295,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
if !sysAcc {
transfers = append(transfers, transfer{
From: addr,
To: builtin.ReserveAddress,
To: ReserveAddress,
Amt: act.Balance,
})
}
@@ -311,13 +317,11 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
available = st.GetAvailableBalance(act.Balance)
}
if !available.IsZero() {
transfers = append(transfers, transfer{
From: addr,
To: builtin.ReserveAddress,
Amt: available,
})
}
transfers = append(transfers, transfer{
From: addr,
To: ReserveAddress,
Amt: available,
})
}
return nil
})
@@ -327,7 +331,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
// Execute transfers from previous step
for _, t := range transfers {
if err := doTransfer(tree, t.From, t.To, t.Amt, transferCb); err != nil {
if err := doTransfer(cb, tree, t.From, t.To, t.Amt); err != nil {
return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
}
}
@@ -366,7 +370,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
nbalance := big.Min(prevBalance, AccountCap)
if nbalance.Sign() != 0 {
transfersBack = append(transfersBack, transfer{
From: builtin.ReserveAddress,
From: ReserveAddress,
To: addr,
Amt: nbalance,
})
@@ -393,7 +397,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
mfunds := minerFundsAlloc(power, totalPower)
transfersBack = append(transfersBack, transfer{
From: builtin.ReserveAddress,
From: ReserveAddress,
To: minfo.Worker,
Amt: mfunds,
})
@@ -413,7 +417,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
if lbsectors.Length() > 0 {
transfersBack = append(transfersBack, transfer{
From: builtin.ReserveAddress,
From: ReserveAddress,
To: minfo.Worker,
Amt: BaseMinerBalance,
})
@@ -430,7 +434,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
}
for _, t := range transfersBack {
if err := doTransfer(tree, t.From, t.To, t.Amt, transferCb); err != nil {
if err := doTransfer(cb, tree, t.From, t.To, t.Amt); err != nil {
return cid.Undef, xerrors.Errorf("transfer %s %s->%s failed: %w", t.Amt, t.From, t.To, err)
}
}
@@ -440,7 +444,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
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 {
if err := doTransfer(cb, tree, builtin0.BurntFundsActorAddr, ReserveAddress, burntAct.Balance); err != nil {
return cid.Undef, xerrors.Errorf("failed to unburn funds: %w", err)
}
@@ -456,7 +460,7 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
}
difference := types.BigSub(DesiredReimbursementBalance, reimb.Balance)
if err := doTransfer(tree, builtin.ReserveAddress, reimbAddr, difference, transferCb); err != nil {
if err := doTransfer(cb, tree, ReserveAddress, reimbAddr, difference); err != nil {
return cid.Undef, xerrors.Errorf("failed to top up reimbursement account: %w", err)
}
@@ -475,39 +479,6 @@ func UpgradeFaucetBurnRecovery(ctx context.Context, sm *StateManager, cb ExecCal
return cid.Undef, xerrors.Errorf("resultant state tree account balance was not correct: %s", total)
}
if cb != nil {
// record the transfer in execution traces
fakeMsg := &types.Message{
From: builtin.SystemActorAddr,
To: builtin.SystemActorAddr,
Value: big.Zero(),
Nonce: uint64(epoch),
}
fakeRct := &types.MessageReceipt{
ExitCode: 0,
Return: nil,
GasUsed: 0,
}
if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{
MessageReceipt: *fakeRct,
ActorErr: nil,
ExecutionTrace: types.ExecutionTrace{
Msg: fakeMsg,
MsgRct: fakeRct,
Error: "",
Duration: 0,
GasCharges: nil,
Subcalls: subcalls,
},
Duration: 0,
GasCosts: nil,
}); err != nil {
return cid.Undef, xerrors.Errorf("recording transfers: %w", err)
}
}
return tree.Flush(ctx)
}
@@ -543,17 +514,17 @@ func UpgradeIgnition(ctx context.Context, sm *StateManager, cb ExecCallback, roo
return cid.Undef, xerrors.Errorf("second split address: %w", err)
}
err = resetGenesisMsigs0(ctx, sm, store, tree, build.UpgradeLiftoffHeight)
err = resetGenesisMsigs(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)
err = splitGenesisMultisig(ctx, cb, split1, store, tree, 50)
if err != nil {
return cid.Undef, xerrors.Errorf("splitting first msig: %w", err)
}
err = splitGenesisMultisig0(ctx, cb, split2, store, tree, 50, epoch)
err = splitGenesisMultisig(ctx, cb, split2, store, tree, 50)
if err != nil {
return cid.Undef, xerrors.Errorf("splitting second msig: %w", err)
}
@@ -574,17 +545,22 @@ func UpgradeRefuel(ctx context.Context, sm *StateManager, cb ExecCallback, root
return cid.Undef, xerrors.Errorf("getting state tree: %w", err)
}
err = resetMultisigVesting0(ctx, store, tree, builtin.SaftAddress, 0, 0, big.Zero())
addr, err := address.NewFromString("t0122")
if err != nil {
return cid.Undef, xerrors.Errorf("getting address: %w", err)
}
err = resetMultisigVesting(ctx, store, tree, addr, 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())
err = resetMultisigVesting(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())
err = resetMultisigVesting(ctx, store, tree, builtin.RootVerifierAddress, 0, 0, big.Zero())
if err != nil {
return cid.Undef, xerrors.Errorf("tweaking msig vesting: %w", err)
}
@@ -679,7 +655,7 @@ func setNetworkName(ctx context.Context, store adt.Store, tree *state.StateTree,
return nil
}
func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64, epoch abi.ChainEpoch) error {
func splitGenesisMultisig(ctx context.Context, cb ExecCallback, addr address.Address, store adt0.Store, tree *state.StateTree, portions uint64) error {
if portions < 1 {
return xerrors.Errorf("cannot split into 0 portions")
}
@@ -748,11 +724,6 @@ func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Ad
}
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 {
@@ -769,46 +740,13 @@ func splitGenesisMultisig0(ctx context.Context, cb ExecCallback, addr address.Ad
return xerrors.Errorf("setting new msig actor state: %w", err)
}
if err := doTransfer(tree, addr, idAddr, newIbal, transferCb); err != nil {
if err := doTransfer(cb, tree, addr, idAddr, newIbal); err != nil {
return xerrors.Errorf("transferring split msig balance: %w", err)
}
i++
}
if cb != nil {
// record the transfer in execution traces
fakeMsg := &types.Message{
From: builtin.SystemActorAddr,
To: addr,
Value: big.Zero(),
Nonce: uint64(epoch),
}
fakeRct := &types.MessageReceipt{
ExitCode: 0,
Return: nil,
GasUsed: 0,
}
if err := cb(fakeMsg.Cid(), fakeMsg, &vm.ApplyRet{
MessageReceipt: *fakeRct,
ActorErr: nil,
ExecutionTrace: types.ExecutionTrace{
Msg: fakeMsg,
MsgRct: fakeRct,
Error: "",
Duration: 0,
GasCharges: nil,
Subcalls: subcalls,
},
Duration: 0,
GasCosts: nil,
}); err != nil {
return xerrors.Errorf("recording transfers: %w", err)
}
}
return nil
}
@@ -835,7 +773,7 @@ func makeKeyAddr(splitAddr address.Address, count uint64) (address.Address, erro
}
// 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 {
func resetGenesisMsigs(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)
@@ -885,7 +823,7 @@ func resetGenesisMsigs0(ctx context.Context, sm *StateManager, store adt0.Store,
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 {
func resetMultisigVesting(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)
+13 -14
View File
@@ -16,15 +16,14 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/cbor"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
init2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/init"
rt2 "github.com/filecoin-project/specs-actors/v2/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/builtin"
init0 "github.com/filecoin-project/specs-actors/actors/builtin/init"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/gen"
. "github.com/filecoin-project/lotus/chain/stmgr"
@@ -46,7 +45,7 @@ type testActor struct {
}
// must use existing actor that an account is allowed to exec.
func (testActor) Code() cid.Cid { return builtin0.PaymentChannelActorCodeID }
func (testActor) Code() cid.Cid { return builtin.PaymentChannelActorCodeID }
func (testActor) State() cbor.Er { return new(testActorState) }
type testActorState struct {
@@ -76,7 +75,7 @@ func (ta testActor) Exports() []interface{} {
}
}
func (ta *testActor) Constructor(rt rt2.Runtime, params *abi.EmptyValue) *abi.EmptyValue {
func (ta *testActor) Constructor(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue {
rt.ValidateImmediateCallerAcceptAny()
rt.StateCreate(&testActorState{11})
//fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Receiver())
@@ -84,7 +83,7 @@ func (ta *testActor) Constructor(rt rt2.Runtime, params *abi.EmptyValue) *abi.Em
return abi.Empty
}
func (ta *testActor) TestMethod(rt rt2.Runtime, params *abi.EmptyValue) *abi.EmptyValue {
func (ta *testActor) TestMethod(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue {
rt.ValidateImmediateCallerAcceptAny()
var st testActorState
rt.StateReadonly(&st)
@@ -176,15 +175,15 @@ func TestForkHeightTriggers(t *testing.T) {
var msgs []*types.SignedMessage
enc, err := actors.SerializeParams(&init2.ExecParams{CodeCID: (testActor{}).Code()})
enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()})
if err != nil {
t.Fatal(err)
}
m := &types.Message{
From: cg.Banker(),
To: _init.Address,
Method: _init.Methods.Exec,
To: lotusinit.Address,
Method: builtin.MethodsInit.Exec,
Params: enc,
GasLimit: types.TestGasLimit,
}
@@ -274,15 +273,15 @@ func TestForkRefuseCall(t *testing.T) {
cg.SetStateManager(sm)
enc, err := actors.SerializeParams(&init2.ExecParams{CodeCID: (testActor{}).Code()})
enc, err := actors.SerializeParams(&init0.ExecParams{CodeCID: (testActor{}).Code()})
if err != nil {
t.Fatal(err)
}
m := &types.Message{
From: cg.Banker(),
To: _init.Address,
Method: _init.Methods.Exec,
To: lotusinit.Address,
Method: builtin.MethodsInit.Exec,
Params: enc,
GasLimit: types.TestGasLimit,
Value: types.NewInt(0),
+51 -134
View File
@@ -6,6 +6,11 @@ import (
"fmt"
"sync"
"github.com/filecoin-project/lotus/chain/actors/builtin"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
@@ -18,23 +23,15 @@ import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network"
// Used for genesis.
msig0 "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/builtin/cron"
_init "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/actors/builtin/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/multisig"
"github.com/filecoin-project/lotus/chain/actors/builtin/paych"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
@@ -46,8 +43,6 @@ const LookbackNoLimit = abi.ChainEpoch(-1)
var log = logging.Logger("statemgr")
type StateManagerAPI interface {
Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error)
GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error)
LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error)
LookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error)
ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error)
@@ -200,7 +195,6 @@ func (sm *StateManager) TipSetState(ctx context.Context, ts *types.TipSet) (st c
func traceFunc(trace *[]*api.InvocResult) func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
return func(mcid cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
ir := &api.InvocResult{
MsgCid: mcid,
Msg: msg,
MsgRct: &ret.MessageReceipt,
ExecutionTrace: ret.ExecutionTrace,
@@ -209,9 +203,6 @@ func traceFunc(trace *[]*api.InvocResult) func(mcid cid.Cid, msg *types.Message,
if ret.ActorErr != nil {
ir.Error = ret.ActorErr.Error()
}
if ret.GasCosts != nil {
ir.GasCost = MakeMsgGasCost(msg, ret)
}
*trace = append(*trace, ir)
return nil
}
@@ -238,10 +229,9 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetVMCirculatingSupply,
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: baseFee,
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
return sm.newVM(ctx, vmopt)
@@ -252,17 +242,22 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
}
runCron := func(epoch abi.ChainEpoch) error {
runCron := func() error {
// TODO: this nonce-getting is a tiny bit ugly
ca, err := vmi.StateTree().GetActor(builtin0.SystemActorAddr)
if err != nil {
return err
}
cronMsg := &types.Message{
To: cron.Address,
From: builtin.SystemActorAddr,
Nonce: uint64(epoch),
To: builtin0.CronActorAddr,
From: builtin0.SystemActorAddr,
Nonce: ca.Nonce,
Value: types.NewInt(0),
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little
Method: cron.Methods.EpochTick,
Method: builtin0.MethodsCron.EpochTick,
Params: nil,
}
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
@@ -284,7 +279,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
for i := parentEpoch; i < epoch; i++ {
if i > parentEpoch {
// run cron for null rounds if any
if err := runCron(i); err != nil {
if err := runCron(); err != nil {
return cid.Undef, cid.Undef, err
}
@@ -313,7 +308,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
}
var receipts []cbg.CBORMarshaler
processedMsgs := make(map[cid.Cid]struct{})
processedMsgs := map[cid.Cid]bool{}
for _, b := range bms {
penalty := types.NewInt(0)
gasReward := big.Zero()
@@ -337,7 +332,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
return cid.Undef, cid.Undef, err
}
}
processedMsgs[m.Cid()] = struct{}{}
processedMsgs[m.Cid()] = true
}
params, err := actors.SerializeParams(&reward.AwardBlockRewardParams{
@@ -350,15 +345,20 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
return cid.Undef, cid.Undef, xerrors.Errorf("failed to serialize award params: %w", err)
}
sysAct, actErr := vmi.StateTree().GetActor(builtin0.SystemActorAddr)
if actErr != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("failed to get system actor: %w", actErr)
}
rwMsg := &types.Message{
From: builtin.SystemActorAddr,
From: builtin0.SystemActorAddr,
To: reward.Address,
Nonce: uint64(epoch),
Nonce: sysAct.Nonce,
Value: types.NewInt(0),
GasFeeCap: types.NewInt(0),
GasPremium: types.NewInt(0),
GasLimit: 1 << 30,
Method: reward.Methods.AwardBlockReward,
Method: builtin0.MethodsReward.AwardBlockReward,
Params: params,
}
ret, actErr := vmi.ApplyImplicitMessage(ctx, rwMsg)
@@ -376,7 +376,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
}
}
if err := runCron(epoch); err != nil {
if err := runCron(); err != nil {
return cid.Cid{}, cid.Cid{}, err
}
@@ -430,7 +430,12 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, ts *types.TipSet
parentEpoch = parent.Height
}
r := store.NewChainRand(sm.cs, ts.Cids())
cids := make([]cid.Cid, len(blks))
for i, v := range blks {
cids[i] = v.Cid()
}
r := store.NewChainRand(sm.cs, cids)
blkmsgs, err := sm.cs.BlockMsgsForTipset(ts)
if err != nil {
@@ -728,7 +733,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
}
if r != nil {
return cur, r, foundMsg, nil
return pts, r, foundMsg, nil
}
}
@@ -975,7 +980,7 @@ func (sm *StateManager) setupGenesisActors(ctx context.Context) error {
} else if builtin.IsAccountActor(act.Code) {
// should exclude burnt funds actor and "remainder account actor"
// should only ever be "faucet" accounts in testnets
if kaddr == builtin.BurntFundsActorAddr {
if kaddr == builtin0.BurntFundsActorAddr {
return nil
}
@@ -1053,24 +1058,24 @@ func (sm *StateManager) setupPreIgnitionGenesisActorsTestnet(ctx context.Context
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
// 6 months
sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay)
totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
// 1 year
oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay)
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years
sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay)
sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay)
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
@@ -1130,24 +1135,24 @@ func (sm *StateManager) setupPostIgnitionGenesisActors(ctx context.Context) erro
totalsByEpoch := make(map[abi.ChainEpoch]abi.TokenAmount)
// 6 months
sixMonths := abi.ChainEpoch(183 * builtin.EpochsInDay)
sixMonths := abi.ChainEpoch(183 * builtin0.EpochsInDay)
totalsByEpoch[sixMonths] = big.NewInt(49_929_341)
totalsByEpoch[sixMonths] = big.Add(totalsByEpoch[sixMonths], big.NewInt(32_787_700))
// 1 year
oneYear := abi.ChainEpoch(365 * builtin.EpochsInDay)
oneYear := abi.ChainEpoch(365 * builtin0.EpochsInDay)
totalsByEpoch[oneYear] = big.NewInt(22_421_712)
// 2 years
twoYears := abi.ChainEpoch(2 * 365 * builtin.EpochsInDay)
twoYears := abi.ChainEpoch(2 * 365 * builtin0.EpochsInDay)
totalsByEpoch[twoYears] = big.NewInt(7_223_364)
// 3 years
threeYears := abi.ChainEpoch(3 * 365 * builtin.EpochsInDay)
threeYears := abi.ChainEpoch(3 * 365 * builtin0.EpochsInDay)
totalsByEpoch[threeYears] = big.NewInt(87_637_883)
// 6 years
sixYears := abi.ChainEpoch(6 * 365 * builtin.EpochsInDay)
sixYears := abi.ChainEpoch(6 * 365 * builtin0.EpochsInDay)
totalsByEpoch[sixYears] = big.NewInt(100_000_000)
totalsByEpoch[sixYears] = big.Add(totalsByEpoch[sixYears], big.NewInt(300_000_000))
@@ -1281,7 +1286,7 @@ func (sm *StateManager) GetFilLocked(ctx context.Context, st *state.StateTree) (
}
func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, error) {
burnt, err := st.GetActor(builtin.BurntFundsActorAddr)
burnt, err := st.GetActor(builtin0.BurntFundsActorAddr)
if err != nil {
return big.Zero(), xerrors.Errorf("failed to load burnt actor: %w", err)
}
@@ -1289,16 +1294,7 @@ func GetFilBurnt(ctx context.Context, st *state.StateTree) (abi.TokenAmount, err
return burnt.Balance, nil
}
func (sm *StateManager) GetVMCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
cs, err := sm.GetVMCirculatingSupplyDetailed(ctx, height, st)
if err != nil {
return types.EmptyInt, err
}
return cs.FilCirculating, err
}
func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
func (sm *StateManager) GetCirculatingSupplyDetailed(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (api.CirculatingSupply, error) {
sm.genesisMsigLk.Lock()
defer sm.genesisMsigLk.Unlock()
if sm.preIgnitionGenInfos == nil {
@@ -1361,91 +1357,12 @@ func (sm *StateManager) GetVMCirculatingSupplyDetailed(ctx context.Context, heig
}
func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.ChainEpoch, st *state.StateTree) (abi.TokenAmount, error) {
circ := big.Zero()
unCirc := big.Zero()
err := st.ForEach(func(a address.Address, actor *types.Actor) error {
switch {
case actor.Balance.IsZero():
// Do nothing for zero-balance actors
break
case a == _init.Address ||
a == reward.Address ||
a == verifreg.Address ||
// The power actor itself should never receive funds
a == power.Address ||
a == builtin.SystemActorAddr ||
a == builtin.CronActorAddr ||
a == builtin.BurntFundsActorAddr ||
a == builtin.SaftAddress ||
a == builtin.ReserveAddress:
unCirc = big.Add(unCirc, actor.Balance)
case a == market.Address:
mst, err := market.Load(sm.cs.Store(ctx), actor)
if err != nil {
return err
}
lb, err := mst.TotalLocked()
if err != nil {
return err
}
circ = big.Add(circ, big.Sub(actor.Balance, lb))
unCirc = big.Add(unCirc, lb)
case builtin.IsAccountActor(actor.Code) || builtin.IsPaymentChannelActor(actor.Code):
circ = big.Add(circ, actor.Balance)
case builtin.IsStorageMinerActor(actor.Code):
mst, err := miner.Load(sm.cs.Store(ctx), actor)
if err != nil {
return err
}
ab, err := mst.AvailableBalance(actor.Balance)
if err == nil {
circ = big.Add(circ, ab)
unCirc = big.Add(unCirc, big.Sub(actor.Balance, ab))
} else {
// Assume any error is because the miner state is "broken" (lower actor balance than locked funds)
// In this case, the actor's entire balance is considered "uncirculating"
unCirc = big.Add(unCirc, actor.Balance)
}
case builtin.IsMultisigActor(actor.Code):
mst, err := multisig.Load(sm.cs.Store(ctx), actor)
if err != nil {
return err
}
lb, err := mst.LockedBalance(height)
if err != nil {
return err
}
ab := big.Sub(actor.Balance, lb)
circ = big.Add(circ, big.Max(ab, big.Zero()))
unCirc = big.Add(unCirc, big.Min(actor.Balance, lb))
default:
return xerrors.Errorf("unexpected actor: %s", a)
}
return nil
})
csi, err := sm.GetCirculatingSupplyDetailed(ctx, height, st)
if err != nil {
return types.EmptyInt, err
return big.Zero(), err
}
total := big.Add(circ, unCirc)
if !total.Equals(types.TotalFilecoinInt) {
return types.EmptyInt, xerrors.Errorf("total filecoin didn't add to expected amount: %s != %s", total, types.TotalFilecoinInt)
}
return circ, nil
return csi.FilCirculating, nil
}
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
+44 -73
View File
@@ -12,6 +12,7 @@ import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors/policy"
cid "github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
@@ -23,16 +24,16 @@ import (
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/rt"
builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
exported0 "github.com/filecoin-project/specs-actors/actors/builtin/exported"
proof0 "github.com/filecoin-project/specs-actors/actors/runtime/proof"
exported2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/exported"
"github.com/filecoin-project/lotus/api"
"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/market"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/store"
@@ -158,7 +159,7 @@ func GetMinerSectorSet(ctx context.Context, sm *StateManager, ts *types.TipSet,
return mas.LoadSectors(snos)
}
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]builtin.SectorInfo, error) {
func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *StateManager, st cid.Cid, maddr address.Address, rand abi.PoStRandomness) ([]proof0.SectorInfo, error) {
act, err := sm.LoadActorRaw(ctx, maddr, st)
if err != nil {
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
@@ -243,9 +244,9 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return nil, xerrors.Errorf("loading proving sectors: %w", err)
}
out := make([]builtin.SectorInfo, len(sectors))
out := make([]proof0.SectorInfo, len(sectors))
for i, sinfo := range sectors {
out[i] = builtin.SectorInfo{
out[i] = proof0.SectorInfo{
SealProof: spt,
SectorNumber: sinfo.SectorNumber,
SealedCID: sinfo.SealedCID,
@@ -255,6 +256,25 @@ func GetSectorsForWinningPoSt(ctx context.Context, pv ffiwrapper.Verifier, sm *S
return out, nil
}
func StateMinerInfo(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (*miner.MinerInfo, error) {
act, err := sm.LoadActor(ctx, maddr, ts)
if err != nil {
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
}
mas, err := miner.Load(sm.cs.Store(ctx), act)
if err != nil {
return nil, xerrors.Errorf("failed to load miner actor state: %w", err)
}
mi, err := mas.Info()
if err != nil {
return nil, err
}
return &mi, err
}
func GetMinerSlashed(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (bool, error) {
act, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil {
@@ -363,10 +383,9 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
Rand: r,
Bstore: sm.cs.Blockstore(),
Syscalls: sm.cs.VMSys(),
CircSupplyCalc: sm.GetVMCirculatingSupply,
CircSupplyCalc: sm.GetCirculatingSupply,
NtwkVersion: sm.GetNtwkVersion,
BaseFee: ts.Blocks()[0].ParentBaseFee,
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
vmi, err := sm.newVM(ctx, vmopt)
if err != nil {
@@ -392,17 +411,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
return root, trace, nil
}
func LookbackStateGetterForTipset(sm *StateManager, ts *types.TipSet) vm.LookbackStateGetter {
return func(ctx context.Context, round abi.ChainEpoch) (*state.StateTree, error) {
_, st, err := GetLookbackTipSetForRound(ctx, sm, ts, round)
if err != nil {
return nil, err
}
return sm.StateTree(st)
}
}
func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, cid.Cid, error) {
func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, error) {
var lbr abi.ChainEpoch
lb := policy.GetWinningPoStSectorSetLookback(sm.GetNtwkVersion(ctx, round))
if round > lb {
@@ -410,33 +419,16 @@ func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.
}
// more null blocks than our lookback
if lbr >= ts.Height() {
// This should never happen at this point, but may happen before
// network version 3 (where the lookback was only 10 blocks).
st, _, err := sm.TipSetState(ctx, ts)
if err != nil {
return nil, cid.Undef, err
}
return ts, st, nil
if lbr > ts.Height() {
return ts, nil
}
// Get the tipset after the lookback tipset, or the next non-null one.
nextTs, err := sm.ChainStore().GetTipsetByHeight(ctx, lbr+1, ts, false)
lbts, err := sm.ChainStore().GetTipsetByHeight(ctx, lbr, ts, true)
if err != nil {
return nil, cid.Undef, xerrors.Errorf("failed to get lookback tipset+1: %w", err)
return nil, xerrors.Errorf("failed to get lookback tipset: %w", err)
}
if lbr > nextTs.Height() {
return nil, cid.Undef, xerrors.Errorf("failed to find non-null tipset %s (%d) which is known to exist, found %s (%d)", ts.Key(), ts.Height(), nextTs.Key(), nextTs.Height())
}
lbts, err := sm.ChainStore().GetTipSetFromKey(nextTs.Parents())
if err != nil {
return nil, cid.Undef, xerrors.Errorf("failed to resolve lookback tipset: %w", err)
}
return lbts, nextTs.ParentState(), nil
return lbts, nil
}
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) {
@@ -464,20 +456,17 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
rbase = entries[len(entries)-1]
}
lbts, lbst, err := GetLookbackTipSetForRound(ctx, sm, ts, round)
lbts, err := GetLookbackTipSetForRound(ctx, sm, ts, round)
if err != nil {
return nil, xerrors.Errorf("getting lookback miner actor state: %w", err)
}
act, err := sm.LoadActorRaw(ctx, maddr, lbst)
if xerrors.Is(err, types.ErrActorNotFound) {
_, err := sm.LoadActor(ctx, maddr, ts)
if err != nil {
return nil, xerrors.Errorf("loading miner in current state: %w", err)
}
return nil, nil
lbst, _, err := sm.TipSetState(ctx, lbts)
if err != nil {
return nil, err
}
act, err := sm.LoadActorRaw(ctx, maddr, lbst)
if err != nil {
return nil, xerrors.Errorf("failed to load miner actor: %w", err)
}
@@ -559,7 +548,8 @@ func init() {
methods := make(map[abi.MethodNum]MethodMeta, len(exports))
// Explicitly add send, it's special.
methods[builtin.MethodSend] = MethodMeta{
// Note that builtin2.MethodSend = builtin0.MethodSend = 0.
methods[builtin0.MethodSend] = MethodMeta{
Name: "Send",
Params: reflect.TypeOf(new(abi.EmptyValue)),
Ret: reflect.TypeOf(new(abi.EmptyValue)),
@@ -583,9 +573,11 @@ func init() {
fnName = strings.TrimSuffix(fnName[strings.LastIndexByte(fnName, '.')+1:], "-fm")
switch abi.MethodNum(number) {
case builtin.MethodSend:
case builtin0.MethodSend:
// Note that builtin2.MethodSend = builtin0.MethodSend = 0.
panic("method 0 is reserved for Send")
case builtin.MethodConstructor:
case builtin0.MethodConstructor:
// Note that builtin2.MethodConstructor = builtin0.MethodConstructor = 1.
if fnName != "Constructor" {
panic("method 1 is reserved for Constructor")
}
@@ -614,14 +606,6 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
return reflect.New(m.Ret.Elem()).Interface().(cbg.CBORUnmarshaler), nil
}
func GetParamType(actCode cid.Cid, method abi.MethodNum) (cbg.CBORUnmarshaler, error) {
m, found := MethodsMap[actCode][method]
if !found {
return nil, fmt.Errorf("unknown method %d for actor %s", method, actCode)
}
return reflect.New(m.Params.Elem()).Interface().(cbg.CBORUnmarshaler), nil
}
func minerHasMinPower(ctx context.Context, sm *StateManager, addr address.Address, ts *types.TipSet) (bool, error) {
pact, err := sm.LoadActor(ctx, power.Address, ts)
if err != nil {
@@ -717,16 +701,3 @@ func CheckTotalFIL(ctx context.Context, sm *StateManager, ts *types.TipSet) (abi
return sum, nil
}
func MakeMsgGasCost(msg *types.Message, ret *vm.ApplyRet) api.MsgGasCost {
return api.MsgGasCost{
Message: msg.Cid(),
GasUsed: big.NewInt(ret.GasUsed),
BaseFeeBurn: ret.GasCosts.BaseFeeBurn,
OverEstimationBurn: ret.GasCosts.OverEstimationBurn,
MinerPenalty: ret.GasCosts.MinerPenalty,
MinerTip: ret.GasCosts.MinerTip,
Refund: ret.GasCosts.Refund,
TotalCost: big.Sub(msg.RequiredFunds(), ret.GasCosts.Refund),
}
}
-214
View File
@@ -1,214 +0,0 @@
package store
import (
"context"
"time"
"github.com/filecoin-project/lotus/chain/types"
)
// WrapHeadChangeCoalescer wraps a ReorgNotifee with a head change coalescer.
// minDelay is the minimum coalesce delay; when a head change is first received, the coalescer will
// wait for that long to coalesce more head changes.
// maxDelay is the maximum coalesce delay; the coalescer will not delay delivery of a head change
// more than that.
// mergeInterval is the interval that triggers additional coalesce delay; if the last head change was
// within the merge interval when the coalesce timer fires, then the coalesce time is extended
// by min delay and up to max delay total.
func WrapHeadChangeCoalescer(fn ReorgNotifee, minDelay, maxDelay, mergeInterval time.Duration) ReorgNotifee {
c := NewHeadChangeCoalescer(fn, minDelay, maxDelay, mergeInterval)
return c.HeadChange
}
// HeadChangeCoalescer is a stateful reorg notifee which coalesces incoming head changes
// with pending head changes to reduce state computations from head change notifications.
type HeadChangeCoalescer struct {
notify ReorgNotifee
ctx context.Context
cancel func()
eventq chan headChange
revert []*types.TipSet
apply []*types.TipSet
}
type headChange struct {
revert, apply []*types.TipSet
}
// NewHeadChangeCoalescer creates a HeadChangeCoalescer.
func NewHeadChangeCoalescer(fn ReorgNotifee, minDelay, maxDelay, mergeInterval time.Duration) *HeadChangeCoalescer {
ctx, cancel := context.WithCancel(context.Background())
c := &HeadChangeCoalescer{
notify: fn,
ctx: ctx,
cancel: cancel,
eventq: make(chan headChange),
}
go c.background(minDelay, maxDelay, mergeInterval)
return c
}
// HeadChange is the ReorgNotifee callback for the stateful coalescer; it receives an incoming
// head change and schedules dispatch of a coalesced head change in the background.
func (c *HeadChangeCoalescer) HeadChange(revert, apply []*types.TipSet) error {
select {
case c.eventq <- headChange{revert: revert, apply: apply}:
return nil
case <-c.ctx.Done():
return c.ctx.Err()
}
}
// Close closes the coalescer and cancels the background dispatch goroutine.
// Any further notification will result in an error.
func (c *HeadChangeCoalescer) Close() error {
select {
case <-c.ctx.Done():
default:
c.cancel()
}
return nil
}
// Implementation details
func (c *HeadChangeCoalescer) background(minDelay, maxDelay, mergeInterval time.Duration) {
var timerC <-chan time.Time
var first, last time.Time
for {
select {
case evt := <-c.eventq:
c.coalesce(evt.revert, evt.apply)
now := time.Now()
last = now
if first.IsZero() {
first = now
}
if timerC == nil {
timerC = time.After(minDelay)
}
case now := <-timerC:
sinceFirst := now.Sub(first)
sinceLast := now.Sub(last)
if sinceLast < mergeInterval && sinceFirst < maxDelay {
// coalesce some more
maxWait := maxDelay - sinceFirst
wait := minDelay
if maxWait < wait {
wait = maxWait
}
timerC = time.After(wait)
} else {
// dispatch
c.dispatch()
first = time.Time{}
last = time.Time{}
timerC = nil
}
case <-c.ctx.Done():
if c.revert != nil || c.apply != nil {
c.dispatch()
}
return
}
}
}
func (c *HeadChangeCoalescer) coalesce(revert, apply []*types.TipSet) {
// newly reverted tipsets cancel out with pending applys.
// similarly, newly applied tipsets cancel out with pending reverts.
// pending tipsets
pendRevert := make(map[types.TipSetKey]struct{}, len(c.revert))
for _, ts := range c.revert {
pendRevert[ts.Key()] = struct{}{}
}
pendApply := make(map[types.TipSetKey]struct{}, len(c.apply))
for _, ts := range c.apply {
pendApply[ts.Key()] = struct{}{}
}
// incoming tipsets
reverting := make(map[types.TipSetKey]struct{}, len(revert))
for _, ts := range revert {
reverting[ts.Key()] = struct{}{}
}
applying := make(map[types.TipSetKey]struct{}, len(apply))
for _, ts := range apply {
applying[ts.Key()] = struct{}{}
}
// coalesced revert set
// - pending reverts are cancelled by incoming applys
// - incoming reverts are cancelled by pending applys
newRevert := make([]*types.TipSet, 0, len(c.revert)+len(revert))
for _, ts := range c.revert {
_, cancel := applying[ts.Key()]
if cancel {
continue
}
newRevert = append(newRevert, ts)
}
for _, ts := range revert {
_, cancel := pendApply[ts.Key()]
if cancel {
continue
}
newRevert = append(newRevert, ts)
}
// coalesced apply set
// - pending applys are cancelled by incoming reverts
// - incoming applys are cancelled by pending reverts
newApply := make([]*types.TipSet, 0, len(c.apply)+len(apply))
for _, ts := range c.apply {
_, cancel := reverting[ts.Key()]
if cancel {
continue
}
newApply = append(newApply, ts)
}
for _, ts := range apply {
_, cancel := pendRevert[ts.Key()]
if cancel {
continue
}
newApply = append(newApply, ts)
}
// commit the coalesced sets
c.revert = newRevert
c.apply = newApply
}
func (c *HeadChangeCoalescer) dispatch() {
err := c.notify(c.revert, c.apply)
if err != nil {
log.Errorf("error dispatching coalesced head change notification: %s", err)
}
c.revert = nil
c.apply = nil
}
-72
View File
@@ -1,72 +0,0 @@
package store
import (
"testing"
"time"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/mock"
)
func TestHeadChangeCoalescer(t *testing.T) {
notif := make(chan headChange, 1)
c := NewHeadChangeCoalescer(func(revert, apply []*types.TipSet) error {
notif <- headChange{apply: apply, revert: revert}
return nil
},
100*time.Millisecond,
200*time.Millisecond,
10*time.Millisecond,
)
defer c.Close() //nolint
b0 := mock.MkBlock(nil, 0, 0)
root := mock.TipSet(b0)
bA := mock.MkBlock(root, 1, 1)
tA := mock.TipSet(bA)
bB := mock.MkBlock(root, 1, 2)
tB := mock.TipSet(bB)
tAB := mock.TipSet(bA, bB)
bC := mock.MkBlock(root, 1, 3)
tABC := mock.TipSet(bA, bB, bC)
bD := mock.MkBlock(root, 1, 4)
tABCD := mock.TipSet(bA, bB, bC, bD)
bE := mock.MkBlock(root, 1, 5)
tABCDE := mock.TipSet(bA, bB, bC, bD, bE)
c.HeadChange(nil, []*types.TipSet{tA}) //nolint
c.HeadChange(nil, []*types.TipSet{tB}) //nolint
c.HeadChange([]*types.TipSet{tA, tB}, []*types.TipSet{tAB}) //nolint
c.HeadChange([]*types.TipSet{tAB}, []*types.TipSet{tABC}) //nolint
change := <-notif
if len(change.revert) != 0 {
t.Fatalf("expected empty revert set but got %d elements", len(change.revert))
}
if len(change.apply) != 1 {
t.Fatalf("expected single element apply set but got %d elements", len(change.apply))
}
if change.apply[0] != tABC {
t.Fatalf("expected to apply tABC")
}
c.HeadChange([]*types.TipSet{tABC}, []*types.TipSet{tABCD}) //nolint
c.HeadChange([]*types.TipSet{tABCD}, []*types.TipSet{tABCDE}) //nolint
change = <-notif
if len(change.revert) != 1 {
t.Fatalf("expected single element revert set but got %d elements", len(change.revert))
}
if change.revert[0] != tABC {
t.Fatalf("expected to revert tABC")
}
if len(change.apply) != 1 {
t.Fatalf("expected single element apply set but got %d elements", len(change.apply))
}
if change.apply[0] != tABCDE {
t.Fatalf("expected to revert tABC")
}
}

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